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.
53 #include <jim-subcmd.h>
55 static int array_cmd_exists(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
57 /* Just a regular [info exists] */
58 Jim_SetResultInt(interp
, Jim_GetVariable(interp
, argv
[0], 0) != 0);
62 static int array_cmd_get(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
64 Jim_Obj
*objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
70 if (argc
== 1 || Jim_CompareStringImmediate(interp
, argv
[1], "*")) {
71 /* Optimise the "all" case */
72 if (Jim_IsList(objPtr
)) {
73 if (Jim_ListLength(interp
, objPtr
) % 2 != 0) {
74 /* A list with an odd number of elements */
78 else if (Jim_DictSize(interp
, objPtr
) < 0) {
79 /* Can't be converted to a dictionary */
82 Jim_SetResult(interp
, objPtr
);
86 /* Return a list of keys and values where the keys match the pattern */
87 return Jim_DictValues(interp
, objPtr
, argv
[1]);
90 static int array_cmd_names(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
92 Jim_Obj
*objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
98 return Jim_DictKeys(interp
, objPtr
, argc
== 1 ? NULL
: argv
[1]);
101 static int array_cmd_unset(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
107 Jim_Obj
**dictValuesObj
;
109 if (argc
== 1 || Jim_CompareStringImmediate(interp
, argv
[1], "*")) {
110 /* Unset the whole array */
111 Jim_UnsetVariable(interp
, argv
[0], JIM_NONE
);
115 objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
117 if (Jim_DictPairs(interp
, objPtr
, &dictValuesObj
, &len
) != JIM_OK
) {
121 /* Create a new object with the values which don't match */
122 resultObj
= Jim_NewDictObj(interp
, NULL
, 0);
124 for (i
= 0; i
< len
; i
+= 2) {
125 if (!Jim_StringMatchObj(interp
, argv
[1], dictValuesObj
[i
], 0)) {
126 Jim_DictAddElement(interp
, resultObj
, dictValuesObj
[i
], dictValuesObj
[i
+ 1]);
129 Jim_Free(dictValuesObj
);
131 Jim_SetVariable(interp
, argv
[0], resultObj
);
135 static int array_cmd_size(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
140 /* Not found means zero length */
141 objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
143 len
= Jim_DictSize(interp
, objPtr
);
149 Jim_SetResultInt(interp
, len
);
154 static int array_cmd_set(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
158 Jim_Obj
*listObj
= argv
[1];
161 len
= Jim_ListLength(interp
, listObj
);
163 Jim_SetResultString(interp
, "list must have an even number of elements", -1);
167 dictObj
= Jim_GetVariable(interp
, argv
[0], JIM_UNSHARED
);
169 /* Doesn't exist, so just set the list directly */
170 return Jim_SetVariable(interp
, argv
[0], listObj
);
173 if (Jim_IsShared(dictObj
)) {
174 dictObj
= Jim_DuplicateObj(interp
, dictObj
);
177 for (i
= 0; i
< len
; i
+= 2) {
181 Jim_ListIndex(interp
, listObj
, i
, &nameObj
, JIM_NONE
);
182 Jim_ListIndex(interp
, listObj
, i
+ 1, &valueObj
, JIM_NONE
);
184 Jim_DictAddElement(interp
, dictObj
, nameObj
, valueObj
);
186 return Jim_SetVariable(interp
, argv
[0], dictObj
);
189 static const jim_subcmd_type array_command_table
[] = {
195 /* Description: Does array exist? */
198 "arrayName ?pattern?",
202 /* Description: Array contents as name value list */
205 "arrayName ?pattern?",
209 /* Description: Array keys as a list */
216 /* Description: Set array from list */
223 /* Description: Number of elements in array */
226 "arrayName ?pattern?",
230 /* Description: Unset elements of an array */
236 int Jim_arrayInit(Jim_Interp
*interp
)
238 if (Jim_PackageProvide(interp
, "array", "1.0", JIM_ERRMSG
))
241 Jim_CreateCommand(interp
, "array", Jim_SubCmdProc
, (void *)array_command_table
, NULL
);