Fixed free(3) by mistake
authorshort <>
Sun, 1 Jul 2001 14:22:09 +0000 (14:22 +0000)
committershort <>
Sun, 1 Jul 2001 14:22:09 +0000 (14:22 +0000)
 - 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

cfgfile.c

index 735b701..7c2353a 100644 (file)
--- 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);