00001
00021 #include "mainInt.h"
00022 #include "abc.h"
00023 #include "cmdInt.h"
00024 #include <ctype.h>
00025
00029
00030 static int CmdCommandPrintCompare( Abc_Command ** ppC1, Abc_Command ** ppC2 );
00031
00035
00047 int cmdCheckShellEscape( Abc_Frame_t * pAbc, int argc, char ** argv)
00048 {
00049 if (argv[0][0] == '!')
00050 {
00051 const int size = 4096;
00052 int i;
00053 char buffer[4096];
00054 strncpy (buffer, &argv[0][1], size);
00055 for (i = 1; i < argc; ++i)
00056 {
00057 strncat (buffer, " ", size);
00058 strncat (buffer, argv[i], size);
00059 }
00060 if (buffer[0] == 0)
00061 strncpy (buffer, "/bin/sh", size);
00062 system (buffer);
00063
00064
00065
00066
00067
00068
00069 return 1;
00070 }
00071 else
00072 {
00073 return 0;
00074 }
00075 }
00076
00088 int CmdCommandDispatch( Abc_Frame_t * pAbc, int argc, char **argv )
00089 {
00090 Abc_Ntk_t * pNetCopy;
00091 int (*pFunc) ( Abc_Frame_t *, int, char ** );
00092 Abc_Command * pCommand;
00093 char * value;
00094 int fError;
00095 int clk;
00096
00097 if ( argc == 0 )
00098 return 0;
00099
00100 if ( cmdCheckShellEscape( pAbc, argc, argv ) == 1 )
00101 return 0;
00102
00103
00104 if ( !st_lookup( pAbc->tCommands, argv[0], (char **)&pCommand ) )
00105 {
00106 fprintf( pAbc->Err, "** cmd error: unknown command '%s'\n", argv[0] );
00107 return 1;
00108 }
00109
00110
00111 if ( pCommand->fChange )
00112 {
00113 if ( pAbc->pNtkCur && Abc_FrameIsFlagEnabled( "backup" ) )
00114 {
00115 pNetCopy = Abc_NtkDup( pAbc->pNtkCur );
00116 Abc_FrameSetCurrentNetwork( pAbc, pNetCopy );
00117
00118
00119 Abc_FrameSwapCurrentAndBackup( pAbc );
00120 }
00121 }
00122
00123
00124 clk = Extra_CpuTime();
00125 pFunc = (int (*)(Abc_Frame_t *, int, char **))pCommand->pFunc;
00126 fError = (*pFunc)( pAbc, argc, argv );
00127 pAbc->TimeCommand += (Extra_CpuTime() - clk);
00128
00129
00130
00131 if ( fError == 0 && !pAbc->fAutoexac )
00132 {
00133 if ( st_lookup( pAbc->tFlags, "autoexec", &value ) )
00134 {
00135 pAbc->fAutoexac = 1;
00136 fError = Cmd_CommandExecute( pAbc, value );
00137 pAbc->fAutoexac = 0;
00138 }
00139 }
00140 return fError;
00141 }
00142
00154 char * CmdSplitLine( Abc_Frame_t * pAbc, char *sCommand, int *argc, char ***argv )
00155 {
00156 char *p, *start, c;
00157 int i, j;
00158 char *new_arg;
00159 Vec_Ptr_t * vArgs;
00160 int single_quote, double_quote;
00161
00162 vArgs = Vec_PtrAlloc( 10 );
00163
00164 p = sCommand;
00165 for ( ;; )
00166 {
00167
00168 while ( isspace( ( int ) *p ) )
00169 {
00170 p++;
00171 }
00172
00173
00174 single_quote = double_quote = 0;
00175 for ( start = p; ( c = *p ) != '\0'; p++ )
00176 {
00177 if ( c == ';' || c == '#' || isspace( ( int ) c ) )
00178 {
00179 if ( !single_quote && !double_quote )
00180 {
00181 break;
00182 }
00183 }
00184 if ( c == '\'' )
00185 {
00186 single_quote = !single_quote;
00187 }
00188 if ( c == '"' )
00189 {
00190 double_quote = !double_quote;
00191 }
00192 }
00193 if ( single_quote || double_quote )
00194 {
00195 ( void ) fprintf( pAbc->Err, "** cmd warning: ignoring unbalanced quote ...\n" );
00196 }
00197 if ( start == p )
00198 break;
00199
00200 new_arg = ALLOC( char, p - start + 1 );
00201 j = 0;
00202 for ( i = 0; i < p - start; i++ )
00203 {
00204 c = start[i];
00205 if ( ( c != '\'' ) && ( c != '\"' ) )
00206 {
00207 new_arg[j++] = isspace( ( int ) c ) ? ' ' : start[i];
00208 }
00209 }
00210 new_arg[j] = '\0';
00211 Vec_PtrPush( vArgs, new_arg );
00212 }
00213
00214 *argc = vArgs->nSize;
00215 *argv = (char **)Vec_PtrReleaseArray( vArgs );
00216 Vec_PtrFree( vArgs );
00217 if ( *p == ';' )
00218 {
00219 p++;
00220 }
00221 else if ( *p == '#' )
00222 {
00223 for ( ; *p != 0; p++ );
00224 }
00225 return p;
00226 }
00227
00239 int CmdApplyAlias( Abc_Frame_t * pAbc, int *argcp, char ***argvp, int *loop )
00240 {
00241 int i, argc, stopit, added, offset, did_subst, subst, fError, newc, j;
00242 char *arg, **argv, **newv;
00243 Abc_Alias *alias;
00244
00245 argc = *argcp;
00246 argv = *argvp;
00247 stopit = 0;
00248 for ( ; *loop < 200; ( *loop )++ )
00249 {
00250 if ( argc == 0 )
00251 return 0;
00252 if ( stopit != 0 || st_lookup( pAbc->tAliases, argv[0], (char **) &alias ) == 0 )
00253 {
00254 return 0;
00255 }
00256 if ( strcmp( argv[0], alias->argv[0] ) == 0 )
00257 {
00258 stopit = 1;
00259 }
00260 FREE( argv[0] );
00261 added = alias->argc - 1;
00262
00263
00264 if ( added != 0 )
00265 {
00266 argv = REALLOC( char *, argv, argc + added );
00267 for ( i = argc - 1; i >= 1; i-- )
00268 {
00269 argv[i + added] = argv[i];
00270 }
00271 for ( i = 1; i <= added; i++ )
00272 {
00273 argv[i] = NULL;
00274 }
00275 argc += added;
00276 }
00277 subst = 0;
00278 for ( i = 0, offset = 0; i < alias->argc; i++, offset++ )
00279 {
00280 arg = CmdHistorySubstitution( pAbc, alias->argv[i], &did_subst );
00281 if ( arg == NULL )
00282 {
00283 *argcp = argc;
00284 *argvp = argv;
00285 return ( 1 );
00286 }
00287 if ( did_subst != 0 )
00288 {
00289 subst = 1;
00290 }
00291 fError = 0;
00292 do
00293 {
00294 arg = CmdSplitLine( pAbc, arg, &newc, &newv );
00295
00296
00297
00298
00299 if ( arg[0] == '\0' )
00300 {
00301 break;
00302 }
00303 fError = CmdApplyAlias( pAbc, &newc, &newv, loop );
00304 if ( fError == 0 )
00305 {
00306 fError = CmdCommandDispatch( pAbc, newc, newv );
00307 }
00308 CmdFreeArgv( newc, newv );
00309 }
00310 while ( fError == 0 );
00311 if ( fError != 0 )
00312 {
00313 *argcp = argc;
00314 *argvp = argv;
00315 return ( 1 );
00316 }
00317 added = newc - 1;
00318 if ( added != 0 )
00319 {
00320 argv = REALLOC( char *, argv, argc + added );
00321 for ( j = argc - 1; j > offset; j-- )
00322 {
00323 argv[j + added] = argv[j];
00324 }
00325 argc += added;
00326 }
00327 for ( j = 0; j <= added; j++ )
00328 {
00329 argv[j + offset] = newv[j];
00330 }
00331 FREE( newv );
00332 offset += added;
00333 }
00334 if ( subst == 1 )
00335 {
00336 for ( i = offset; i < argc; i++ )
00337 {
00338 FREE( argv[i] );
00339 }
00340 argc = offset;
00341 }
00342 *argcp = argc;
00343 *argvp = argv;
00344 }
00345
00346 fprintf( pAbc->Err, "** cmd warning: alias loop\n" );
00347 return 1;
00348 }
00349
00361 char * CmdHistorySubstitution( Abc_Frame_t * pAbc, char *line, int *changed )
00362 {
00363
00364 *changed = 0;
00365 return line;
00366 }
00367
00379 FILE * CmdFileOpen( Abc_Frame_t * pAbc, char *sFileName, char *sMode, char **pFileNameReal, int silent )
00380 {
00381 char * sRealName, * sPathUsr, * sPathLib, * sPathAll;
00382 FILE * pFile;
00383
00384 if (strcmp(sFileName, "-") == 0) {
00385 if (strcmp(sMode, "w") == 0) {
00386 sRealName = Extra_UtilStrsav( "stdout" );
00387 pFile = stdout;
00388 }
00389 else {
00390 sRealName = Extra_UtilStrsav( "stdin" );
00391 pFile = stdin;
00392 }
00393 }
00394 else {
00395 sRealName = NULL;
00396 if (strcmp(sMode, "r") == 0) {
00397
00398
00399 sPathUsr = Cmd_FlagReadByName(pAbc,"open_path");
00400 sPathLib = Cmd_FlagReadByName(pAbc,"lib_path");
00401
00402 if ( sPathUsr == NULL && sPathLib == NULL ) {
00403 sPathAll = NULL;
00404 }
00405 else if ( sPathUsr == NULL ) {
00406 sPathAll = Extra_UtilStrsav( sPathLib );
00407 }
00408 else if ( sPathLib == NULL ) {
00409 sPathAll = Extra_UtilStrsav( sPathUsr );
00410 }
00411 else {
00412 sPathAll = ALLOC( char, strlen(sPathLib)+strlen(sPathUsr)+5 );
00413 sprintf( sPathAll, "%s:%s",sPathUsr, sPathLib );
00414 }
00415 if ( sPathAll != NULL ) {
00416 sRealName = Extra_UtilFileSearch(sFileName, sPathAll, "r");
00417 FREE( sPathAll );
00418 }
00419 }
00420 if (sRealName == NULL) {
00421 sRealName = Extra_UtilTildeExpand(sFileName);
00422 }
00423 if ((pFile = fopen(sRealName, sMode)) == NULL) {
00424 if (! silent) {
00425 perror(sRealName);
00426 }
00427 }
00428 }
00429 if ( pFileNameReal )
00430 *pFileNameReal = sRealName;
00431 else
00432 FREE(sRealName);
00433
00434 return pFile;
00435 }
00436
00448 void CmdFreeArgv( int argc, char **argv )
00449 {
00450 int i;
00451 for ( i = 0; i < argc; i++ )
00452 FREE( argv[i] );
00453 FREE( argv );
00454 }
00455
00467 void CmdCommandFree( Abc_Command * pCommand )
00468 {
00469 free( pCommand->sGroup );
00470 free( pCommand->sName );
00471 free( pCommand );
00472 }
00473
00474
00486 void CmdCommandPrint( Abc_Frame_t * pAbc, bool fPrintAll )
00487 {
00488 char *key, *value;
00489 st_generator * gen;
00490 Abc_Command ** ppCommands;
00491 Abc_Command * pCommands;
00492 int nCommands, i;
00493 char * sGroupCur;
00494 int LenghtMax, nColumns, iCom = 0;
00495
00496
00497 nCommands = st_count( pAbc->tCommands );
00498 ppCommands = ALLOC( Abc_Command *, nCommands );
00499 i = 0;
00500 st_foreach_item( pAbc->tCommands, gen, &key, &value )
00501 {
00502 pCommands = (Abc_Command *)value;
00503 if ( fPrintAll || pCommands->sName[0] != '_' )
00504 ppCommands[i++] = pCommands;
00505 }
00506 nCommands = i;
00507
00508
00509 qsort( (void *)ppCommands, nCommands, sizeof(Abc_Command *),
00510 (int (*)(const void *, const void *)) CmdCommandPrintCompare );
00511 assert( CmdCommandPrintCompare( ppCommands, ppCommands + nCommands - 1 ) <= 0 );
00512
00513
00514 LenghtMax = 0;
00515 for ( i = 0; i < nCommands; i++ )
00516 if ( LenghtMax < (int)strlen(ppCommands[i]->sName) )
00517 LenghtMax = (int)strlen(ppCommands[i]->sName);
00518
00519 nColumns = 79 / (LenghtMax + 2);
00520
00521
00522 fprintf( pAbc->Out, " Welcome to ABC!" );
00523
00524
00525 sGroupCur = NULL;
00526 for ( i = 0; i < nCommands; i++ )
00527 if ( sGroupCur && strcmp( sGroupCur, ppCommands[i]->sGroup ) == 0 )
00528 {
00529 if ( iCom++ % nColumns == 0 )
00530 fprintf( pAbc->Out, "\n" );
00531
00532 fprintf( pAbc->Out, " %-*s", LenghtMax, ppCommands[i]->sName );
00533 }
00534 else
00535 {
00536
00537 fprintf( pAbc->Out, "\n" );
00538 fprintf( pAbc->Out, "\n" );
00539 fprintf( pAbc->Out, "%s commands:\n", ppCommands[i]->sGroup );
00540
00541 fprintf( pAbc->Out, " %-*s", LenghtMax, ppCommands[i]->sName );
00542
00543 sGroupCur = ppCommands[i]->sGroup;
00544
00545 iCom = 1;
00546 }
00547 fprintf( pAbc->Out, "\n" );
00548 FREE( ppCommands );
00549 }
00550
00562 int CmdCommandPrintCompare( Abc_Command ** ppC1, Abc_Command ** ppC2 )
00563 {
00564 Abc_Command * pC1 = *ppC1;
00565 Abc_Command * pC2 = *ppC2;
00566 int RetValue;
00567
00568 RetValue = strcmp( pC1->sGroup, pC2->sGroup );
00569 if ( RetValue < 0 )
00570 return -1;
00571 if ( RetValue > 0 )
00572 return 1;
00573
00574
00575
00576 if ( pC1->sName[0] != '_' && pC2->sName[0] == '_' )
00577 return -1;
00578 if ( pC1->sName[0] == '_' && pC2->sName[0] != '_' )
00579 return 1;
00580
00581 RetValue = strcmp( pC1->sName, pC2->sName );
00582 if ( RetValue < 0 )
00583 return -1;
00584 if ( RetValue > 0 )
00585 return 1;
00586
00587 assert( 0 );
00588 return 0;
00589 }
00590
00602 int CmdNamePrintCompare( char ** ppC1, char ** ppC2 )
00603 {
00604 return strcmp( *ppC1, *ppC2 );
00605 }
00606
00618 void CmdPrintTable( st_table * tTable, int fAliases )
00619 {
00620 st_generator * gen;
00621 char ** ppNames;
00622 char * key, * value;
00623 int nNames, i;
00624
00625
00626 ppNames = ALLOC( char *, st_count(tTable) );
00627 nNames = 0;
00628 st_foreach_item( tTable, gen, &key, &value )
00629 ppNames[nNames++] = key;
00630
00631
00632 qsort( (void *)ppNames, nNames, sizeof(char *),
00633 (int (*)(const void *, const void *))CmdNamePrintCompare );
00634
00635
00636 for ( i = 0; i < nNames; i++ )
00637 {
00638 st_lookup( tTable, ppNames[i], &value );
00639 if ( fAliases )
00640 CmdCommandAliasPrint( Abc_FrameGetGlobalFrame(), (Abc_Alias *)value );
00641 else
00642 fprintf( stdout, "%-15s %-15s\n", ppNames[i], value );
00643 }
00644 free( ppNames );
00645 }
00646