2 * Implements the array command for jim
4 * (c) 2008 Steve Bennett <steveb@workware.net.au>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * The views and conclusions contained in the software and documentation
31 * are those of the authors and should not be interpreted as representing
32 * official policies, either expressed or implied, of the Jim Tcl Project.
34 * Based on code originally from Tcl 6.7:
36 * Copyright 1987-1991 Regents of the University of California
37 * Permission to use, copy, modify, and distribute this
38 * software and its documentation for any purpose and without
39 * fee is hereby granted, provided that the above copyright
40 * notice appear in all copies. The University of California
41 * makes no representations about the suitability of this
42 * software for any purpose. It is provided "as is" without
43 * express or implied warranty.
52 #include <jim-subcmd.h>
54 static int array_cmd_exists(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
56 /* Just a regular [info exists] */
57 Jim_Obj
*dictObj
= Jim_GetVariable(interp
, argv
[0], JIM_UNSHARED
);
58 Jim_SetResultInt(interp
, dictObj
&& Jim_DictSize(interp
, dictObj
) != -1);
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
);
71 patternObj
= (argc
== 1) ? NULL
: argv
[1];
73 /* Optimise the "all" case */
74 if (patternObj
== NULL
|| Jim_CompareStringImmediate(interp
, patternObj
, "*")) {
75 if (Jim_IsList(objPtr
) && Jim_ListLength(interp
, objPtr
) % 2 == 0) {
76 /* A list with an even number of elements */
77 Jim_SetResult(interp
, objPtr
);
82 return Jim_DictMatchTypes(interp
, objPtr
, patternObj
, JIM_DICTMATCH_KEYS
, JIM_DICTMATCH_KEYS
| JIM_DICTMATCH_VALUES
);
85 static int array_cmd_names(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
87 Jim_Obj
*objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
93 return Jim_DictMatchTypes(interp
, objPtr
, argc
== 1 ? NULL
: argv
[1], JIM_DICTMATCH_KEYS
, JIM_DICTMATCH_KEYS
);
96 static int array_cmd_unset(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
102 Jim_Obj
**dictValuesObj
;
104 if (argc
== 1 || Jim_CompareStringImmediate(interp
, argv
[1], "*")) {
105 /* Unset the whole array */
106 Jim_UnsetVariable(interp
, argv
[0], JIM_NONE
);
110 objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
112 if (objPtr
== NULL
) {
113 /* Doesn't exist, so nothing to do */
117 if (Jim_DictPairs(interp
, objPtr
, &dictValuesObj
, &len
) != JIM_OK
) {
118 /* Variable is not an array - tclsh ignores this and returns nothing - be compatible */
119 Jim_SetResultString(interp
, "", -1);
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
);
147 /* Variable is not an array - tclsh ignores this and returns 0 - be compatible */
148 Jim_SetResultInt(interp
, 0);
153 Jim_SetResultInt(interp
, len
);
158 static int array_cmd_stat(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
160 Jim_Obj
*objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
162 return Jim_DictInfo(interp
, objPtr
);
164 Jim_SetResultFormatted(interp
, "\"%#s\" isn't an array", argv
[0], NULL
);
168 static int array_cmd_set(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
172 Jim_Obj
*listObj
= argv
[1];
175 len
= Jim_ListLength(interp
, listObj
);
177 Jim_SetResultString(interp
, "list must have an even number of elements", -1);
181 dictObj
= Jim_GetVariable(interp
, argv
[0], JIM_UNSHARED
);
183 /* Doesn't exist, so just set the list directly */
184 return Jim_SetVariable(interp
, argv
[0], listObj
);
186 else if (Jim_DictSize(interp
, dictObj
) < 0) {
190 if (Jim_IsShared(dictObj
)) {
191 dictObj
= Jim_DuplicateObj(interp
, dictObj
);
194 for (i
= 0; i
< len
; i
+= 2) {
198 Jim_ListIndex(interp
, listObj
, i
, &nameObj
, JIM_NONE
);
199 Jim_ListIndex(interp
, listObj
, i
+ 1, &valueObj
, JIM_NONE
);
201 Jim_DictAddElement(interp
, dictObj
, nameObj
, valueObj
);
203 return Jim_SetVariable(interp
, argv
[0], dictObj
);
206 static const jim_subcmd_type array_command_table
[] = {
212 /* Description: Does array exist? */
215 "arrayName ?pattern?",
219 /* Description: Array contents as name value list */
222 "arrayName ?pattern?",
226 /* Description: Array keys as a list */
233 /* Description: Set array from list */
240 /* Description: Number of elements in array */
247 /* Description: Print statistics about an array */
250 "arrayName ?pattern?",
254 /* Description: Unset elements of an array */
260 int Jim_arrayInit(Jim_Interp
*interp
)
262 if (Jim_PackageProvide(interp
, "array", "1.0", JIM_ERRMSG
))
265 Jim_CreateCommand(interp
, "array", Jim_SubCmdProc
, (void *)array_command_table
, NULL
);