1 |
/* |
2 |
openisis - an open implementation of the CDS/ISIS database |
3 |
Version 0.8.x (patchlevel see file Version) |
4 |
Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org |
5 |
|
6 |
This library is free software; you can redistribute it and/or |
7 |
modify it under the terms of the GNU Lesser General Public |
8 |
License as published by the Free Software Foundation; either |
9 |
version 2.1 of the License, or (at your option) any later version. |
10 |
|
11 |
This library is distributed in the hope that it will be useful, |
12 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 |
Lesser General Public License for more details. |
15 |
|
16 |
You should have received a copy of the GNU Lesser General Public |
17 |
License along with this library; if not, write to the Free Software |
18 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 |
|
20 |
see README for more information |
21 |
EOH */ |
22 |
|
23 |
/* |
24 |
$Id: openisistcl.087.c,v 1.2 2003/04/08 00:20:54 kripke Exp $ |
25 |
tcl/tk binding |
26 |
*/ |
27 |
|
28 |
#include <errno.h> |
29 |
#include <limits.h> |
30 |
#include <stdio.h> |
31 |
#include <stdlib.h> |
32 |
#include <string.h> |
33 |
#include <openisis.h> |
34 |
#include <openisistcl.h> |
35 |
|
36 |
#ifdef WIN32 |
37 |
#define snprintf _snprintf |
38 |
#endif |
39 |
|
40 |
/* ************************************************************ |
41 |
private functions |
42 |
*/ |
43 |
|
44 |
#define SESPRE "oises" |
45 |
#define SPLEN 5 |
46 |
|
47 |
#define MAXVALLEN 4096 /* <= INT_MAX */ |
48 |
|
49 |
#define BUFLEN 32 |
50 |
#define PRNBUF(fmt,arg) \ |
51 |
memset (buf, 0, BUFLEN); \ |
52 |
snprintf (buf, BUFLEN - 1, fmt, arg); |
53 |
#define PRNBUF2(fmt,a1,a2) \ |
54 |
memset (buf, 0, BUFLEN); \ |
55 |
snprintf (buf, BUFLEN - 1, fmt, a1, a2); |
56 |
|
57 |
typedef struct { |
58 |
OpenIsisSession ses; |
59 |
long idx; |
60 |
int dbid; |
61 |
OpenIsisSet ois; |
62 |
} OIT_Set; |
63 |
|
64 |
static int OIT_CmdSess _ANSI_ARGS_ ( |
65 |
( OpenIsisSession ses, Tcl_Interp *ip, int argc, const char **argv ) ); |
66 |
|
67 |
static int OIT_CmdDb _ANSI_ARGS_ ( |
68 |
( int *dbid, Tcl_Interp *ip, int argc, const char **argv ) ); |
69 |
|
70 |
static int OIT_FreeDb _ANSI_ARGS_ ( |
71 |
( int *dbid, Tcl_Interp *ip, int argc, const char **argv ) ); |
72 |
|
73 |
static int OIT_CmdSet _ANSI_ARGS_ ( |
74 |
( OIT_Set *set, Tcl_Interp *ip, int argc, const char **argv ) ); |
75 |
|
76 |
static int OIT_FreeSet _ANSI_ARGS_ ( |
77 |
( OIT_Set *set, Tcl_Interp *ip, int argc, const char **argv ) ); |
78 |
|
79 |
static int scanLong (const char *str, long *res) { |
80 |
char *endp; |
81 |
if (0 == str) { |
82 |
return 0; |
83 |
} |
84 |
*res = strtol (str, &endp, 0); |
85 |
if (LONG_MAX == *res || LONG_MIN == *res) { |
86 |
return 0; |
87 |
} |
88 |
if (endp == str) { |
89 |
return 0; |
90 |
} |
91 |
return 1; |
92 |
} |
93 |
|
94 |
static int scanInt (const char *str, int *res) { |
95 |
long lval; |
96 |
if (! scanLong (str, &lval)) { |
97 |
return 0; |
98 |
} |
99 |
if (INT_MAX <= lval || INT_MIN >= lval) { |
100 |
return 0; |
101 |
} |
102 |
*res = (int) lval; |
103 |
return 1; |
104 |
} |
105 |
|
106 |
static OpenIsisSession scanSes (const char *str) { |
107 |
int sid; |
108 |
if (strncmp (SESPRE, str, SPLEN)) { |
109 |
return (OpenIsisSession)0; |
110 |
} |
111 |
if (! scanInt (str + SPLEN, &sid)) { |
112 |
return (OpenIsisSession)0; |
113 |
} |
114 |
return openIsisId2Session (sid); |
115 |
} |
116 |
|
117 |
static int resultSes (Tcl_Interp *ip, OpenIsisSession ses) { |
118 |
char buf[BUFLEN]; |
119 |
int rt; |
120 |
|
121 |
rt = openIsisSession2Id (ses); |
122 |
if (0 > rt) { |
123 |
PRNBUF ("%d", rt); |
124 |
Tcl_SetResult (ip, buf, TCL_VOLATILE); |
125 |
return TCL_ERROR; |
126 |
} |
127 |
|
128 |
PRNBUF2 ("%s%d", SESPRE, rt); |
129 |
Tcl_CreateCommand (ip, buf, (Tcl_CmdProc*)OIT_CmdSess, |
130 |
(ClientData)ses, (Tcl_CmdDeleteProc*)0); |
131 |
Tcl_SetResult (ip, buf, TCL_VOLATILE); |
132 |
return TCL_OK; |
133 |
} |
134 |
|
135 |
static int _SetCnt = 0; /* ??? */ |
136 |
static int NewSetCounterFor (OIT_Set *set) { |
137 |
return _SetCnt++; |
138 |
} |
139 |
|
140 |
static char *Rec2String (OpenIsisRec *rec, Tcl_DString *ds) { |
141 |
Tcl_DStringInit (ds); |
142 |
|
143 |
if (0 != rec) { |
144 |
OpenIsisField *fld; |
145 |
char val[MAXVALLEN]; |
146 |
char buf[BUFLEN]; |
147 |
unsigned len; |
148 |
for (fld = rec->field; rec->len > fld - rec->field; ++fld) { |
149 |
Tcl_DStringStartSublist (ds); |
150 |
PRNBUF ("%ld", fld->tag); |
151 |
Tcl_DStringAppendElement (ds, buf); |
152 |
if (0 != fld->len) { |
153 |
if (0 == (len = (unsigned) fld->len) || MAXVALLEN <= len) { |
154 |
fprintf (stderr, "truncation of %ld %ld %ld\n", |
155 |
rec->rowid, fld->tag, fld->len); |
156 |
len = MAXVALLEN - 1; |
157 |
} |
158 |
strncpy (val, fld->val, len) [len] = 0; |
159 |
} |
160 |
else { |
161 |
*val = 0; |
162 |
} |
163 |
Tcl_DStringAppendElement (ds, val); |
164 |
Tcl_DStringEndSublist (ds); |
165 |
} |
166 |
} |
167 |
|
168 |
return Tcl_DStringValue (ds); |
169 |
} |
170 |
|
171 |
static int OIT_ReadRec ( |
172 |
Tcl_Interp *ip, OpenIsisSession ses, int dbid, int row |
173 |
) { |
174 |
Tcl_DString ds; |
175 |
OpenIsisRec *rec = openIsisDRead (ses, dbid, row); |
176 |
Tcl_SetResult (ip, Rec2String (rec, &ds), TCL_VOLATILE); |
177 |
if (0 != rec) { |
178 |
free (rec); |
179 |
} |
180 |
Tcl_DStringFree (&ds); |
181 |
return TCL_OK; |
182 |
} |
183 |
|
184 |
static int Append2Rec ( |
185 |
OpenIsisSession ses, OpenIsisRec **recp, const char *tag, const char *val |
186 |
) { |
187 |
int ntag; |
188 |
if (0 == val || ! scanInt (tag, &ntag) || 0 >= ntag) { |
189 |
return 0; |
190 |
} |
191 |
OPENISIS_RADDS (ses, *recp, ntag, val, !0); |
192 |
return 1; |
193 |
} |
194 |
|
195 |
/* ============================ general ================================ |
196 |
*/ |
197 |
|
198 |
/* openIsisCLog ( int level, const char *filename ) |
199 |
*/ |
200 |
static int OIT_Log ( |
201 |
ClientData cd, Tcl_Interp *ip, int argc, const char **argv |
202 |
) { |
203 |
const char *fname = (char*)0; |
204 |
int lvl; |
205 |
|
206 |
switch (argc) { |
207 |
case 3: |
208 |
fname = argv[2]; |
209 |
case 2: |
210 |
if (scanInt (argv[1], &lvl) && -1 <= lvl && 9 >= lvl) { |
211 |
break; |
212 |
} |
213 |
if (1 == strlen (argv[1])) { |
214 |
lvl = *argv[1]; |
215 |
break; |
216 |
} |
217 |
default: |
218 |
Tcl_AppendResult (ip, |
219 |
"usage: ", argv[0], " <level> [<filename>]", (char*)0); |
220 |
return TCL_ERROR; |
221 |
} |
222 |
|
223 |
openIsisCLog (lvl, fname); /* fname currently ignored */ |
224 |
return TCL_OK; |
225 |
} |
226 |
|
227 |
/* openIsisCInit(int argc, const char **argv,OpenIsisCLockFunc lock) |
228 |
incl. openIsisCOpen ( OpenIsisRec *args ) |
229 |
*/ |
230 |
|
231 |
static int OIT_Init ( |
232 |
ClientData cd, Tcl_Interp *ip, int argc, const char **argv |
233 |
) { |
234 |
char buf[BUFLEN]; |
235 |
int rt; |
236 |
|
237 |
rt = openIsisCInit (argc - 1, argv + 1, 0); |
238 |
if (0 != rt) { |
239 |
PRNBUF ("%d", rt); |
240 |
Tcl_SetResult (ip, buf, TCL_VOLATILE); |
241 |
return TCL_ERROR; |
242 |
} |
243 |
|
244 |
return resultSes (ip, OPENISIS_SES0 ()); |
245 |
} |
246 |
|
247 |
/* cDOpenv ( const char *dbname, const char **argv, int argc ) |
248 |
*/ |
249 |
static int OIT_Open ( |
250 |
ClientData cd, Tcl_Interp *ip, int argc, const char **argv |
251 |
) { |
252 |
Tcl_CmdInfo cinfo; |
253 |
char buf[BUFLEN]; |
254 |
int *dbid; |
255 |
int rt; |
256 |
|
257 |
if (2 > argc) { |
258 |
Tcl_AppendResult (ip, |
259 |
"usage: ", argv[0], " <dbname> [args...]", (char*)0); |
260 |
return TCL_ERROR; |
261 |
} |
262 |
|
263 |
errno = 0; |
264 |
rt = openIsisCDOpenv (argv[1], argv + 2, argc - 2); |
265 |
if (0 > rt) { |
266 |
if (0 != errno) { |
267 |
Tcl_SetResult (ip, strerror (errno), TCL_VOLATILE); |
268 |
} |
269 |
else { |
270 |
PRNBUF ("%d", rt); |
271 |
Tcl_SetResult (ip, buf, TCL_VOLATILE); |
272 |
} |
273 |
return TCL_ERROR; |
274 |
} |
275 |
|
276 |
PRNBUF ("oidb%d", rt); |
277 |
*(dbid = (int*) Tcl_Alloc (sizeof (int))) = rt; |
278 |
if (! Tcl_GetCommandInfo (ip, buf, &cinfo)) { |
279 |
Tcl_CreateCommand (ip, buf, (Tcl_CmdProc*)OIT_CmdDb, |
280 |
(ClientData)dbid, (Tcl_CmdDeleteProc*)OIT_FreeDb); |
281 |
} |
282 |
Tcl_SetResult (ip, buf, TCL_VOLATILE); |
283 |
return TCL_OK; |
284 |
} |
285 |
|
286 |
|
287 |
/* ============================ session ================================ |
288 |
*/ |
289 |
|
290 |
static int OIT_CmdSess ( |
291 |
OpenIsisSession ses, Tcl_Interp *ip, int argc, const char **argv |
292 |
) { |
293 |
if (2 != argc || strncmp ("new", argv[1], strlen (argv[1]))) { |
294 |
Tcl_AppendResult (ip, |
295 |
"usage: ", argv[0], " new", (char*)0); |
296 |
return TCL_ERROR; |
297 |
} |
298 |
|
299 |
return resultSes (ip, openIsisCSession ((OpenIsisRec*)0)); |
300 |
} |
301 |
|
302 |
/* ============================ db ================================ |
303 |
*/ |
304 |
|
305 |
static int OIT_CmdDb ( |
306 |
int *dbid, Tcl_Interp *ip, int argc, const char **argv |
307 |
) { |
308 |
OpenIsisSession ses = (OpenIsisSession)0; |
309 |
const char *sname = ""; |
310 |
const char *rname = ""; |
311 |
char buf[BUFLEN]; |
312 |
unsigned len; |
313 |
int rt; |
314 |
|
315 |
if (2 > argc || 0 == (len = strlen (argv[1]))) { |
316 |
goto usage; |
317 |
} |
318 |
switch (*argv[1]) { |
319 |
|
320 |
case 'a': |
321 |
if (0 == strncmp ("append", argv[1], len)) { |
322 |
Tcl_DString ds; |
323 |
OpenIsisRec *rec; |
324 |
long rid; |
325 |
int fidx = 3; |
326 |
|
327 |
if (5 > argc || 0 == (argc & 1)) { |
328 |
goto usage; |
329 |
} |
330 |
if (! scanLong (argv[2], &rid)) { |
331 |
goto usage; |
332 |
} |
333 |
if (0 == strncmp ("-session", argv[3], strlen (argv[3]))) { |
334 |
if (0 == (ses = scanSes (sname = argv[4]))) { |
335 |
goto nosess; |
336 |
} |
337 |
if ((fidx = 5) == argc) { |
338 |
goto usage; |
339 |
} |
340 |
} |
341 |
if (0 == ses) { |
342 |
ses = OPENISIS_SES0 (); |
343 |
} |
344 |
|
345 |
if (0 == (rec = openIsisDRead (ses, *dbid, rid))) { |
346 |
rname = argv[2]; |
347 |
goto norec; |
348 |
} |
349 |
while (fidx < argc) { |
350 |
if (! Append2Rec (ses, &rec, argv[fidx], argv[1 + fidx])) { |
351 |
Tcl_AppendResult (ip, argv[0], |
352 |
": error appending field ", argv[fidx], (char*)0); |
353 |
return TCL_ERROR; |
354 |
} |
355 |
fidx += 2; |
356 |
} |
357 |
|
358 |
Tcl_SetResult (ip, Rec2String (rec, &ds), TCL_VOLATILE); |
359 |
if (0 != rec) { |
360 |
free (rec); |
361 |
} |
362 |
Tcl_DStringFree (&ds); |
363 |
return TCL_OK; |
364 |
|
365 |
} /* 'a' */ |
366 |
goto usage; |
367 |
|
368 |
case 'c': |
369 |
if (1 != len) { |
370 |
if (0 == strncmp ("close", argv[1], len)) { |
371 |
if (2 != argc) { |
372 |
goto usage; |
373 |
} |
374 |
Tcl_DeleteCommand (ip, (char*)argv[0]); |
375 |
return TCL_OK; |
376 |
} |
377 |
if (0 == strncmp ("check", argv[1], len)) { |
378 |
int flags = 0; |
379 |
if (2 != argc) { |
380 |
if (3 != argc) { |
381 |
goto usage; |
382 |
} |
383 |
if (! scanInt (argv[2], &flags)) { |
384 |
goto usage; |
385 |
} |
386 |
} |
387 |
rt = openIsisCDCheck (*dbid, flags); |
388 |
if (0 == rt) { |
389 |
return TCL_OK; |
390 |
} |
391 |
PRNBUF ("%d", rt); |
392 |
Tcl_SetResult (ip, buf, TCL_VOLATILE); |
393 |
return TCL_ERROR; |
394 |
} |
395 |
} |
396 |
goto usage; |
397 |
|
398 |
case 'd': |
399 |
|
400 |
/* $db delete <rowid> */ |
401 |
goto usage; |
402 |
|
403 |
case 'i': |
404 |
|
405 |
/* $db insert {rec} */ |
406 |
goto usage; |
407 |
|
408 |
case 'm': |
409 |
if (0 == strncmp ("maxrowid", argv[1], len)) { |
410 |
if (2 != argc) { |
411 |
if (4 != argc || |
412 |
strncmp ("-session", argv[2], strlen (argv[2]))) { |
413 |
goto usage; |
414 |
} |
415 |
if (0 == (ses = scanSes (sname = argv[3]))) { |
416 |
goto nosess; |
417 |
} |
418 |
} |
419 |
if (0 == ses) { |
420 |
ses = OPENISIS_SES0 (); |
421 |
} |
422 |
rt = openIsisDMaxId (ses, *dbid); |
423 |
PRNBUF ("%d", rt); |
424 |
if (0 > rt) { |
425 |
Tcl_AppendResult (ip, |
426 |
"could not determine max rowid: ", buf, (char*)0); |
427 |
return TCL_ERROR; |
428 |
} |
429 |
Tcl_SetResult (ip, buf, TCL_VOLATILE); |
430 |
return TCL_OK; |
431 |
} |
432 |
goto usage; |
433 |
|
434 |
case 'q': { |
435 |
OIT_Set *set; |
436 |
const char *key; |
437 |
long mode = OPENISIS_QRY_KEYEQ; |
438 |
long skip = 0; |
439 |
long lrt; |
440 |
int j; |
441 |
|
442 |
if (strncmp ("query", argv[1], len)) { |
443 |
goto usage; |
444 |
} |
445 |
if (3 > argc) { |
446 |
goto usage; |
447 |
} |
448 |
key = argv[2]; |
449 |
for (j = 3; argc > j; ++j) { |
450 |
if (argv[j][0] != '-') { |
451 |
goto usage; |
452 |
} |
453 |
switch (argv[j][1]) { |
454 |
case 'm': |
455 |
if (strncmp ("-mode", argv[j], strlen (argv[j]))) { |
456 |
goto usage; |
457 |
} |
458 |
if (argc <= ++j) { |
459 |
goto usage; |
460 |
} |
461 |
if (! scanLong (argv[j], &mode)) { |
462 |
goto usage; |
463 |
} |
464 |
continue; |
465 |
case 's': { |
466 |
unsigned ll = strlen (argv[j]); |
467 |
if (3 > ll) { |
468 |
goto usage; |
469 |
} |
470 |
if (0 == strncmp ("-session", argv[j], ll)) { |
471 |
if (argc <= ++j) { |
472 |
goto usage; |
473 |
} |
474 |
if (0 == (ses = scanSes (sname = argv[j]))) { |
475 |
goto nosess; |
476 |
} |
477 |
continue; |
478 |
} |
479 |
if (0 == strncmp ("-skip", argv[j], ll)) { |
480 |
if (argc <= ++j) { |
481 |
goto usage; |
482 |
} |
483 |
if (! scanLong (argv[j], &skip)) { |
484 |
goto usage; |
485 |
} |
486 |
continue; |
487 |
} |
488 |
} /* fall thru */ |
489 |
default: |
490 |
goto usage; |
491 |
} |
492 |
} /* for args */ |
493 |
|
494 |
if (0 == ses) { |
495 |
ses = OPENISIS_SES0 (); |
496 |
} |
497 |
set = (OIT_Set*) Tcl_Alloc (sizeof (OIT_Set)); |
498 |
set->ois.len = set->idx = 0; |
499 |
set->ses = ses; |
500 |
set->dbid = *dbid; |
501 |
lrt = openIsisDQuery (ses, &(set->ois), *dbid, key, mode, skip); |
502 |
|
503 |
if (0 > lrt) { |
504 |
Tcl_Free ((ClientData)set); |
505 |
PRNBUF ("%ld", lrt); |
506 |
Tcl_SetResult (ip, buf, TCL_VOLATILE); |
507 |
return TCL_ERROR; |
508 |
} |
509 |
|
510 |
rt = NewSetCounterFor (set); |
511 |
PRNBUF ("oiset%d", rt); |
512 |
Tcl_CreateCommand (ip, buf, (Tcl_CmdProc*)OIT_CmdSet, |
513 |
(ClientData)set, (Tcl_CmdDeleteProc*)OIT_FreeSet); |
514 |
Tcl_SetResult (ip, buf, TCL_VOLATILE); |
515 |
return TCL_OK; |
516 |
|
517 |
} /* 'q' */ |
518 |
goto usage; |
519 |
|
520 |
case 'r': { |
521 |
long rid; |
522 |
|
523 |
if (strncmp ("read", argv[1], len)) { |
524 |
goto usage; |
525 |
} |
526 |
switch (argc) { |
527 |
case 5: |
528 |
if (strncmp ("-session", argv[3], strlen (argv[3]))) { |
529 |
goto usage; |
530 |
} |
531 |
if (0 == (ses = scanSes (sname = argv[4]))) { |
532 |
goto nosess; |
533 |
} |
534 |
case 3: |
535 |
if (scanLong (argv[2], &rid) && 0 <= rid) { |
536 |
break; |
537 |
} |
538 |
default: |
539 |
goto usage; |
540 |
} |
541 |
if (0 == ses) { |
542 |
ses = OPENISIS_SES0 (); |
543 |
} |
544 |
|
545 |
return OIT_ReadRec (ip, ses, *dbid, rid); |
546 |
|
547 |
} /* 'r' */ |
548 |
goto usage; |
549 |
|
550 |
case 'u': |
551 |
if (0 == strncmp ("update", argv[1], len)) { |
552 |
Tcl_DString ds; |
553 |
OpenIsisRec *rec; |
554 |
long rid; |
555 |
int fidx = 3; |
556 |
|
557 |
if (5 > argc || 0 == (argc & 1)) { |
558 |
goto usage; |
559 |
} |
560 |
if (! scanLong (argv[2], &rid)) { |
561 |
goto usage; |
562 |
} |
563 |
if (0 == strncmp ("-session", argv[3], strlen (argv[3]))) { |
564 |
if (0 == (ses = scanSes (sname = argv[4]))) { |
565 |
goto nosess; |
566 |
} |
567 |
if ((fidx = 5) == argc) { |
568 |
goto usage; |
569 |
} |
570 |
} |
571 |
if (0 == ses) { |
572 |
ses = OPENISIS_SES0 (); |
573 |
} |
574 |
|
575 |
if (0 == (rec = openIsisRDup (ses, (OpenIsisRec*)0, 1024, !0))) { |
576 |
Tcl_AppendResult (ip, argv[0], |
577 |
": cannot allocate record", (char*)0); |
578 |
return TCL_ERROR; |
579 |
} |
580 |
while (fidx < argc) { |
581 |
if (! Append2Rec (ses, &rec, argv[fidx], argv[1 + fidx])) { |
582 |
Tcl_AppendResult (ip, argv[0], |
583 |
": error appending field ", argv[fidx], (char*)0); |
584 |
return TCL_ERROR; |
585 |
} |
586 |
fidx += 2; |
587 |
} |
588 |
|
589 |
rec->rowid = rid; |
590 |
rt = openIsisDWrite (ses, *dbid, rec); |
591 |
if (0 != rt) { |
592 |
PRNBUF ("%d", rt); |
593 |
Tcl_SetResult (ip, buf, TCL_VOLATILE); |
594 |
return TCL_ERROR; |
595 |
} |
596 |
Tcl_SetResult (ip, Rec2String (rec, &ds), TCL_VOLATILE); |
597 |
if (0 != rec) { |
598 |
free (rec); |
599 |
} |
600 |
Tcl_DStringFree (&ds); |
601 |
return TCL_OK; |
602 |
|
603 |
} /* 'u' */ |
604 |
goto usage; |
605 |
|
606 |
} /* switch (*argv[1]) */ |
607 |
|
608 |
usage: |
609 |
Tcl_AppendResult (ip, "ops on db:\n ", argv[0], |
610 |
" check [<flags>] |", |
611 |
" close |", |
612 |
" maxrowid [-session <id>] |", |
613 |
" query <key> [-session <id>] [-mode <mode>] [-skip <skip>] |", |
614 |
" read <rowid> [-session <id>]\n", |
615 |
/* |
616 |
"ops on recs:\n ", argv[0], |
617 |
" append <rowid> [-session <id>] <fields> |", |
618 |
" delete <rowid> [-session <id>] |", |
619 |
" insert [-session <id>] <fields> |", |
620 |
" update [-session <id>] <fields>", |
621 |
*/ |
622 |
(char*)0); |
623 |
return TCL_ERROR; |
624 |
|
625 |
nosess: |
626 |
Tcl_AppendResult (ip, argv[0], ": no such session: ", sname, (char*)0); |
627 |
return TCL_ERROR; |
628 |
|
629 |
norec: |
630 |
Tcl_AppendResult (ip, argv[0], ": no such record: ", rname, (char*)0); |
631 |
return TCL_ERROR; |
632 |
} |
633 |
|
634 |
static int OIT_FreeDb ( |
635 |
int *dbid, Tcl_Interp *ip, int argc, const char **argv |
636 |
) { |
637 |
char buf[BUFLEN]; |
638 |
int rt; |
639 |
|
640 |
rt = openIsisCDClose (*dbid); |
641 |
if (0 == rt) { |
642 |
Tcl_Free ((ClientData)dbid); |
643 |
return TCL_OK; |
644 |
} |
645 |
|
646 |
PRNBUF2 ("%d: %d", *dbid, rt); |
647 |
Tcl_Free ((ClientData)dbid); |
648 |
Tcl_AppendResult (ip, "could not close database ", buf, (char*)0); |
649 |
return TCL_ERROR; |
650 |
} |
651 |
|
652 |
/* ============================ set ================================ |
653 |
*/ |
654 |
|
655 |
static int OIT_CmdSet ( |
656 |
OIT_Set *set, Tcl_Interp *ip, int argc, const char **argv |
657 |
) { |
658 |
unsigned len; |
659 |
|
660 |
switch (argc) { |
661 |
|
662 |
case 3: { |
663 |
int idx; |
664 |
if (0 == (len = strlen (argv[1])) || 'g' != *argv[1]) { |
665 |
goto usage; |
666 |
} |
667 |
if (strncmp ("get", argv[1], len)) { |
668 |
goto usage; |
669 |
} |
670 |
if (! scanInt (argv[2], &idx)) { |
671 |
goto usage; |
672 |
} |
673 |
if (0 > idx || set->ois.len <= idx) { |
674 |
char buf[BUFLEN]; |
675 |
PRNBUF2 ("%d / %ld", idx, set->ois.len); |
676 |
Tcl_AppendResult (ip, "index out of bounds: ", buf, (char*)0); |
677 |
return TCL_ERROR; |
678 |
} |
679 |
return OIT_ReadRec (ip, set->ses, set->dbid, set->ois.id[idx]); |
680 |
|
681 |
} /* 3 */ |
682 |
|
683 |
case 2: |
684 |
if (0 != (len = strlen (argv[1])) && 'g' != *argv[1]) { |
685 |
break; |
686 |
} |
687 |
default: |
688 |
goto usage; |
689 |
|
690 |
} /* switch (argc) */ |
691 |
|
692 |
switch (*argv[1]) { |
693 |
|
694 |
case 'c': |
695 |
if (0 == strncmp ("close", argv[1], len)) { |
696 |
Tcl_DeleteCommand (ip, (char*)argv[0]); |
697 |
return TCL_OK; |
698 |
} |
699 |
break; |
700 |
|
701 |
case 'l': |
702 |
if (0 == strncmp ("list", argv[1], len)) { |
703 |
char buf[BUFLEN]; |
704 |
long *rid; |
705 |
int j; |
706 |
|
707 |
for (j = 0, rid = set->ois.id; set->ois.len > j; ++j, ++rid) { |
708 |
PRNBUF ("%ld", *rid); |
709 |
Tcl_AppendElement (ip, buf); |
710 |
} |
711 |
return TCL_OK; |
712 |
} |
713 |
break; |
714 |
|
715 |
case 'n': |
716 |
if (0 == strncmp ("next", argv[1], len)) { |
717 |
if (set->ois.len > set->idx) { |
718 |
char buf[BUFLEN]; |
719 |
PRNBUF ("%ld", set->ois.id[set->idx++]); |
720 |
Tcl_AppendElement (ip, buf); |
721 |
} |
722 |
return TCL_OK; |
723 |
} |
724 |
break; |
725 |
|
726 |
case 'r': |
727 |
if (0 == strncmp ("rewind", argv[1], len)) { |
728 |
set->idx = 0; |
729 |
return TCL_OK; |
730 |
} |
731 |
break; |
732 |
|
733 |
case 's': |
734 |
if (0 == strncmp ("size", argv[1], len)) { |
735 |
char buf[BUFLEN]; |
736 |
PRNBUF ("%ld", set->ois.len); |
737 |
Tcl_SetResult (ip, buf, TCL_VOLATILE); |
738 |
return TCL_OK; |
739 |
} |
740 |
break; |
741 |
|
742 |
} /* switch (*argv[1]) */ |
743 |
|
744 |
usage: |
745 |
Tcl_AppendResult (ip, "usage: ", argv[0], |
746 |
" close | get <index> | list | next | rewind | size", |
747 |
(char*)0); |
748 |
return TCL_ERROR; |
749 |
} |
750 |
|
751 |
static int OIT_FreeSet ( |
752 |
OIT_Set *set, Tcl_Interp *ip, int argc, const char **argv |
753 |
) { |
754 |
Tcl_Free ((ClientData)set); |
755 |
return TCL_OK; |
756 |
} |
757 |
|
758 |
/* ************************************************************ |
759 |
public functions |
760 |
*/ |
761 |
|
762 |
int |
763 |
OpenisisTcl_Init ( Tcl_Interp *ip ) |
764 |
{ |
765 |
Tcl_CreateCommand (ip, "openIsisInit", (Tcl_CmdProc*)OIT_Init, |
766 |
(ClientData)0, (Tcl_CmdDeleteProc*)0); |
767 |
Tcl_CreateCommand (ip, "openIsisLog", (Tcl_CmdProc*)OIT_Log, |
768 |
(ClientData)0, (Tcl_CmdDeleteProc*)0); |
769 |
Tcl_CreateCommand (ip, "openIsisOpen", (Tcl_CmdProc*)OIT_Open, |
770 |
(ClientData)0, (Tcl_CmdDeleteProc*)0); |
771 |
return TCL_OK; |
772 |
} |
773 |
|
774 |
int |
775 |
OpenisisTcl_AppInit ( Tcl_Interp *interp ) { |
776 |
if ( TCL_ERROR == OpenisisTcl_Init( interp ) ) return TCL_ERROR; |
777 |
return Tcl_AppInit( interp ); |
778 |
} |
779 |
|