src/base/cmd/cmdUtils.c File Reference

#include "mainInt.h"
#include "abc.h"
#include "cmdInt.h"
#include <ctype.h>
Include dependency graph for cmdUtils.c:

Go to the source code of this file.

Functions

static int CmdCommandPrintCompare (Abc_Command **ppC1, Abc_Command **ppC2)
int cmdCheckShellEscape (Abc_Frame_t *pAbc, int argc, char **argv)
int CmdCommandDispatch (Abc_Frame_t *pAbc, int argc, char **argv)
char * CmdSplitLine (Abc_Frame_t *pAbc, char *sCommand, int *argc, char ***argv)
int CmdApplyAlias (Abc_Frame_t *pAbc, int *argcp, char ***argvp, int *loop)
char * CmdHistorySubstitution (Abc_Frame_t *pAbc, char *line, int *changed)
FILE * CmdFileOpen (Abc_Frame_t *pAbc, char *sFileName, char *sMode, char **pFileNameReal, int silent)
void CmdFreeArgv (int argc, char **argv)
void CmdCommandFree (Abc_Command *pCommand)
void CmdCommandPrint (Abc_Frame_t *pAbc, bool fPrintAll)
int CmdNamePrintCompare (char **ppC1, char **ppC2)
void CmdPrintTable (st_table *tTable, int fAliases)

Function Documentation

int CmdApplyAlias ( Abc_Frame_t pAbc,
int *  argcp,
char ***  argvp,
int *  loop 
)

Function*************************************************************

Synopsis [Replaces parts of the command line string by aliases if given.]

Description []

SideEffects []

SeeAlso []

Definition at line 239 of file cmdUtils.c.

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         /* shift all the arguments to the right */
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                  * If there's a complete `;' terminated command in `arg',
00297                  * when split_line() returns arg[0] != '\0'.
00298                  */
00299                 if ( arg[0] == '\0' )
00300                 { /* just a bunch of words */
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 }

int cmdCheckShellEscape ( Abc_Frame_t pAbc,
int  argc,
char **  argv 
)

FUNCTION DEFINITIONS ///Function*************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 47 of file cmdUtils.c.

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                 // NOTE: Since we reconstruct the cmdline by concatenating
00065                 // the parts, we lose information. So a command like
00066                 // `!ls "file name"` will be sent to the system as
00067                 // `ls file name` which is a BUG
00068 
00069         return 1;
00070         }
00071         else
00072         {
00073                 return 0;
00074         }
00075 }

int CmdCommandDispatch ( Abc_Frame_t pAbc,
int  argc,
char **  argv 
)

Function*************************************************************

Synopsis [Executes one command.]

Description []

SideEffects []

SeeAlso []

Definition at line 88 of file cmdUtils.c.

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     // get the command
00104     if ( !st_lookup( pAbc->tCommands, argv[0], (char **)&pCommand ) )
00105     {   // the command is not in the table
00106         fprintf( pAbc->Err, "** cmd error: unknown command '%s'\n", argv[0] );
00107         return 1;
00108     }
00109 
00110     // get the backup network if the command is going to change the network
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             // swap the current network and the backup network 
00118             // to prevent the effect of resetting the short names
00119             Abc_FrameSwapCurrentAndBackup( pAbc );
00120         }
00121     }
00122 
00123     // execute the command
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     // automatic execution of arbitrary command after each command 
00130     // usually this is a passive command ... 
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 }

void CmdCommandFree ( Abc_Command pCommand  ) 

Function*************************************************************

Synopsis [Frees the previously allocated command.]

Description []

SideEffects []

SeeAlso []

Definition at line 467 of file cmdUtils.c.

00468 {
00469     free( pCommand->sGroup );
00470     free( pCommand->sName );
00471     free( pCommand );
00472 }

void CmdCommandPrint ( Abc_Frame_t pAbc,
bool  fPrintAll 
)

Function*************************************************************

Synopsis [Prints commands alphabetically by group.]

Description []

SideEffects []

SeeAlso []

Definition at line 486 of file cmdUtils.c.

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     // put all commands into one array
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     // sort command by group and then by name, alphabetically
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     // get the longest command name
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     // get the number of columns
00519     nColumns = 79 / (LenghtMax + 2);
00520 
00521     // print the starting message 
00522     fprintf( pAbc->Out, "                        Welcome to ABC!" );
00523 
00524     // print the command by group
00525     sGroupCur = NULL;
00526     for ( i = 0; i < nCommands; i++ )
00527         if ( sGroupCur && strcmp( sGroupCur, ppCommands[i]->sGroup ) == 0 )
00528         { // this command belongs to the same group as the previous one
00529             if ( iCom++ % nColumns == 0 )
00530                 fprintf( pAbc->Out, "\n" ); 
00531             // print this command
00532             fprintf( pAbc->Out, " %-*s", LenghtMax, ppCommands[i]->sName );
00533         }
00534         else
00535         { // this command starts the new group of commands
00536             // start the new group
00537             fprintf( pAbc->Out, "\n" );
00538             fprintf( pAbc->Out, "\n" );
00539             fprintf( pAbc->Out, "%s commands:\n", ppCommands[i]->sGroup );
00540             // print this command
00541             fprintf( pAbc->Out, " %-*s", LenghtMax, ppCommands[i]->sName );
00542             // remember current command group
00543             sGroupCur = ppCommands[i]->sGroup;
00544             // reset the command counter
00545             iCom = 1;
00546         }
00547     fprintf( pAbc->Out, "\n" );
00548     FREE( ppCommands );
00549 }

int CmdCommandPrintCompare ( Abc_Command **  ppC1,
Abc_Command **  ppC2 
) [static]

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

] DECLARATIONS ///

Function*************************************************************

Synopsis [Comparision function used for sorting commands.]

Description []

SideEffects []

SeeAlso []

Definition at line 562 of file cmdUtils.c.

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     // the command belong to the same group
00574 
00575     // put commands with "_" at the end of the list
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      // should not be two indentical commands
00587     assert( 0 );
00588     return 0;
00589 }

FILE* CmdFileOpen ( Abc_Frame_t pAbc,
char *  sFileName,
char *  sMode,
char **  pFileNameReal,
int  silent 
)

Function*************************************************************

Synopsis [Opens the file with path (now, disabled).]

Description []

SideEffects []

SeeAlso []

Definition at line 379 of file cmdUtils.c.

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             /* combine both pathes if exist */
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 }

void CmdFreeArgv ( int  argc,
char **  argv 
)

Function*************************************************************

Synopsis [Frees the previously allocated argv array.]

Description []

SideEffects []

SeeAlso []

Definition at line 448 of file cmdUtils.c.

00449 {
00450     int i;
00451     for ( i = 0; i < argc; i++ )
00452         FREE( argv[i] );
00453     FREE( argv );
00454 }

char* CmdHistorySubstitution ( Abc_Frame_t pAbc,
char *  line,
int *  changed 
)

Function*************************************************************

Synopsis [Performs history substitution (now, disabled).]

Description []

SideEffects []

SeeAlso []

Definition at line 361 of file cmdUtils.c.

00362 {
00363     // as of today, no history substitution 
00364     *changed = 0;
00365     return line;
00366 }

int CmdNamePrintCompare ( char **  ppC1,
char **  ppC2 
)

Function*************************************************************

Synopsis [Comparision function used for sorting commands.]

Description []

SideEffects []

SeeAlso []

Definition at line 602 of file cmdUtils.c.

00603 {
00604     return strcmp( *ppC1, *ppC2 );
00605 }

void CmdPrintTable ( st_table tTable,
int  fAliases 
)

Function*************************************************************

Synopsis [Comparision function used for sorting commands.]

Description []

SideEffects []

SeeAlso []

Definition at line 618 of file cmdUtils.c.

00619 {
00620     st_generator * gen;
00621     char ** ppNames;
00622     char * key, * value;
00623     int nNames, i;
00624 
00625     // collect keys in the array
00626     ppNames = ALLOC( char *, st_count(tTable) );
00627     nNames = 0;
00628     st_foreach_item( tTable, gen, &key, &value )
00629         ppNames[nNames++] = key;
00630 
00631     // sort array by name
00632     qsort( (void *)ppNames, nNames, sizeof(char *), 
00633         (int (*)(const void *, const void *))CmdNamePrintCompare );
00634 
00635     // print in this order
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 }

char* CmdSplitLine ( Abc_Frame_t pAbc,
char *  sCommand,
int *  argc,
char ***  argv 
)

Function*************************************************************

Synopsis [Splits the command line string into individual commands.]

Description []

SideEffects []

SeeAlso []

Definition at line 154 of file cmdUtils.c.

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         // skip leading white space 
00168         while ( isspace( ( int ) *p ) )
00169         {
00170             p++;
00171         }
00172 
00173         // skip until end of this token 
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++ ); // skip to end of line 
00224     }
00225     return p;
00226 }


Generated on Tue Jan 5 12:18:44 2010 for abc70930 by  doxygen 1.6.1