コード例 #1
0
ファイル: parser.c プロジェクト: Totktonada/shell
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;
}
コード例 #2
0
ファイル: parser.c プロジェクト: Totktonada/shell
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);
}
コード例 #3
0
ファイル: parser.c プロジェクト: Totktonada/shell
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;
}
コード例 #4
0
ファイル: shell.c プロジェクト: vfrenkel/os_shell
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;
}