CommandNode *parser_buildtree(List tokens, Diagnostic *diag) { ParserContext ctx = {NULL, NULL, NULL, NULL}; ParserState state = ST_COMMAND; /* Open top-level subshell */ state = parser_process_token(&ctx, state, "("); while (tokens != NULL && state != ST_ERROR) { state = parser_process_token(&ctx, state, list_head_str(tokens)); tokens = tokens->next; } /* Close top-level subshell */ if (state != ST_ERROR) state = parser_process_token(&ctx, state, ")"); /* Check result status */ if (state != ST_ERROR && state != ST_REDIRECT_FILENAME && ctx.expr_stack == NULL && ctx.current_expr != NULL && ctx.current_expr->next==NULL) { /* success */ list_free(ctx.current_expr); fix_arguments_order(ctx.current_command); diag->error = 0; return ctx.current_command; } else { /* failure */ List stack; /* free all CommandNode entities */ free_command_list(ctx.current_expr); stack = ctx.expr_stack; while (stack != NULL) { free_command_list(list_head_list(stack)); stack = list_pop(stack); } diag->error = 1; diag->error_message = "Syntax error"; return NULL; } }
static void fini(void *udata) { free_command_list(); }