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));
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);
}
{
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);
}
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 *
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);
}
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);
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);