int main() { cmd_list *list; parser_info pinfo; init_parser(&pinfo); do { list = parse_cmd_list(&pinfo); switch (pinfo.error) { case 0: print_cmd_list(stdout, list, 1); destroy_cmd_list(list); list = NULL; break; case 16: fprintf(stderr, "Parser: empty command;\n"); break; default: /* TODO: flush read buffer, * possibly via buffer function. */ fprintf(stderr, "Parser: bad command;\n"); break; } if (pinfo.cur_lex->type == LEX_EOFILE) exit(pinfo.error); } while (1); return 0; }
void destroy_cmd_pipeline(cmd_pipeline *pipeline) { cmd_pipeline_item *current; cmd_pipeline_item *next; if (pipeline == NULL) return; current = pipeline->first_item; while (current != NULL) { next = current->next; destroy_argv(current->argv); destroy_cmd_list(current->cmd_lst); free(current); current = next; } if (pipeline->input != NULL) free(pipeline->input); if (pipeline->output != NULL) free(pipeline->output); free(pipeline); }
cmd_list *parse_cmd_list(parser_info *pinfo) { int bracket_terminated = 0; int lex_term = 0; cmd_list *list = make_cmd_list(pinfo); cmd_list_item *cur_item = NULL, *tmp_item = NULL; #ifdef PARSER_DEBUG parser_print_action(pinfo, "parse_cmd_list()", 0); #endif if (pinfo->cur_lex != NULL) bracket_terminated = (pinfo->cur_lex->type == LEX_BRACKET_OPEN); parser_get_lex(pinfo); if (pinfo->error) goto error; switch (pinfo->cur_lex->type) { case LEX_EOLINE: case LEX_EOFILE: /* Empty cmd list */ pinfo->error = 16; /* Error 16 */ goto error; default: /* Do nothing */ break; } do { tmp_item = parse_cmd_list_item(pinfo); if (pinfo->error) goto error; if (list->first_item == NULL) list->first_item = cur_item = tmp_item; else cur_item = cur_item->next = tmp_item; switch (pinfo->cur_lex->type) { case LEX_BACKGROUND: case LEX_BRACKET_CLOSE: case LEX_EOLINE: case LEX_EOFILE: lex_term = 1; break; default: pinfo->error = (cur_item->rel == REL_NONE) ? 15 : 0; /* Error 15 */ break; } } while (!lex_term && !pinfo->error); if (pinfo->error) goto error; if (pinfo->cur_lex->type == LEX_BACKGROUND) { pinfo->error = (cur_item->rel == REL_NONE) ? 0 : 13; /* Error 13 */ if (pinfo->error) goto error; list->foreground = 0; parser_get_lex(pinfo); } if (pinfo->error) goto error; switch (pinfo->cur_lex->type) { case LEX_BRACKET_CLOSE: pinfo->error = (bracket_terminated) ? 0 : 5; /* Error 5 */ break; case LEX_EOLINE: case LEX_EOFILE: pinfo->error = (bracket_terminated) ? 6 : 0; /* Error 6 */ break; default: pinfo->error = 14; /* Error 14 */ break; } if (pinfo->error) goto error; pinfo->error = ((cur_item->rel == REL_NONE) || (cur_item->rel == REL_BOTH)) ? 0 : 7; /* Error 7 */ if (pinfo->error) goto error; cur_item->rel = REL_NONE; #ifdef PARSER_DEBUG parser_print_action(pinfo, "parse_cmd_list()", 1); #endif return list; error: #ifdef PARSER_DEBUG parser_print_error(pinfo, "parse_cmd_list()"); #endif destroy_cmd_list(list); return NULL; }
int evaluate(struct SLList *tokens) { struct SLList cmds; init_list(&cmds); IOModifier prev_mod = NO_MODIFIER; struct ExecutableCmd *exe = (struct ExecutableCmd *)malloc(sizeof(struct ExecutableCmd)); init_executable_cmd(exe); while (tokens->length != 0) { struct Token *tok = pop_front(tokens); // check for output redirection conflicts here. if ( prev_mod == PIPE ) { if (exe->output_redir_to) { // conflict // dump the token and cmd lists. destroy_token(tok); while ( (tok = pop_front(tokens)) ) destroy_token(tok); destroy_exe_cmd(exe); destroy_cmd_list(&cmds); fprintf(stderr, "error: syntax error in output redirection.\n"); return -1; } add_back(&cmds, exe); exe = (struct ExecutableCmd *)malloc(sizeof(struct ExecutableCmd)); init_executable_cmd(exe); prev_mod = NO_MODIFIER; } // use previous token's mod, if mod exists, // and this token's info to populate redirection of exe. if (prev_mod == INPUT_REDIR) { exe->input_redir_from = make_file_path(tok->name); } else if (prev_mod == OUTPUT_REDIR) { exe->output_redir_to = make_file_path(tok->name); } else if (prev_mod == ERR_OUTPUT_REDIR) { exe->err_output_redir_to = make_file_path(tok->name); } if ( prev_mod == NO_MODIFIER ) { if ( (exe->full_path = find_cmd(tok->name)) != NULL ) { exe->args = populate_args(tok); if (tok->mod == NO_MODIFIER) { add_back(&cmds, exe); } } else { fprintf(stderr, "error: not a valid command.\n"); destroy_token(tok); destroy_exe_cmd(exe); destroy_cmd_list(&cmds); return -1; } } else if (tok->mod == NO_MODIFIER) { add_back(&cmds, exe); } prev_mod = tok->mod; destroy_token(tok); } // Execute the commands. int exe_status = execute_cmds(&cmds); // TODO: destroy the cmds list. destroy_cmd_list(&cmds); // return 0 if everything went peachy. return exe_status; }