1 /* 2 ***** BEGIN LICENSE BLOCK ***** 3 4 Copyright (C) 2001-2020 Olof Hagsand 5 6 This file is part of CLIgen. 7 8 Licensed under the Apache License, Version 2.0 (the "License"); 9 you may not use this file except in compliance with the License. 10 You may obtain a copy of the License at 11 12 http://www.apache.org/licenses/LICENSE-2.0 13 14 Unless required by applicable law or agreed to in writing, software 15 distributed under the License is distributed on an "AS IS" BASIS, 16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 See the License for the specific language governing permissions and 18 limitations under the License. 19 20 Alternatively, the contents of this file may be used under the terms of 21 the GNU General Public License Version 2 or later (the "GPL"), 22 in which case the provisions of the GPL are applicable instead 23 of those above. If you wish to allow use of your version of this file only 24 under the terms of the GPL, and not to allow others to 25 use your version of this file under the terms of Apache License version 2, indicate 26 your decision by deleting the provisions above and replace them with the 27 notice and other provisions required by the GPL. If you do not delete 28 the provisions above, a recipient may use your version of this file under 29 the terms of any one of the Apache License version 2 or the GPL. 30 31 ***** END LICENSE BLOCK ***** 32 33 */ 34 35 #ifndef _CLIGEN_OBJECT_H_ 36 #define _CLIGEN_OBJECT_H_ 37 38 #define CLIGEN_DELIMITERS " \t" 39 #define CLIGEN_QUOTES "\"" 40 41 /* 42 * Parse tree nodes. The different types are associated to 43 * different fields in the parse tree node object, each interpreted/parsed 44 * differently. 45 */ 46 enum cg_objtype{ 47 CO_COMMAND, /* Simple string parsing */ 48 CO_VARIABLE, /* Parse as type eg int */ 49 CO_REFERENCE /* Symbolic reference to other tree */ 50 }; 51 52 /* 53 * Types 54 */ 55 enum cligen_result{ 56 CG_EOF = -2, 57 CG_ERROR = -1, 58 CG_NOMATCH = 0, 59 CG_MATCH = 1, 60 CG_MULTIPLE = 2, 61 }; 62 typedef enum cligen_result cligen_result; 63 64 /* 65 * Callback function type. Is called after a specific syntax node has been identified., 66 * arg is an optionalargument 67 * argc is number of variables (1...) 68 * argv[] is a vector of variables. The first is always the whole syntax string as entered. 69 */ 70 typedef int (cg_fnstype_t)(cligen_handle h, cvec *vars, cg_var *arg); 71 typedef int (cgv_fnstype_t)(cligen_handle h, cvec *vars, cvec *argv); 72 73 /* Expand callback function for vector arguments (should be in cligen_expand.h) 74 Returns 0 if handled expand, that is, it returned commands for 'name' 75 1 if did not handle expand 76 -1 on error. 77 */ 78 typedef int (expandv_cb)(cligen_handle h, /* handler: cligen or userhandle */ 79 char *name, /* name of this function (in text) */ 80 cvec *cvv, /* vars vector of values in command */ 81 cvec *argv, /* argument vector given to callback */ 82 cvec *commands,/* vector of commands */ 83 cvec *helptexts /* vector of help-texts */ 84 ); 85 86 /* Translate callback. Translate a variable, eg from cleartext to 87 encrypted passwords The variable type must be kept */ 88 typedef int (translate_cb_t)(cligen_handle h, cg_var *cv); 89 90 /*! Cligen ^Z suspension callback 91 */ 92 typedef int (cligen_susp_cb_t)(void *h, char *, int, int *); 93 94 /*! Cligen ^C interrupt callback 95 */ 96 typedef int (cligen_interrupt_cb_t)(cligen_handle h); 97 98 typedef struct parse_tree parse_tree; 99 100 /*! A CLIgen object may have one or several callbacks. This type defines one callback 101 */ 102 struct cg_callback { /* Linked list of command callbacks */ 103 struct cg_callback *cc_next; /**< Next callback in list. */ 104 cgv_fnstype_t *cc_fn_vec; /**< callback/function pointer using cvec. */ 105 char *cc_fn_str; /**< callback/function name. malloced */ 106 cvec *cc_cvec; /**< callback/function arguments */ 107 }; 108 109 /* 110 * If cligen object is a variable, this is its variable spec. 111 * But it is not complete, it is a part of a cg_obj. 112 * A cg_var is the value of such a varspec. 113 */ 114 struct cg_varspec{ 115 enum cv_type cgs_vtype; /* its type */ 116 char *cgs_show; /* help text of variable */ 117 char *cgs_expand_fn_str; /* expand callback string */ 118 expandv_cb *cgs_expandv_fn; /* expand callback see pt_expand */ 119 cvec *cgs_expand_fn_vec; /* expand callback argument vector */ 120 char *cgs_translate_fn_str; /* translate function string */ 121 translate_cb_t *cgs_translate_fn; /* variable translate function */ 122 char *cgs_choice; /* list of choices */ 123 /* int range / str length of cvv_low/upper bound intervals. Note, the two 124 * range-cvvs must have the same length. */ 125 int cgs_rangelen; 126 /* array of lower bound of intervals range. If cv type is CGV_EMPTY 127 * it means the min value of the type (eg <a:int32 range[40]> */ 128 cvec *cgs_rangecvv_low; 129 cvec *cgs_rangecvv_upp; /* array of upper bound of intervals */ 130 cvec *cgs_regex; /* List of regular expressions */ 131 uint8_t cgs_dec64_n; /* negative decimal exponential 1..18 */ 132 }; 133 typedef struct cg_varspec cg_varspec; 134 135 /* Default number of fraction digits if type is DEC64 */ 136 #define CGV_DEC64_N_DEFAULT 2 137 138 /* General purpose flags for cg_obj co_flags type 139 */ 140 #define CO_FLAGS_HIDE 0x01 /* Don't show in help/completion */ 141 #define CO_FLAGS_MARK 0x02 /* Only used internally (for recursion avoidance) */ 142 #define CO_FLAGS_TREEREF 0x04 /* This node is top of expanded sub-tree */ 143 #define CO_FLAGS_REFDONE 0x08 /* This reference has already been expanded */ 144 #define CO_FLAGS_OPTION 0x10 /* Generated from optional [] */ 145 #define CO_FLAGS_MATCH 0x20 /* For sets: avoid selecting same more than once */ 146 147 /*! cligen gen object is a parse-tree node. A cg_obj is either a command or a variable 148 * A cg_obj 149 * @code 150 * o <--- cg_obj 151 * ^ 152 * | 153 * up 154 * [0 1..n] 155 * | | | 156 * v v v 157 * o o o <--- cg_obj 158 * @endcode 159 */ 160 struct cg_obj{ 161 parse_tree **co_ptvec; /* Child parse-tree (see co_next macro below) */ 162 int co_pt_len; /* Length of parse-tree vector */ 163 struct cg_obj *co_prev; /* Parent */ 164 enum cg_objtype co_type; /* Type of object: command, variable or tree 165 reference */ 166 char *co_command; /* malloc:ed matching string / name or type */ 167 struct cg_callback *co_callbacks; /* linked list of callbacks and arguments */ 168 cvec *co_cvec; /* List of cligen variables (XXX: not visible to 169 callbacks) */ 170 #ifdef CO_HELPVEC 171 cvec *co_helpvec; /* Vector of CLIgen helptexts */ 172 #else 173 char *co_help; /* Helptext */ 174 #endif 175 uint32_t co_flags; /* General purpose flags, see CO_FLAGS_HIDE and others above */ 176 struct cg_obj *co_ref; /* Ref to original (if this is expanded) */ 177 struct cg_obj *co_treeref_orig; /* Ref to original (if this is a tree reference) */ 178 char *co_value; /* Expanded value can be a string with a constant. 179 Store the constant in the original variable. */ 180 union { /* depends on co_type: */ 181 struct { } cou_cmd; /* CO_COMMAND */ 182 struct cg_varspec cou_var; /* CO_VARIABLE */ 183 // struct cg_varspec cou_tree; /* CO_REFERENCE */ 184 } u; 185 }; 186 187 typedef struct cg_obj cg_obj; 188 189 /* Access macro to cligen object variable specification */ 190 #define co2varspec(co) &(co)->u.cou_var 191 192 /* Access fields for code traversing parse tree */ 193 #define co_vtype u.cou_var.cgs_vtype 194 #define co_show u.cou_var.cgs_show 195 #define co_expand_fn_str u.cou_var.cgs_expand_fn_str 196 #define co_expandv_fn u.cou_var.cgs_expandv_fn 197 #define co_expand_fn_vec u.cou_var.cgs_expand_fn_vec 198 #define co_translate_fn_str u.cou_var.cgs_translate_fn_str 199 #define co_translate_fn u.cou_var.cgs_translate_fn 200 #define co_choice u.cou_var.cgs_choice 201 #define co_keyword u.cou_var.cgs_choice 202 #define co_rangelen u.cou_var.cgs_rangelen 203 #define co_rangecvv_low u.cou_var.cgs_rangecvv_low 204 #define co_rangecvv_upp u.cou_var.cgs_rangecvv_upp 205 #define co_regex u.cou_var.cgs_regex 206 #define co_dec64_n u.cou_var.cgs_dec64_n 207 208 /* 209 * Prototypes 210 */ 211 cg_obj* co_up(cg_obj *co); 212 int co_up_set(cg_obj *co, cg_obj *cop); 213 cg_obj* co_top(cg_obj *co0); 214 parse_tree *co_pt_get(cg_obj *co); 215 int co_pt_set(cg_obj *co, parse_tree *pt); 216 int co_pt_clear(cg_obj *co); 217 void co_flags_set(cg_obj *co, uint32_t flag); 218 void co_flags_reset(cg_obj *co, uint32_t flag); 219 int co_flags_get(cg_obj *co, uint32_t flag); 220 int co_sets_get(cg_obj *co); 221 void co_sets_set(cg_obj *co, int sets); 222 cg_obj *co_new_only(void); 223 cg_obj *co_new(char *cmd, cg_obj *prev); 224 cg_obj *cov_new(enum cv_type cvtype, cg_obj *prev); 225 int co_pref(cg_obj *co, int exact); 226 int co_callback_copy(struct cg_callback *cc0, struct cg_callback **ccn); 227 int co_copy(cg_obj *co, cg_obj *parent, cg_obj **conp); 228 int co_eq(cg_obj *co1, cg_obj *co2); 229 int co_free(cg_obj *co, int recursive); 230 cg_obj *co_insert(parse_tree *pt, cg_obj *co); 231 cg_obj *co_find_one(parse_tree *pt, char *name); 232 int co_value_set(cg_obj *co, char *str); 233 #if defined(__GNUC__) && __GNUC__ >= 3 234 char *cligen_reason(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); 235 #else 236 char *cligen_reason(const char *fmt, ...); 237 #endif 238 239 #endif /* _CLIGEN_OBJECT_H_ */ 240 241