0e76f96debe49492741086b53815964b41a6556e
[fw/openocd] / src / helper / jim-nvp.c
1 /* SPDX-License-Identifier: BSD-2-Clause-Views */
2
3 /* Jim - A small embeddable Tcl interpreter
4  *
5  * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
6  * Copyright 2005 Clemens Hintze <c.hintze@gmx.net>
7  * Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net>
8  * Copyright 2008 oharboe - Ã˜yvind Harboe - oyvind.harboe@zylin.com
9  * Copyright 2008 Andrew Lunn <andrew@lunn.ch>
10  * Copyright 2008 Duane Ellis <openocd@duaneellis.com>
11  * Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>
12  * Copyright 2008 Steve Bennett <steveb@workware.net.au>
13  * Copyright 2009 Nico Coesel <ncoesel@dealogic.nl>
14  * Copyright 2009 Zachary T Welch zw@superlucidity.net
15  * Copyright 2009 David Brownell
16  * Copyright (c) 2005-2011 Jim Tcl Project. All rights reserved.
17  */
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "jim-nvp.h"
24 #include <string.h>
25
26 int jim_get_nvp(Jim_Interp *interp,
27         Jim_Obj *objptr, const struct jim_nvp *nvp_table, const struct jim_nvp **result)
28 {
29         struct jim_nvp *n;
30         int e;
31
32         e = jim_nvp_name2value_obj(interp, nvp_table, objptr, &n);
33         if (e == JIM_ERR)
34                 return e;
35
36         /* Success? found? */
37         if (n->name) {
38                 /* remove const */
39                 *result = (struct jim_nvp *)n;
40                 return JIM_OK;
41         } else
42                 return JIM_ERR;
43 }
44
45 struct jim_nvp *jim_nvp_name2value_simple(const struct jim_nvp *p, const char *name)
46 {
47         while (p->name) {
48                 if (strcmp(name, p->name) == 0)
49                         break;
50                 p++;
51         }
52         return (struct jim_nvp *)p;
53 }
54
55 struct jim_nvp *jim_nvp_name2value_nocase_simple(const struct jim_nvp *p, const char *name)
56 {
57         while (p->name) {
58                 if (strcasecmp(name, p->name) == 0)
59                         break;
60                 p++;
61         }
62         return (struct jim_nvp *)p;
63 }
64
65 int jim_nvp_name2value_obj(Jim_Interp *interp, const struct jim_nvp *p, Jim_Obj *o, struct jim_nvp **result)
66 {
67         return jim_nvp_name2value(interp, p, Jim_String(o), result);
68 }
69
70 int jim_nvp_name2value(Jim_Interp *interp, const struct jim_nvp *_p, const char *name, struct jim_nvp **result)
71 {
72         const struct jim_nvp *p;
73
74         p = jim_nvp_name2value_simple(_p, name);
75
76         /* result */
77         if (result)
78                 *result = (struct jim_nvp *)p;
79
80         /* found? */
81         if (p->name)
82                 return JIM_OK;
83         else
84                 return JIM_ERR;
85 }
86
87 int jim_nvp_name2value_obj_nocase(Jim_Interp *interp,
88         const struct jim_nvp *p,
89         Jim_Obj *o,
90         struct jim_nvp **puthere)
91 {
92         return jim_nvp_name2value_nocase(interp, p, Jim_String(o), puthere);
93 }
94
95 int jim_nvp_name2value_nocase(Jim_Interp *interp, const struct jim_nvp *_p, const char *name,
96         struct jim_nvp **puthere)
97 {
98         const struct jim_nvp *p;
99
100         p = jim_nvp_name2value_nocase_simple(_p, name);
101
102         if (puthere)
103                 *puthere = (struct jim_nvp *)p;
104                                                 /* found */
105         if (p->name)
106                 return JIM_OK;
107         else
108                 return JIM_ERR;
109 }
110
111 int jim_nvp_value2name_obj(Jim_Interp *interp, const struct jim_nvp *p, Jim_Obj *o, struct jim_nvp **result)
112 {
113         int e;
114         jim_wide w;
115
116         e = Jim_GetWide(interp, o, &w);
117         if (e != JIM_OK)
118                 return e;
119
120         return jim_nvp_value2name(interp, p, w, result);
121 }
122
123 struct jim_nvp *jim_nvp_value2name_simple(const struct jim_nvp *p, int value)
124 {
125         while (p->name) {
126                 if (value == p->value)
127                         break;
128                 p++;
129         }
130         return (struct jim_nvp *)p;
131 }
132
133 int jim_nvp_value2name(Jim_Interp *interp, const struct jim_nvp *_p, int value, struct jim_nvp **result)
134 {
135         const struct jim_nvp *p;
136
137         p = jim_nvp_value2name_simple(_p, value);
138
139         if (result)
140                 *result = (struct jim_nvp *)p;
141
142         if (p->name)
143                 return JIM_OK;
144         else
145                 return JIM_ERR;
146 }
147
148 int jim_getopt_setup(struct jim_getopt_info *p, Jim_Interp *interp, int argc, Jim_Obj *const *argv)
149 {
150         memset(p, 0, sizeof(*p));
151         p->interp = interp;
152         p->argc = argc;
153         p->argv = argv;
154
155         return JIM_OK;
156 }
157
158 void jim_getopt_debug(struct jim_getopt_info *p)
159 {
160         int x;
161
162         fprintf(stderr, "---args---\n");
163         for (x = 0; x < p->argc; x++)
164                 fprintf(stderr, "%2d) %s\n", x, Jim_String(p->argv[x]));
165         fprintf(stderr, "-------\n");
166 }
167
168 int jim_getopt_obj(struct jim_getopt_info *goi, Jim_Obj **puthere)
169 {
170         Jim_Obj *o;
171
172         o = NULL;               /* failure */
173         if (goi->argc) {
174                 /* success */
175                 o = goi->argv[0];
176                 goi->argc -= 1;
177                 goi->argv += 1;
178         }
179         if (puthere)
180                 *puthere = o;
181         if (o)
182                 return JIM_OK;
183         else
184                 return JIM_ERR;
185 }
186
187 int jim_getopt_string(struct jim_getopt_info *goi, const char **puthere, int *len)
188 {
189         int r;
190         Jim_Obj *o;
191         const char *cp;
192
193         r = jim_getopt_obj(goi, &o);
194         if (r == JIM_OK) {
195                 cp = Jim_GetString(o, len);
196                 if (puthere) {
197                         *puthere = cp;
198                 }
199         }
200         return r;
201 }
202
203 int jim_getopt_double(struct jim_getopt_info *goi, double *puthere)
204 {
205         int r;
206         Jim_Obj *o;
207         double _safe;
208
209         if (!puthere)
210                 puthere = &_safe;
211
212         r = jim_getopt_obj(goi, &o);
213         if (r == JIM_OK) {
214                 r = Jim_GetDouble(goi->interp, o, puthere);
215                 if (r != JIM_OK)
216                         Jim_SetResultFormatted(goi->interp, "not a number: %#s", o);
217         }
218         return r;
219 }
220
221 int jim_getopt_wide(struct jim_getopt_info *goi, jim_wide *puthere)
222 {
223         int r;
224         Jim_Obj *o;
225         jim_wide _safe;
226
227         if (!puthere)
228                 puthere = &_safe;
229
230         r = jim_getopt_obj(goi, &o);
231         if (r == JIM_OK)
232                 r = Jim_GetWide(goi->interp, o, puthere);
233         return r;
234 }
235
236 int jim_getopt_nvp(struct jim_getopt_info *goi, const struct jim_nvp *nvp, struct jim_nvp **puthere)
237 {
238         struct jim_nvp *_safe;
239         Jim_Obj *o;
240         int e;
241
242         if (!puthere)
243                 puthere = &_safe;
244
245         e = jim_getopt_obj(goi, &o);
246         if (e == JIM_OK)
247                 e = jim_nvp_name2value_obj(goi->interp, nvp, o, puthere);
248
249         return e;
250 }
251
252 void jim_getopt_nvp_unknown(struct jim_getopt_info *goi, const struct jim_nvp *nvptable, int hadprefix)
253 {
254         if (hadprefix)
255                 jim_set_result_nvp_unknown(goi->interp, goi->argv[-2], goi->argv[-1], nvptable);
256         else
257                 jim_set_result_nvp_unknown(goi->interp, NULL, goi->argv[-1], nvptable);
258 }
259
260 int jim_getopt_enum(struct jim_getopt_info *goi, const char *const *lookup, int *puthere)
261 {
262         int _safe;
263         Jim_Obj *o;
264         int e;
265
266         if (!puthere)
267                 puthere = &_safe;
268         e = jim_getopt_obj(goi, &o);
269         if (e == JIM_OK)
270                 e = Jim_GetEnum(goi->interp, o, lookup, puthere, "option", JIM_ERRMSG);
271         return e;
272 }
273
274 void jim_set_result_nvp_unknown(Jim_Interp *interp,
275         Jim_Obj *param_name, Jim_Obj *param_value, const struct jim_nvp *nvp)
276 {
277         if (param_name)
278                 Jim_SetResultFormatted(interp,
279                         "%#s: Unknown: %#s, try one of: ",
280                         param_name,
281                         param_value);
282         else
283                 Jim_SetResultFormatted(interp, "Unknown param: %#s, try one of: ", param_value);
284         while (nvp->name) {
285                 const char *a;
286                 const char *b;
287
288                 if ((nvp + 1)->name) {
289                         a = nvp->name;
290                         b = ", ";
291                 } else {
292                         a = "or ";
293                         b = nvp->name;
294                 }
295                 Jim_AppendStrings(interp, Jim_GetResult(interp), a, b, NULL);
296                 nvp++;
297         }
298 }
299
300 const char *jim_debug_argv_string(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
301 {
302         static Jim_Obj *debug_string_obj;
303
304         int x;
305
306         if (debug_string_obj)
307                 Jim_FreeObj(interp, debug_string_obj);
308
309         debug_string_obj = Jim_NewEmptyStringObj(interp);
310         for (x = 0; x < argc; x++)
311                 Jim_AppendStrings(interp, debug_string_obj, Jim_String(argv[x]), " ", NULL);
312
313         return Jim_String(debug_string_obj);
314 }