From: short <> Date: Sun, 1 Jul 2001 14:22:09 +0000 (+0000) Subject: Fixed free(3) by mistake X-Git-Tag: rel_F4_0_3_alpha_8_gts3~5 X-Git-Url: http://git.jankratochvil.net/?p=tac_plus.git;a=commitdiff_plain;h=66d08c650a705a99a4a8454550e53709f6d9eec5;hp=72205dd2ca8ed37d59c03a69039f827cb377fc98 Fixed free(3) by mistake - free(3)d outer 'when' block during destruction of inner 'when' block Optimalization: Introduced Dungeon with Starvation for outer 'when' blocks when crossing 'service' or 'cmd' block boundary --- diff --git a/cfgfile.c b/cfgfile.c index 735b701..7c2353a 100644 --- a/cfgfile.c +++ b/cfgfile.c @@ -844,15 +844,10 @@ sym_get(); parse(S_separator); if (field) { \ field = tac_strdup(sym_buf); static struct expr *when_expr_root; - -static void when_expr_root_init TAC_ARGS((void)); - -static void -when_expr_root_init() -{ - free_expr(when_expr_root); - when_expr_root = new_expr(S_and); -} +#define WHEN_EXPR_ROOT_SANE() \ + (when_expr_root && !when_expr_root->next && when_expr_root->type==S_and) +#define WHEN_EXPR_ROOT_EMPTY() \ + (WHEN_EXPR_ROOT_SANE() && !when_expr_root->u.and_or.child_first) static struct expr *parse_expr_node TAC_ARGS((int single_item)); @@ -962,24 +957,38 @@ parse_when_decl() return (parse_expr_node(0 /* single_item */)); } +static void when_expr_root_init TAC_ARGS((void)); + +static void +when_expr_root_init() +{ + free_expr(when_expr_root); + when_expr_root = new_expr(S_and); +} + static int push_parsed_when_decl TAC_ARGS((void)); static int push_parsed_when_decl() { - struct expr *new_expr; + struct expr *parsed_expr; - new_expr = parse_when_decl(); - if (!new_expr) + parsed_expr = parse_when_decl(); + if (!parsed_expr) + return (1); + if (!WHEN_EXPR_ROOT_SANE()) { + report(LOG_ERR, "INTERNAL: when_expr_root not valid during push_parsed_when_decl()!"); + free_expr(parsed_expr); return (1); - if (new_expr->next) { - report(LOG_ERR, "Illegal filled next field of parsed expr"); - free_expr(new_expr); + } + if (parsed_expr->next) { + report(LOG_ERR, "INTERNAL: Illegal filled next field of parsed expr"); + free_expr(parsed_expr); return (1); } - new_expr->next = when_expr_root->u.and_or.child_first; - when_expr_root->u.and_or.child_first = new_expr; - when_expr_root->line = new_expr->line; + parsed_expr->next = when_expr_root->u.and_or.child_first; + when_expr_root->u.and_or.child_first = parsed_expr; + when_expr_root->line = parsed_expr->line; return (0); } @@ -990,12 +999,17 @@ pop_when_decl() { struct expr *first_expr; + if (!WHEN_EXPR_ROOT_SANE()) { + report(LOG_ERR, "INTERNAL: when_expr_root not valid during pop_when_decl()!"); + return (1); + } first_expr = when_expr_root->u.and_or.child_first; if (!first_expr) { report(LOG_ERR, "No expr in stack and pop_when_decl() called"); return (1); } when_expr_root->u.and_or.child_first = first_expr->next; + first_expr->next = NULL; free_expr(first_expr); return (0); } @@ -1008,6 +1022,41 @@ copy_current_when_decl() return (dupl_expr(when_expr_root)); } +static struct expr *when_expr_dungeon; + +static void starve_when_decl TAC_ARGS((void)); + +static void +starve_when_decl() +{ + if (!WHEN_EXPR_ROOT_SANE()) { + report(LOG_WARNING, "INTERNAL: when_expr_root not sane during starve_when_decl!"); + } + when_expr_root->next = when_expr_dungeon; + when_expr_dungeon = when_expr_root; + when_expr_root = NULL; + when_expr_root_init(); +} + +static int feed_when_decl TAC_ARGS((void)); + +static int +feed_when_decl() +{ + if (!when_expr_dungeon) { + report(LOG_ERR, "INTERNAL: No expr in dungeon and feed_when_decl() called"); + return (1); + } + if (!WHEN_EXPR_ROOT_EMPTY()) { + report(LOG_WARNING, "INTERNAL: Some 'when' expression found still pushed in dungeon during feed_when_decl()!"); + } + free_expr(when_expr_root); + when_expr_root = when_expr_dungeon; + when_expr_dungeon = when_expr_dungeon->next; + when_expr_root->next = NULL; + return (0); +} + ENTITY *entity_lookup TAC_ARGS((int type, const char *name)); ENTITY * @@ -1507,14 +1556,16 @@ parse_svcs() sym_get(); parse(S_openbra); - + starve_when_decl(); result->value1 = parse_cmd_matches(); + parse(S_closebra); + if (feed_when_decl()) + tac_exit(1); /* no error return possibility */ + result->type = N_svc_cmd; result->when = copy_current_when_decl(); expr_sink_register(result->when); - parse(S_closebra); - result->next = parse_svcs(); return (result); } @@ -1551,15 +1602,19 @@ parse_svcs() result->value1 = tac_strdup(sym_buf); break; } + sym_get(); parse(S_openbra); + starve_when_decl(); result->dflt = parse_opt_attr_default(); result->value = parse_attrs(); - result->when = copy_current_when_decl(); - expr_sink_register(result->when); parse(S_closebra); + feed_when_decl(); + + result->when = copy_current_when_decl(); + expr_sink_register(result->when); result->next = parse_svcs(); return (result); @@ -2198,7 +2253,7 @@ const char *cfile; fclose(cf); return (1); } - if (!when_expr_root || when_expr_root->type!=S_and || when_expr_root->u.and_or.child_first) { + if (!WHEN_EXPR_ROOT_EMPTY() || when_expr_dungeon) { report(LOG_ERR, "Some 'when' expression found still pushed on stack"); fclose(cf); return (1);