BufferState Tokenizer::bufferType(char ch) { string chStr = string(1, ch); if (isLetter(ch)) { return BufferState::VariableOrKeywordState; } else if (isSpecialToken(ch)) { return BufferState::SpecialTokenState; } else if (isDigit(ch)) { return BufferState::IntConstantState; } else if (ch == '\"') { return BufferState::StringConstantState; } else if (isWhitespace(ch)) { return BufferState::WhiteSpaceState; } else if (ch == '#') { return BufferState::CommentState; } else if (isOperatorSubstring(chStr)) { return BufferState::OperatorState; } else { return BufferState::ErrorState; } }
void execTokens(int numTokens, char** tokens) { pipeline* pl = malloc(sizeof(pipeline)); pl->next = NULL; pl->command = NULL; pipeline* lastPipe = pl; bool hasFileIn = false; int fileIn[2]; // pretends to be a pipe to pass to execSimple // actually just a regular array bool hasSpecial = false; int i; for(i = 0; i < numTokens; hasSpecial = false) { simpleCmd* cmd = malloc(sizeof(simpleCmd)); cmd->name = tokens[i]; // allocate enough space for all remaining tokens, plus null terminator // this will be more than we need in many cases, but it's easy cmd->args = (char**) malloc((numTokens - i + 1) * sizeof(char*)); int j; for(j = 0; j < numTokens - i; j++) { if (isSpecialToken(tokens[i + j])) { hasSpecial = true; break; } cmd->args[j] = tokens[i + j]; } i += j; // advances i to the next token to read if (hasSpecial) { specials: switch(tokens[i][0]) { // deal w/ special token: // '|' -> advance past to next token case '|' : i++; break; // '<' -> open file desriptor, set up pipe case '<' : { i++; if(i >= numTokens) { fprintf(stderr, "%s", "quash: syntax error after '<'\n"); return; } char* filename = tokens[i]; int fd = open(filename, O_RDONLY); if(fd < 0) { fprintf(stderr, "quash: could not open file: %s\n", filename); return; } hasFileIn = true; fileIn[0]=fd; fileIn[1]=fd; i++; // should be followed by a special symbol // rather than a commaand, so jump to the // appropriate place unless we are at the end if(i < numTokens) { goto specials; } break; } // '>' -> convert to new builtin (writef) case '>' : if (tokens[i][1] == '>') { tokens[i] = "appendf"; } else { tokens[i] = "writef"; } break; // '&' -> ? (deal w/ later? Should only occur at end) : dealt with in main } } cmd->args[j] = NULL; pipeline* nextPipe = malloc(sizeof(pipeline)); nextPipe->command = cmd; nextPipe->next = NULL; lastPipe->next = nextPipe; lastPipe = nextPipe; } // drop dummy block, pass null for stdin runPipeline(pl->next, hasFileIn ? fileIn : NULL); freePipeline(pl); if(hasFileIn) { close(fileIn[0]); } }