summaryrefslogtreecommitdiffstats
path: root/src/base/cmd
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2005-07-29 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2005-07-29 08:01:00 -0700
commit888e5bed5d7f56a5d86d91a6e8e88f3e5a3454dc (patch)
tree11d48c9e9069f54dc300c3571ae63c744c802c50 /src/base/cmd
parent7f94414388cce67bd3cc1a6d6269f0ed31ed0d06 (diff)
downloadabc-888e5bed5d7f56a5d86d91a6e8e88f3e5a3454dc.tar.gz
abc-888e5bed5d7f56a5d86d91a6e8e88f3e5a3454dc.tar.bz2
abc-888e5bed5d7f56a5d86d91a6e8e88f3e5a3454dc.zip
Version abc50729
Diffstat (limited to 'src/base/cmd')
-rw-r--r--src/base/cmd/cmd.c1498
-rw-r--r--src/base/cmd/cmd.h65
-rw-r--r--src/base/cmd/cmdAlias.c120
-rw-r--r--src/base/cmd/cmdApi.c104
-rw-r--r--src/base/cmd/cmdFlag.c112
-rw-r--r--src/base/cmd/cmdHist.c55
-rw-r--r--src/base/cmd/cmdInt.h82
-rw-r--r--src/base/cmd/cmdUtils.c598
-rw-r--r--src/base/cmd/module.make6
9 files changed, 2640 insertions, 0 deletions
diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c
new file mode 100644
index 00000000..aa15c0af
--- /dev/null
+++ b/src/base/cmd/cmd.c
@@ -0,0 +1,1498 @@
+/**CFile****************************************************************
+
+ FileName [cmd.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Command file.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "mainInt.h"
+#include "cmdInt.h"
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int CmdCommandTime ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandEcho ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandQuit ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandUsage ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandWhich ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandHistory ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandAlias ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandUnalias ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandHelp ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandSource ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandSetVariable ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandUnsetVariable ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandUndo ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandRecall ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandEmpty ( Abc_Frame_t * pAbc, int argc, char ** argv );
+#ifdef WIN32
+static int CmdCommandLs ( Abc_Frame_t * pAbc, int argc, char ** argv );
+#endif
+static int CmdCommandSis ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandMvsis ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function********************************************************************
+
+ Synopsis [Initializes the command package.]
+
+ SideEffects [Commands are added to the command table.]
+
+ SeeAlso [Cmd_End]
+
+******************************************************************************/
+void Cmd_Init( Abc_Frame_t * pAbc )
+{
+ pAbc->tCommands = st_init_table(strcmp, st_strhash);
+ pAbc->tAliases = st_init_table(strcmp, st_strhash);
+ pAbc->tFlags = st_init_table(strcmp, st_strhash);
+ pAbc->aHistory = Vec_PtrAlloc( 100 );
+
+ Cmd_CommandAdd( pAbc, "Basic", "time", CmdCommandTime, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "echo", CmdCommandEcho, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "quit", CmdCommandQuit, 0);
+// Cmd_CommandAdd( pAbc, "Basic", "usage", CmdCommandUsage, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "history", CmdCommandHistory, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "alias", CmdCommandAlias, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "unalias", CmdCommandUnalias, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "help", CmdCommandHelp, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "source", CmdCommandSource, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "set", CmdCommandSetVariable, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "unset", CmdCommandUnsetVariable, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "undo", CmdCommandUndo, 0);
+// Cmd_CommandAdd( pAbc, "Basic", "recall", CmdCommandRecall, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "empty", CmdCommandEmpty, 0);
+#ifdef WIN32
+ Cmd_CommandAdd( pAbc, "Basic", "ls", CmdCommandLs, 0 );
+#endif
+
+ Cmd_CommandAdd( pAbc, "Various", "sis", CmdCommandSis, 1);
+ Cmd_CommandAdd( pAbc, "Various", "mvsis", CmdCommandMvsis, 1);
+}
+
+/**Function********************************************************************
+
+ Synopsis [Ends the command package.]
+
+ Description [Ends the command package. Tables are freed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+void Cmd_End( Abc_Frame_t * pAbc )
+{
+ st_generator * gen;
+ char * pKey, * pValue;
+ int i;
+
+// st_free_table( pAbc->tCommands, (void (*)()) 0, CmdCommandFree );
+// st_free_table( pAbc->tAliases, (void (*)()) 0, CmdCommandAliasFree );
+// st_free_table( pAbc->tFlags, free, free );
+
+ st_foreach_item( pAbc->tCommands, gen, (char **)&pKey, (char **)&pValue )
+ CmdCommandFree( (Abc_Command *)pValue );
+ st_free_table( pAbc->tCommands );
+
+ st_foreach_item( pAbc->tAliases, gen, (char **)&pKey, (char **)&pValue )
+ CmdCommandAliasFree( (Abc_Alias *)pValue );
+ st_free_table( pAbc->tAliases );
+
+ st_foreach_item( pAbc->tFlags, gen, (char **)&pKey, (char **)&pValue )
+ free( pKey ), free( pValue );
+ st_free_table( pAbc->tFlags );
+
+ for ( i = 0; i < pAbc->aHistory->nSize; i++ )
+ free( pAbc->aHistory->pArray[i] );
+ Vec_PtrFree( pAbc->aHistory );
+}
+
+
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandTime( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int c;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc != util_optind )
+ {
+ goto usage;
+ }
+
+ pAbc->TimeTotal += pAbc->TimeCommand;
+ fprintf( pAbc->Out, "elapse: %3.2f seconds, total: %3.2f seconds\n",
+ (float)pAbc->TimeCommand / CLOCKS_PER_SEC, (float)pAbc->TimeTotal / CLOCKS_PER_SEC );
+ pAbc->TimeCommand = 0;
+ return 0;
+
+ usage:
+ fprintf( pAbc->Err, "usage: time [-h]\n" );
+ fprintf( pAbc->Err, " -h \t\tprint the command usage\n" );
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandEcho( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int i;
+ int c;
+ int n = 1;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "hn" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'n':
+ n = 0;
+ break;
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ for ( i = util_optind; i < argc; i++ )
+ fprintf( pAbc->Out, "%s ", argv[i] );
+ if ( n )
+ fprintf( pAbc->Out, "\n" );
+ else
+ fflush ( pAbc->Out );
+ return 0;
+
+ usage:
+ fprintf( pAbc->Err, "usage: echo [-h] string \n" );
+ fprintf( pAbc->Err, " -n \t\tsuppress newline at the end\n" );
+ fprintf( pAbc->Err, " -h \t\tprint the command usage\n" );
+ return ( 1 );
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandQuit( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int c;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "hs" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ case 's':
+ return -2;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc != util_optind )
+ goto usage;
+ return -1;
+
+ usage:
+ fprintf( pAbc->Err, "usage: quit [-h] [-s]\n" );
+ fprintf( pAbc->Err, " -h print the command usage\n" );
+ fprintf( pAbc->Err,
+ " -s frees all the memory before quitting\n" );
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandUsage( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int c;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc != util_optind )
+ goto usage;
+ util_print_cpu_stats( pAbc->Out );
+ return 0;
+
+ usage:
+ fprintf( pAbc->Err, "usage: usage [-h]\n" );
+ fprintf( pAbc->Err, " -h \t\tprint the command usage\n" );
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandWhich( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ return 0;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandHistory( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int i, num;
+ int size;
+ int c;
+ num = 30;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ }
+ }
+
+ if ( argc > 3 )
+ goto usage;
+
+ size = pAbc->aHistory->nSize;
+ num = ( num < size ) ? num : size;
+ for ( i = size - num; i < size; i++ )
+ fprintf( pAbc->Out, "%s", pAbc->aHistory->pArray[i] );
+ return 0;
+
+ usage:
+ fprintf( pAbc->Err, "usage: history [-h] [num]\n" );
+ fprintf( pAbc->Err, " -h \t\tprint the command usage\n" );
+ fprintf( pAbc->Err, " num \t\tprint the last num commands\n" );
+ return ( 1 );
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandAlias( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char *key, *value;
+ st_generator *gen;
+ int c;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+
+ if ( argc == 1 )
+ {
+ st_foreach_item( pAbc->tAliases, gen, &key, &value )
+ CmdCommandAliasPrint( pAbc, ( Abc_Alias * ) value );
+ return 0;
+
+ }
+ else if ( argc == 2 )
+ {
+ if ( st_lookup( pAbc->tAliases, argv[1], &value ) )
+ CmdCommandAliasPrint( pAbc, ( Abc_Alias * ) value );
+ return 0;
+ }
+
+ // delete any existing alias
+ key = argv[1];
+ if ( st_delete( pAbc->tAliases, &key, &value ) )
+ CmdCommandAliasFree( ( Abc_Alias * ) value );
+ CmdCommandAliasAdd( pAbc, argv[1], argc - 2, argv + 2 );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: alias [-h] [command [string]]\n" );
+ fprintf( pAbc->Err, " -h \t\tprint the command usage\n" );
+ return ( 1 );
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandUnalias( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int i;
+ char *key, *value;
+ int c;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc < 2 )
+ {
+ goto usage;
+ }
+
+ for ( i = 1; i < argc; i++ )
+ {
+ key = argv[i];
+ if ( st_delete( pAbc->tAliases, &key, &value ) )
+ {
+ CmdCommandAliasFree( ( Abc_Alias * ) value );
+ }
+ }
+ return 0;
+
+ usage:
+ fprintf( pAbc->Err, "usage: unalias [-h] alias_names\n" );
+ fprintf( pAbc->Err, " -h \t\tprint the command usage\n" );
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandHelp( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ bool fPrintAll;
+ int c;
+
+ fPrintAll = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "ah" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'a':
+ case 'v':
+ fPrintAll ^= 1;
+ break;
+ break;
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc != util_optind )
+ goto usage;
+
+ CmdCommandPrint( pAbc, fPrintAll );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: help [-a] [-h]\n" );
+ fprintf( pAbc->Err, " prints the list of available commands by group\n" );
+ fprintf( pAbc->Err, " -a toggle printing hidden commands [default = %s]\n", fPrintAll? "yes": "no" );
+ fprintf( pAbc->Err, " -h print the command usage\n" );
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandSource( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int c, echo, prompt, silent, interactive, quit_count, lp_count;
+ int status = 0; /* initialize so that lint doesn't complain */
+ int lp_file_index, did_subst;
+ char *prompt_string, *real_filename, line[MAX_STR], *command;
+ FILE *fp;
+
+ interactive = silent = prompt = echo = 0;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "hipsx" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ case 'i': /* a hack to distinguish EOF from stdin */
+ interactive = 1;
+ break;
+ case 'p':
+ prompt = 1;
+ break;
+ case 's':
+ silent = 1;
+ break;
+ case 'x':
+ echo ^= 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ /* added to avoid core-dumping when no script file is specified */
+ if ( argc == util_optind )
+ {
+ goto usage;
+ }
+
+ lp_file_index = util_optind;
+ lp_count = 0;
+
+ /*
+ * FIX (Tom, 5/7/95): I'm not sure what the purpose of this outer do loop
+ * is. In particular, lp_file_index is never modified in the loop, so it
+ * looks it would just read the same file over again. Also, SIS had
+ * lp_count initialized to -1, and hence, any file sourced by SIS (if -l or
+ * -t options on "source" were used in SIS) would actually be executed
+ * twice.
+ */
+ do
+ {
+ lp_count++; /* increment the loop counter */
+
+ fp = CmdFileOpen( pAbc, argv[lp_file_index], "r", &real_filename, silent );
+ if ( fp == NULL )
+ {
+ FREE( real_filename );
+ return !silent; /* error return if not silent */
+ }
+
+ quit_count = 0;
+ do
+ {
+ if ( prompt )
+ {
+ prompt_string = Cmd_FlagReadByName( pAbc, "prompt" );
+ if ( prompt_string == NULL )
+ prompt_string = "abc> ";
+
+ }
+ else
+ {
+ prompt_string = NIL( char );
+ }
+
+ /* clear errors -- e.g., EOF reached from stdin */
+ clearerr( fp );
+
+ /* read another command line */
+// if (CmdFgetsFilec(line, MAX_STR, fp, prompt_string) == NULL) {
+// Abc_UtilsPrintPrompt(prompt_string);
+// fflush(stdout);
+ if ( fgets( line, MAX_STR, fp ) == NULL )
+ {
+ if ( interactive )
+ {
+ if ( quit_count++ < 5 )
+ {
+ fprintf( pAbc->Err, "\nUse \"quit\" to leave ABC.\n" );
+ continue;
+ }
+ status = -1; /* fake a 'quit' */
+ }
+ else
+ {
+ status = 0; /* successful end of 'source' ; loop? */
+ }
+ break;
+ }
+ quit_count = 0;
+
+ if ( echo )
+ {
+ fprintf( pAbc->Out, "abc - > %s", line );
+ }
+ command = CmdHistorySubstitution( pAbc, line, &did_subst );
+ if ( command == NIL( char ) )
+ {
+ status = 1;
+ break;
+ }
+ if ( did_subst )
+ {
+ if ( interactive )
+ {
+ fprintf( pAbc->Out, "%s\n", command );
+ }
+ }
+ if ( command != line )
+ {
+ ( void ) strcpy( line, command );
+ }
+ if ( interactive && *line != '\0' )
+ {
+ Cmd_HistoryAddCommand( pAbc, util_strsav(line) );
+ if ( pAbc->Hst != NIL( FILE ) )
+ {
+ fprintf( pAbc->Hst, "%s\n", line );
+ ( void ) fflush( pAbc->Hst );
+ }
+ }
+
+ status = Cmd_CommandExecute( pAbc, line );
+ }
+ while ( status == 0 );
+
+ if ( fp != stdin )
+ {
+ if ( status > 0 )
+ {
+ fprintf( pAbc->Err,
+ "** cmd error: aborting 'source %s'\n",
+ real_filename );
+ }
+ ( void ) fclose( fp );
+ }
+ FREE( real_filename );
+
+ }
+ while ( ( status == 0 ) && ( lp_count <= 0 ) );
+
+ return status;
+
+ usage:
+ fprintf( pAbc->Err, "usage: source [-h] [-p] [-s] [-x] file_name\n" );
+ fprintf( pAbc->Err, "\t-h print the command usage\n" );
+ fprintf( pAbc->Err, "\t-p supply prompt before reading each line\n" );
+ fprintf( pAbc->Err, "\t-s silently ignore nonexistant file\n" );
+ fprintf( pAbc->Err, "\t-x echo each line as it is executed\n" );
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandSetVariable( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char *flag_value, *key, *value;
+ st_generator *gen;
+ int c;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+ if ( argc == 0 || argc > 3 )
+ {
+ goto usage;
+ }
+ else if ( argc == 1 )
+ {
+ st_foreach_item( pAbc->tFlags, gen, &key, &value )
+ {
+ fprintf( pAbc->Out, "%s\t%s\n", key, value );
+ }
+ return 0;
+ }
+ else
+ {
+ key = argv[1];
+ if ( st_delete( pAbc->tFlags, &key, &value ) )
+ {
+ FREE( key );
+ FREE( value );
+ }
+
+ flag_value = argc == 2 ? util_strsav( "" ) : util_strsav( argv[2] );
+
+ ( void ) st_insert( pAbc->tFlags, util_strsav( argv[1] ),
+ flag_value );
+
+ if ( strcmp( argv[1], "abcout" ) == 0 )
+ {
+ if ( pAbc->Out != stdout )
+ {
+ ( void ) fclose( pAbc->Out );
+ }
+ if ( strcmp( flag_value, "" ) == 0 )
+ {
+ flag_value = "-";
+ }
+ pAbc->Out = CmdFileOpen( pAbc, flag_value, "w", NIL( char * ), 0 );
+ if ( pAbc->Out == NULL )
+ {
+ pAbc->Out = stdout;
+ }
+#if HAVE_SETVBUF
+ setvbuf( pAbc->Out, ( char * ) NULL, _IOLBF, 0 );
+#endif
+ }
+ if ( strcmp( argv[1], "abcerr" ) == 0 )
+ {
+ if ( pAbc->Err != stderr )
+ {
+ ( void ) fclose( pAbc->Err );
+ }
+ if ( strcmp( flag_value, "" ) == 0 )
+ {
+ flag_value = "-";
+ }
+ pAbc->Err = CmdFileOpen( pAbc, flag_value, "w", NIL( char * ), 0 );
+ if ( pAbc->Err == NULL )
+ {
+ pAbc->Err = stderr;
+ }
+#if HAVE_SETVBUF
+ setvbuf( pAbc->Err, ( char * ) NULL, _IOLBF, 0 );
+#endif
+ }
+ if ( strcmp( argv[1], "history" ) == 0 )
+ {
+ if ( pAbc->Hst != NIL( FILE ) )
+ {
+ ( void ) fclose( pAbc->Hst );
+ }
+ if ( strcmp( flag_value, "" ) == 0 )
+ {
+ pAbc->Hst = NIL( FILE );
+ }
+ else
+ {
+ pAbc->Hst =
+ CmdFileOpen( pAbc, flag_value, "w", NIL( char * ), 0 );
+ if ( pAbc->Hst == NULL )
+ {
+ pAbc->Hst = NIL( FILE );
+ }
+ }
+ }
+ return 0;
+ }
+
+ usage:
+ fprintf( pAbc->Err, "usage: set [-h] [name] [value]\n" );
+ fprintf( pAbc->Err, "\t sets the value of parameter <name>\n" );
+ fprintf( pAbc->Err, "\t-h : print the command usage\n" );
+ return 1;
+
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandUnsetVariable( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int i;
+ char *key, *value;
+ int c;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc < 2 )
+ {
+ goto usage;
+ }
+
+ for ( i = 1; i < argc; i++ )
+ {
+ key = argv[i];
+ if ( st_delete( pAbc->tFlags, &key, &value ) )
+ {
+ FREE( key );
+ FREE( value );
+ }
+ }
+ return 0;
+
+
+ usage:
+ fprintf( pAbc->Err, "usage: unset [-h] variables \n" );
+ fprintf( pAbc->Err, " -h \t\tprint the command usage\n" );
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandUndo( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ if ( pAbc->pNtkCur == NULL )
+ {
+ fprintf( pAbc->Out, "Empty network.\n" );
+ return 0;
+ }
+
+ // if there are no arguments on the command line
+ // set the current network to be the network from the previous step
+ if ( argc == 1 )
+ return CmdCommandRecall( pAbc, argc, argv );
+
+ fprintf( pAbc->Err, "usage: undo\n" );
+ fprintf( pAbc->Err, " sets the current network to be the previously saved network\n" );
+ return 1;
+
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandRecall( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ Abc_Ntk_t * pNtk;
+ int iStep, iStepFound;
+ int nNetsToSave, c;
+ char * pValue;
+ int iStepStart, iStepStop;
+
+ if ( pAbc->pNtkCur == NULL )
+ {
+ fprintf( pAbc->Out, "Empty network.\n" );
+ return 0;
+ }
+
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ // get the number of networks to save
+ pValue = Cmd_FlagReadByName( pAbc, "savesteps" );
+ // if the value of steps to save is not set, assume 1-level undo
+ if ( pValue == NULL )
+ nNetsToSave = 1;
+ else
+ nNetsToSave = atoi(pValue);
+
+ // if there are no arguments on the command line
+ // set the current network to be the network from the previous step
+ if ( argc == 1 )
+ {
+ // get the previously saved network
+ pNtk = Abc_NtkBackup(pAbc->pNtkCur);
+ if ( pNtk == NULL )
+ fprintf( pAbc->Out, "There is no previously saved network.\n" );
+ else // set the current network to be the copy of the previous one
+ Abc_FrameSetCurrentNetwork( pAbc, Abc_NtkDup(pNtk) );
+ return 0;
+ }
+ if ( argc == 2 ) // the second argument is the number of the step to return to
+ {
+ // read the number of the step to return to
+ iStep = atoi(argv[1]);
+ // check whether it is reasonable
+ if ( iStep >= pAbc->nSteps )
+ {
+ iStepStart = pAbc->nSteps - nNetsToSave;
+ if ( iStepStart <= 0 )
+ iStepStart = 1;
+ iStepStop = pAbc->nSteps;
+ if ( iStepStop <= 0 )
+ iStepStop = 1;
+ if ( iStepStart == iStepStop )
+ fprintf( pAbc->Out, "Can only recall step %d.\n", iStepStop );
+ else
+ fprintf( pAbc->Out, "Can only recall steps %d-%d.\n", iStepStart, iStepStop );
+ }
+ else if ( iStep < 0 )
+ fprintf( pAbc->Out, "Cannot recall step %d.\n", iStep );
+ else if ( iStep == 0 )
+ Abc_FrameDeleteAllNetworks( pAbc );
+ else
+ {
+ // scroll backward through the list of networks
+ // to determine if such a network exist
+ iStepFound = 0;
+ for ( pNtk = pAbc->pNtkCur; pNtk; pNtk = Abc_NtkBackup(pNtk) )
+ if ( (iStepFound = Abc_NtkStep(pNtk)) == iStep )
+ break;
+ if ( pNtk == NULL )
+ {
+ iStepStart = iStepFound;
+ if ( iStepStart <= 0 )
+ iStepStart = 1;
+ iStepStop = pAbc->nSteps;
+ if ( iStepStop <= 0 )
+ iStepStop = 1;
+ if ( iStepStart == iStepStop )
+ fprintf( pAbc->Out, "Can only recall step %d.\n", iStepStop );
+ else
+ fprintf( pAbc->Out, "Can only recall steps %d-%d.\n", iStepStart, iStepStop );
+ }
+ else
+ Abc_FrameSetCurrentNetwork( pAbc, Abc_NtkDup(pNtk) );
+ }
+ return 0;
+ }
+
+usage:
+
+ fprintf( pAbc->Err, "usage: recall <num>\n" );
+ fprintf( pAbc->Err, " set the current network to be one of the previous networks\n" );
+ fprintf( pAbc->Err, "<num> : level to return to [default = previous]\n" );
+ return 1;
+}
+
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandEmpty( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int c;
+
+ if ( pAbc->pNtkCur == NULL )
+ {
+ fprintf( pAbc->Out, "Empty network.\n" );
+ return 0;
+ }
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ Abc_FrameDeleteAllNetworks( pAbc );
+ Abc_FrameRestart( pAbc );
+ return 0;
+usage:
+
+ fprintf( pAbc->Err, "usage: empty [-h]\n" );
+ fprintf( pAbc->Err, " removes all the currently stored networks\n" );
+ fprintf( pAbc->Err, " -h : print the command usage\n");
+ return 1;
+}
+
+
+#if 0
+
+/**Function********************************************************************
+
+ Synopsis [Donald's version.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandUndo( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ Abc_Ntk_t * pNtkTemp;
+ int id, c;
+
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+ if (util_optind <= argc) {
+ pNtkTemp = pAbc->pNtk;
+ pAbc->pNtk = pAbc->pNtkSaved;
+ pAbc->pNtkSaved = pNtkTemp;
+ }
+ id = atoi(argv[util_optind]);
+ pNtkTemp = Cmd_HistoryGetSnapshot(pAbc, id);
+ if (!pNtkTemp)
+ fprintf( pAbc->Err, "Snapshot %d does not exist\n", id);
+ else
+ pAbc->pNtk = Abc_NtkDup(pNtkTemp, Abc_NtkMan(pNtkTemp));
+
+ return 0;
+usage:
+ fprintf( pAbc->Err, "usage: undo\n" );
+ fprintf( pAbc->Err, " swaps the current network and the backup network\n" );
+ return 1;
+}
+
+#endif
+
+
+#ifdef WIN32
+/**Function*************************************************************
+
+ Synopsis [Command to print the contents of the current directory (Windows).]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+#include <io.h>
+
+// these structures are defined in <io.h> but are for some reason invisible
+typedef unsigned long _fsize_t; // Could be 64 bits for Win32
+
+struct _finddata_t {
+ unsigned attrib;
+ time_t time_create; // -1 for FAT file systems
+ time_t time_access; // -1 for FAT file systems
+ time_t time_write;
+ _fsize_t size;
+ char name[260];
+};
+
+extern long _findfirst( char *filespec, struct _finddata_t *fileinfo );
+extern int _findnext( long handle, struct _finddata_t *fileinfo );
+extern int _findclose( long handle );
+
+int CmdCommandLs( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ struct _finddata_t c_file;
+ long hFile;
+ int fLong = 0;
+ int fOnlyBLIF = 0;
+ char Buffer[25];
+ int Counter = 0;
+ int fPrintedNewLine;
+ char c;
+
+ util_getopt_reset();
+ while ( (c = util_getopt(argc, argv, "lb") ) != EOF )
+ {
+ switch (c)
+ {
+ case 'l':
+ fLong = 1;
+ break;
+ case 'b':
+ fOnlyBLIF = 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ // find first .mv file in current directory
+ if( (hFile = _findfirst( ((fOnlyBLIF)? "*.mv": "*.*"), &c_file )) == -1L )
+ {
+ if ( fOnlyBLIF )
+ fprintf( pAbc->Out, "No *.mv files in the current directory.\n" );
+ else
+ fprintf( pAbc->Out, "No files in the current directory.\n" );
+ }
+ else
+ {
+ if ( fLong )
+ {
+ fprintf( pAbc->Out, " File Date Size | File Date Size \n" );
+ fprintf( pAbc->Out, " ----------------------------------------------------------------------------- \n" );
+ do
+ {
+ strcpy( Buffer, ctime( &(c_file.time_write) ) );
+ Buffer[16] = 0;
+ fprintf( pAbc->Out, " %-17s %.24s%7ld", c_file.name, Buffer+4, c_file.size );
+ if ( ++Counter % 2 == 0 )
+ {
+ fprintf( pAbc->Out, "\n" );
+ fPrintedNewLine = 1;
+ }
+ else
+ {
+ fprintf( pAbc->Out, " |" );
+ fPrintedNewLine = 0;
+ }
+ }
+ while( _findnext( hFile, &c_file ) == 0 );
+ }
+ else
+ {
+ do
+ {
+ fprintf( pAbc->Out, " %-18s", c_file.name );
+ if ( ++Counter % 4 == 0 )
+ {
+ fprintf( pAbc->Out, "\n" );
+ fPrintedNewLine = 1;
+ }
+ else
+ {
+ fprintf( pAbc->Out, " " );
+ fPrintedNewLine = 0;
+ }
+ }
+ while( _findnext( hFile, &c_file ) == 0 );
+ }
+ if ( !fPrintedNewLine )
+ fprintf( pAbc->Out, "\n" );
+ _findclose( hFile );
+ }
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "Usage: ls [-l] [-b]\n" );
+ fprintf( pAbc->Err, " print the file names in the current directory\n" );
+ fprintf( pAbc->Err, " -l : print in the long format [default = short]\n" );
+ fprintf( pAbc->Err, " -b : print only .mv files [default = all]\n" );
+ return 1;
+}
+#endif
+
+
+
+#ifdef WIN32
+#define unlink _unlink
+#endif
+
+/**Function********************************************************************
+
+ Synopsis [Calls SIS internally.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandSis( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ FILE * pFile;
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkNew;
+ char Command[1000], Buffer[100];
+ char * pSisName;
+ int i;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ goto usage;
+ }
+
+ if ( strcmp( argv[0], "sis" ) != 0 )
+ {
+ fprintf( pErr, "Wrong command: \"%s\".\n", argv[0] );
+ goto usage;
+ }
+
+ if ( argc == 1 )
+ goto usage;
+ if ( strcmp( argv[1], "-h" ) == 0 )
+ goto usage;
+ if ( strcmp( argv[1], "-?" ) == 0 )
+ goto usage;
+
+ // check if SIS is available
+ if ( (pFile = fopen( "sis.exe", "r" )) )
+ pSisName = "sis.exe";
+ else if ( (pFile = fopen( "sis", "r" )) )
+ pSisName = "sis";
+ else if ( pFile == NULL )
+ {
+ fprintf( pErr, "Cannot find \"%s\" or \"%s\" in the current directory.\n", "sis.exe", "sis" );
+ goto usage;
+ }
+ fclose( pFile );
+
+ if ( Abc_NtkIsLogicBdd(pNtk) )
+ Abc_NtkBddToSop(pNtk);
+
+ // write out the current network
+ Io_WriteBlifLogic( pNtk, "_sis_in.blif", 1 );
+
+ // create the file for sis
+ sprintf( Command, "%s -x -c ", pSisName );
+ strcat ( Command, "\"" );
+ strcat ( Command, "read_blif _sis_in.blif" );
+ strcat ( Command, "; " );
+ for ( i = 1; i < argc; i++ )
+ {
+ sprintf( Buffer, " %s", argv[i] );
+ strcat( Command, Buffer );
+ }
+ strcat( Command, "; " );
+ strcat( Command, "write_blif _sis_out.blif" );
+ strcat( Command, "\"" );
+
+ // call SIS
+ if ( system( Command ) )
+ {
+ fprintf( pErr, "The following command has returned non-zero exit status:\n" );
+ fprintf( pErr, "\"%s\"\n", Command );
+ unlink( "_sis_in.blif" );
+ goto usage;
+ }
+
+ // read in the SIS output
+ if ( (pFile = fopen( "_sis_out.blif", "r" )) == NULL )
+ {
+ fprintf( pErr, "Cannot open SIS output file \"%s\".\n", "_sis_out.blif" );
+ unlink( "_sis_in.blif" );
+ goto usage;
+ }
+ fclose( pFile );
+
+ // set the new network
+ pNtkNew = Io_Read( "_sis_out.blif", 1 );
+ // set the original spec of the new network
+ if ( pNtk->pSpec )
+ {
+ FREE( pNtkNew->pSpec );
+ pNtkNew->pSpec = util_strsav( pNtk->pSpec );
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkNew );
+
+ // remove temporary networks
+ unlink( "_sis_in.blif" );
+ unlink( "_sis_out.blif" );
+ return 0;
+
+usage:
+ fprintf( pErr, "\n" );
+ fprintf( pErr, "Usage: sis [-h] <com>\n");
+ fprintf( pErr, " invokes SIS command for the current ABC network\n" );
+ fprintf( pErr, " (the executable of SIS should be in the same directory)\n" );
+ fprintf( pErr, " -h : print the command usage\n" );
+ fprintf( pErr, " <com> : a SIS command (or a semicolon-separated list of commands in quotes)\n" );
+ fprintf( pErr, " Example 1: sis eliminate 0\n" );
+ fprintf( pErr, " Example 2: sis \"ps; rd; fx; ps\"\n" );
+ fprintf( pErr, " Example 3: sis source script.rugged\n" );
+ return 1; // error exit
+}
+
+
+/**Function********************************************************************
+
+ Synopsis [Calls SIS internally.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandMvsis( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ FILE * pFile;
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkNew;
+ char Command[1000], Buffer[100];
+ char * pMvsisName;
+ int i;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ goto usage;
+ }
+
+ if ( strcmp( argv[0], "mvsis" ) != 0 )
+ {
+ fprintf( pErr, "Wrong command: \"%s\".\n", argv[0] );
+ goto usage;
+ }
+
+ if ( argc == 1 )
+ goto usage;
+ if ( strcmp( argv[1], "-h" ) == 0 )
+ goto usage;
+ if ( strcmp( argv[1], "-?" ) == 0 )
+ goto usage;
+
+ // check if MVSIS is available
+ if ( (pFile = fopen( "mvsis.exe", "r" )) )
+ pMvsisName = "mvsis.exe";
+ else if ( (pFile = fopen( "mvsis", "r" )) )
+ pMvsisName = "mvsis";
+ else if ( pFile == NULL )
+ {
+ fprintf( pErr, "Cannot find \"%s\" or \"%s\" in the current directory.\n", "mvsis.exe", "mvsis" );
+ goto usage;
+ }
+ fclose( pFile );
+
+ if ( Abc_NtkIsLogicBdd(pNtk) )
+ Abc_NtkBddToSop(pNtk);
+
+ // write out the current network
+ Io_WriteBlifLogic( pNtk, "_mvsis_in.blif", 1 );
+
+ // create the file for MVSIS
+ sprintf( Command, "%s -x -c ", pMvsisName );
+ strcat ( Command, "\"" );
+ strcat ( Command, "read_blif _mvsis_in.blif" );
+ strcat ( Command, "; " );
+ for ( i = 1; i < argc; i++ )
+ {
+ sprintf( Buffer, " %s", argv[i] );
+ strcat( Command, Buffer );
+ }
+ strcat( Command, "; " );
+ strcat( Command, "write_blif _mvsis_out.blif" );
+ strcat( Command, "\"" );
+
+ // call MVSIS
+ if ( system( Command ) )
+ {
+ fprintf( pErr, "The following command has returned non-zero exit status:\n" );
+ fprintf( pErr, "\"%s\"\n", Command );
+ unlink( "_mvsis_in.blif" );
+ goto usage;
+ }
+
+ // read in the MVSIS output
+ if ( (pFile = fopen( "_mvsis_out.blif", "r" )) == NULL )
+ {
+ fprintf( pErr, "Cannot open MVSIS output file \"%s\".\n", "_mvsis_out.blif" );
+ unlink( "_mvsis_in.blif" );
+ goto usage;
+ }
+ fclose( pFile );
+
+ // set the new network
+ pNtkNew = Io_Read( "_mvsis_out.blif", 1 );
+ // set the original spec of the new network
+ if ( pNtk->pSpec )
+ {
+ FREE( pNtkNew->pSpec );
+ pNtkNew->pSpec = util_strsav( pNtk->pSpec );
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkNew );
+
+ // remove temporary networks
+ unlink( "_mvsis_in.blif" );
+ unlink( "_mvsis_out.blif" );
+ return 0;
+
+usage:
+ fprintf( pErr, "\n" );
+ fprintf( pErr, "Usage: mvsis [-h] <com>\n");
+ fprintf( pErr, " invokes MVSIS command for the current ABC network\n" );
+ fprintf( pErr, " (the executable of MVSIS should be in the same directory)\n" );
+ fprintf( pErr, " -h : print the command usage\n" );
+ fprintf( pErr, " <com> : a MVSIS command (or a semicolon-separated list of commands in quotes)\n" );
+ fprintf( pErr, " Example 1: mvsis fraig_sweep\n" );
+ fprintf( pErr, " Example 2: mvsis \"ps; fxu; ps\"\n" );
+ fprintf( pErr, " Example 3: mvsis source mvsis.rugged\n" );
+ return 1; // error exit
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/cmd/cmd.h b/src/base/cmd/cmd.h
new file mode 100644
index 00000000..6389afae
--- /dev/null
+++ b/src/base/cmd/cmd.h
@@ -0,0 +1,65 @@
+/**CFile****************************************************************
+
+ FileName [cmd.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [External declarations of the command package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmd.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __CMD_H__
+#define __CMD_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct MvCommand Abc_Command; // one command
+typedef struct MvAlias Abc_Alias; // one alias
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== cmd.c ===========================================================*/
+extern void Cmd_Init();
+extern void Cmd_End();
+/*=== cmdApi.c ========================================================*/
+extern void Cmd_CommandAdd( Abc_Frame_t * pAbc, char * sGroup, char * sName, void * pFunc, int fChanges );
+extern int Cmd_CommandExecute( Abc_Frame_t * pAbc, char * sCommand );
+/*=== cmdFlag.c ========================================================*/
+extern char * Cmd_FlagReadByName( Abc_Frame_t * pAbc, char * flag );
+extern void Cmd_FlagDeleteByName( Abc_Frame_t * pAbc, char * key );
+extern void Cmd_FlagUpdateValue( Abc_Frame_t * pAbc, char * key, char * value );
+/*=== cmdHist.c ========================================================*/
+extern void Cmd_HistoryAddCommand( Abc_Frame_t * pAbc, char * command );
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/src/base/cmd/cmdAlias.c b/src/base/cmd/cmdAlias.c
new file mode 100644
index 00000000..37220ef0
--- /dev/null
+++ b/src/base/cmd/cmdAlias.c
@@ -0,0 +1,120 @@
+/**CFile****************************************************************
+
+ FileName [cmdAlias.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures dealing with aliases in the command package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmdAlias.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cmdInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CmdCommandAliasAdd( Abc_Frame_t * pAbc, char * sName, int argc, char ** argv )
+{
+ Abc_Alias * pAlias;
+ int fStatus, i;
+
+ pAlias = ALLOC(Abc_Alias, 1);
+ pAlias->sName = util_strsav(sName);
+ pAlias->argc = argc;
+ pAlias->argv = ALLOC(char *, pAlias->argc);
+ for(i = 0; i < argc; i++)
+ pAlias->argv[i] = util_strsav(argv[i]);
+ fStatus = st_insert( pAbc->tAliases, pAlias->sName, (char *) pAlias );
+ assert(!fStatus);
+}
+
+/**Function********************************************************************
+
+ Synopsis [required]
+
+ Description [optional]
+
+ SideEffects [required]
+
+ SeeAlso [optional]
+
+******************************************************************************/
+void CmdCommandAliasPrint( Abc_Frame_t * pAbc, Abc_Alias * pAlias )
+{
+ int i;
+ fprintf(pAbc->Out, "%s\t", pAlias->sName);
+ for(i = 0; i < pAlias->argc; i++)
+ fprintf( pAbc->Out, " %s", pAlias->argv[i] );
+ fprintf( pAbc->Out, "\n" );
+}
+
+/**Function********************************************************************
+
+ Synopsis [required]
+
+ Description [optional]
+
+ SideEffects [required]
+
+ SeeAlso [optional]
+
+******************************************************************************/
+char * CmdCommandAliasLookup( Abc_Frame_t * pAbc, char * sCommand )
+{
+ Abc_Alias * pAlias;
+ char * value;
+ if (!st_lookup( pAbc->tAliases, sCommand, &value))
+ return sCommand;
+ pAlias = (Abc_Alias *) value;
+ return pAlias->argv[0];
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CmdCommandAliasFree( Abc_Alias * pAlias )
+{
+ CmdFreeArgv( pAlias->argc, pAlias->argv );
+ FREE(pAlias->sName);
+ FREE(pAlias);
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/cmd/cmdApi.c b/src/base/cmd/cmdApi.c
new file mode 100644
index 00000000..8dd67637
--- /dev/null
+++ b/src/base/cmd/cmdApi.c
@@ -0,0 +1,104 @@
+/**CFile****************************************************************
+
+ FileName [cmdApi.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [External procedures of the command package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmdApi.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "mainInt.h"
+#include "cmdInt.h"
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cmd_CommandAdd( Abc_Frame_t * pAbc, char * sGroup, char * sName, void * pFunc, int fChanges )
+{
+ char * key, * value;
+ Abc_Command * pCommand;
+ int fStatus;
+
+ key = sName;
+ if ( st_delete( pAbc->tCommands, &key, &value ) )
+ {
+ // delete existing definition for this command
+ fprintf( pAbc->Err, "Cmd warning: redefining '%s'\n", sName );
+ CmdCommandFree( (Abc_Command *)value );
+ }
+
+ // create the new command
+ pCommand = ALLOC( Abc_Command, 1 );
+ pCommand->sName = util_strsav( sName );
+ pCommand->sGroup = util_strsav( sGroup );
+ pCommand->pFunc = pFunc;
+ pCommand->fChange = fChanges;
+ fStatus = st_insert( pAbc->tCommands, sName, (char *)pCommand );
+ assert( !fStatus ); // the command should not be in the table
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cmd_CommandExecute( Abc_Frame_t * pAbc, char * sCommand )
+{
+ int fStatus = 0, argc, loop;
+ char * sCommandNext, **argv;
+
+ if ( !pAbc->fAutoexac )
+ Cmd_HistoryAddCommand(pAbc, sCommand);
+ sCommandNext = sCommand;
+ do
+ {
+ sCommandNext = CmdSplitLine( pAbc, sCommandNext, &argc, &argv );
+ loop = 0;
+ fStatus = CmdApplyAlias( pAbc, &argc, &argv, &loop );
+ if ( fStatus == 0 )
+ fStatus = CmdCommandDispatch( pAbc, argc, argv );
+ CmdFreeArgv( argc, argv );
+ }
+ while ( fStatus == 0 && *sCommandNext != '\0' );
+ return fStatus;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/cmd/cmdFlag.c b/src/base/cmd/cmdFlag.c
new file mode 100644
index 00000000..96f1f251
--- /dev/null
+++ b/src/base/cmd/cmdFlag.c
@@ -0,0 +1,112 @@
+/**CFile****************************************************************
+
+ FileName [cmdFlag.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures working with flags.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmdFlag.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "mainInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+/**Function********************************************************************
+
+ Synopsis [Looks up value of flag in table of named values.]
+
+ Description [The command parser maintains a table of named values. These
+ are manipulated using the 'set' and 'unset' commands. The value of the
+ named flag is returned, or NIL(char) is returned if the flag has not been
+ set.]
+
+ SideEffects []
+
+******************************************************************************/
+char * Cmd_FlagReadByName( Abc_Frame_t * pAbc, char * flag )
+{
+ char *value;
+
+ if (st_lookup(pAbc->tFlags, flag, &value)) {
+ return value;
+ }
+ else {
+ return NIL(char);
+ }
+}
+
+
+/**Function********************************************************************
+
+ Synopsis [Updates a set value by calling instead of set command.]
+
+ Description [Updates a set value by calling instead of set command.]
+
+ SideEffects []
+
+******************************************************************************/
+void Cmd_FlagUpdateValue( Abc_Frame_t * pAbc, char * key, char * value )
+{
+ char *oldValue, *newValue;
+
+ if (!key)
+ return;
+ if (value)
+ newValue = util_strsav(value);
+ else
+ newValue = util_strsav("");
+
+ if (st_delete(pAbc->tFlags, &key, &oldValue))
+ FREE(oldValue);
+
+ st_insert(pAbc->tFlags, key, newValue);
+}
+
+
+/**Function********************************************************************
+
+ Synopsis [Deletes a set value by calling instead of unset command.]
+
+ Description [Deletes a set value by calling instead of unset command.]
+
+ SideEffects []
+
+******************************************************************************/
+void Cmd_FlagDeleteByName( Abc_Frame_t * pAbc, char * key )
+{
+ char *value;
+
+ if (!key)
+ return;
+
+ if (st_delete(pAbc->tFlags, &key, &value)) {
+ FREE(key);
+ FREE(value);
+ }
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/cmd/cmdHist.c b/src/base/cmd/cmdHist.c
new file mode 100644
index 00000000..5b46ea00
--- /dev/null
+++ b/src/base/cmd/cmdHist.c
@@ -0,0 +1,55 @@
+/**CFile****************************************************************
+
+ FileName [cmdHist.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures working with history.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmdHist.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "mainInt.h"
+#include "cmd.h"
+#include "cmdInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cmd_HistoryAddCommand( Abc_Frame_t * p, char * command )
+{
+ char Buffer[500];
+ strcpy( Buffer, command );
+ if ( command[strlen(command)-1] != '\n' )
+ strcat( Buffer, "\n" );
+ Vec_PtrPush( p->aHistory, util_strsav(Buffer) );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/base/cmd/cmdInt.h b/src/base/cmd/cmdInt.h
new file mode 100644
index 00000000..f0289ad4
--- /dev/null
+++ b/src/base/cmd/cmdInt.h
@@ -0,0 +1,82 @@
+/**CFile****************************************************************
+
+ FileName [cmdInt.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Internal declarations of the command package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmdInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __CMD_INT_H__
+#define __CMD_INT_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "mainInt.h"
+#include "cmd.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+struct MvCommand
+{
+ char * sName; // the command name
+ char * sGroup; // the group name
+ void * pFunc; // the function to execute the command
+ int fChange; // set to 1 to mark that the network is changed
+};
+
+struct MvAlias
+{
+ char * sName; // the alias name
+ int argc; // the number of alias parts
+ char ** argv; // the alias parts
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== cmdAlias.c =============-========================================*/
+extern void CmdCommandAliasAdd( Abc_Frame_t * pAbc, char * sName, int argc, char ** argv );
+extern void CmdCommandAliasPrint( Abc_Frame_t * pAbc, Abc_Alias * pAlias );
+extern char * CmdCommandAliasLookup( Abc_Frame_t * pAbc, char * sCommand );
+extern void CmdCommandAliasFree( Abc_Alias * p );
+/*=== cmdUtils.c =======================================================*/
+extern int CmdCommandDispatch( Abc_Frame_t * pAbc, int argc, char ** argv );
+extern char * CmdSplitLine( Abc_Frame_t * pAbc, char * sCommand, int * argc, char *** argv );
+extern int CmdApplyAlias( Abc_Frame_t * pAbc, int * argc, char *** argv, int * loop );
+extern char * CmdHistorySubstitution( Abc_Frame_t * pAbc, char * line, int * changed );
+extern FILE * CmdFileOpen( Abc_Frame_t * pAbc, char * sFileName, char * sMode, char ** pFileNameReal, int silent );
+extern void CmdFreeArgv( int argc, char ** argv );
+extern void CmdCommandFree( Abc_Command * pCommand );
+extern void CmdCommandPrint( Abc_Frame_t * pAbc, bool fPrintAll );
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/src/base/cmd/cmdUtils.c b/src/base/cmd/cmdUtils.c
new file mode 100644
index 00000000..67a290a2
--- /dev/null
+++ b/src/base/cmd/cmdUtils.c
@@ -0,0 +1,598 @@
+/**CFile****************************************************************
+
+ FileName [cmdUtils.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Various utilities of the command package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmdUtils.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "mainInt.h"
+#include "abc.h"
+#include "cmdInt.h"
+#include <ctype.h> // proper declaration of isspace
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int CmdCommandPrintCompare( Abc_Command ** ppC1, Abc_Command ** ppC2 );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int cmdCheckShellEscape( Abc_Frame_t * pAbc, int argc, char ** argv)
+{
+ if (argv[0][0] == '!')
+ {
+ const int size = 4096;
+ int i;
+ char buffer[4096];
+ strncpy (buffer, &argv[0][1], size);
+ for (i = 1; i < argc; ++i)
+ {
+ strncat (buffer, " ", size);
+ strncat (buffer, argv[i], size);
+ }
+ if (buffer[0] == 0)
+ strncpy (buffer, "/bin/sh", size);
+ system (buffer);
+
+ // NOTE: Since we reconstruct the cmdline by concatenating
+ // the parts, we lose information. So a command like
+ // `!ls "file name"` will be sent to the system as
+ // `ls file name` which is a BUG
+
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Executes one command.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int CmdCommandDispatch( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ Abc_Ntk_t * pNetCopy;
+ int (*pFunc) ( Abc_Frame_t *, int, char ** );
+ Abc_Command * pCommand;
+ char * value;
+ int fError;
+ int clk;
+
+ if ( argc == 0 )
+ return 0;
+
+ if ( cmdCheckShellEscape( pAbc, argc, argv ) == 1 )
+ return 0;
+
+ // get the command
+ if ( !st_lookup( pAbc->tCommands, argv[0], (char **)&pCommand ) )
+ { // the command is not in the table
+ fprintf( pAbc->Err, "** cmd error: unknown command '%s'\n", argv[0] );
+ return 1;
+ }
+
+ // get the backup network if the command is going to change the network
+ if ( pCommand->fChange )
+ {
+ if ( pAbc->pNtkCur )
+ {
+ pNetCopy = Abc_NtkDup( pAbc->pNtkCur );
+ Abc_FrameSetCurrentNetwork( pAbc, pNetCopy );
+ // swap the current network and the backup network
+ // to prevent the effect of resetting the short names
+ Abc_FrameSwapCurrentAndBackup( pAbc );
+ }
+ }
+
+ // execute the command
+ clk = util_cpu_time();
+ pFunc = ( int (*)( Abc_Frame_t *, int, char ** ) ) pCommand->pFunc;
+ fError = (*pFunc)( pAbc, argc, argv );
+ pAbc->TimeCommand += (util_cpu_time() - clk);
+
+// if ( !fError && pCommand->fChange && pAbc->pNtkCur )
+// {
+// Cmd_HistoryAddSnapshot(pAbc, pAbc->pNet);
+// }
+
+ // automatic execution of arbitrary command after each command
+ // usually this is a passive command ...
+ if ( fError == 0 && !pAbc->fAutoexac )
+ {
+ if ( st_lookup( pAbc->tFlags, "autoexec", &value ) )
+ {
+ pAbc->fAutoexac = 1;
+ fError = Cmd_CommandExecute( pAbc, value );
+ pAbc->fAutoexac = 0;
+ }
+ }
+ return fError;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Splits the command line string into individual commands.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * CmdSplitLine( Abc_Frame_t * pAbc, char *sCommand, int *argc, char ***argv )
+{
+ char *p, *start, c;
+ int i, j;
+ char *new_arg;
+ Vec_Ptr_t * vArgs;
+ int single_quote, double_quote;
+
+ vArgs = Vec_PtrAlloc( 10 );
+
+ p = sCommand;
+ for ( ;; )
+ {
+ // skip leading white space
+ while ( isspace( ( int ) *p ) )
+ {
+ p++;
+ }
+
+ // skip until end of this token
+ single_quote = double_quote = 0;
+ for ( start = p; ( c = *p ) != '\0'; p++ )
+ {
+ if ( c == ';' || c == '#' || isspace( ( int ) c ) )
+ {
+ if ( !single_quote && !double_quote )
+ {
+ break;
+ }
+ }
+ if ( c == '\'' )
+ {
+ single_quote = !single_quote;
+ }
+ if ( c == '"' )
+ {
+ double_quote = !double_quote;
+ }
+ }
+ if ( single_quote || double_quote )
+ {
+ ( void ) fprintf( pAbc->Err, "** cmd warning: ignoring unbalanced quote ...\n" );
+ }
+ if ( start == p )
+ break;
+
+ new_arg = ALLOC( char, p - start + 1 );
+ j = 0;
+ for ( i = 0; i < p - start; i++ )
+ {
+ c = start[i];
+ if ( ( c != '\'' ) && ( c != '\"' ) )
+ {
+ new_arg[j++] = isspace( ( int ) c ) ? ' ' : start[i];
+ }
+ }
+ new_arg[j] = '\0';
+ Vec_PtrPush( vArgs, new_arg );
+ }
+
+ *argc = vArgs->nSize;
+ *argv = (char **)Vec_PtrReleaseArray( vArgs );
+ Vec_PtrFree( vArgs );
+ if ( *p == ';' )
+ {
+ p++;
+ }
+ else if ( *p == '#' )
+ {
+ for ( ; *p != 0; p++ ); // skip to end of line
+ }
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Replaces parts of the command line string by aliases if given.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int CmdApplyAlias( Abc_Frame_t * pAbc, int *argcp, char ***argvp, int *loop )
+{
+ int i, argc, stopit, added, offset, did_subst, subst, fError, newc, j;
+ char *arg, **argv, **newv;
+ Abc_Alias *alias;
+
+ argc = *argcp;
+ argv = *argvp;
+ stopit = 0;
+ for ( ; *loop < 20; ( *loop )++ )
+ {
+ if ( argc == 0 )
+ return 0;
+ if ( stopit != 0 || st_lookup( pAbc->tAliases, argv[0], (char **) &alias ) == 0 )
+ {
+ return 0;
+ }
+ if ( strcmp( argv[0], alias->argv[0] ) == 0 )
+ {
+ stopit = 1;
+ }
+ FREE( argv[0] );
+ added = alias->argc - 1;
+
+ /* shift all the arguments to the right */
+ if ( added != 0 )
+ {
+ argv = REALLOC( char *, argv, argc + added );
+ for ( i = argc - 1; i >= 1; i-- )
+ {
+ argv[i + added] = argv[i];
+ }
+ for ( i = 1; i <= added; i++ )
+ {
+ argv[i] = NIL( char );
+ }
+ argc += added;
+ }
+ subst = 0;
+ for ( i = 0, offset = 0; i < alias->argc; i++, offset++ )
+ {
+ arg = CmdHistorySubstitution( pAbc, alias->argv[i], &did_subst );
+ if ( arg == NIL( char ) )
+ {
+ *argcp = argc;
+ *argvp = argv;
+ return ( 1 );
+ }
+ if ( did_subst != 0 )
+ {
+ subst = 1;
+ }
+ fError = 0;
+ do
+ {
+ arg = CmdSplitLine( pAbc, arg, &newc, &newv );
+ /*
+ * If there's a complete `;' terminated command in `arg',
+ * when split_line() returns arg[0] != '\0'.
+ */
+ if ( arg[0] == '\0' )
+ { /* just a bunch of words */
+ break;
+ }
+ fError = CmdApplyAlias( pAbc, &newc, &newv, loop );
+ if ( fError == 0 )
+ {
+ fError = CmdCommandDispatch( pAbc, newc, newv );
+ }
+ CmdFreeArgv( newc, newv );
+ }
+ while ( fError == 0 );
+ if ( fError != 0 )
+ {
+ *argcp = argc;
+ *argvp = argv;
+ return ( 1 );
+ }
+ added = newc - 1;
+ if ( added != 0 )
+ {
+ argv = REALLOC( char *, argv, argc + added );
+ for ( j = argc - 1; j > offset; j-- )
+ {
+ argv[j + added] = argv[j];
+ }
+ argc += added;
+ }
+ for ( j = 0; j <= added; j++ )
+ {
+ argv[j + offset] = newv[j];
+ }
+ FREE( newv );
+ offset += added;
+ }
+ if ( subst == 1 )
+ {
+ for ( i = offset; i < argc; i++ )
+ {
+ FREE( argv[i] );
+ }
+ argc = offset;
+ }
+ *argcp = argc;
+ *argvp = argv;
+ }
+
+ fprintf( pAbc->Err, "** cmd warning: alias loop\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs history substitution (now, disabled).]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * CmdHistorySubstitution( Abc_Frame_t * pAbc, char *line, int *changed )
+{
+ // as of today, no history substitution
+ *changed = 0;
+ return line;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Opens the file with path (now, disabled).]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+FILE * CmdFileOpen( Abc_Frame_t * pAbc, char *sFileName, char *sMode, char **pFileNameReal, int silent )
+{
+ char * sRealName, * sPathUsr, * sPathLib, * sPathAll;
+ FILE * pFile;
+
+ if (strcmp(sFileName, "-") == 0) {
+ if (strcmp(sMode, "w") == 0) {
+ sRealName = util_strsav( "stdout" );
+ pFile = stdout;
+ }
+ else {
+ sRealName = util_strsav( "stdin" );
+ pFile = stdin;
+ }
+ }
+ else {
+ sRealName = NULL;
+ if (strcmp(sMode, "r") == 0) {
+
+ /* combine both pathes if exist */
+ sPathUsr = Cmd_FlagReadByName(pAbc,"open_path");
+ sPathLib = Cmd_FlagReadByName(pAbc,"lib_path");
+
+ if ( sPathUsr == NULL && sPathLib == NULL ) {
+ sPathAll = NULL;
+ }
+ else if ( sPathUsr == NULL ) {
+ sPathAll = util_strsav( sPathLib );
+ }
+ else if ( sPathLib == NULL ) {
+ sPathAll = util_strsav( sPathUsr );
+ }
+ else {
+ sPathAll = ALLOC( char, strlen(sPathLib)+strlen(sPathUsr)+5 );
+ sprintf( sPathAll, "%s:%s",sPathUsr, sPathLib );
+ }
+ if ( sPathAll != NIL(char) ) {
+ sRealName = util_file_search(sFileName, sPathAll, "r");
+ FREE( sPathAll );
+ }
+ }
+ if (sRealName == NIL(char)) {
+ sRealName = util_tilde_expand(sFileName);
+ }
+ if ((pFile = fopen(sRealName, sMode)) == NIL(FILE)) {
+ if (! silent) {
+ perror(sRealName);
+ }
+ }
+ }
+ if ( pFileNameReal )
+ *pFileNameReal = sRealName;
+ else
+ FREE(sRealName);
+
+ return pFile;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the previously allocated argv array.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CmdFreeArgv( int argc, char **argv )
+{
+ int i;
+ for ( i = 0; i < argc; i++ )
+ FREE( argv[i] );
+ FREE( argv );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the previously allocated command.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CmdCommandFree( Abc_Command * pCommand )
+{
+ free( pCommand->sGroup );
+ free( pCommand->sName );
+ free( pCommand );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints commands alphabetically by group.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CmdCommandPrint( Abc_Frame_t * pAbc, bool fPrintAll )
+{
+ char *key, *value;
+ st_generator * gen;
+ Abc_Command ** ppCommands;
+ Abc_Command * pCommands;
+ int nCommands, i;
+ char * sGroupCur;
+ int LenghtMax, nColumns, iCom = 0;
+
+ // put all commands into one array
+ nCommands = st_count( pAbc->tCommands );
+ ppCommands = ALLOC( Abc_Command *, nCommands );
+ i = 0;
+ st_foreach_item( pAbc->tCommands, gen, &key, &value )
+ {
+ pCommands = (Abc_Command *)value;
+ if ( fPrintAll || pCommands->sName[0] != '_' )
+ ppCommands[i++] = pCommands;
+ }
+ nCommands = i;
+
+ // sort command by group and then by name, alphabetically
+ qsort( (void *)ppCommands, nCommands, sizeof(Abc_Command *),
+ (int (*)(const void *, const void *)) CmdCommandPrintCompare );
+ assert( CmdCommandPrintCompare( ppCommands, ppCommands + nCommands - 1 ) <= 0 );
+
+ // get the longest command name
+ LenghtMax = 0;
+ for ( i = 0; i < nCommands; i++ )
+ if ( LenghtMax < (int)strlen(ppCommands[i]->sName) )
+ LenghtMax = (int)strlen(ppCommands[i]->sName);
+ // get the number of columns
+ nColumns = 79 / (LenghtMax + 2);
+
+ // print the starting message
+ fprintf( pAbc->Out, " Welcome to ABC!" );
+
+ // print the command by group
+ sGroupCur = NULL;
+ for ( i = 0; i < nCommands; i++ )
+ if ( sGroupCur && strcmp( sGroupCur, ppCommands[i]->sGroup ) == 0 )
+ { // this command belongs to the same group as the previous one
+ if ( iCom++ % nColumns == 0 )
+ fprintf( pAbc->Out, "\n" );
+ // print this command
+ fprintf( pAbc->Out, " %-*s", LenghtMax, ppCommands[i]->sName );
+ }
+ else
+ { // this command starts the new group of commands
+ // start the new group
+ fprintf( pAbc->Out, "\n" );
+ fprintf( pAbc->Out, "\n" );
+ fprintf( pAbc->Out, "%s commands:\n", ppCommands[i]->sGroup );
+ // print this command
+ fprintf( pAbc->Out, " %-*s", LenghtMax, ppCommands[i]->sName );
+ // remember current command group
+ sGroupCur = ppCommands[i]->sGroup;
+ // reset the command counter
+ iCom = 1;
+ }
+ fprintf( pAbc->Out, "\n" );
+ FREE( ppCommands );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Comparision function used for sorting commands.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int CmdCommandPrintCompare( Abc_Command ** ppC1, Abc_Command ** ppC2 )
+{
+ Abc_Command * pC1 = *ppC1;
+ Abc_Command * pC2 = *ppC2;
+ int RetValue;
+
+ RetValue = strcmp( pC1->sGroup, pC2->sGroup );
+ if ( RetValue < 0 )
+ return -1;
+ if ( RetValue > 0 )
+ return 1;
+ // the command belong to the same group
+
+ // put commands with "_" at the end of the list
+ if ( pC1->sName[0] != '_' && pC2->sName[0] == '_' )
+ return -1;
+ if ( pC1->sName[0] == '_' && pC2->sName[0] != '_' )
+ return 1;
+
+ RetValue = strcmp( pC1->sName, pC2->sName );
+ if ( RetValue < 0 )
+ return -1;
+ if ( RetValue > 0 )
+ return 1;
+ // should not be two indentical commands
+ assert( 0 );
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/base/cmd/module.make b/src/base/cmd/module.make
new file mode 100644
index 00000000..1eca3f65
--- /dev/null
+++ b/src/base/cmd/module.make
@@ -0,0 +1,6 @@
+SRC += src/base/cmd/cmd.c \
+ src/base/cmd/cmdAlias.c \
+ src/base/cmd/cmdApi.c \
+ src/base/cmd/cmdFlag.c \
+ src/base/cmd/cmdHist.c \
+ src/base/cmd/cmdUtils.c