Release bumped to "gts4".
[tac_plus.git] / cfgeval.h
1 #ifndef CFGEVAL_H
2 #define CFGEVAL_H 1
3
4 #include "tac_plus.h"
5
6 #include "utils.h"
7
8
9 struct entity;
10 typedef struct entity ENTITY;
11 enum invalidate_scan {
12     IS_REQUEST = 0,
13     IS_VALUE   = 1,
14     IS_EVAL    = 2,
15     IS_MAX     = 3
16 };
17
18 enum eval_result {
19     ER_UNKNOWN,
20     ER_FALSE,
21     ER_TRUE
22 };
23
24 enum value_scan_func_result {
25     VSFR_CONTINUE,      /* for value_scan_entity() it means 'not found' */
26     VSFR_FOUND,         /* immediately return from the whole value_scan_entity() */
27     VSFR_STOP           /* backtrack (stop) this branch, scan further; nevere returned by value_scan_entity() */
28 };
29
30 struct membership {
31     struct tac_list_node parent_node;   /* to_child_membership_list , AKA legacy "member" */
32     struct tac_list_node  child_node;   /* to_parent_membership_list */
33
34     struct {
35         unsigned seq;                   /* corresponds to global request_scan_seq */
36         struct tac_list_node virtual_membership_node;
37     } request_scan;             /*   cfg_request() scanning */
38
39     struct {
40         unsigned seq;                   /* corresponds to global eval_scan_seq */
41         unsigned unsolved:1;            /* we haven't yet decreased
42                                          * parent_entity->eval_scan.unsolved_to_child_membership_num */
43     } eval_scan;                /*     expr_eval() scanning, many per value_scan */
44
45     struct expr *when;
46 };
47 #define MEMBERSHIP_TO_PARENT_ENTITY(membership) \
48         (&TAC_MEMBER_STRUCT(ENTITY, tac_list_node_get_list(&(membership)->parent_node), to_child_membership_list ))
49 #define MEMBERSHIP_TO_CHILD_ENTITY(membership) \
50         (&TAC_MEMBER_STRUCT(ENTITY, tac_list_node_get_list(&(membership)-> child_node), to_parent_membership_list))
51 #define PARENT_NODE_TO_MEMBERSHIP(parent_node_) \
52         (&TAC_MEMBER_STRUCT(struct membership, (parent_node_), parent_node))
53 #define  CHILD_NODE_TO_MEMBERSHIP( child_node_) \
54         (&TAC_MEMBER_STRUCT(struct membership, ( child_node_),  child_node))
55 #define UNSOLVED_CHILD_NODE_TO_MEMBERSHIP(unsolved_child_node_) \
56         (&TAC_MEMBER_STRUCT(struct membership, (unsolved_child_node_), eval_scan.unsolved_child_node))
57 #define VIRTUAL_MEMBERSHIP_NODE_TO_MEMBERSHIP(virtual_membership_node_) \
58         (&TAC_MEMBER_STRUCT(struct membership, (virtual_membership_node_), request_scan.virtual_membership_node))
59
60 struct expr {
61     struct {
62         unsigned seq;                   /* corresponds to global eval_scan_seq */
63         enum eval_result result;        /* known result of this whole branch */
64         unsigned loop_reported:1;       /* prevent excessive logging */
65     } request_scan;             /*   cfg_request() scanning */
66
67     struct {
68         unsigned seq;                   /* corresponds to global eval_scan_seq */
69         union {
70
71         struct {                /* for S_host, S_user or S_group */
72                         /* connected to either "entity->eval_scan.notify_expr_list"
73                          * or to global "eval_notified_expr_list"
74                          */
75             struct tac_list_node notify_expr_node;      /* gets removed on this expr->seq!= */
76         } entity;
77
78         } u;
79     } eval_scan;                /*     expr_eval() scanning, many per value_scan */
80
81     struct membership *membership;      /* our owner */
82     struct expr *parent;        /* NULL if we are the root expr */
83                                 /* "parent" also (mis)used by expr_sink_{register,commit}() ! */
84     struct expr *next;          /* used in childs of S_and / S_or */
85     int type;                   /* S_not, S_and, S_or, S_host, S_user or S_group */
86     int line;
87     union {
88
89     struct {
90         struct expr *child;
91     } not;
92
93     struct {
94         struct expr *child_first;       /* linked by expr->next */
95     } and_or;
96
97     struct {            /* for S_host, S_user or S_group */
98         const char *name;
99         ENTITY *entity;
100     } entity;
101
102     } u;
103 };
104 #define EXPR_ENTITY_TO_NOTIFYING_ENTITY(expr_) \
105         (&TAC_MEMBER_STRUCT(ENTITY, tac_list_node_get_list(&(expr_)->eval_scan.u.entity.notify_expr_node), eval_scan.notify_expr_list))
106 #define NOTIFY_EXPR_NODE_TO_EXPR(notify_expr_node_) \
107         (&TAC_MEMBER_STRUCT(struct expr, (notify_expr_node_), eval_scan.u.entity.notify_expr_node))
108
109 typedef enum value_scan_func_result (*value_scan_func_t) TAC_ARGS((ENTITY *entity,void *func_data));
110 extern void (*value_scan_forward_seen_hook) TAC_ARGS((struct membership *membership));
111
112
113 extern int request_scan_user_known;     /* have we allowed to 'solve' S_user entities at all? */
114
115
116 extern void unlink_expr TAC_ARGS((struct expr *expr));
117 extern void free_expr TAC_ARGS((struct expr *expr));
118 extern void scan_free_entity TAC_ARGS((ENTITY *entity));
119 extern struct expr *new_expr TAC_ARGS((int type));
120 extern enum value_scan_func_result value_scan_entity TAC_ARGS((ENTITY *entity, int recurse, value_scan_func_t func, void *func_data));
121 extern struct membership *value_scan_backward TAC_ARGS((ENTITY *entity));
122 extern enum eval_result expr_eval TAC_ARGS((struct expr *expr_single));
123 extern struct expr *dupl_expr TAC_ARGS((const struct expr *in));
124 extern void scan_init_entity TAC_ARGS((ENTITY *entity));
125 extern struct membership *enlist_entity_direct TAC_ARGS((ENTITY *parent, ENTITY *child, struct expr *when));
126 extern struct membership *virtual_enlist_entity_direct TAC_ARGS((ENTITY *parent, ENTITY *child));
127 extern void scan_invalidate_entities_hashtable TAC_ARGS((void **hashtable, enum invalidate_scan what));
128 extern void request_scan_begin TAC_ARGS((void));
129 extern void eval_force_belong_entity TAC_ARGS((ENTITY *entity));
130 extern void expr_sink_register TAC_ARGS((struct expr *expr));
131 extern int expr_sink_commit TAC_ARGS((void));
132
133
134 #endif /* CFGEVAL_H */