Use of <a href="/cvs/aolserver/aolserver/nsd/tclinit.c#A_NsTclGetServer">NsTclGetServer</a> call to verify when a server is required for a command.
1 | /* |
2 | * The contents of this file are subject to the AOLserver Public License |
3 | * Version 1.1 (the "License"); you may not use this file except in |
4 | * compliance with the License. You may obtain a copy of the License at |
5 | * http://aolserver.com/. |
6 | * |
7 | * Software distributed under the License is distributed on an "AS IS" |
8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See |
9 | * the License for the specific language governing rights and limitations |
10 | * under the License. |
11 | * |
12 | * The Original Code is AOLserver Code and related documentation |
13 | * distributed by AOL. |
14 | * |
15 | * The Initial Developer of the Original Code is America Online, |
16 | * Inc. Portions created by AOL are Copyright (C) 1999 America Online, |
17 | * Inc. All Rights Reserved. |
18 | * |
19 | * Alternatively, the contents of this file may be used under the terms |
20 | * of the GNU General Public License (the "GPL"), in which case the |
21 | * provisions of GPL are applicable instead of those above. If you wish |
22 | * to allow use of your version of this file only under the terms of the |
23 | * GPL and not to allow others to use your version of this file under the |
24 | * License, indicate your decision by deleting the provisions above and |
25 | * replace them with the notice and other provisions required by the GPL. |
26 | * If you do not delete the provisions above, a recipient may use your |
27 | * version of this file under either the License or the GPL. |
28 | */ |
29 | |
30 | /* |
31 | * tclset.c -- |
32 | * |
33 | * Implements the tcl ns_set commands |
34 | */ |
35 | |
36 | static const char *RCSID = "@(#) $Header: /cvsroot-fuse/aolserver/aolserver/nsd/tclset.c,v 1.19 2005/08/01 20:27:35 jgdavidson Exp $, compiled: " __DATE__ " " __TIME__; |
37 | |
38 | #include "nsd.h" |
39 | |
40 | /* |
41 | * The following represent the valid combinations of |
42 | * NS_TCL_SET flags |
43 | */ |
44 | |
45 | #define SET_DYNAMIC 'd' |
46 | #define SET_STATIC 't' |
47 | #define SET_SHARED_DYNAMIC 's' |
48 | #define SET_SHARED_STATIC 'p' |
49 | |
50 | #define IS_DYNAMIC(id) \ |
51 | (*(id) == SET_DYNAMIC || *(id) == SET_SHARED_DYNAMIC) |
52 | #define IS_SHARED(id) \ |
53 | (*(id) == SET_SHARED_DYNAMIC || *(id) == SET_SHARED_STATIC) |
54 | |
55 | /* |
56 | * Local functions defined in this file |
57 | */ |
58 | |
59 | static int <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupSet">LookupSet</a>(NsInterp *itPtr, char *id, int delete, Ns_Set **setPtr); |
60 | static int <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupObjSet">LookupObjSet</a>(NsInterp *itPtr, Tcl_Obj *idPtr, int delete, |
61 | Ns_Set **setPtr); |
62 | static int <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupInterpSet">LookupInterpSet</a>(Tcl_Interp *interp, char *id, int delete, |
63 | Ns_Set **setPtr); |
64 | static int <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_EnterSet">EnterSet</a>(NsInterp *itPtr, Ns_Set *set, int flags); |
65 | |
66 | |
67 | /* |
68 | *---------------------------------------------------------------------- |
69 | * |
70 | * <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_Ns_TclEnterSet">Ns_TclEnterSet</a> -- |
71 | * |
72 | * Give this Tcl interpreter access to an existing Ns_Set. |
73 | * |
74 | * Results: |
75 | * TCL_OK or TCL_ERROR. |
76 | * |
77 | * Side effects: |
78 | * A pointer to the Ns_Set is added to the interpreter's list of |
79 | * sets; a new handle is generated and appended to interp result. |
80 | * |
81 | *---------------------------------------------------------------------- |
82 | */ |
83 | |
84 | int |
85 | <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_Ns_TclEnterSet">Ns_TclEnterSet</a>(Tcl_Interp *interp, Ns_Set *set, int flags) |
86 | { |
87 | NsInterp *itPtr = <a href="/cvs/aolserver/aolserver/nsd/tclinit.c#A_NsGetInterpData">NsGetInterpData</a>(interp); |
88 | |
89 | if (itPtr == NULL) { |
90 | Tcl_SetResult(interp, "ns_set not supported", TCL_STATIC); |
91 | return TCL_ERROR; |
92 | } |
93 | return <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_EnterSet">EnterSet</a>(itPtr, set, flags); |
94 | } |
95 | |
96 | |
97 | /* |
98 | *---------------------------------------------------------------------- |
99 | * |
100 | * <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_Ns_TclGetSet">Ns_TclGetSet</a> -- |
101 | * |
102 | * Given a Tcl ns_set handle, return a pointer to the Ns_Set. |
103 | * |
104 | * Results: |
105 | * An Ns_Set pointer, or NULL if error. |
106 | * |
107 | * Side effects: |
108 | * None. |
109 | * |
110 | *---------------------------------------------------------------------- |
111 | */ |
112 | |
113 | Ns_Set * |
114 | <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_Ns_TclGetSet">Ns_TclGetSet</a>(Tcl_Interp *interp, char *id) |
115 | { |
116 | Ns_Set *set; |
117 | |
118 | if (<a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupInterpSet">LookupInterpSet</a>(interp, id, 0, &set) != TCL_OK) { |
119 | return NULL; |
120 | } |
121 | return set; |
122 | } |
123 | |
124 | |
125 | /* |
126 | *---------------------------------------------------------------------- |
127 | * |
128 | * <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_Ns_TclGetSet2">Ns_TclGetSet2</a> -- |
129 | * |
130 | * Like <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_Ns_TclGetSet">Ns_TclGetSet</a>, but sends errors to the tcl interp. |
131 | * |
132 | * Results: |
133 | * TCL result. |
134 | * |
135 | * Side effects: |
136 | * None. |
137 | * |
138 | *---------------------------------------------------------------------- |
139 | */ |
140 | |
141 | int |
142 | <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_Ns_TclGetSet2">Ns_TclGetSet2</a>(Tcl_Interp *interp, char *id, Ns_Set **setPtr) |
143 | { |
144 | return <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupInterpSet">LookupInterpSet</a>(interp, id, 0, setPtr); |
145 | } |
146 | |
147 | |
148 | /* |
149 | *---------------------------------------------------------------------- |
150 | * |
151 | * <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_Ns_TclFreeSet">Ns_TclFreeSet</a> -- |
152 | * |
153 | * Free a set id, and if own by Tcl, the underlying Ns_Set. |
154 | * |
155 | * Results: |
156 | * NS_OK/NS_ERROR. |
157 | * |
158 | * Side effects: |
159 | * Will free the set matching the passed-in set id, and all of |
160 | * its associated data. |
161 | * |
162 | *---------------------------------------------------------------------- |
163 | */ |
164 | |
165 | int |
166 | <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_Ns_TclFreeSet">Ns_TclFreeSet</a>(Tcl_Interp *interp, char *id) |
167 | { |
168 | Ns_Set *set; |
169 | |
170 | if (<a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupInterpSet">LookupInterpSet</a>(interp, id, 1, &set) != TCL_OK) { |
171 | return TCL_ERROR; |
172 | } |
173 | if (IS_DYNAMIC(id)) { |
174 | <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetFree">Ns_SetFree</a>(set); |
175 | } |
176 | return TCL_OK; |
177 | } |
178 | |
179 | |
180 | /* |
181 | *---------------------------------------------------------------------- |
182 | * |
183 | * <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_NsTclSetObjCmd">NsTclSetObjCmd</a> -- |
184 | * |
185 | * Implelments ns_set. |
186 | * |
187 | * Results: |
188 | * Tcl result. |
189 | * |
190 | * Side effects: |
191 | * See docs. |
192 | * |
193 | *---------------------------------------------------------------------- |
194 | */ |
195 | |
196 | int |
197 | <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_NsTclSetObjCmd">NsTclSetObjCmd</a>(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj **objv) |
198 | { |
199 | Ns_Set *set, *set2Ptr, **sets; |
200 | int locked, i, flags; |
201 | char *key, *val, *name, *split; |
202 | Tcl_DString ds; |
203 | Tcl_HashTable *tablePtr; |
204 | Tcl_HashEntry *hPtr; |
205 | Tcl_HashSearch search; |
206 | NsInterp *itPtr = arg; |
207 | Tcl_Obj *objPtr; |
208 | static CONST char *opts[] = { |
209 | "array", "cleanup", "copy", "cput", "create", "delete", |
210 | "delkey", "find", "free", "get", "icput", "idelete", |
211 | "idelkey", "ifind", "iget", "isnull", "iunique", "key", |
212 | "list", "merge", "move", "name", "new", "print", "purge", |
213 | "put", "size", "split", "<a href="/cvs/aolserver/aolserver/nsd/nswin32.c#A_truncate">truncate</a>", "unique", "update", |
214 | "value", NULL, |
215 | }; |
216 | enum { |
217 | SArrayIdx, SCleanupIdx, SCopyIdx, SCPutIdx, SCreateidx, |
218 | SDeleteIdx, SDelkeyIdx, SFindIdx, SFreeIdx, SGetIdx, |
219 | SICPutIdx, SIDeleteIdx, SIDelkeyIdx, SIFindIdx, SIGetIdx, |
220 | SIsNullIdx, SIUniqueIdx, SKeyIdx, SListIdx, SMergeIdx, |
221 | SMoveIdx, sINameIdx, SNewIdx, SPrintIdx, spurgeidx, SPutIdx, |
222 | SSizeIdx, SSplitIdx, STruncateIdx, SUniqueIdx, SUpdateIdx, |
223 | SValueIdx |
224 | }; |
225 | int opt; |
226 | |
227 | if (objc < 2) { |
228 | Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); |
229 | return TCL_ERROR; |
230 | } |
231 | if (Tcl_GetIndexFromObj(interp, objv[1], opts, "option", 0, |
232 | &opt) != TCL_OK) { |
233 | return TCL_ERROR; |
234 | } |
235 | if (opt == SCreateidx) { |
236 | opt = SNewIdx; |
237 | } |
238 | |
239 | switch (opt) { |
240 | case SCleanupIdx: |
241 | tablePtr = &itPtr->sets; |
242 | hPtr = Tcl_FirstHashEntry(tablePtr, &search); |
243 | while (hPtr != NULL) { |
244 | key = Tcl_GetHashKey(tablePtr, hPtr); |
245 | if (IS_DYNAMIC(key)) { |
246 | set = Tcl_GetHashValue(hPtr); |
247 | <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetFree">Ns_SetFree</a>(set); |
248 | } |
249 | hPtr = Tcl_NextHashEntry(&search); |
250 | } |
251 | Tcl_DeleteHashTable(tablePtr); |
252 | Tcl_InitHashTable(tablePtr, TCL_STRING_KEYS); |
253 | break; |
254 | |
255 | case SListIdx: |
256 | if (objc == 2) { |
257 | tablePtr = &itPtr->sets; |
258 | locked = 0; |
259 | } else if (STREQ(Tcl_GetString(objv[2]), "-shared")) { |
260 | tablePtr = &itPtr->servPtr->sets.table; |
261 | locked = 1; |
262 | Ns_MutexLock(&itPtr->servPtr->sets.lock); |
263 | } else { |
264 | Tcl_WrongNumArgs(interp, 2, objv, "?-shared?"); |
265 | return TCL_ERROR; |
266 | } |
267 | if (tablePtr != NULL) { |
268 | hPtr = Tcl_FirstHashEntry(tablePtr, &search); |
269 | while (hPtr != NULL) { |
270 | Tcl_AppendElement(interp, Tcl_GetHashKey(tablePtr, hPtr)); |
271 | hPtr = Tcl_NextHashEntry(&search); |
272 | } |
273 | } |
274 | if (locked) { |
275 | Ns_MutexUnlock(&itPtr->servPtr->sets.lock); |
276 | } |
277 | break; |
278 | |
279 | case SNewIdx: |
280 | case SCopyIdx: |
281 | case SSplitIdx: |
282 | /* |
283 | * The following commands create new sets. |
284 | */ |
285 | |
286 | flags = NS_TCL_SET_DYNAMIC; |
287 | i = 2; |
288 | if (objc > 2) { |
289 | char *oflag = Tcl_GetString(objv[2]); |
290 | if (STREQ(oflag, "-shared") || STREQ(oflag, "-persist")) { |
291 | flags |= NS_TCL_SET_SHARED; |
292 | ++i; |
293 | } |
294 | } |
295 | |
296 | switch (opt) { |
297 | case SNewIdx: |
298 | name = (i < objc) ? Tcl_GetString(objv[i++]) : NULL; |
299 | set = <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetCreate">Ns_SetCreate</a>(name); |
300 | while (i < objc) { |
301 | key = Tcl_GetString(objv[i++]); |
302 | val = (i < objc) ? Tcl_GetString(objv[i++]) : NULL; |
303 | <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetPut">Ns_SetPut</a>(set, key, val); |
304 | } |
305 | <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_EnterSet">EnterSet</a>(itPtr, set, flags); |
306 | break; |
307 | |
308 | case SCopyIdx: |
309 | if (i >= objc) { |
310 | Tcl_WrongNumArgs(interp, 2, objv, "?-shared? setId"); |
311 | return TCL_ERROR; |
312 | } |
313 | if (<a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupObjSet">LookupObjSet</a>(itPtr, objv[i], 0, &set) != TCL_OK) { |
314 | return TCL_ERROR; |
315 | } |
316 | <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_EnterSet">EnterSet</a>(itPtr, <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetCopy">Ns_SetCopy</a>(set), flags); |
317 | break; |
318 | |
319 | case SSplitIdx: |
320 | if ((objc - i) < 1) { |
321 | Tcl_WrongNumArgs(interp, 2, objv, "?-shared? setId ?splitChar"); |
322 | return TCL_ERROR; |
323 | } |
324 | if (<a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupObjSet">LookupObjSet</a>(itPtr, objv[i++], 0, &set) != TCL_OK) { |
325 | return TCL_ERROR; |
326 | } |
327 | split = (i < objc) ? Tcl_GetString(objv[i]) : "."; |
328 | sets = <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetSplit">Ns_SetSplit</a>(set, *split); |
329 | for (i = 0; sets[i] != NULL; i++) { |
330 | <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_EnterSet">EnterSet</a>(itPtr, sets[i], flags); |
331 | } |
332 | ns_free(sets); |
333 | break; |
334 | } |
335 | break; |
336 | |
337 | default: |
338 | /* |
339 | * All futher commands require a valid set. |
340 | */ |
341 | |
342 | if (objc < 3) { |
343 | Tcl_WrongNumArgs(interp, 2, objv, "setId ?args?"); |
344 | return TCL_ERROR; |
345 | } |
346 | if (<a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupObjSet">LookupObjSet</a>(itPtr, objv[2], 0, &set) != TCL_OK) { |
347 | return TCL_ERROR; |
348 | } |
349 | |
350 | switch (opt) { |
351 | case SArrayIdx: |
352 | case SSizeIdx: |
353 | case sINameIdx: |
354 | case SPrintIdx: |
355 | case SFreeIdx: |
356 | /* |
357 | * These commands require only the set. |
358 | */ |
359 | |
360 | if (objc != 3) { |
361 | Tcl_WrongNumArgs(interp, 2, objv, "setId"); |
362 | return TCL_ERROR; |
363 | } |
364 | switch (opt) { |
365 | case SArrayIdx: |
366 | Tcl_DStringInit(&ds); |
367 | for (i = 0; i < Ns_SetSize(set); ++i) { |
368 | Tcl_DStringAppendElement(&ds, Ns_SetKey(set, i)); |
369 | Tcl_DStringAppendElement(&ds, Ns_SetValue(set, i)); |
370 | } |
371 | Tcl_DStringResult(interp, &ds); |
372 | break; |
373 | |
374 | case SSizeIdx: |
375 | objPtr = Tcl_NewIntObj(Ns_SetSize(set)); |
376 | Tcl_SetObjResult(interp, objPtr); |
377 | break; |
378 | |
379 | case sINameIdx: |
380 | Tcl_SetResult(interp, set->name, TCL_VOLATILE); |
381 | break; |
382 | |
383 | case SPrintIdx: |
384 | <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetPrint">Ns_SetPrint</a>(set); |
385 | break; |
386 | |
387 | case SFreeIdx: |
388 | <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_Ns_TclFreeSet">Ns_TclFreeSet</a>(interp, Tcl_GetString(objv[2])); |
389 | break; |
390 | } |
391 | break; |
392 | |
393 | case SFindIdx: |
394 | case SIFindIdx: |
395 | case SGetIdx: |
396 | case SIGetIdx: |
397 | case SDelkeyIdx: |
398 | case SIDelkeyIdx: |
399 | case SUniqueIdx: |
400 | case SIUniqueIdx: |
401 | /* |
402 | * These commands require a set and string key. |
403 | */ |
404 | |
405 | if (objc != 4) { |
406 | Tcl_WrongNumArgs(interp, 2, objv, "setId key"); |
407 | return TCL_ERROR; |
408 | } |
409 | key = Tcl_GetString(objv[3]); |
410 | switch (opt) { |
411 | case SFindIdx: |
412 | objPtr = Tcl_NewIntObj(<a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetFind">Ns_SetFind</a>(set, key)); |
413 | Tcl_SetObjResult(interp, objPtr); |
414 | break; |
415 | |
416 | case SGetIdx: |
417 | Tcl_SetResult(interp, <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetGet">Ns_SetGet</a>(set, key), TCL_VOLATILE); |
418 | break; |
419 | |
420 | case SDeleteIdx: |
421 | case SDelkeyIdx: |
422 | <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetDeleteKey">Ns_SetDeleteKey</a>(set, key); |
423 | break; |
424 | |
425 | case SUniqueIdx: |
426 | objPtr = Tcl_NewIntObj(<a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetUnique">Ns_SetUnique</a>(set, key)); |
427 | Tcl_SetObjResult(interp, objPtr); |
428 | break; |
429 | |
430 | case SIFindIdx: |
431 | objPtr = Tcl_NewIntObj(<a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetIFind">Ns_SetIFind</a>(set, key)); |
432 | Tcl_SetObjResult(interp, objPtr); |
433 | break; |
434 | |
435 | case SIGetIdx: |
436 | Tcl_SetResult(interp, <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetIGet">Ns_SetIGet</a>(set, key), TCL_VOLATILE); |
437 | break; |
438 | |
439 | case SIDeleteIdx: |
440 | case SIDelkeyIdx: |
441 | <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetIDeleteKey">Ns_SetIDeleteKey</a>(set, key); |
442 | break; |
443 | |
444 | case SIUniqueIdx: |
445 | objPtr = Tcl_NewIntObj(<a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetIUnique">Ns_SetIUnique</a>(set, key)); |
446 | Tcl_SetObjResult(interp, objPtr); |
447 | break; |
448 | } |
449 | break; |
450 | |
451 | case SValueIdx: |
452 | case SIsNullIdx: |
453 | case SKeyIdx: |
454 | case SDeleteIdx: |
455 | case STruncateIdx: |
456 | /* |
457 | * These commands require a set and key/value index. |
458 | */ |
459 | |
460 | if (objc != 4) { |
461 | Tcl_WrongNumArgs(interp, 2, objv, "setId index"); |
462 | return TCL_ERROR; |
463 | } |
464 | if (Tcl_GetIntFromObj(interp, objv[3], &i) != TCL_OK) { |
465 | return TCL_ERROR; |
466 | } |
467 | if (i < 0) { |
468 | Tcl_AppendResult(interp, "invalid index \"", |
469 | Tcl_GetString(objv[3]), "\": must be >= 0", NULL); |
470 | return TCL_ERROR; |
471 | } |
472 | if (i >= Ns_SetSize(set)) { |
473 | Tcl_AppendResult(interp, "invalid index \"", |
474 | Tcl_GetString(objv[3]), |
475 | "\": beyond range of set fields", NULL); |
476 | return TCL_ERROR; |
477 | } |
478 | switch (opt) { |
479 | case SValueIdx: |
480 | val = Ns_SetValue(set, i); |
481 | Tcl_SetResult(interp, val, TCL_VOLATILE); |
482 | break; |
483 | |
484 | case SIsNullIdx: |
485 | val = Ns_SetValue(set, i); |
486 | objPtr = Tcl_NewBooleanObj(val ? 0 : 1); |
487 | Tcl_SetObjResult(interp, objPtr); |
488 | break; |
489 | |
490 | case SKeyIdx: |
491 | key = Ns_SetKey(set, i); |
492 | Tcl_SetResult(interp, key, TCL_VOLATILE); |
493 | break; |
494 | |
495 | case SDeleteIdx: |
496 | <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetDelete">Ns_SetDelete</a>(set, i); |
497 | break; |
498 | |
499 | case STruncateIdx: |
500 | <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetTrunc">Ns_SetTrunc</a>(set, i); |
501 | break; |
502 | } |
503 | break; |
504 | |
505 | case SPutIdx: |
506 | case SUpdateIdx: |
507 | case SCPutIdx: |
508 | case SICPutIdx: |
509 | /* |
510 | * These commands require a set, key, and value. |
511 | */ |
512 | |
513 | if (objc != 5) { |
514 | Tcl_WrongNumArgs(interp, 2, objv, "setId key value"); |
515 | return TCL_ERROR; |
516 | } |
517 | key = Tcl_GetString(objv[3]); |
518 | val = Tcl_GetString(objv[4]); |
519 | switch (opt) { |
520 | case SUpdateIdx: |
521 | <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetDeleteKey">Ns_SetDeleteKey</a>(set, key); |
522 | i = <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetPut">Ns_SetPut</a>(set, key, val); |
523 | break; |
524 | |
525 | case SICPutIdx: |
526 | i = <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetIFind">Ns_SetIFind</a>(set, key); |
527 | if (i < 0) { |
528 | i = <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetPut">Ns_SetPut</a>(set, key, val); |
529 | } |
530 | break; |
531 | |
532 | case SCPutIdx: |
533 | i = <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetFind">Ns_SetFind</a>(set, key); |
534 | if (i < 0) { |
535 | i = <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetPut">Ns_SetPut</a>(set, key, val); |
536 | } |
537 | break; |
538 | |
539 | case SPutIdx: |
540 | i = <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetPut">Ns_SetPut</a>(set, key, val); |
541 | break; |
542 | } |
543 | objPtr = Tcl_NewIntObj(i); |
544 | Tcl_SetObjResult(interp, objPtr); |
545 | break; |
546 | |
547 | case SMergeIdx: |
548 | case SMoveIdx: |
549 | /* |
550 | * These commands require two sets. |
551 | */ |
552 | |
553 | if (objc != 4) { |
554 | Tcl_WrongNumArgs(interp, 2, objv, "setTo setFrom"); |
555 | return TCL_ERROR; |
556 | } |
557 | if (<a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupObjSet">LookupObjSet</a>(itPtr, objv[3], 0, &set2Ptr) != TCL_OK) { |
558 | return TCL_ERROR; |
559 | } |
560 | if (opt == SMergeIdx) { |
561 | <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetMerge">Ns_SetMerge</a>(set, set2Ptr); |
562 | } else { |
563 | <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetMove">Ns_SetMove</a>(set, set2Ptr); |
564 | } |
565 | Tcl_SetObjResult(interp, objv[2]); |
566 | break; |
567 | } |
568 | } |
569 | |
570 | return TCL_OK; |
571 | } |
572 | |
573 | |
574 | |
575 | /* |
576 | *---------------------------------------------------------------------- |
577 | * |
578 | * <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_NsTclParseHeaderCmd">NsTclParseHeaderCmd</a> -- |
579 | * |
580 | * This wraps <a href="/cvs/aolserver/aolserver/nsd/request.c#A_Ns_ParseHeader">Ns_ParseHeader</a>. |
581 | * |
582 | * Results: |
583 | * Tcl result. |
584 | * |
585 | * Side effects: |
586 | * <a href="/cvs/aolserver/aolserver/nsd/adpparse.c#A_Parse">Parse</a> an HTTP header and add it to an existing set; see |
587 | * <a href="/cvs/aolserver/aolserver/nsd/request.c#A_Ns_ParseHeader">Ns_ParseHeader</a>. |
588 | * |
589 | *---------------------------------------------------------------------- |
590 | */ |
591 | |
592 | int |
593 | <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_NsTclParseHeaderCmd">NsTclParseHeaderCmd</a>(ClientData arg, Tcl_Interp *interp, int argc, char **argv) |
594 | { |
595 | NsInterp *itPtr = arg; |
596 | Ns_Set *set; |
597 | Ns_HeaderCaseDisposition disp; |
598 | |
599 | if (argc != 3 && argc != 4) { |
600 | Tcl_AppendResult(interp, "wrong # of args: should be \"", |
601 | argv[0], " set header ?tolower|toupper|preserve?\"", NULL); |
602 | return TCL_ERROR; |
603 | } |
604 | if (<a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupSet">LookupSet</a>(itPtr, argv[1], 0, &set) != TCL_OK) { |
605 | return TCL_ERROR; |
606 | } |
607 | if (argc < 4) { |
608 | disp = ToLower; |
609 | } else if (STREQ(argv[3], "toupper")) { |
610 | disp = ToUpper; |
611 | } else if (STREQ(argv[3], "tolower")) { |
612 | disp = ToLower; |
613 | } else if (STREQ(argv[3], "preserve")) { |
614 | disp = Preserve; |
615 | } else { |
616 | Tcl_AppendResult(interp, "unknown case disposition \"", argv[3], |
617 | "\": should be toupper, tolower, or preserve", NULL); |
618 | return TCL_ERROR; |
619 | } |
620 | if (<a href="/cvs/aolserver/aolserver/nsd/request.c#A_Ns_ParseHeader">Ns_ParseHeader</a>(set, argv[2], disp) != NS_OK) { |
621 | Tcl_AppendResult(interp, "invalid header: ", argv[2], NULL); |
622 | return TCL_ERROR; |
623 | } |
624 | return TCL_OK; |
625 | } |
626 | |
627 | |
628 | /* |
629 | *---------------------------------------------------------------------- |
630 | * |
631 | * <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_EnterSet">EnterSet</a> -- |
632 | * |
633 | * Add an Ns_Set to an interp, creating a new unique id. |
634 | * |
635 | * Results: |
636 | * TCL_OK or TCL_ERROR. |
637 | * |
638 | * Side effects: |
639 | * Set will be entered in the shared or private table. |
640 | * |
641 | *---------------------------------------------------------------------- |
642 | */ |
643 | |
644 | static int |
645 | <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_EnterSet">EnterSet</a>(NsInterp *itPtr, Ns_Set *set, int flags) |
646 | { |
647 | Tcl_HashTable *tablePtr; |
648 | Tcl_HashEntry *hPtr; |
649 | int new, next; |
650 | unsigned char type; |
651 | char buf[20]; |
652 | |
653 | if (flags & NS_TCL_SET_SHARED) { |
654 | /* |
655 | * Lock the global mutex and use the shared sets. |
656 | */ |
657 | |
658 | if (flags & NS_TCL_SET_DYNAMIC) { |
659 | type = SET_SHARED_DYNAMIC; |
660 | } else { |
661 | type = SET_SHARED_STATIC; |
662 | } |
663 | tablePtr = &itPtr->servPtr->sets.table; |
664 | Ns_MutexLock(&itPtr->servPtr->sets.lock); |
665 | } else { |
666 | tablePtr = &itPtr->sets; |
667 | if (flags & NS_TCL_SET_DYNAMIC) { |
668 | type = SET_DYNAMIC; |
669 | } else { |
670 | type = SET_STATIC; |
671 | } |
672 | } |
673 | |
674 | /* |
675 | * Allocate a new set IDs until we find an unused one. |
676 | */ |
677 | |
678 | next = tablePtr->numEntries; |
679 | do { |
680 | sprintf(buf, "%c%u", type, next); |
681 | ++next; |
682 | hPtr = Tcl_CreateHashEntry(tablePtr, buf, &new); |
683 | } while (!new); |
684 | Tcl_SetHashValue(hPtr, set); |
685 | Tcl_AppendElement(itPtr->interp, buf); |
686 | |
687 | /* |
688 | * Unlock the global mutex (locked above) if it's a persistent set. |
689 | */ |
690 | if (flags & NS_TCL_SET_SHARED) { |
691 | Ns_MutexUnlock(&itPtr->servPtr->sets.lock); |
692 | } |
693 | return TCL_OK; |
694 | } |
695 | |
696 | |
697 | /* |
698 | *---------------------------------------------------------------------- |
699 | * |
700 | * <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupSet">LookupSet</a> -- |
701 | * |
702 | * Take a tcl set handle and return a matching Set. This |
703 | * takes both persistent and dynamic set handles. |
704 | * |
705 | * Results: |
706 | * TCL_OK or TCL_ERROR. |
707 | * |
708 | * Side effects: |
709 | * If delete is set, then the hash entry will be removed. |
710 | * Set will be returned in given setPtr. |
711 | * |
712 | *---------------------------------------------------------------------- |
713 | */ |
714 | |
715 | static int |
716 | <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupObjSet">LookupObjSet</a>(NsInterp *itPtr, Tcl_Obj *idPtr, int delete, Ns_Set **setPtr) |
717 | { |
718 | return <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupSet">LookupSet</a>(itPtr, Tcl_GetString(idPtr), delete, setPtr); |
719 | } |
720 | |
721 | static int |
722 | <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupInterpSet">LookupInterpSet</a>(Tcl_Interp *interp, char *id, int delete, Ns_Set **setPtr) |
723 | { |
724 | NsInterp *itPtr; |
725 | |
726 | itPtr = <a href="/cvs/aolserver/aolserver/nsd/tclinit.c#A_NsGetInterpData">NsGetInterpData</a>(interp); |
727 | if (itPtr == NULL) { |
728 | Tcl_SetResult(interp, "ns_set not supported", TCL_STATIC); |
729 | return TCL_ERROR; |
730 | } |
731 | return <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupSet">LookupSet</a>(itPtr, id, delete, setPtr); |
732 | } |
733 | |
734 | static int |
735 | <a href="/cvs/aolserver/aolserver/nsd/tclset.c#A_LookupSet">LookupSet</a>(NsInterp *itPtr, char *id, int delete, Ns_Set **setPtr) |
736 | { |
737 | Tcl_HashTable *tablePtr; |
738 | Tcl_HashEntry *hPtr; |
739 | Ns_Set *set; |
740 | |
741 | /* |
742 | * If it's a persistent set, use the shared table, otherwise |
743 | * use the private table. |
744 | */ |
745 | |
746 | set = NULL; |
747 | if (IS_SHARED(id)) { |
748 | tablePtr = &itPtr->servPtr->sets.table; |
749 | Ns_MutexLock(&itPtr->servPtr->sets.lock); |
750 | } else { |
751 | tablePtr = &itPtr->sets; |
752 | } |
753 | hPtr = Tcl_FindHashEntry(tablePtr, id); |
754 | if (hPtr != NULL) { |
755 | set = (Ns_Set *) Tcl_GetHashValue(hPtr); |
756 | if (delete) { |
757 | Tcl_DeleteHashEntry(hPtr); |
758 | } |
759 | } |
760 | if (IS_SHARED(id)) { |
761 | Ns_MutexUnlock(&itPtr->servPtr->sets.lock); |
762 | } |
763 | if (set == NULL) { |
764 | Tcl_AppendResult(itPtr->interp, "no such set: ", id, NULL); |
765 | return TCL_ERROR; |
766 | } |
767 | *setPtr = set; |
768 | return TCL_OK; |
769 | } |
Copyright © 2010 Geeknet, Inc. All rights reserved. Terms of Use