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
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.
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);
65 static int array_cmd_get(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
71 Jim_Obj
*objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
73 Jim_Obj
**dictValuesObj
;
79 if (argc
== 1 || Jim_CompareStringImmediate(interp
, argv
[1], "*")) {
83 /* If it is a dictionary or list with an even number of elements, nothing else to do */
85 if (Jim_IsDict(objPtr
) || (Jim_IsList(objPtr
) && Jim_ListLength(interp
, objPtr
) % 2 == 0)) {
86 Jim_SetResult(interp
, objPtr
);
91 if (Jim_DictKeysVector(interp
, objPtr
, NULL
, 0, &dictObj
, JIM_ERRMSG
) != JIM_OK
) {
95 if (Jim_DictPairs(interp
, dictObj
, &dictValuesObj
, &len
) != JIM_OK
) {
100 /* Return the whole array */
101 Jim_SetResult(interp
, dictObj
);
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
);
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
);
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
)
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
);
147 objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
149 if (Jim_DictKeysVector(interp
, objPtr
, NULL
, 0, &dictObj
, JIM_ERRMSG
) != JIM_OK
) {
153 if (Jim_DictPairs(interp
, dictObj
, &dictValuesObj
, &len
) != JIM_OK
) {
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
);
171 static int array_cmd_size(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
176 /* Not found means zero length */
177 objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
179 len
= Jim_DictSize(interp
, objPtr
);
185 Jim_SetResultInt(interp
, len
);
190 static int array_cmd_set(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
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
);
204 Jim_SetResultString(interp
, "list must have an even number of elements", -1);
207 for (i
= 0; i
< len
&& rc
== JIM_OK
; i
+= 2) {
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
);
220 static const jim_subcmd_type array_command_table
[] = {
223 .function
= array_cmd_exists
,
226 .description
= "Does array exist?"
229 .args
= "arrayName ?pattern?",
230 .function
= array_cmd_get
,
233 .description
= "Array contents as name value list"
236 .args
= "arrayName ?pattern?",
237 .function
= array_cmd_names
,
240 .description
= "Array keys as a list"
243 .args
= "arrayName list",
244 .function
= array_cmd_set
,
247 .description
= "Set array from list"
251 .function
= array_cmd_size
,
254 .description
= "Number of elements in array"
257 .args
= "arrayName ?pattern?",
258 .function
= array_cmd_unset
,
261 .description
= "Unset elements of an array"
267 int Jim_arrayInit(Jim_Interp
*interp
)
269 if (Jim_PackageProvide(interp
, "array", "1.0", JIM_ERRMSG
))
272 Jim_CreateCommand(interp
, "array", Jim_SubCmdProc
, (void *)array_command_table
, NULL
);