#include "ast/ast.h" #include #include #include "ast/ast_accessors.h" static const size_t ast_size_ltable[] = { [AST_COMMAND] = sizeof(struct ast_command), [AST_IF] = sizeof(struct ast_if), [AST_LOGICAL] = sizeof(struct ast_logical), [AST_LIST] = sizeof(struct ast_list), [AST_REDIRECTION] = sizeof(struct ast_redirection), [AST_PIPELINE] = sizeof(struct ast_pipeline), [AST_WHILE] = sizeof(struct ast_while), [AST_ASSIGN] = sizeof(struct ast_assign), [AST_FOR] = sizeof(struct ast_for), [AST_FUNCTION] = sizeof(struct ast_function), [AST_SUBSHELL] = sizeof(struct ast_subshell) }; struct ast *ast_create(enum ast_node type) { struct ast *a = calloc(1, ast_size_ltable[type]); if (!a) { fprintf(stderr, "ast_create: calloc failed.\n"); return NULL; } a->type = type; return a; } static void free_str_args(struct string **args) { if (!args) { return; } size_t i = 0; while (args[i]) { string_free(args[i]); i++; } free(args); } static void _free_ast_command(struct ast *ast) { free_str_args(((struct ast_command *)ast)->args); free(ast); } static void _free_ast_if(struct ast *ast) { ast_free(get_i(ast, 0)); ast_free(get_i(ast, 1)); ast_free(get_i(ast, 2)); free(ast); } static void _free_ast_list(struct ast *ast) { for (size_t i = 0; i < ((struct ast_list *)ast)->nb_children; i++) { ast_free(get_i(ast, i)); } free(((struct ast_list *)ast)->children); free(ast); } static void _free_ast_logical(struct ast *ast) { ast_free(((struct ast_logical *)ast)->left); ast_free(((struct ast_logical *)ast)->right); free(ast); } static void _free_ast_pipeline(struct ast *ast) { ast_free(((struct ast_pipeline *)ast)->left); ast_free(((struct ast_pipeline *)ast)->right); free(ast); } static void _free_redir_struct(struct ast *ast) { struct ast_redirection *ast_r = ((struct ast_redirection *)ast); string_free(ast_r->redirect.fd); string_free(ast_r->redirect.file); string_free(ast_r->redirect.redir); } static void _free_ast_redirection(struct ast *ast) { ast_free(((struct ast_redirection *)ast)->expr); _free_redir_struct(ast); free(ast); } static void _free_ast_while(struct ast *ast) { ast_free(((struct ast_while *)ast)->cond); ast_free(((struct ast_while *)ast)->body); free(ast); } static void _free_ast_assign(struct ast *ast) { string_free(((struct ast_assign *)ast)->name); string_free(((struct ast_assign *)ast)->val); free(ast); } static void _free_ast_for(struct ast *ast) { struct ast_for *ast_f = ((struct ast_for *)ast); ast_free(ast_f->left); ast_free(ast_f->right); string_free(ast_f->var); // Someone probably forgot to free the ast itself free(ast); } static void _free_ast_function(struct ast *ast) { struct ast_function *ast_fun = ((struct ast_function *)ast); ast_free(ast_fun->body); string_free(ast_fun->name); free(ast); } static void _free_ast_subshell(struct ast *ast) { ast_free(((struct ast_subshell *)ast)->body); free(ast); } typedef void (*free_fct)(struct ast *); static const free_fct free_function_ltable[] = { [AST_COMMAND] = _free_ast_command, [AST_IF] = _free_ast_if, [AST_LOGICAL] = _free_ast_logical, [AST_LIST] = _free_ast_list, [AST_PIPELINE] = _free_ast_pipeline, [AST_REDIRECTION] = _free_ast_redirection, [AST_WHILE] = _free_ast_while, [AST_ASSIGN] = _free_ast_assign, [AST_FOR] = _free_ast_for, [AST_FUNCTION] = _free_ast_function, [AST_SUBSHELL] = _free_ast_subshell }; void ast_free(struct ast *ast) { if (!ast) { return; } free_function_ltable[ast->type](ast); }