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.
54 #include "jimautoconf.h"
55 #include "jim-subcmd.h"
57 static int array_cmd_exists(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
59 /* Just a regular [info exists] */
60 Jim_SetResultInt(interp
, Jim_GetVariable(interp
, argv
[0], 0) != 0);
64 static int array_cmd_get(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
66 Jim_Obj
*objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
72 if (argc
== 1 || Jim_CompareStringImmediate(interp
, argv
[1], "*")) {
73 /* Optimise the "all" case */
74 if (Jim_IsList(objPtr
)) {
75 if (Jim_ListLength(interp
, objPtr
) % 2 != 0) {
76 /* A list with an odd number of elements */
80 else if (Jim_DictSize(interp
, objPtr
) < 0) {
81 /* Can't be converted to a dictionary */
84 Jim_SetResult(interp
, objPtr
);
88 /* Return a list of keys and values where the keys match the pattern */
89 return Jim_DictValues(interp
, objPtr
, argv
[1]);
92 static int array_cmd_names(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
94 Jim_Obj
*objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
100 return Jim_DictKeys(interp
, objPtr
, argc
== 1 ? NULL
: argv
[1]);
103 static int array_cmd_unset(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
109 Jim_Obj
**dictValuesObj
;
111 if (argc
== 1 || Jim_CompareStringImmediate(interp
, argv
[1], "*")) {
112 /* Unset the whole array */
113 Jim_UnsetVariable(interp
, argv
[0], JIM_NONE
);
117 objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
119 if (Jim_DictPairs(interp
, objPtr
, &dictValuesObj
, &len
) != JIM_OK
) {
123 /* Create a new object with the values which don't match */
124 resultObj
= Jim_NewDictObj(interp
, NULL
, 0);
126 for (i
= 0; i
< len
; i
+= 2) {
127 if (!Jim_StringMatchObj(interp
, argv
[1], dictValuesObj
[i
], 0)) {
128 Jim_DictAddElement(interp
, resultObj
, dictValuesObj
[i
], dictValuesObj
[i
+ 1]);
131 Jim_Free(dictValuesObj
);
133 Jim_SetVariable(interp
, argv
[0], resultObj
);
137 static int array_cmd_size(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
142 /* Not found means zero length */
143 objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
145 len
= Jim_DictSize(interp
, objPtr
);
151 Jim_SetResultInt(interp
, len
);
156 static int array_cmd_set(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
160 Jim_Obj
*listObj
= argv
[1];
163 len
= Jim_ListLength(interp
, listObj
);
165 Jim_SetResultString(interp
, "list must have an even number of elements", -1);
169 dictObj
= Jim_GetVariable(interp
, argv
[0], JIM_UNSHARED
);
171 /* Doesn't exist, so just set the list directly */
172 return Jim_SetVariable(interp
, argv
[0], listObj
);
175 if (Jim_IsShared(dictObj
)) {
176 dictObj
= Jim_DuplicateObj(interp
, dictObj
);
179 for (i
= 0; i
< len
; i
+= 2) {
183 Jim_ListIndex(interp
, listObj
, i
, &nameObj
, JIM_NONE
);
184 Jim_ListIndex(interp
, listObj
, i
+ 1, &valueObj
, JIM_NONE
);
186 Jim_DictAddElement(interp
, dictObj
, nameObj
, valueObj
);
188 return Jim_SetVariable(interp
, argv
[0], dictObj
);
191 static const jim_subcmd_type array_command_table
[] = {
197 /* Description: Does array exist? */
200 "arrayName ?pattern?",
204 /* Description: Array contents as name value list */
207 "arrayName ?pattern?",
211 /* Description: Array keys as a list */
218 /* Description: Set array from list */
225 /* Description: Number of elements in array */
228 "arrayName ?pattern?",
232 /* Description: Unset elements of an array */
238 int Jim_arrayInit(Jim_Interp
*interp
)
240 if (Jim_PackageProvide(interp
, "array", "1.0", JIM_ERRMSG
))
243 Jim_CreateCommand(interp
, "array", Jim_SubCmdProc
, (void *)array_command_table
, NULL
);