From 59715d67be598352ad057d3c0bc09ebc0b81d8f0 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Tue, 4 Nov 2014 00:43:01 +0100
Subject: [PATCH] arand use tclap

---
 arand2/src/arand.cpp | 167 ++++++++++++++-----------------------------
 1 file changed, 52 insertions(+), 115 deletions(-)

diff --git a/arand2/src/arand.cpp b/arand2/src/arand.cpp
index 316e99a031..1096b6a6f9 100644
--- a/arand2/src/arand.cpp
+++ b/arand2/src/arand.cpp
@@ -2,15 +2,10 @@
  * arand.cpp
  *
  *  Created on: 26. 3. 2014
- *	  Author: tomas
+ *	  Author: Tomas Pecka
  */
 
-#include <iostream>
-#include <cstdlib>
-#include <climits>
-#include <cfloat>
-#include <getopt.h>
-#include <cstring>
+#include <tclap/CmdLine.h>
 
 #include <automaton/FSM/NFA.h>
 #include <regexp/unbounded/UnboundedRegExp.h>
@@ -18,130 +13,72 @@
 #include "automaton/generate/RandomAutomatonFactory.h"
 #include "regexp/generate/RandomRegExpFactory.h"
 
-void help( void )
-{
-	std::cout << "arand" << std::endl;
-	std::cout << "Generates random automaton." << std::endl;
-	std::cout << "Usage: arand -t type -n=N -d=D -a=A" << std::endl << std::endl;
-	std::cout << "  -t, --type FSM/RE. " << std::endl;
-	std::cout << "  -n, --nodes=N \t Number of nodes of automata." << std::endl;
-	std::cout << "  -d, --density=D \t Percentage of transitions to generate. 1.0 = automata graph is tree, 100.0 = every possible transition." << std::endl;
-	std::cout << "  -l, --leafNodes=N \t Number of leaf nodes of regexp." << std::endl;
-	std::cout << "  -h, --height=N \t Height of regexp." << std::endl;
-	std::cout << "  -a, --alphabet=A \t Alphabet size." << std::endl;
-}
-
-
-int main(int argc, char* argv[])
-{
-	static struct option long_options[] = {
-	  // common
-	  {"help",		no_argument,		NULL,	'h'},
-	  {"alphabet",		required_argument,	NULL,	'a' },
-	  {"type",		required_argument,	NULL,	't'},
+int main(int argc, char* argv[]) {
+	try {
+		TCLAP::CmdLine cmd("Random generator binary", ' ', "0.01");
 
-	  // automaton options
-	  {"density",		required_argument,	NULL,	'd' },
-	  {"nodes",		required_argument,	NULL,	'n' },
+		std::vector<std::string> allowed;
+		allowed.push_back("FSM");
+		allowed.push_back("RE");
+		TCLAP::ValuesConstraint<std::string> allowedVals( allowed );
 
-	  // automaton options
-	  {"leafNodes",		required_argument,	NULL,	'l' },
-	  {"height",		required_argument,	NULL,	'h' },
+		TCLAP::ValueArg<std::string> type(	"t",	"type",		"Type of generated structure",		true,	"FSM",	&allowedVals);
+		cmd.add( type );
 
-	  // common options
-	  {0,			0,			0,	'\0'}
-	};
+		TCLAP::ValueArg<int> alphabetSize(	"a",	"alphabetSize",	"Alphabet size",			false,	3,	"integer");
+		cmd.add( alphabetSize );
 
-	int long_index = 0, opt = 0;
+		TCLAP::ValueArg<double> density(	"d",	"density",	"Automaton's transition density",	false,	10,	"double");
+		cmd.add( density );
 
-	// string type;
-	int statesCount = INT_MAX, alphabetSize = INT_MAX, leafNodes = INT_MAX, height = INT_MAX;
-	double density = DBL_MAX;
-	std::string type;
+		TCLAP::ValueArg<int> nodes(		"n",	"nodes",	"Number of automaton's nodes",		false,	5,	"integer");
+		cmd.add( nodes );
 
-	while( ( opt = getopt_long( argc, argv,"a:t:d:n:l:h:", long_options, & long_index ) )  != -1 )
-	{
-		switch( opt )
-		{
+		TCLAP::ValueArg<int> leafNodes(		"l",	"leafNodes",	"Number of regexp's leaf nodes",	false,	5,	"integer");
+		cmd.add( leafNodes );
 
-		case 't':
-			type.assign( optarg, strlen( optarg ) );
-			break;
+		TCLAP::ValueArg<int> depth(		"e",	"depth",	"Depth of the regexp",			false,	5,	"integer");
+		cmd.add( depth );
 
-		case 'n':
-			statesCount = std::stoi( optarg, nullptr, 10 );
-			break;
+		cmd.parse(argc,argv);
 
-		case 'd':
-			density = std::stod( optarg, nullptr );
-			break;
+		if(!type.isSet()) throw exception::AlibException("Type is not defined.");
+		if( type.getValue() == "FSM" ) {
 
-		case 'l':
-			leafNodes = std::stoi( optarg, nullptr, 10 );
-			break;
+			if(!density.isSet()) throw exception::AlibException("Density is not defined.");
+			if( density.getValue() < 1 || density.getValue() > 100 )
+			{
+				//TODO: floating point arithmetic
+				throw exception::AlibException("You must specify density as a number between 1 and 100.");
+				return 1;
+			}
 
-		case 'h':
-			height = std::stod( optarg, nullptr );
-			break;
+			if(!nodes.isSet()) throw exception::AlibException("Number of nodes is not defined.");
+			if(!alphabetSize.isSet()) throw exception::AlibException("Alphabet size is not defined.");
 
-		case 'a':
-			alphabetSize = std::stoi( optarg, nullptr, 10 );
-			break;
+			automaton::NFA res = automaton::generate::RandomAutomatonFactory::generateNFA( nodes.getValue(), alphabetSize.getValue(), density.getValue() );
+			alib::DataFactory::toStdout(res);
+		} else if( type.getValue() == "RE" ) {
 
-		case 'v':
-		default:
-			help( );
-			return 0;
-		}
-	}
+			if(!depth.isSet()) throw exception::AlibException("Depth is not defined.");
 
-	if( type == "FSM" ) {
-
-		if( density < 1 || density > 100 )
-		{
-			//TODO: floating point arithmetic
-			std::cerr << "You must specify density as a number between 1 and 100." << std::endl;
-			return 1;
-		}
-
-		if( statesCount == INT_MAX )
-		{
-			std::cerr << "You must specify number of states." << std::endl;
-			return 1;
-		}
+			if(!leafNodes.isSet()) throw exception::AlibException("Number of leaf nodes is not defined.");
+			if(!alphabetSize.isSet()) throw exception::AlibException("Alphabet size is not defined.");
 
-		if( alphabetSize == INT_MAX )
-		{
-			std::cerr << "You must specify alphabet or at least its size." << std::endl;
-			return 1;
+			regexp::UnboundedRegExp res = regexp::generate::RandomRegExpFactory::generateUnboundedRegExp(leafNodes.getValue(), depth.getValue(), alphabetSize.getValue() );
+			alib::DataFactory::toStdout(res);
+		} else {
+			throw exception::AlibException("Invalid type.");
 		}
 
-		automaton::NFA res = automaton::generate::RandomAutomatonFactory::generateNFA( statesCount, alphabetSize, density );
-		alib::DataFactory::toStdout(res);
-	} else if( type == "RE" ) {
-
-		if( height == INT_MAX )
-		{
-			//TODO: floating point arithmetic
-			std::cerr << "You must specify prefered height of the regexp." << std::endl;
-			return 1;
-		}
-
-		if( leafNodes == INT_MAX )
-		{
-			std::cerr << "You must specify number of leaf noded (symbol, epsilon and empty)." << std::endl;
-			return 1;
-		}
-
-		if( alphabetSize == INT_MAX )
-		{
-			std::cerr << "You must specify alphabet or at least its size." << std::endl;
-			return 1;
-		}
-
-		regexp::UnboundedRegExp res = regexp::generate::RandomRegExpFactory::generateUnboundedRegExp(leafNodes, height, alphabetSize );
-		alib::DataFactory::toStdout(res);
+		return 0;
+	} catch( const exception::AlibException & e ) {
+		alib::DataFactory::toStdout( e );
+		return 1;
+	} catch(const TCLAP::ArgException& exception) {
+		std::cout << exception.error() << std::endl;
+		return 2;
+	} catch (...) {
+		return 127;
 	}
-
-	return 0;
 }
-- 
GitLab