#ifndef _IFCONFIG_PARSE_H #define _IFCONFIG_PARSE_H #include #include #include #include #include #include struct match; struct parser; extern struct pbranch command_root; typedef int (*parser_exec_t)(prop_dictionary_t, prop_dictionary_t); typedef int (*parser_match_t)(const struct parser *, const struct match *, struct match *, int, const char *); typedef int (*parser_init_t)(struct parser *); struct match { prop_dictionary_t m_env; const struct parser *m_nextparser; const struct parser *m_parser; int m_argidx; parser_exec_t m_exec; }; /* method table */ struct parser_methods { parser_match_t pm_match; parser_init_t pm_init; }; struct parser { const struct parser_methods *p_methods; parser_exec_t p_exec; const char *p_name; struct parser *p_nextparser; bool p_initialized; }; struct branch { SIMPLEQ_ENTRY(branch) b_next; struct parser *b_nextparser; }; struct pbranch { struct parser pb_parser; SIMPLEQ_HEAD(, branch) pb_branches; bool pb_match_first; const struct branch *pb_brinit; size_t pb_nbrinit; }; struct pterm { struct parser pt_parser; const char *pt_key; }; extern const struct parser_methods paddr_methods; extern const struct parser_methods pbranch_methods; extern const struct parser_methods piface_methods; extern const struct parser_methods pinteger_methods; extern const struct parser_methods pstr_methods; extern const struct parser_methods pkw_methods; extern const struct parser_methods pterm_methods; #define PTERM_INITIALIZER(__pt, __name, __exec, __key) \ { \ .pt_parser = {.p_name = (__name), .p_methods = &pterm_methods, \ .p_exec = (__exec)}, \ .pt_key = (__key) \ } #define PBRANCH_INITIALIZER(__pb, __name, __brs, __nbr, __match_first) \ { \ .pb_parser = {.p_name = (__name), .p_methods = &pbranch_methods},\ .pb_branches = SIMPLEQ_HEAD_INITIALIZER((__pb)->pb_branches), \ .pb_brinit = (__brs), \ .pb_nbrinit = (__nbr), \ .pb_match_first = (__match_first) \ } #define PSTR_INITIALIZER(__ps, __name, __defexec, __defkey, __defnext) \ { \ .ps_parser = {.p_name = (__name), .p_methods = &pstr_methods, \ .p_exec = (__defexec), \ .p_nextparser = (__defnext)}, \ .ps_key = (__defkey) \ } #define PADDR_INITIALIZER(__pa, __name, __defexec, __addrkey, \ __maskkey, __activator, __deactivator, __defnext) \ { \ .pa_parser = {.p_name = (__name), .p_methods = &paddr_methods, \ .p_exec = (__defexec), \ .p_nextparser = (__defnext)}, \ .pa_addrkey = (__addrkey), \ .pa_maskkey = (__maskkey), \ .pa_activator = (__activator), \ .pa_deactivator = (__deactivator), \ } #define PIFACE_INITIALIZER(__pif, __name, __defexec, __defkey, __defnext)\ { \ .pif_parser = {.p_name = (__name), .p_methods = &piface_methods,\ .p_exec = (__defexec), \ .p_nextparser = (__defnext)}, \ .pif_key = (__defkey) \ } #define PINTEGER_INITIALIZER1(__pi, __name, __min, __max, __base, \ __defexec, __defkey, __defnext) \ { \ .pi_parser = {.p_name = (__name), .p_methods = &pinteger_methods,\ .p_exec = (__defexec), \ .p_nextparser = (__defnext), \ .p_initialized = false}, \ .pi_min = (__min), \ .pi_max = (__max), \ .pi_base = (__base), \ .pi_key = (__defkey) \ } #define PINTEGER_INITIALIZER(__pi, __name, __base, __defexec, __defkey, \ __defnext) \ PINTEGER_INITIALIZER1(__pi, __name, INTMAX_MIN, INTMAX_MAX, \ __base, __defexec, __defkey, __defnext) #define PKW_INITIALIZER(__pk, __name, __defexec, __defkey, __kws, __nkw,\ __defnext) \ { \ .pk_parser = {.p_name = (__name), \ .p_exec = (__defexec), \ .p_methods = &pkw_methods, \ .p_initialized = false}, \ .pk_keywords = SIMPLEQ_HEAD_INITIALIZER((__pk)->pk_keywords), \ .pk_kwinit = (__kws), \ .pk_nkwinit = (__nkw), \ .pk_keyinit = (__defkey), \ .pk_nextinit = (__defnext) \ } #define IFKW(__word, __flag) \ { \ .k_word = (__word), .k_neg = true, .k_type = KW_T_INT, \ .k_int = (__flag), \ .k_negint = -(__flag) \ } #define KW_T_NONE 0 #define KW_T_OBJ 1 #define KW_T_INT 2 #define KW_T_STR 3 #define KW_T_BOOL 4 #define KW_T_UINT 5 struct kwinst { SIMPLEQ_ENTRY(kwinst) k_next; int k_type; const char *k_word; const char *k_key; const char *k_act; const char *k_deact; const char *k_altdeact; parser_exec_t k_exec; union kwval { int64_t u_sint; uint64_t u_uint; const char *u_str; prop_object_t u_obj; bool u_bool; } k_u, k_negu; #define k_int k_u.u_sint #define k_uint k_u.u_uint #define k_str k_u.u_str #define k_obj k_u.u_obj #define k_bool k_u.u_bool #define k_negint k_negu.u_sint #define k_neguint k_negu.u_uint #define k_negstr k_negu.u_str #define k_negobj k_negu.u_obj #define k_negbool k_negu.u_bool bool k_neg; /* allow negative form, -keyword */ struct parser *k_nextparser; }; struct pkw { struct parser pk_parser; const char *pk_key; const char *pk_keyinit; const struct kwinst *pk_kwinit; size_t pk_nkwinit; SIMPLEQ_HEAD(, kwinst) pk_keywords; }; #define pk_nextinit pk_parser.p_nextparser #define pk_execinit pk_parser.p_exec struct pstr { struct parser ps_parser; const char *ps_key; }; struct pinteger { struct parser pi_parser; int64_t pi_min; int64_t pi_max; int pi_base; const char *pi_key; }; struct intrange { SIMPLEQ_ENTRY(intrange) r_next; int64_t r_bottom; int64_t r_top; struct parser *r_nextparser; }; struct pranges { struct parser pr_parser; SIMPLEQ_HEAD(, intrange) pr_ranges; }; struct paddr_prefix { int16_t pfx_len; struct sockaddr pfx_addr; }; static inline size_t paddr_prefix_size(const struct paddr_prefix *pfx) { return offsetof(struct paddr_prefix, pfx_addr) + pfx->pfx_addr.sa_len; } struct paddr { struct parser pa_parser; const char *pa_addrkey; const char *pa_maskkey; const char *pa_activator; const char *pa_deactivator; }; struct piface { struct parser pif_parser; const char *pif_key; }; struct prest { struct parser pr_parser; }; struct prest *prest_create(const char *); struct paddr *paddr_create(const char *, parser_exec_t, const char *, const char *, struct parser *); struct pstr *pstr_create(const char *, parser_exec_t, const char *, struct parser *); struct piface *piface_create(const char *, parser_exec_t, const char *, struct parser *); struct pkw *pkw_create(const char *, parser_exec_t, const char *, const struct kwinst *, size_t, struct parser *); struct pranges *pranges_create(const char *, parser_exec_t, const char *, const struct intrange *, size_t, struct parser *); struct pbranch *pbranch_create(const char *, const struct branch *, size_t, bool); int pbranch_addbranch(struct pbranch *, struct parser *); int pbranch_setbranches(struct pbranch *, const struct branch *, size_t); int parse(int, char **, const struct parser *, struct match *, size_t *, int *); int matches_exec(const struct match *, prop_dictionary_t, size_t); int parser_init(struct parser *); #endif /* _IFCONFIG_PARSE_H */