#ifndef CFGEVAL_H #define CFGEVAL_H 1 #include "tac_plus.h" #include "utils.h" struct entity; typedef struct entity ENTITY; enum invalidate_scan { IS_REQUEST = 0, IS_VALUE = 1, IS_EVAL = 2, IS_MAX = 3 }; enum eval_result { ER_UNKNOWN, ER_FALSE, ER_TRUE }; enum value_scan_func_result { VSFR_CONTINUE, /* for value_scan_entity() it means 'not found' */ VSFR_FOUND, /* immediately return from the whole value_scan_entity() */ VSFR_STOP /* backtrack (stop) this branch, scan further; nevere returned by value_scan_entity() */ }; struct membership { struct tac_list_node parent_node; /* to_child_membership_list , AKA legacy "member" */ struct tac_list_node child_node; /* to_parent_membership_list */ struct { unsigned seq; /* corresponds to global request_scan_seq */ struct tac_list_node virtual_membership_node; } request_scan; /* cfg_request() scanning */ struct { unsigned seq; /* corresponds to global eval_scan_seq */ unsigned unsolved:1; /* we haven't yet decreased * parent_entity->eval_scan.unsolved_to_child_membership_num */ } eval_scan; /* expr_eval() scanning, many per value_scan */ struct expr *when; }; #define MEMBERSHIP_TO_PARENT_ENTITY(membership) \ (&TAC_MEMBER_STRUCT(ENTITY, tac_list_node_get_list(&(membership)->parent_node), to_child_membership_list )) #define MEMBERSHIP_TO_CHILD_ENTITY(membership) \ (&TAC_MEMBER_STRUCT(ENTITY, tac_list_node_get_list(&(membership)-> child_node), to_parent_membership_list)) #define PARENT_NODE_TO_MEMBERSHIP(parent_node_) \ (&TAC_MEMBER_STRUCT(struct membership, (parent_node_), parent_node)) #define CHILD_NODE_TO_MEMBERSHIP( child_node_) \ (&TAC_MEMBER_STRUCT(struct membership, ( child_node_), child_node)) #define UNSOLVED_CHILD_NODE_TO_MEMBERSHIP(unsolved_child_node_) \ (&TAC_MEMBER_STRUCT(struct membership, (unsolved_child_node_), eval_scan.unsolved_child_node)) #define VIRTUAL_MEMBERSHIP_NODE_TO_MEMBERSHIP(virtual_membership_node_) \ (&TAC_MEMBER_STRUCT(struct membership, (virtual_membership_node_), request_scan.virtual_membership_node)) struct expr { struct { unsigned seq; /* corresponds to global eval_scan_seq */ enum eval_result result; /* known result of this whole branch */ unsigned loop_reported:1; /* prevent excessive logging */ } request_scan; /* cfg_request() scanning */ struct { unsigned seq; /* corresponds to global eval_scan_seq */ union { struct { /* for S_host, S_user or S_group */ /* connected to either "entity->eval_scan.notify_expr_list" * or to global "eval_notified_expr_list" */ struct tac_list_node notify_expr_node; /* gets removed on this expr->seq!= */ } entity; } u; } eval_scan; /* expr_eval() scanning, many per value_scan */ struct membership *membership; /* our owner */ struct expr *parent; /* NULL if we are the root expr */ /* "parent" also (mis)used by expr_sink_{register,commit}() ! */ struct expr *next; /* used in childs of S_and / S_or */ int type; /* S_not, S_and, S_or, S_host, S_user or S_group */ int line; union { struct { struct expr *child; } not; struct { struct expr *child_first; /* linked by expr->next */ } and_or; struct { /* for S_host, S_user or S_group */ const char *name; ENTITY *entity; } entity; } u; }; #define EXPR_ENTITY_TO_NOTIFYING_ENTITY(expr_) \ (&TAC_MEMBER_STRUCT(ENTITY, tac_list_node_get_list(&(expr_)->eval_scan.u.entity.notify_expr_node), eval_scan.notify_expr_list)) #define NOTIFY_EXPR_NODE_TO_EXPR(notify_expr_node_) \ (&TAC_MEMBER_STRUCT(struct expr, (notify_expr_node_), eval_scan.u.entity.notify_expr_node)) typedef enum value_scan_func_result (*value_scan_func_t) TAC_ARGS((ENTITY *entity,void *func_data)); extern void (*value_scan_forward_seen_hook) TAC_ARGS((struct membership *membership)); extern int request_scan_user_known; /* have we allowed to 'solve' S_user entities at all? */ extern void unlink_expr TAC_ARGS((struct expr *expr)); extern void free_expr TAC_ARGS((struct expr *expr)); extern void scan_free_entity TAC_ARGS((ENTITY *entity)); extern struct expr *new_expr TAC_ARGS((int type)); extern enum value_scan_func_result value_scan_entity TAC_ARGS((ENTITY *entity, int recurse, value_scan_func_t func, void *func_data)); extern struct membership *value_scan_backward TAC_ARGS((ENTITY *entity)); extern enum eval_result expr_eval TAC_ARGS((struct expr *expr_single)); extern struct expr *dupl_expr TAC_ARGS((const struct expr *in)); extern void scan_init_entity TAC_ARGS((ENTITY *entity)); extern struct membership *enlist_entity_direct TAC_ARGS((ENTITY *parent, ENTITY *child, struct expr *when)); extern struct membership *virtual_enlist_entity_direct TAC_ARGS((ENTITY *parent, ENTITY *child)); extern void scan_invalidate_entities_hashtable TAC_ARGS((void **hashtable, enum invalidate_scan what)); extern void request_scan_begin TAC_ARGS((void)); extern void eval_force_belong_entity TAC_ARGS((ENTITY *entity)); extern void expr_sink_register TAC_ARGS((struct expr *expr)); extern int expr_sink_commit TAC_ARGS((void)); #endif /* CFGEVAL_H */