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