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_SetResultInt(interp
, Jim_GetVariable(interp
, argv
[0], 0) != 0);
61 static int array_cmd_get(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
63 Jim_Obj
*objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
70 patternObj
= (argc
== 1) ? NULL
: argv
[1];
72 /* Optimise the "all" case */
73 if (patternObj
== NULL
|| Jim_CompareStringImmediate(interp
, patternObj
, "*")) {
74 if (Jim_IsList(objPtr
) && Jim_ListLength(interp
, objPtr
) % 2 == 0) {
75 /* A list with an even number of elements */
76 Jim_SetResult(interp
, objPtr
);
81 /* Return a list of keys and values where the keys match the pattern */
82 return Jim_DictValues(interp
, objPtr
, patternObj
);
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_DictKeys(interp
, objPtr
, argc
== 1 ? NULL
: argv
[1]);
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
) {
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_stat(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
156 Jim_Obj
*objPtr
= Jim_GetVariable(interp
, argv
[0], JIM_NONE
);
158 return Jim_DictInfo(interp
, objPtr
);
160 Jim_SetResultFormatted(interp
, "\"%#s\" isn't an array", argv
[0], NULL
);
164 static int array_cmd_set(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
168 Jim_Obj
*listObj
= argv
[1];
171 len
= Jim_ListLength(interp
, listObj
);
173 Jim_SetResultString(interp
, "list must have an even number of elements", -1);
177 dictObj
= Jim_GetVariable(interp
, argv
[0], JIM_UNSHARED
);
179 /* Doesn't exist, so just set the list directly */
180 return Jim_SetVariable(interp
, argv
[0], listObj
);
182 else if (Jim_DictSize(interp
, dictObj
) < 0) {
186 if (Jim_IsShared(dictObj
)) {
187 dictObj
= Jim_DuplicateObj(interp
, dictObj
);
190 for (i
= 0; i
< len
; i
+= 2) {
194 Jim_ListIndex(interp
, listObj
, i
, &nameObj
, JIM_NONE
);
195 Jim_ListIndex(interp
, listObj
, i
+ 1, &valueObj
, JIM_NONE
);
197 Jim_DictAddElement(interp
, dictObj
, nameObj
, valueObj
);
199 return Jim_SetVariable(interp
, argv
[0], dictObj
);
202 static const jim_subcmd_type array_command_table
[] = {
208 /* Description: Does array exist? */
211 "arrayName ?pattern?",
215 /* Description: Array contents as name value list */
218 "arrayName ?pattern?",
222 /* Description: Array keys as a list */
229 /* Description: Set array from list */
236 /* Description: Number of elements in array */
243 /* Description: Print statistics about an array */
246 "arrayName ?pattern?",
250 /* Description: Unset elements of an array */
256 int Jim_arrayInit(Jim_Interp
*interp
)
258 if (Jim_PackageProvide(interp
, "array", "1.0", JIM_ERRMSG
))
261 Jim_CreateCommand(interp
, "array", Jim_SubCmdProc
, (void *)array_command_table
, NULL
);