usbmodeswitch: Updated to v.1.2.6 from shibby's branch.
[tomato.git] / release / src / router / usbmodeswitch / jim / jim-array.c
blob89a86f07104b7632f4edf6c9e94360c128170cf3
2 /*
3 * Implements the array command for jim
5 * (c) 2008 Steve Bennett <steveb@workware.net.au>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials
16 * provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * The views and conclusions contained in the software and documentation
32 * are those of the authors and should not be interpreted as representing
33 * official policies, either expressed or implied, of the Jim Tcl Project.
35 * Based on code originally from Tcl 6.7:
37 * Copyright 1987-1991 Regents of the University of California
38 * Permission to use, copy, modify, and distribute this
39 * software and its documentation for any purpose and without
40 * fee is hereby granted, provided that the above copyright
41 * notice appear in all copies. The University of California
42 * makes no representations about the suitability of this
43 * software for any purpose. It is provided "as is" without
44 * express or implied warranty.
47 #include <limits.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <stdio.h>
51 #include <unistd.h>
52 #include <errno.h>
54 #include "jim.h"
55 #include "jimautoconf.h"
56 #include "jim-subcmd.h"
58 static int array_cmd_exists(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
60 /* Just a regular [info exists] */
61 Jim_SetResultInt(interp, Jim_GetVariable(interp, argv[0], 0) != 0);
62 return JIM_OK;
65 static int array_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
67 int i;
68 int len;
69 int all = 0;
70 Jim_Obj *resultObj;
71 Jim_Obj *objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
72 Jim_Obj *dictObj;
73 Jim_Obj **dictValuesObj;
75 if (!objPtr) {
76 return JIM_OK;
79 if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) {
80 all = 1;
83 /* If it is a dictionary or list with an even number of elements, nothing else to do */
84 if (all) {
85 if (Jim_IsDict(objPtr) || (Jim_IsList(objPtr) && Jim_ListLength(interp, objPtr) % 2 == 0)) {
86 Jim_SetResult(interp, objPtr);
87 return JIM_OK;
91 if (Jim_DictKeysVector(interp, objPtr, NULL, 0, &dictObj, JIM_ERRMSG) != JIM_OK) {
92 return JIM_ERR;
95 if (Jim_DictPairs(interp, dictObj, &dictValuesObj, &len) != JIM_OK) {
96 return JIM_ERR;
99 if (all) {
100 /* Return the whole array */
101 Jim_SetResult(interp, dictObj);
103 else {
104 /* Only return the matching values */
105 resultObj = Jim_NewListObj(interp, NULL, 0);
107 for (i = 0; i < len; i += 2) {
108 if (Jim_StringMatchObj(interp, argv[1], dictValuesObj[i], 0)) {
109 Jim_ListAppendElement(interp, resultObj, dictValuesObj[i]);
110 Jim_ListAppendElement(interp, resultObj, dictValuesObj[i + 1]);
114 Jim_SetResult(interp, resultObj);
116 Jim_Free(dictValuesObj);
117 return JIM_OK;
121 static int array_cmd_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
123 Jim_Obj *objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
125 if (!objPtr) {
126 return JIM_OK;
129 return Jim_DictKeys(interp, objPtr, argc == 1 ? NULL : argv[1]);
132 static int array_cmd_unset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
134 int i;
135 int len;
136 Jim_Obj *resultObj;
137 Jim_Obj *objPtr;
138 Jim_Obj *dictObj;
139 Jim_Obj **dictValuesObj;
141 if (argc == 1 || Jim_CompareStringImmediate(interp, argv[1], "*")) {
142 /* Unset the whole array */
143 Jim_UnsetVariable(interp, argv[0], JIM_NONE);
144 return JIM_OK;
147 objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
149 if (Jim_DictKeysVector(interp, objPtr, NULL, 0, &dictObj, JIM_ERRMSG) != JIM_OK) {
150 return JIM_ERR;
153 if (Jim_DictPairs(interp, dictObj, &dictValuesObj, &len) != JIM_OK) {
154 return JIM_ERR;
157 /* Create a new object with the values which don't match */
158 resultObj = Jim_NewDictObj(interp, NULL, 0);
160 for (i = 0; i < len; i += 2) {
161 if (!Jim_StringMatchObj(interp, argv[1], dictValuesObj[i], 0)) {
162 Jim_DictAddElement(interp, resultObj, dictValuesObj[i], dictValuesObj[i + 1]);
165 Jim_Free(dictValuesObj);
167 Jim_SetVariable(interp, argv[0], resultObj);
168 return JIM_OK;
171 static int array_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
173 Jim_Obj *objPtr;
174 int len = 0;
176 /* Not found means zero length */
177 objPtr = Jim_GetVariable(interp, argv[0], JIM_NONE);
178 if (objPtr) {
179 len = Jim_DictSize(interp, objPtr);
180 if (len < 0) {
181 return JIM_ERR;
185 Jim_SetResultInt(interp, len);
187 return JIM_OK;
190 static int array_cmd_set(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
192 int i;
193 int len;
194 int rc = JIM_OK;
195 Jim_Obj *listObj = argv[1];
197 if (Jim_GetVariable(interp, argv[0], JIM_NONE) == NULL) {
198 /* Doesn't exist, so just set the list directly */
199 return Jim_SetVariable(interp, argv[0], listObj);
202 len = Jim_ListLength(interp, listObj);
203 if (len % 2) {
204 Jim_SetResultString(interp, "list must have an even number of elements", -1);
205 return JIM_ERR;
207 for (i = 0; i < len && rc == JIM_OK; i += 2) {
208 Jim_Obj *nameObj;
209 Jim_Obj *valueObj;
211 Jim_ListIndex(interp, listObj, i, &nameObj, JIM_NONE);
212 Jim_ListIndex(interp, listObj, i + 1, &valueObj, JIM_NONE);
214 rc = Jim_SetDictKeysVector(interp, argv[0], &nameObj, 1, valueObj, JIM_ERRMSG);
217 return rc;
220 static const jim_subcmd_type array_command_table[] = {
221 { .cmd = "exists",
222 .args = "arrayName",
223 .function = array_cmd_exists,
224 .minargs = 1,
225 .maxargs = 1,
226 .description = "Does array exist?"
228 { .cmd = "get",
229 .args = "arrayName ?pattern?",
230 .function = array_cmd_get,
231 .minargs = 1,
232 .maxargs = 2,
233 .description = "Array contents as name value list"
235 { .cmd = "names",
236 .args = "arrayName ?pattern?",
237 .function = array_cmd_names,
238 .minargs = 1,
239 .maxargs = 2,
240 .description = "Array keys as a list"
242 { .cmd = "set",
243 .args = "arrayName list",
244 .function = array_cmd_set,
245 .minargs = 2,
246 .maxargs = 2,
247 .description = "Set array from list"
249 { .cmd = "size",
250 .args = "arrayName",
251 .function = array_cmd_size,
252 .minargs = 1,
253 .maxargs = 1,
254 .description = "Number of elements in array"
256 { .cmd = "unset",
257 .args = "arrayName ?pattern?",
258 .function = array_cmd_unset,
259 .minargs = 1,
260 .maxargs = 2,
261 .description = "Unset elements of an array"
263 { .cmd = 0,
267 int Jim_arrayInit(Jim_Interp *interp)
269 if (Jim_PackageProvide(interp, "array", "1.0", JIM_ERRMSG))
270 return JIM_ERR;
272 Jim_CreateCommand(interp, "array", Jim_SubCmdProc, (void *)array_command_table, NULL);
273 return JIM_OK;