int Config_load(const char *config_file, const char *db_file) { int rc = 0; tst_t *settings = NULL; struct tagbstring SETTINGS_VAR = bsStatic("settings"); struct tagbstring MIMETYPES_VAR = bsStatic("mimetypes"); settings = Parse_config_file(config_file); check(settings != NULL, "Error parsing config file: %s.", config_file); rc = Config_setup(db_file); check(rc == 0, "Failed to configure config db: %s", db_file); rc = AST_walk(settings, Server_load); check(rc == 0, "Failed to process the config file: %s", config_file); Value *set = AST_get(settings, settings, &SETTINGS_VAR, VAL_HASH); if(set) { rc = AST_walk_hash(settings, set, Settings_load); check(rc == 0, "Failed to load the settings. Aborting."); } rc = Mimetypes_import(); check(rc == 0, "Failed to import default mimetypes."); Value *mime = AST_get(settings, settings, &MIMETYPES_VAR, VAL_HASH); if(mime) { AST_walk_hash(settings, mime, Mimetypes_load); check(rc == 0, "Failed to load the mimetypes. Aborting."); } rc = Config_commit(); check(rc == 0, "Failed to commit config db: %s", db_file); AST_destroy(settings); DB_close(); return 0; error: AST_destroy(settings); DB_close(); return -1; }
char *test_parser() { tst_t *settings = Parse_config_file("tests/sample.conf"); mu_assert(settings, "Error parsing."); AST_walk(settings, check_callback); AST_destroy(settings); return NULL; }
static void AST_destroy_value(Value *val) { switch(val->type) { case VAL_QSTRING: Token_destroy(val->as.string); break; case VAL_NUMBER: Token_destroy(val->as.number); break; case VAL_CLASS: Class_destroy(val->as.cls); break; case VAL_LIST: AST_destroy_list(val->as.list); break; case VAL_HASH: AST_destroy(val->as.hash); break; case VAL_IDENT: Token_destroy(val->as.ident); break; case VAL_REF: Token_destroy(val->as.ref); break; default: log_err("Unknown value type ID: %d. Tell Zed.", val->type); } free(val); }
/* The following function deletes the value associated with a ** symbol. The symbol can be either a terminal or nonterminal. ** "yymajor" is the symbol code, and "yypminor" is a pointer to ** the value. */ static void yy_destructor( yyParser *yypParser, /* The parser */ YYCODETYPE yymajor, /* Type code for object to destroy */ YYMINORTYPE *yypminor /* The object to be destroyed */ ){ ParseARG_FETCH; switch( yymajor ){ /* Here is inserted the actions which take place when a ** terminal or non-terminal is destroyed. This can happen ** when the symbol is popped from the stack during a ** reduce or during error processing or when a parser is ** being destroyed before it is finished parsing. ** ** Note: during a reduce, the only symbols destroyed are those ** which appear on the RHS of the rule, but which are not used ** inside the C code. */ /* TERMINAL Destructor */ case 1: /* EOF */ case 2: /* QSTRING */ case 3: /* NUMBER */ case 4: /* IDENT */ case 5: /* EQ */ case 6: /* CLASS */ case 7: /* LPAREN */ case 8: /* RPAREN */ case 9: /* COMMA */ case 10: /* LBRACE */ case 11: /* RBRACE */ case 12: /* LBRACKET */ case 13: /* RBRACKET */ case 14: /* COLON */ { #line 28 "src/parser.y" Token_destroy((yypminor->yy0)); #line 419 "src/parser.c" } break; case 18: /* assignment */ { #line 56 "src/parser.y" free((yypminor->yy7)); #line 426 "src/parser.c" } break; case 23: /* parameters */ { #line 67 "src/parser.y" AST_destroy((yypminor->yy13)); #line 433 "src/parser.c" } break; case 26: /* hash_pair */ { #line 107 "src/parser.y" free((yypminor->yy17)); #line 440 "src/parser.c" } break; default: break; /* If no destructor action specified: do nothing */ } }
static void Class_destroy(Class *cls) { Token_destroy(cls->ident); AST_destroy(cls->params); free(cls); }