Param_t *parseStrings(char* str, Param_t *param) { //test input redirect if(isInputRedirect(str)) { if(param->inputRedirect != NULL) printf("input redirect is already filled"); else param->inputRedirect = str; } //test output redirect else if(isOutputRedirect(str)) { if(param->outputRedirect != NULL) printf("output redirect is already filled"); else param->outputRedirect = str; } //test background else if(isBackground(str)) { param->background = 1; } else { //add all other parameters to the argument vector //param->argumentvector[i] } return param; }
/** * Parse Tokens * Description: Takes a TokenList and a Command object and parses the TokenList in order * to generate a command (list of programs in a pipeline); * Returns: true on success; false otherwise */ bool parseTokens( TokenList tokens, Command * command ) { bool success = true; Program *currentProgram = command->program = newProgram(); bool begin = true; for (int i = 0; i < tokens.count; i++) { char * token = tokens.tokens[i]; // Check if we are at the beginning of a program if ( begin ) { if ( strncmp( token, "time", max( strlen( token ), strlen( "time" ) ) ) == 0 ) { currentProgram->name = token; currentProgram->next = newProgram(); currentProgram = currentProgram->next; begin = true; // If we have at least two tokens left and the next one is a pipe // then make a blank timed program // Note: This doesn't do anything since we don't allow // piped time commands but this would help support it // in the future and it currently prevents better // error checking if ( i + 2 < tokens.count && isPipe( tokens.tokens[i+1] ) ) { currentProgram->name = NULL; currentProgram->next = newProgram(); currentProgram = currentProgram->next; i++; } // The beginning of a program cannot be <, >, &, or | } else if ( !isRedirection( token ) && !isPipe( token ) && !isBackground( token ) ) { currentProgram->name = token; currentProgram->argv[currentProgram->argc++] = token; // Don't come back here again until we process a new program begin = false; } else { error("Program may not start with <, >, |, or &"); success = false; break; } } else { // Process redirection if ( isRedirection( token ) ) { // Only one level of redirection allowed if ( currentProgram->redirect == DEFAULT ) { // Need to have at least one token after a redirect if ( i+1 < tokens.count ) { if ( !isRedirection(tokens.tokens[i+1]) && !isPipe(tokens.tokens[i+1]) && !isBackground(tokens.tokens[i+1]) ) { currentProgram->redirectResource = tokens.tokens[i+1]; currentProgram->redirect = getRedirect( token ); // Skip a token i++; } else { error("Expected file after a redirect"); success = false; break; } } // We can have redirections like <file or >file else if ( strlen( token ) > 1 ) { currentProgram->redirectResource = token+1; currentProgram->redirect = getRedirect( token ); } else { error("Expected file after a redirect"); success = false; break; } } else { error("Only one level of redirection allowed"); success = false; break; } // Process pipe } else if ( isPipe( token ) ) { // Check if there's a token after this one if ( i+1 < tokens.count ) { currentProgram->next = newProgram(); currentProgram = currentProgram->next; begin = true; } else { error("Expected program after pipe"); success = false; break; } // Process background } else if ( isBackground( token ) ) { // & must be last token if ( i+1 >= tokens.count ) command->background = true; else { error("& can only be placed at end of command"); success = false; } break; } // Plain old argument else currentProgram->argv[currentProgram->argc++] = token; } } return success; }