/* * Take a command string and break it up into an argc, argv list while * handling quoting and wildcards. The returned argument list and * strings are in static memory, and so are overwritten on each call. * The argument list is ended with a NULL pointer for convenience. * Returns TRUE if successful, or FALSE on an error with a message * already output. */ BOOL makeArgs(const char * cmd, int * retArgc, const char *** retArgv) { const char * argument; char * cp; char * cpOut; char * newStrings; const char ** fileTable; const char ** newArgTable; int newArgTableSize; int fileCount; int len; int ch; int quote; BOOL quotedWildCards; BOOL unquotedWildCards; static int stringsLength; static char * strings; static int argCount; static int argTableSize; static const char ** argTable; /* * Clear the returned values until we know them. */ argCount = 0; *retArgc = 0; *retArgv = NULL; /* * Copy the command string into a buffer that we can modify, * reallocating it if necessary. */ len = strlen(cmd) + 1; if (len > stringsLength) { newStrings = realloc(strings, len); if (newStrings == NULL) { fprintf(stderr, "Cannot allocate string\n"); return FALSE; } strings = newStrings; stringsLength = len; } memcpy(strings, cmd, len); cp = strings; /* * Keep parsing the command string as long as there are any * arguments left. */ while (*cp) { /* * Save the beginning of this argument. */ argument = cp; cpOut = cp; /* * Reset quoting and wildcarding for this argument. */ quote = '\0'; quotedWildCards = FALSE; unquotedWildCards = FALSE; /* * Loop over the string collecting the next argument while * looking for quoted strings or quoted characters, and * remembering whether there are any wildcard characters * in the argument. */ while (*cp) { ch = *cp++; /* * If we are not in a quote and we see a blank then * this argument is done. */ if (isBlank(ch) && (quote == '\0')) break; /* * If we see a backslash then accept the next * character no matter what it is. */ if (ch == '\\') { ch = *cp++; /* * Make sure there is a next character. */ if (ch == '\0') { fprintf(stderr, "Bad quoted character\n"); return FALSE; } /* * Remember whether the quoted character * is a wildcard. */ if (isWildCard(ch)) quotedWildCards = TRUE; *cpOut++ = ch; continue; } /* * If we see one of the wildcard characters then * remember whether it was seen inside or outside * of quotes. */ if (isWildCard(ch)) { if (quote) quotedWildCards = TRUE; else unquotedWildCards = TRUE; } /* * If we were in a quote and we saw the same quote * character again then the quote is done. */ if (ch == quote) { quote = '\0'; continue; } /* * If we weren't in a quote and we see either type * of quote character, then remember that we are * now inside of a quote. */ if ((quote == '\0') && ((ch == '\'') || (ch == '"'))) { quote = ch; continue; } /* * Store the character. */ *cpOut++ = ch; } /* * Make sure that quoting is terminated properly. */ if (quote) { fprintf(stderr, "Unmatched quote character\n"); return FALSE; } /* * Null terminate the argument if it had shrunk, and then * skip over all blanks to the next argument, nulling them * out too. */ if (cp != cpOut) *cpOut = '\0'; while (isBlank(*cp)) *cp++ = '\0'; /* * If both quoted and unquoted wildcards were used then * complain since we don't handle them properly. */ if (quotedWildCards && unquotedWildCards) { fprintf(stderr, "Cannot use quoted and unquoted wildcards\n"); return FALSE; } /* * Expand the argument into the matching filenames or accept * it as is depending on whether there were any unquoted * wildcard characters in it. */ if (unquotedWildCards) { /* * Expand the argument into the matching filenames. */ fileCount = expandWildCards(argument, &fileTable); /* * Return an error if the wildcards failed to match. */ if (fileCount < 0) return FALSE; if (fileCount == 0) { fprintf(stderr, "Wildcard expansion error\n"); return FALSE; } } else { /* * Set up to only store the argument itself. */ fileTable = &argument; fileCount = 1; } /* * Now reallocate the argument table to hold the file name. */ if (argCount + fileCount >= argTableSize) { newArgTableSize = argCount + fileCount + 1; newArgTable = (const char **) realloc(argTable, (sizeof(const char *) * newArgTableSize)); if (newArgTable == NULL) { fprintf(stderr, "No memory for arg list\n"); return FALSE; } argTable = newArgTable; argTableSize = newArgTableSize; } /* * Copy the new arguments to the end of the old ones. */ memcpy((void *) &argTable[argCount], (const void *) fileTable, (sizeof(const char **) * fileCount)); /* * Add to the argument count. */ argCount += fileCount; } /* * Null terminate the argument list and return it. */ argTable[argCount] = NULL; /*arithmetic part code*/ int i; int j; int flag = 1; int res; char *env; static char *result = NULL; if (result == NULL) { result = malloc(sizeof (char) * 256); if (result == NULL) { fprintf(stderr, "Memory error\n"); return FALSE; } } for ( i = 0; i < argCount; i++) { if (argTable[i][0] == '$') { if (argTable[i][1] == '(') { memcpy(result, argTable[i], strlen(argTable[i])); for (j = 2; argTable[i][j] != '\0'; j++) { if (isdigit(result[j])) flag = 0; else if (result[j] == '+' || result[j] == '-' || result[j] == 'x' || result[j] == '/') { if (flag == 1) { fprintf(stderr, "Wrong arithmetic expression\n"); return FALSE; } flag = 1; } else if (result[j] == ')') { result[j] = '\0'; if (result[j + 1] != '\0') { fprintf(stderr, "Wrong arithmetic expression\n"); return FALSE; } } else { fprintf(stderr, "Wrong arithmetic expression\n"); return FALSE; } } res = eval_expr(&result[2]); sprintf(result, "%d", res); argTable[i] = result; } else { env = getenv(&argTable[i][1]); if (env != NULL) argTable[i] = env; else argTable[i] = "\0"; } } } *retArgc = argCount; *retArgv = argTable; return TRUE; }
/* * Take a command string and break it up into an argc, argv list while * handling quoting and wildcards. The returned argument list and * strings are in static memory, and so are overwritten on each call. * The argument list is ended with a NULL pointer for convenience. * Returns TRUE if successful, or FALSE on an error with a message * already output. */ BOOL makeArgs(const char * cmd, int * retArgc, const char *** retArgv) { const char * argument; char * cp; char * cpOut; char * newStrings; const char ** fileTable; const char ** newArgTable; int newArgTableSize; int fileCount; int len; int ch; int quote; BOOL quotedWildCards; BOOL unquotedWildCards; BOOL dollarMode; static int stringsLength; static char * strings; static int argCount; static int argTableSize; static const char ** argTable; /* * Clear the returned values until we know them. */ argCount = 0; *retArgc = 0; *retArgv = NULL; /* * Copy the command string into a buffer that we can modify, * reallocating it if necessary. */ len = strlen(cmd) + 1; if (len > stringsLength) { newStrings = realloc(strings, len); if (newStrings == NULL) { fprintf(stderr, "Cannot allocate string\n"); return FALSE; } strings = newStrings; stringsLength = len; } memcpy(strings, cmd, len); cp = strings; /* * Keep parsing the command string as long as there are any * arguments left. */ while (*cp) { /* * Save the beginning of this argument. */ argument = cp; cpOut = cp; /* * Reset quoting and wildcarding for this argument. */ quote = '\0'; quotedWildCards = FALSE; unquotedWildCards = FALSE; dollarMode = FALSE; /* * Loop over the string collecting the next argument while * looking for quoted strings or quoted characters, and * remembering whether there are any wildcard characters * in the argument. */ while (*cp) { ch = *cp++; /* * If we are not in a quote and we see a blank then * this argument is done. */ if (isBlank(ch) && (quote == '\0')) break; /* * If we see a backslash then accept the next * character no matter what it is. */ if (ch == '\\') { ch = *cp++; /* * Make sure there is a next character. */ if (ch == '\0') { fprintf(stderr, "Bad quoted character\n"); return FALSE; } /* * Remember whether the quoted character * is a wildcard. */ if (isWildCard(ch)) quotedWildCards = TRUE; *cpOut++ = ch; continue; } /* * If we see one of the wildcard characters then * remember whether it was seen inside or outside * of quotes. */ if (isWildCard(ch) && !dollarMode) { if (quote) quotedWildCards = TRUE; else unquotedWildCards = TRUE; } /* * If we were in a quote and we saw the same quote * character again then the quote is done. */ if (ch == quote) { quote = '\0'; continue; } /* * If we weren't in a quote and we see either type * of quote character, then remember that we are * now inside of a quote. */ if ((quote == '\0') && ((ch == '\'') || (ch == '"'))) { quote = ch; continue; } /* * TP1 * If we see a $ */ if(ch == '$' && !quote) { dollarMode = TRUE; } /* * Store the character. */ *cpOut++ = ch; } /* * Make sure that quoting is terminated properly. */ if (quote) { fprintf(stderr, "Unmatched quote character\n"); return FALSE; } /* * Null terminate the argument if it had shrunk, and then * skip over all blanks to the next argument, nulling them * out too. */ if (cp != cpOut) *cpOut = '\0'; while (isBlank(*cp)) *cp++ = '\0'; if(dollarMode) { if(*(argument+1)=='$'){ char* buff = (char*)malloc(5*sizeof(char)); sprintf(buff,"%d",getpid()); argument=buff; }else if(*(argument+1)=='['){ char* buff = (char*)malloc((strlen(argument)-3)*sizeof(char)); strncpy(buff,argument+2,strlen(argument)-3); printf("test %s\n",infixToPrefix(buff)); }else{ argument=getenv(argument+1); } } /* * If both quoted and unquoted wildcards were used then * complain since we don't handle them properly. */ if (quotedWildCards && unquotedWildCards) { fprintf(stderr, "Cannot use quoted and unquoted wildcards\n"); return FALSE; } /* * Expand the argument into the matching filenames or accept * it as is depending on whether there were any unquoted * wildcard characters in it. */ if (unquotedWildCards) { /* * Expand the argument into the matching filenames. */ fileCount = expandWildCards(argument, &fileTable); /* * Return an error if the wildcards failed to match. */ if (fileCount < 0) return FALSE; if (fileCount == 0) { fprintf(stderr, "Wildcard expansion error\n"); return FALSE; } } else { /* * Set up to only store the argument itself. */ fileTable = &argument; fileCount = 1; } /* * Now reallocate the argument table to hold the file name. */ if (argCount + fileCount >= argTableSize) { newArgTableSize = argCount + fileCount + 1; newArgTable = (const char **) realloc(argTable, (sizeof(const char *) * newArgTableSize)); if (newArgTable == NULL) { fprintf(stderr, "No memory for arg list\n"); return FALSE; } argTable = newArgTable; argTableSize = newArgTableSize; } /* * Copy the new arguments to the end of the old ones. */ memcpy((void *) &argTable[argCount], (const void *) fileTable, (sizeof(const char **) * fileCount)); /* * Add to the argument count. */ argCount += fileCount; } /* * Null terminate the argument list and return it. */ argTable[argCount] = NULL; *retArgc = argCount; *retArgv = argTable; return TRUE; }
void expandFileNames( char *string, STRINGLIST **sourceList, STRINGLIST **macroList ) { char *s, *t = NULL; STRINGLIST *p; // Main list pointer STRINGLIST *pNew, // Pointer to new list *pBack; // Pointer to one element back char *saveText = NULL; for (pBack = NULL, p = *sourceList; p;) { // If no expand-character is found, continue to next list element. if (!_tcspbrk(p->text, string)) { pBack = p; p = pBack->next; continue; } // Either expand macros or wildcards. if (*string == '$') { t = expandMacros(p->text, macroList); FREE(p->text); } else { // If the wildcard string does not expand to anything, go to // next list elment. Do not remove p from the original list // else we must check for null elsewhere. // -- do not attempt to expand wildcards that // occur in inference rules if (isRule(p->text) || (pNew = expandWildCards(p->text)) == NULL) { pBack = p; p = pBack->next; continue; } saveText = p->text; } // At this point we have a list of expanded names to replace p with. if (pBack) { pBack->next = p->next; FREE_STRINGLIST(p); p = pBack->next; } else { *sourceList = p->next; FREE_STRINGLIST(p); p = *sourceList; } if (*string == '$') { // if expanding macros char *str = t; if ((s = nextComponent(&str))) { do { // put expanded names pNew = makeNewStrListElement(); // at front of list pNew->text = makeString(s); // so we won't try to prependItem(sourceList, pNew); // re-expand them if (!pBack) pBack = pNew; } while ((s = nextComponent(&str))); } FREE(t); continue; } else if (pNew) { // if matches for * ? if (!pBack) for (pBack = pNew; pBack->next; pBack = pBack->next) ; appendItem(&pNew, *sourceList); // put at front of old list *sourceList = pNew; } FREE(saveText); } }