X-Git-Url: http://jsfdemo.indexdata.com/?a=blobdiff_plain;f=ir-tcl.c;h=a9742c167f388782ef122f32489de454c64b25a2;hb=9825e269f78f31048f1ba02dd618773fdb6ddc69;hp=9eddd5f47ea5e70a9822917ae45e347333a28057;hpb=c10f5ecfbd81e3a9bda4cca310e13b066a520f4a;p=ir-tcl-moved-to-github.git diff --git a/ir-tcl.c b/ir-tcl.c index 9eddd5f..a9742c1 100644 --- a/ir-tcl.c +++ b/ir-tcl.c @@ -5,7 +5,66 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ir-tcl.c,v $ - * Revision 1.75 1996-02-19 15:41:53 adam + * Revision 1.91 1996-07-03 13:31:11 adam + * The xmalloc/xfree functions from YAZ are used to manage memory. + * + * Revision 1.90 1996/06/27 14:21:00 adam + * Yet another Windows port. + * + * Revision 1.89 1996/06/11 15:27:15 adam + * Event type set to connect a little earlier in the do_connect function. + * + * Revision 1.88 1996/06/03 09:04:22 adam + * Changed a few logf calls. + * + * Revision 1.87 1996/05/29 06:37:51 adam + * Function ir_tcl_get_grs_r enhanced so that specific elements can be + * extracted. + * + * Revision 1.86 1996/03/20 13:54:04 adam + * The Tcl_File structure is only manipulated in the Tk-event interface + * in tkinit.c. + * + * Revision 1.85 1996/03/15 11:15:48 adam + * Modified to use new prototypes for p_query_rpn and p_query_scan. + * + * Revision 1.84 1996/03/07 12:42:49 adam + * Better logging when callback is invoked. + * + * Revision 1.83 1996/03/05 09:21:09 adam + * Bug fix: memory used by GRS records wasn't freed. + * Rewrote some of the error handling code - the connection is always + * closed before failback is called. + * If failback is defined the send APDU methods (init, search, ...) will + * return OK but invoke failback (as is the case if the write operation + * fails). + * Bug fix: ref_count in assoc object could grow if fraction of PDU was + * read. + * + * Revision 1.82 1996/02/29 15:30:21 adam + * Export of IrTcl functionality to extensions. + * + * Revision 1.81 1996/02/26 18:38:32 adam + * Work on export of set methods. + * + * Revision 1.80 1996/02/23 17:31:39 adam + * More functions made available to the wais tcl extension. + * + * Revision 1.79 1996/02/23 13:41:38 adam + * Work on public access to simple ir class system. + * + * Revision 1.78 1996/02/21 10:16:08 adam + * Simplified select handling. Only one function ir_tcl_select_set has + * to be externally defined. + * + * Revision 1.77 1996/02/20 17:52:58 adam + * Uses the YAZ oid system to name record syntax object identifiers. + * + * Revision 1.76 1996/02/20 16:09:51 adam + * Bug fix: didn't set element set names stamp correctly on result + * set records when element set names were set to the empty string. + * + * Revision 1.75 1996/02/19 15:41:53 adam * Better log messages. * Minor improvement of connect method. * @@ -276,20 +335,52 @@ #include "ir-tclp.h" -typedef struct { - int type; - char *name; - int (*method) (void *obj, Tcl_Interp *interp, int argc, char **argv); -} IrTcl_Method; +static void ir_deleteDiags (IrTcl_Diagnostic **dst_list, int *dst_num); -typedef struct { - void *obj; - IrTcl_Method *tab; -} IrTcl_Methods; +static void ir_select_notify (ClientData clientData, int r, int w, int e); -static void ir_deleteDiags (IrTcl_Diagnostic **dst_list, int *dst_num); -static int do_disconnect (void *obj, Tcl_Interp *interp, - int argc, char **argv); +void ir_select_add (int fd, void *obj) +{ + ir_tcl_select_set (ir_select_notify, fd, obj, 1, 0, 0); +} + +void ir_select_add_write (int fd, void *obj) +{ + ir_tcl_select_set (ir_select_notify, fd, obj, 1, 1, 0); +} + +void ir_select_remove (int fd, void *obj) +{ + ir_tcl_select_set (NULL, fd, obj, 0, 0, 0); +} + +void ir_select_remove_write (int fd, void *obj) +{ + ir_tcl_select_set (ir_select_notify, fd, obj, 1, 0, 0); +} + +static void delete_IR_record (IrTcl_RecordList *rl) +{ + switch (rl->which) + { + case Z_NamePlusRecord_databaseRecord: + switch (rl->u.dbrec.type) + { + case VAL_GRS1: + ir_tcl_grs_del (&rl->u.dbrec.u.grs1); + break; + default: + break; + } + xfree (rl->u.dbrec.buf); + break; + case Z_NamePlusRecord_surrogateDiagnostic: + ir_deleteDiags (&rl->u.surrogateDiagnostics.list, + &rl->u.surrogateDiagnostics.num); + break; + } + xfree (rl->elements); +} static IrTcl_RecordList *new_IR_record (IrTcl_SetObj *setobj, int no, int which, @@ -297,23 +388,14 @@ static IrTcl_RecordList *new_IR_record (IrTcl_SetObj *setobj, { IrTcl_RecordList *rl; + if (elements && !*elements) + elements = NULL; for (rl = setobj->record_list; rl; rl = rl->next) { if (no == rl->no && (!rl->elements || !elements || !strcmp(elements, rl->elements))) { - free (rl->elements); - switch (rl->which) - { - case Z_NamePlusRecord_databaseRecord: - free (rl->u.dbrec.buf); - rl->u.dbrec.buf = NULL; - break; - case Z_NamePlusRecord_surrogateDiagnostic: - ir_deleteDiags (&rl->u.surrogateDiagnostics.list, - &rl->u.surrogateDiagnostics.num); - break; - } + delete_IR_record (rl); break; } } @@ -329,58 +411,45 @@ static IrTcl_RecordList *new_IR_record (IrTcl_SetObj *setobj, return rl; } -static struct { - enum oid_value value; - const char *name; -} IrTcl_recordSyntaxTab[] = { -{ VAL_UNIMARC, "UNIMARC" }, -{ VAL_INTERMARC, "INTERMARC" }, -{ VAL_CCF, "CCF" }, -{ VAL_USMARC, "USMARC" }, -{ VAL_UKMARC, "UKMARC" }, -{ VAL_NORMARC, "NORMARC" }, -{ VAL_LIBRISMARC, "LIBRISMARC" }, -{ VAL_DANMARC, "DANMARC" }, -{ VAL_FINMARC, "FINMARC" }, -{ VAL_MAB, "MAB" }, -{ VAL_CANMARC, "CANMARC" }, -{ VAL_SBN, "SBN" }, -{ VAL_PICAMARC, "PICAMARC" }, -{ VAL_AUSMARC, "AUSMARC" }, -{ VAL_IBERMARC, "IBERMARC" }, -{ VAL_SUTRS, "SUTRS" }, -{ VAL_GRS1, "GRS1" }, -{ 0, NULL } -}; - /* - * IrTcl_eval + * ir_tcl_eval */ -int IrTcl_eval (Tcl_Interp *interp, const char *command) +int ir_tcl_eval (Tcl_Interp *interp, const char *command) { char *tmp = ir_tcl_malloc (strlen(command)+1); int r; + logf (LOG_DEBUG, "Invoking %.23s ...", command); strcpy (tmp, command); r = Tcl_Eval (interp, tmp); if (r == TCL_ERROR) + { logf (LOG_WARN, "Tcl error in line %d: %s", interp->errorLine, interp->result); + } Tcl_FreeResult (interp); - free (tmp); + xfree (tmp); return r; } /* * IrTcl_getRecordSyntaxStr: Return record syntax name of object id */ -static const char *IrTcl_getRecordSyntaxStr (enum oid_value value) +static char *IrTcl_getRecordSyntaxStr (enum oid_value value) { - int i; - for (i = 0; IrTcl_recordSyntaxTab[i].name; i++) - if (IrTcl_recordSyntaxTab[i].value == value) - return IrTcl_recordSyntaxTab[i].name; - return "USMARC"; + int *o; + struct oident ent, *entp; + + ent.proto = PROTO_Z3950; + ent.oclass = CLASS_RECSYN; + ent.value = value; + + o = oid_getoidbyent (&ent); + entp = oid_getentbyoid (o); + + if (!entp) + return ""; + return entp->desc; } /* @@ -388,11 +457,7 @@ static const char *IrTcl_getRecordSyntaxStr (enum oid_value value) */ static enum oid_value IrTcl_getRecordSyntaxVal (const char *name) { - int i; - for (i = 0; IrTcl_recordSyntaxTab[i].name; i++) - if (!strcmp (IrTcl_recordSyntaxTab[i].name, name)) - return IrTcl_recordSyntaxTab[i].value; - return 0; + return oid_getvalbyname (name); } static IrTcl_RecordList *find_IR_record (IrTcl_SetObj *setobj, int no) @@ -413,26 +478,17 @@ static void delete_IR_records (IrTcl_SetObj *setobj) for (rl = setobj->record_list; rl; rl = rl1) { - switch (rl->which) - { - case Z_NamePlusRecord_databaseRecord: - free (rl->u.dbrec.buf); - break; - case Z_NamePlusRecord_surrogateDiagnostic: - ir_deleteDiags (&rl->u.surrogateDiagnostics.list, - &rl->u.surrogateDiagnostics.num); - break; - } + delete_IR_record (rl); rl1 = rl->next; - free (rl); + xfree (rl); } setobj->record_list = NULL; } /* - * get_set_int: Set/get integer value + * ir_tcl_get_set_int: Set/get integer value */ -static int get_set_int (int *val, Tcl_Interp *interp, int argc, char **argv) +int ir_tcl_get_set_int (int *val, Tcl_Interp *interp, int argc, char **argv) { char buf[20]; @@ -447,9 +503,10 @@ static int get_set_int (int *val, Tcl_Interp *interp, int argc, char **argv) } /* - * ir_method: Search for method in table and invoke method handler + * ir_tcl_method: Search for method in table and invoke method handler */ -int ir_method (Tcl_Interp *interp, int argc, char **argv, IrTcl_Methods *tab) +int ir_tcl_method (Tcl_Interp *interp, int argc, char **argv, + IrTcl_Methods *tab, int *ret) { IrTcl_Methods *tab_i = tab; IrTcl_Method *t; @@ -463,45 +520,29 @@ int ir_method (Tcl_Interp *interp, int argc, char **argv, IrTcl_Methods *tab) } else if (!strcmp (t->name, argv[1])) - return (*t->method)(tab_i->obj, interp, argc, argv); + { + *ret = (*t->method)(tab_i->obj, interp, argc, argv); + return TCL_OK; + } if (argc <= 0) return TCL_OK; +#if 0 Tcl_AppendResult (interp, "Bad method: ", argv[1], ". Possible methods:", NULL); for (tab_i = tab; tab_i->tab; tab_i++) for (t = tab_i->tab; t->name; t++) Tcl_AppendResult (interp, " ", t->name, NULL); +#endif + *ret = TCL_ERROR; return TCL_ERROR; } /* - * ir_method_r: Get status for all readable elements + * ir_tcl_named_bits: get/set named bits */ -int ir_method_r (void *obj, Tcl_Interp *interp, int argc, char **argv, - IrTcl_Method *tab) -{ - char *argv_n[3]; - int argc_n; - - argv_n[0] = argv[0]; - argc_n = 2; - for (; tab->name; tab++) - if (tab->type) - { - argv_n[1] = tab->name; - Tcl_AppendResult (interp, "{", NULL); - (*tab->method)(obj, interp, argc_n, argv_n); - Tcl_AppendResult (interp, "} ", NULL); - } - return TCL_OK; -} - -/* - * ir_named_bits: get/set named bits - */ -int ir_named_bits (struct ir_named_entry *tab, Odr_bitmask *ob, - Tcl_Interp *interp, int argc, char **argv) +int ir_tcl_named_bits (struct ir_named_entry *tab, Odr_bitmask *ob, + Tcl_Interp *interp, int argc, char **argv) { struct ir_named_entry *ti; if (argc > 0) @@ -545,7 +586,7 @@ static void set_referenceId (ODR o, Z_ReferenceId **dst, const char *src) static void get_referenceId (char **dst, Z_ReferenceId *src) { - free (*dst); + xfree (*dst); if (!src) { *dst = NULL; @@ -570,6 +611,7 @@ static int do_init_request (void *obj, Tcl_Interp *interp, if (argc <= 0) return TCL_OK; + logf (LOG_DEBUG, "init %s", *argv); if (!p->cs_link) { interp->result = "init: not connected"; @@ -694,7 +736,7 @@ static int do_options (void *obj, Tcl_Interp *interp, ODR_MASK_SET (&p->options, 14); return TCL_OK; } - return ir_named_bits (options_tab, &p->options, interp, argc-2, argv+2); + return ir_tcl_named_bits (options_tab, &p->options, interp, argc-2, argv+2); } /* @@ -800,7 +842,7 @@ static int do_preferredMessageSize (void *obj, Tcl_Interp *interp, p->preferredMessageSize = 30000; return TCL_OK; } - return get_set_int (&p->preferredMessageSize, interp, argc, argv); + return ir_tcl_get_set_int (&p->preferredMessageSize, interp, argc, argv); } /* @@ -816,7 +858,7 @@ static int do_maximumRecordSize (void *obj, Tcl_Interp *interp, p->maximumRecordSize = 30000; return TCL_OK; } - return get_set_int (&p->maximumRecordSize, interp, argc, argv); + return ir_tcl_get_set_int (&p->maximumRecordSize, interp, argc, argv); } /* @@ -829,7 +871,7 @@ static int do_initResult (void *obj, Tcl_Interp *interp, if (argc <= 0) return TCL_OK; - return get_set_int (&p->initResult, interp, argc, argv); + return ir_tcl_get_set_int (&p->initResult, interp, argc, argv); } @@ -848,7 +890,7 @@ static int do_implementationName (void *obj, Tcl_Interp *interp, return ir_tcl_strdel (interp, &p->implementationName); if (argc == 3) { - free (p->implementationName); + xfree (p->implementationName); if (ir_tcl_strdup (interp, &p->implementationName, argv[2]) == TCL_ERROR) return TCL_ERROR; @@ -957,10 +999,10 @@ static int do_idAuthentication (void *obj, Tcl_Interp *interp, if (argc >= 3 || argc == -1) { - free (p->idAuthenticationOpen); - free (p->idAuthenticationGroupId); - free (p->idAuthenticationUserId); - free (p->idAuthenticationPassword); + xfree (p->idAuthenticationOpen); + xfree (p->idAuthenticationGroupId); + xfree (p->idAuthenticationUserId); + xfree (p->idAuthenticationPassword); } if (argc >= 3 || argc <= 0) { @@ -1021,6 +1063,7 @@ static int do_connect (void *obj, Tcl_Interp *interp, return TCL_OK; if (argc == 3) { + logf (LOG_DEBUG, "connect %s %s", *argv, argv[2]); if (p->hostname) { interp->result = "already connected"; @@ -1061,41 +1104,26 @@ static int do_connect (void *obj, Tcl_Interp *interp, } if (ir_tcl_strdup (interp, &p->hostname, argv[2]) == TCL_ERROR) return TCL_ERROR; -#if IRTCL_GENERIC_FILES -#ifdef WINDOWS - p->csFile = Tcl_GetFile (cs_fileno(p->cs_link), TCL_WIN_SOCKET); -#else - p->csFile = Tcl_GetFile (cs_fileno(p->cs_link), TCL_UNIX_FD); -#endif -#endif + p->eventType = "connect"; if ((r=cs_connect (p->cs_link, addr)) < 0) { interp->result = "connect fail"; - do_disconnect (p, NULL, 2, NULL); + ir_tcl_disconnect (p); return TCL_ERROR; } - logf(LOG_DEBUG, "cs_connect() returned %d fd=%d", r, - cs_fileno(p->cs_link)); - p->eventType = "connect"; -#if IRTCL_GENERIC_FILES - ir_select_add (p->csFile, p); -#else ir_select_add (cs_fileno (p->cs_link), p); -#endif if (r == 1) { -#if IRTCL_GENERIC_FILES - ir_select_add_write (p->csFile, p); -#else + logf (LOG_DEBUG, "connect pending fd=%d", cs_fileno(p->cs_link)); ir_select_add_write (cs_fileno (p->cs_link), p); -#endif p->state = IR_TCL_R_Connecting; } else { + logf (LOG_DEBUG, "connect ok fd=%d", cs_fileno(p->cs_link)); p->state = IR_TCL_R_Idle; if (p->callback) - IrTcl_eval (p->interp, p->callback); + ir_tcl_eval (p->interp, p->callback); } } else @@ -1103,47 +1131,24 @@ static int do_connect (void *obj, Tcl_Interp *interp, return TCL_OK; } -/* - * do_disconnect: disconnect method on IR object +/* + * ir_tcl_disconnect: close connection */ -static int do_disconnect (void *obj, Tcl_Interp *interp, - int argc, char **argv) +void ir_tcl_disconnect (IrTcl_Obj *p) { - IrTcl_Obj *p = obj; - - if (argc == 0) - { - p->state = IR_TCL_R_Idle; - p->eventType = NULL; - p->hostname = NULL; - p->cs_link = NULL; -#if IRTCL_GENERIC_FILES - p->csFile = 0; -#endif - return TCL_OK; - } if (p->hostname) { - logf(LOG_DEBUG, "Closing connection to %s", p->hostname); - free (p->hostname); + logf(LOG_DEBUG, "Closing connection to %s", p->hostname); + xfree (p->hostname); p->hostname = NULL; -#if IRTCL_GENERIC_FILES - ir_select_remove_write (p->csFile, p); - ir_select_remove (p->csFile, p); -#else ir_select_remove_write (cs_fileno (p->cs_link), p); ir_select_remove (cs_fileno (p->cs_link), p); -#endif odr_reset (p->odr_in); assert (p->cs_link); cs_close (p->cs_link); p->cs_link = NULL; -#if IRTCL_GENERIC_FILES - Tcl_FreeFile (p->csFile); - p->csFile = NULL; -#endif ODR_MASK_ZERO (&p->options); ODR_MASK_SET (&p->options, 0); @@ -1158,6 +1163,25 @@ static int do_disconnect (void *obj, Tcl_Interp *interp, ir_tcl_del_q (p); } assert (!p->cs_link); +} + +/* + * do_disconnect: disconnect method on IR object + */ +static int do_disconnect (void *obj, Tcl_Interp *interp, + int argc, char **argv) +{ + IrTcl_Obj *p = obj; + + if (argc == 0) + { + p->state = IR_TCL_R_Idle; + p->eventType = NULL; + p->hostname = NULL; + p->cs_link = NULL; + return TCL_OK; + } + ir_tcl_disconnect (p); return TCL_OK; } @@ -1175,7 +1199,7 @@ static int do_comstack (void *o, Tcl_Interp *interp, return ir_tcl_strdel (interp, &obj->comstackType); else if (argc == 3) { - free (obj->comstackType); + xfree (obj->comstackType); if (ir_tcl_strdup (interp, &obj->comstackType, argv[2]) == TCL_ERROR) return TCL_ERROR; } @@ -1236,7 +1260,7 @@ static int do_callback (void *obj, Tcl_Interp *interp, return ir_tcl_strdel (interp, &p->callback); if (argc == 3) { - free (p->callback); + xfree (p->callback); if (argv[2][0]) { if (ir_tcl_strdup (interp, &p->callback, argv[2]) == TCL_ERROR) @@ -1265,7 +1289,7 @@ static int do_failback (void *obj, Tcl_Interp *interp, return ir_tcl_strdel (interp, &p->failback); else if (argc == 3) { - free (p->failback); + xfree (p->failback); if (argv[2][0]) { if (ir_tcl_strdup (interp, &p->failback, argv[2]) == TCL_ERROR) @@ -1294,7 +1318,7 @@ static int do_initResponse (void *obj, Tcl_Interp *interp, return ir_tcl_strdel (interp, &p->initResponse); if (argc == 3) { - free (p->initResponse); + xfree (p->initResponse); if (argv[2][0]) { if (ir_tcl_strdup (interp, &p->initResponse, argv[2]) == TCL_ERROR) @@ -1381,8 +1405,8 @@ static int do_databaseNames (void *obj, Tcl_Interp *interp, if (argc == -1) { for (i=0; inum_databaseNames; i++) - free (p->databaseNames[i]); - free (p->databaseNames); + xfree (p->databaseNames[i]); + xfree (p->databaseNames); } if (argc <= 0) { @@ -1399,18 +1423,19 @@ static int do_databaseNames (void *obj, Tcl_Interp *interp, if (p->databaseNames) { for (i=0; inum_databaseNames; i++) - free (p->databaseNames[i]); - free (p->databaseNames); + xfree (p->databaseNames[i]); + xfree (p->databaseNames); } p->num_databaseNames = argc - 2; p->databaseNames = - ir_tcl_malloc (sizeof(*p->databaseNames) * p->num_databaseNames); + ir_tcl_malloc (sizeof(*p->databaseNames) * (1+p->num_databaseNames)); for (i=0; inum_databaseNames; i++) { if (ir_tcl_strdup (interp, &p->databaseNames[i], argv[2+i]) == TCL_ERROR) return TCL_ERROR; } + p->databaseNames[i] = NULL; return TCL_OK; } @@ -1427,7 +1452,7 @@ static int do_replaceIndicator (void *obj, Tcl_Interp *interp, p->replaceIndicator = 1; return TCL_OK; } - return get_set_int (&p->replaceIndicator, interp, argc, argv); + return ir_tcl_get_set_int (&p->replaceIndicator, interp, argc, argv); } /* @@ -1444,7 +1469,7 @@ static int do_queryType (void *obj, Tcl_Interp *interp, return ir_tcl_strdel (interp, &p->queryType); if (argc == 3) { - free (p->queryType); + xfree (p->queryType); if (ir_tcl_strdup (interp, &p->queryType, argv[2]) == TCL_ERROR) return TCL_ERROR; } @@ -1484,7 +1509,7 @@ static int do_smallSetUpperBound (void *o, Tcl_Interp *interp, p->smallSetUpperBound = 0; return TCL_OK; } - return get_set_int (&p->smallSetUpperBound, interp, argc, argv); + return ir_tcl_get_set_int (&p->smallSetUpperBound, interp, argc, argv); } /* @@ -1500,7 +1525,7 @@ static int do_largeSetLowerBound (void *o, Tcl_Interp *interp, p->largeSetLowerBound = 2; return TCL_OK; } - return get_set_int (&p->largeSetLowerBound, interp, argc, argv); + return ir_tcl_get_set_int (&p->largeSetLowerBound, interp, argc, argv); } /* @@ -1516,7 +1541,7 @@ static int do_mediumSetPresentNumber (void *o, Tcl_Interp *interp, p->mediumSetPresentNumber = 0; return TCL_OK; } - return get_set_int (&p->mediumSetPresentNumber, interp, argc, argv); + return ir_tcl_get_set_int (&p->mediumSetPresentNumber, interp, argc, argv); } /* @@ -1536,7 +1561,7 @@ static int do_referenceId (void *obj, Tcl_Interp *interp, return ir_tcl_strdel (interp, &p->referenceId); if (argc == 3) { - free (p->referenceId); + xfree (p->referenceId); if (ir_tcl_strdup (interp, &p->referenceId, argv[2]) == TCL_ERROR) return TCL_ERROR; } @@ -1559,18 +1584,24 @@ static int do_preferredRecordSyntax (void *obj, Tcl_Interp *interp, } else if (argc == -1) { - free (p->preferredRecordSyntax); + xfree (p->preferredRecordSyntax); p->preferredRecordSyntax = NULL; return TCL_OK; } if (argc == 3) { - free (p->preferredRecordSyntax); + xfree (p->preferredRecordSyntax); p->preferredRecordSyntax = NULL; if (argv[2][0] && (p->preferredRecordSyntax = ir_tcl_malloc (sizeof(*p->preferredRecordSyntax)))) *p->preferredRecordSyntax = IrTcl_getRecordSyntaxVal (argv[2]); } + else if (argc == 2) + { + Tcl_AppendElement + (interp,!p->preferredRecordSyntax ? "" : + IrTcl_getRecordSyntaxStr(*p->preferredRecordSyntax)); + } return TCL_OK; } @@ -1592,7 +1623,7 @@ static int do_elementSetNames (void *obj, Tcl_Interp *interp, return ir_tcl_strdel (interp, &p->elementSetNames); if (argc == 3) { - free (p->elementSetNames); + xfree (p->elementSetNames); if (ir_tcl_strdup (interp, &p->elementSetNames, argv[2]) == TCL_ERROR) return TCL_ERROR; } @@ -1617,7 +1648,7 @@ static int do_smallSetElementSetNames (void *obj, Tcl_Interp *interp, return ir_tcl_strdel (interp, &p->smallSetElementSetNames); if (argc == 3) { - free (p->smallSetElementSetNames); + xfree (p->smallSetElementSetNames); if (ir_tcl_strdup (interp, &p->smallSetElementSetNames, argv[2]) == TCL_ERROR) return TCL_ERROR; @@ -1643,7 +1674,7 @@ static int do_mediumSetElementSetNames (void *obj, Tcl_Interp *interp, return ir_tcl_strdel (interp, &p->mediumSetElementSetNames); if (argc == 3) { - free (p->mediumSetElementSetNames); + xfree (p->mediumSetElementSetNames); if (ir_tcl_strdup (interp, &p->mediumSetElementSetNames, argv[2]) == TCL_ERROR) return TCL_ERROR; @@ -1653,50 +1684,50 @@ static int do_mediumSetElementSetNames (void *obj, Tcl_Interp *interp, } static IrTcl_Method ir_method_tab[] = { -{ 1, "comstack", do_comstack }, -{ 1, "protocol", do_protocol }, -{ 0, "failback", do_failback }, -{ 0, "failInfo", do_failInfo }, -{ 0, "apduInfo", do_apduInfo }, -{ 0, "logLevel", do_logLevel }, - -{ 0, "eventType", do_eventType }, -{ 1, "connect", do_connect }, -{ 0, "protocolVersion", do_protocolVersion }, -{ 1, "preferredMessageSize", do_preferredMessageSize }, -{ 1, "maximumRecordSize", do_maximumRecordSize }, -{ 1, "implementationName", do_implementationName }, -{ 1, "implementationId", do_implementationId }, -{ 1, "implementationVersion", do_implementationVersion }, -{ 0, "targetImplementationName", do_targetImplementationName }, -{ 0, "targetImplementationId", do_targetImplementationId }, -{ 0, "targetImplementationVersion", do_targetImplementationVersion }, -{ 0, "userInformationField", do_userInformationField }, -{ 1, "idAuthentication", do_idAuthentication }, -{ 0, "options", do_options }, -{ 0, "init", do_init_request }, -{ 0, "initResult", do_initResult }, -{ 0, "disconnect", do_disconnect }, -{ 0, "callback", do_callback }, -{ 0, "initResponse", do_initResponse }, -{ 0, "triggerResourceControl", do_triggerResourceControl }, -{ 0, "initResponse", do_initResponse }, -{ 0, NULL, NULL} +{ "comstack", do_comstack, NULL }, +{ "protocol", do_protocol, NULL }, +{ "failback", do_failback, NULL }, +{ "failInfo", do_failInfo, NULL }, +{ "apduInfo", do_apduInfo, NULL }, +{ "logLevel", do_logLevel, NULL }, + +{ "eventType", do_eventType, NULL }, +{ "connect", do_connect, NULL }, +{ "protocolVersion", do_protocolVersion, NULL }, +{ "preferredMessageSize", do_preferredMessageSize, NULL }, +{ "maximumRecordSize", do_maximumRecordSize, NULL }, +{ "implementationName", do_implementationName, NULL }, +{ "implementationId", do_implementationId, NULL }, +{ "implementationVersion", do_implementationVersion, NULL }, +{ "targetImplementationName", do_targetImplementationName, NULL }, +{ "targetImplementationId", do_targetImplementationId, NULL }, +{ "targetImplementationVersion", do_targetImplementationVersion, NULL}, +{ "userInformationField", do_userInformationField, NULL}, +{ "idAuthentication", do_idAuthentication, NULL}, +{ "options", do_options, NULL}, +{ "init", do_init_request, NULL}, +{ "initResult", do_initResult, NULL}, +{ "disconnect", do_disconnect, NULL}, +{ "callback", do_callback, NULL}, +{ "initResponse", do_initResponse, NULL}, +{ "triggerResourceControl", do_triggerResourceControl, NULL}, +{ "initResponse", do_initResponse, NULL}, +{ NULL, NULL} }; static IrTcl_Method ir_set_c_method_tab[] = { -{ 0, "databaseNames", do_databaseNames}, -{ 0, "replaceIndicator", do_replaceIndicator}, -{ 0, "queryType", do_queryType }, -{ 0, "preferredRecordSyntax", do_preferredRecordSyntax }, -{ 0, "smallSetUpperBound", do_smallSetUpperBound}, -{ 0, "largeSetLowerBound", do_largeSetLowerBound}, -{ 0, "mediumSetPresentNumber", do_mediumSetPresentNumber}, -{ 0, "referenceId", do_referenceId }, -{ 0, "elementSetNames", do_elementSetNames }, -{ 0, "smallSetElementSetNames", do_smallSetElementSetNames }, -{ 0, "mediumSetElementSetNames", do_mediumSetElementSetNames }, -{ 0, NULL, NULL} +{ "databaseNames", do_databaseNames, NULL}, +{ "replaceIndicator", do_replaceIndicator, NULL}, +{ "queryType", do_queryType, NULL}, +{ "preferredRecordSyntax", do_preferredRecordSyntax, NULL}, +{ "smallSetUpperBound", do_smallSetUpperBound, NULL}, +{ "largeSetLowerBound", do_largeSetLowerBound, NULL}, +{ "mediumSetPresentNumber", do_mediumSetPresentNumber, NULL}, +{ "referenceId", do_referenceId, NULL}, +{ "elementSetNames", do_elementSetNames, NULL}, +{ "smallSetElementSetNames", do_smallSetElementSetNames, NULL}, +{ "mediumSetElementSetNames", do_mediumSetElementSetNames, NULL}, +{ NULL, NULL} }; /* @@ -1707,17 +1738,19 @@ static int ir_obj_method (ClientData clientData, Tcl_Interp *interp, { IrTcl_Methods tab[3]; IrTcl_Obj *p = clientData; + int r; if (argc < 2) - return ir_method_r (clientData, interp, argc, argv, ir_method_tab); - + return TCL_ERROR; + tab[0].tab = ir_method_tab; tab[0].obj = p; tab[1].tab = ir_set_c_method_tab; tab[1].obj = &p->set_inher; tab[2].tab = NULL; - - return ir_method (interp, argc, argv, tab); + + ir_tcl_method (interp, argc, argv, tab, &r); + return r; } /* @@ -1740,20 +1773,21 @@ static void ir_obj_delete (ClientData clientData) tab[1].obj = &obj->set_inher; tab[2].tab = NULL; - ir_method (NULL, -1, NULL, tab); + ir_tcl_method (NULL, -1, NULL, tab, NULL); ir_tcl_del_q (obj); odr_destroy (obj->odr_in); odr_destroy (obj->odr_out); odr_destroy (obj->odr_pr); - free (obj); + xfree (obj); } /* - * ir_obj_mk: IR Object creation + * ir_obj_init: IR Object initialization */ -static int ir_obj_mk (ClientData clientData, Tcl_Interp *interp, - int argc, char **argv) +int ir_obj_init (ClientData clientData, Tcl_Interp *interp, + int argc, char **argv, ClientData *subData, + ClientData parentData) { IrTcl_Methods tab[3]; IrTcl_Obj *obj; @@ -1794,13 +1828,40 @@ static int ir_obj_mk (ClientData clientData, Tcl_Interp *interp, tab[1].obj = &obj->set_inher; tab[2].tab = NULL; - if (ir_method (interp, 0, NULL, tab) == TCL_ERROR) + if (ir_tcl_method (interp, 0, NULL, tab, NULL) == TCL_ERROR) + { + Tcl_AppendResult (interp, "Failed to initialize ", argv[1], NULL); + return TCL_ERROR; + } + *subData = obj; + return TCL_OK; +} + + +/* + * ir_obj_mk: IR Object creation + */ +static int ir_obj_mk (ClientData clientData, Tcl_Interp *interp, + int argc, char **argv) +{ + ClientData subData; + int r = ir_obj_init (clientData, interp, argc, argv, &subData, 0); + + if (r == TCL_ERROR) return TCL_ERROR; Tcl_CreateCommand (interp, argv[1], ir_obj_method, - (ClientData) obj, ir_obj_delete); + subData, ir_obj_delete); return TCL_OK; } +IrTcl_Class ir_obj_class = { + "ir", + ir_obj_init, + ir_obj_method, + ir_obj_delete +}; + + /* ------------------------------------------------------- */ /* * do_search: Do search request @@ -1814,7 +1875,6 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv) IrTcl_SetObj *obj = o; IrTcl_Obj *p; int r; - oident bib1; if (argc <= 0) return TCL_OK; @@ -1822,9 +1882,11 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv) p = obj->parent; if (argc != 3) { + logf (LOG_DEBUG, "search %s", *argv); interp->result = "wrong # args"; return TCL_ERROR; } + logf (LOG_DEBUG, "search %s %s", *argv, argv[2]); if (!obj->set_inher.num_databaseNames) { interp->result = "no databaseNames"; @@ -1840,10 +1902,6 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv) obj->start = 1; - bib1.proto = p->protocol_type; - bib1.oclass = CLASS_ATTSET; - bib1.value = VAL_BIB1; - set_referenceId (p->odr_out, &req->referenceId, obj->set_inher.referenceId); @@ -1896,21 +1954,20 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv) req->mediumSetElementSetNames = NULL; req->query = &query; - + + logf (LOG_DEBUG, "queryType %s", obj->set_inher.queryType); if (!strcmp (obj->set_inher.queryType, "rpn")) { Z_RPNQuery *RPNquery; - RPNquery = p_query_rpn (p->odr_out, argv[2]); + RPNquery = p_query_rpn (p->odr_out, p->protocol_type, argv[2]); if (!RPNquery) { Tcl_AppendResult (interp, "Syntax error in query", NULL); return TCL_ERROR; } - RPNquery->attributeSetId = oid_getoidbyent (&bib1); query.which = Z_Query_type_1; query.u.type_1 = RPNquery; - logf (LOG_DEBUG, "RPN"); } #if CCL2RPN else if (!strcmp (obj->set_inher.queryType, "cclrpn")) @@ -1919,6 +1976,11 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv) int pos; struct ccl_rpn_node *rpn; Z_RPNQuery *RPNquery; + oident bib1; + + bib1.proto = p->protocol_type; + bib1.oclass = CLASS_ATTSET; + bib1.value = VAL_BIB1; rpn = ccl_find_str(p->bibset, argv[2], &error, &pos); if (error) @@ -1927,13 +1989,14 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv) ccl_err_msg(error), NULL); return TCL_ERROR; } +#if 0 ccl_pr_tree (rpn, stderr); fprintf (stderr, "\n"); +#endif assert((RPNquery = ccl_rpn_query(rpn))); RPNquery->attributeSetId = oid_getoidbyent (&bib1); query.which = Z_Query_type_1; query.u.type_1 = RPNquery; - logf (LOG_DEBUG, "CCLRPN"); } #endif else if (!strcmp (obj->set_inher.queryType, "ccl")) @@ -1942,7 +2005,6 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv) query.u.type_2 = &ccl_query; ccl_query.buf = (unsigned char *) argv[2]; ccl_query.len = strlen (argv[2]); - logf (LOG_DEBUG, "CCL"); } else { @@ -1969,7 +2031,7 @@ static int do_searchResponse (void *o, Tcl_Interp *interp, return ir_tcl_strdel (interp, &obj->searchResponse); if (argc == 3) { - free (obj->searchResponse); + xfree (obj->searchResponse); if (argv[2][0]) { if (ir_tcl_strdup (interp, &obj->searchResponse, argv[2]) @@ -1999,7 +2061,7 @@ static int do_presentResponse (void *o, Tcl_Interp *interp, return ir_tcl_strdel (interp, &obj->presentResponse); if (argc == 3) { - free (obj->presentResponse); + xfree (obj->presentResponse); if (argv[2][0]) { if (ir_tcl_strdup (interp, &obj->presentResponse, argv[2]) @@ -2021,8 +2083,11 @@ static int do_resultCount (void *o, Tcl_Interp *interp, IrTcl_SetObj *obj = o; if (argc <= 0) + { + obj->resultCount = 0; return TCL_OK; - return get_set_int (&obj->resultCount, interp, argc, argv); + } + return ir_tcl_get_set_int (&obj->resultCount, interp, argc, argv); } /* @@ -2035,7 +2100,7 @@ static int do_searchStatus (void *o, Tcl_Interp *interp, if (argc <= 0) return TCL_OK; - return get_set_int (&obj->searchStatus, interp, argc, argv); + return ir_tcl_get_set_int (&obj->searchStatus, interp, argc, argv); } /* @@ -2048,7 +2113,7 @@ static int do_presentStatus (void *o, Tcl_Interp *interp, if (argc <= 0) return TCL_OK; - return get_set_int (&obj->presentStatus, interp, argc, argv); + return ir_tcl_get_set_int (&obj->presentStatus, interp, argc, argv); } /* @@ -2065,7 +2130,8 @@ static int do_nextResultSetPosition (void *o, Tcl_Interp *interp, obj->nextResultSetPosition = 0; return TCL_OK; } - return get_set_int (&obj->nextResultSetPosition, interp, argc, argv); + return ir_tcl_get_set_int (&obj->nextResultSetPosition, interp, + argc, argv); } /* @@ -2082,7 +2148,7 @@ static int do_setName (void *o, Tcl_Interp *interp, return ir_tcl_strdel (interp, &obj->setName); if (argc == 3) { - free (obj->setName); + xfree (obj->setName); if (ir_tcl_strdup (interp, &obj->setName, argv[2]) == TCL_ERROR) return TCL_ERROR; @@ -2104,7 +2170,8 @@ static int do_numberOfRecordsReturned (void *o, Tcl_Interp *interp, obj->numberOfRecordsReturned = 0; return TCL_OK; } - return get_set_int (&obj->numberOfRecordsReturned, interp, argc, argv); + return ir_tcl_get_set_int (&obj->numberOfRecordsReturned, interp, + argc, argv); } /* @@ -2211,7 +2278,7 @@ static int do_recordElements (void *o, Tcl_Interp *interp, } if (argc == 3) { - free (obj->recordElements); + xfree (obj->recordElements); return ir_tcl_strdup (NULL, &obj->recordElements, (*argv[2] ? argv[2] : NULL)); } @@ -2230,7 +2297,6 @@ static int ir_diagResult (Tcl_Interp *interp, IrTcl_Diagnostic *list, int num) for (i = 0; iparent; if (!p->cs_link) { @@ -2543,26 +2610,26 @@ static int do_loadFile (void *o, Tcl_Interp *interp, } static IrTcl_Method ir_set_method_tab[] = { - { 0, "search", do_search }, - { 0, "searchResponse", do_searchResponse }, - { 0, "presentResponse", do_presentResponse }, - { 0, "searchStatus", do_searchStatus }, - { 0, "presentStatus", do_presentStatus }, - { 0, "nextResultSetPosition", do_nextResultSetPosition }, - { 0, "setName", do_setName }, - { 0, "resultCount", do_resultCount }, - { 0, "numberOfRecordsReturned", do_numberOfRecordsReturned }, - { 0, "present", do_present }, - { 0, "type", do_type }, - { 0, "getMarc", do_getMarc }, - { 0, "getSutrs", do_getSutrs }, - { 0, "getGrs", do_getGrs }, - { 0, "recordType", do_recordType }, - { 0, "recordElements", do_recordElements }, - { 0, "diag", do_diag }, - { 0, "responseStatus", do_responseStatus }, - { 0, "loadFile", do_loadFile }, - { 0, NULL, NULL} + { "search", do_search, NULL}, + { "searchResponse", do_searchResponse, NULL}, + { "presentResponse", do_presentResponse, NULL}, + { "searchStatus", do_searchStatus, NULL}, + { "presentStatus", do_presentStatus, NULL}, + { "nextResultSetPosition", do_nextResultSetPosition, NULL}, + { "setName", do_setName, NULL}, + { "resultCount", do_resultCount, NULL}, + { "numberOfRecordsReturned", do_numberOfRecordsReturned, NULL}, + { "present", do_present, NULL}, + { "type", do_type, NULL}, + { "getMarc", do_getMarc, NULL}, + { "getSutrs", do_getSutrs, NULL}, + { "getGrs", do_getGrs, NULL}, + { "recordType", do_recordType, NULL}, + { "recordElements", do_recordElements, NULL}, + { "diag", do_diag, NULL}, + { "responseStatus", do_responseStatus, NULL}, + { "loadFile", do_loadFile, NULL}, + { NULL, NULL} }; /* @@ -2573,6 +2640,7 @@ static int ir_set_obj_method (ClientData clientData, Tcl_Interp *interp, { IrTcl_Methods tabs[3]; IrTcl_SetObj *p = clientData; + int r; if (argc < 2) { @@ -2585,7 +2653,8 @@ static int ir_set_obj_method (ClientData clientData, Tcl_Interp *interp, tabs[1].obj = &p->set_inher; tabs[2].tab = NULL; - return ir_method (interp, argc, argv, tabs); + ir_tcl_method (interp, argc, argv, tabs, &r); + return r; } /* @@ -2604,16 +2673,17 @@ static void ir_set_obj_delete (ClientData clientData) tabs[1].obj = &p->set_inher; tabs[2].tab = NULL; - ir_method (NULL, -1, NULL, tabs); + ir_tcl_method (NULL, -1, NULL, tabs, NULL); - free (p); + xfree (p); } /* - * ir_set_obj_mk: IR Set Object creation + * ir_set_obj_init: IR Set Object initialization */ -static int ir_set_obj_mk (ClientData clientData, Tcl_Interp *interp, - int argc, char **argv) +static int ir_set_obj_init (ClientData clientData, Tcl_Interp *interp, + int argc, char **argv, ClientData *subData, + ClientData parentData) { IrTcl_Methods tabs[3]; IrTcl_SetObj *obj; @@ -2624,34 +2694,31 @@ static int ir_set_obj_mk (ClientData clientData, Tcl_Interp *interp, return TCL_ERROR; } obj = ir_tcl_malloc (sizeof(*obj)); - logf (LOG_DEBUG, "ir set create"); - if (argc == 3) + logf (LOG_DEBUG, "ir set create %s", argv[1]); + if (parentData) { - Tcl_CmdInfo parent_info; int i; IrTcl_SetCObj *dst; IrTcl_SetCObj *src; - if (!Tcl_GetCommandInfo (interp, argv[2], &parent_info)) - { - interp->result = "No parent"; - return TCL_ERROR; - } - obj->parent = (IrTcl_Obj *) parent_info.clientData; + obj->parent = (IrTcl_Obj *) parentData; dst = &obj->set_inher; src = &obj->parent->set_inher; if ((dst->num_databaseNames = src->num_databaseNames)) + { dst->databaseNames = ir_tcl_malloc (sizeof (*dst->databaseNames) - * dst->num_databaseNames); + * (1+dst->num_databaseNames)); + for (i = 0; i < dst->num_databaseNames; i++) + if (ir_tcl_strdup (interp, &dst->databaseNames[i], + src->databaseNames[i]) == TCL_ERROR) + return TCL_ERROR; + dst->databaseNames[i] = NULL; + } else dst->databaseNames = NULL; - for (i = 0; i < dst->num_databaseNames; i++) - if (ir_tcl_strdup (interp, &dst->databaseNames[i], - src->databaseNames[i]) == TCL_ERROR) - return TCL_ERROR; if (ir_tcl_strdup (interp, &dst->queryType, src->queryType) == TCL_ERROR) return TCL_ERROR; @@ -2692,14 +2759,48 @@ static int ir_set_obj_mk (ClientData clientData, Tcl_Interp *interp, tabs[0].obj = obj; tabs[1].tab = NULL; - if (ir_method (interp, 0, NULL, tabs) == TCL_ERROR) + if (ir_tcl_method (interp, 0, NULL, tabs, NULL) == TCL_ERROR) return TCL_ERROR; + *subData = obj; + return TCL_OK; +} + +/* + * ir_set_obj_mk: IR Set Object creation + */ +static int ir_set_obj_mk (ClientData clientData, Tcl_Interp *interp, + int argc, char **argv) +{ + ClientData subData; + ClientData parentData = 0; + int r; + + if (argc == 3) + { + Tcl_CmdInfo parent_info; + if (!Tcl_GetCommandInfo (interp, argv[2], &parent_info)) + { + interp->result = "No parent"; + return TCL_ERROR; + } + parentData = parent_info.clientData; + } + r = ir_set_obj_init (clientData, interp, argc, argv, &subData, parentData); + if (r == TCL_ERROR) + return TCL_ERROR; Tcl_CreateCommand (interp, argv[1], ir_set_obj_method, - (ClientData) obj, ir_set_obj_delete); + subData, ir_set_obj_delete); return TCL_OK; } +IrTcl_Class ir_set_obj_class = { + "ir-set", + ir_set_obj_init, + ir_set_obj_method, + ir_set_obj_delete +}; + /* ------------------------------------------------------- */ /* @@ -2711,8 +2812,8 @@ static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv) Z_APDU *apdu; IrTcl_ScanObj *obj = o; IrTcl_Obj *p = obj->parent; - oident bib1; #if CCL2RPN + oident bib1; struct ccl_rpn_node *rpn; int pos; #endif @@ -2724,6 +2825,7 @@ static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv) interp->result = "wrong # args"; return TCL_ERROR; } + logf (LOG_DEBUG, "scan %s %s", *argv, argv[2]); if (!p->set_inher.num_databaseNames) { interp->result = "no databaseNames"; @@ -2735,20 +2837,17 @@ static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv) return TCL_ERROR; } - bib1.proto = p->protocol_type; - bib1.oclass = CLASS_ATTSET; - bib1.value = VAL_BIB1; - apdu = zget_APDU (p->odr_out, Z_APDU_scanRequest); req = apdu->u.scanRequest; set_referenceId (p->odr_out, &req->referenceId, p->set_inher.referenceId); req->num_databaseNames = p->set_inher.num_databaseNames; req->databaseNames = p->set_inher.databaseNames; - req->attributeSet = oid_getoidbyent (&bib1); #if !CCL2RPN - if (!(req->termListAndStartPoint = p_query_scan (p->odr_out, argv[2]))) + if (!(req->termListAndStartPoint = + p_query_scan (p->odr_out, p->protocol_type, + &req->attributeSet, argv[2]))) { Tcl_AppendResult (interp, "Syntax error in query", NULL); return TCL_ERROR; @@ -2760,8 +2859,11 @@ static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv) Tcl_AppendResult (interp, "CCL error: ", ccl_err_msg (r), NULL); return TCL_ERROR; } - ccl_pr_tree (rpn, stderr); - fprintf (stderr, "\n"); + bib1.proto = p->protocol_type; + bib1.oclass = CLASS_ATTSET; + bib1.value = VAL_BIB1; + + req->attributeSet = oid_getoidbyent (&bib1); if (!(req->termListAndStartPoint = ccl_scan_query (rpn))) return TCL_ERROR; #endif @@ -2794,7 +2896,7 @@ static int do_scanResponse (void *o, Tcl_Interp *interp, return ir_tcl_strdel (interp, &obj->scanResponse); if (argc == 3) { - free (obj->scanResponse); + xfree (obj->scanResponse); if (argv[2][0]) { if (ir_tcl_strdup (interp, &obj->scanResponse, argv[2]) @@ -2819,7 +2921,7 @@ static int do_stepSize (void *obj, Tcl_Interp *interp, p->stepSize = 0; return TCL_OK; } - return get_set_int (&p->stepSize, interp, argc, argv); + return ir_tcl_get_set_int (&p->stepSize, interp, argc, argv); } /* @@ -2835,7 +2937,7 @@ static int do_numberOfTermsRequested (void *obj, Tcl_Interp *interp, p->numberOfTermsRequested = 20; return TCL_OK; } - return get_set_int (&p->numberOfTermsRequested, interp, argc, argv); + return ir_tcl_get_set_int (&p->numberOfTermsRequested, interp, argc, argv); } @@ -2852,7 +2954,8 @@ static int do_preferredPositionInResponse (void *obj, Tcl_Interp *interp, p->preferredPositionInResponse = 1; return TCL_OK; } - return get_set_int (&p->preferredPositionInResponse, interp, argc, argv); + return ir_tcl_get_set_int (&p->preferredPositionInResponse, interp, + argc, argv); } /* @@ -2865,7 +2968,7 @@ static int do_scanStatus (void *obj, Tcl_Interp *interp, if (argc <= 0) return TCL_OK; - return get_set_int (&p->scanStatus, interp, argc, argv); + return ir_tcl_get_set_int (&p->scanStatus, interp, argc, argv); } /* @@ -2878,7 +2981,8 @@ static int do_numberOfEntriesReturned (void *obj, Tcl_Interp *interp, if (argc <= 0) return TCL_OK; - return get_set_int (&p->numberOfEntriesReturned, interp, argc, argv); + return ir_tcl_get_set_int (&p->numberOfEntriesReturned, interp, + argc, argv); } /* @@ -2891,7 +2995,7 @@ static int do_positionOfTerm (void *obj, Tcl_Interp *interp, if (argc <= 0) return TCL_OK; - return get_set_int (&p->positionOfTerm, interp, argc, argv); + return ir_tcl_get_set_int (&p->positionOfTerm, interp, argc, argv); } /* @@ -2952,16 +3056,16 @@ static int do_scanLine (void *obj, Tcl_Interp *interp, int argc, char **argv) } static IrTcl_Method ir_scan_method_tab[] = { - { 0, "scan", do_scan }, - { 0, "scanResponse", do_scanResponse }, - { 0, "stepSize", do_stepSize }, - { 0, "numberOfTermsRequested", do_numberOfTermsRequested }, - { 0, "preferredPositionInResponse", do_preferredPositionInResponse }, - { 0, "scanStatus", do_scanStatus }, - { 0, "numberOfEntriesReturned", do_numberOfEntriesReturned }, - { 0, "positionOfTerm", do_positionOfTerm }, - { 0, "scanLine", do_scanLine }, - { 0, NULL, NULL} + { "scan", do_scan, NULL}, + { "scanResponse", do_scanResponse, NULL}, + { "stepSize", do_stepSize, NULL}, + { "numberOfTermsRequested", do_numberOfTermsRequested, NULL}, + { "preferredPositionInResponse", do_preferredPositionInResponse, NULL}, + { "scanStatus", do_scanStatus, NULL}, + { "numberOfEntriesReturned", do_numberOfEntriesReturned, NULL}, + { "positionOfTerm", do_positionOfTerm, NULL}, + { "scanLine", do_scanLine, NULL}, + { NULL, NULL} }; /* @@ -2971,6 +3075,7 @@ static int ir_scan_obj_method (ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { IrTcl_Methods tabs[2]; + int r; if (argc < 2) { @@ -2981,7 +3086,8 @@ static int ir_scan_obj_method (ClientData clientData, Tcl_Interp *interp, tabs[0].obj = clientData; tabs[1].tab = NULL; - return ir_method (interp, argc, argv, tabs); + ir_tcl_method (interp, argc, argv, tabs, &r); + return r; } /* @@ -2996,8 +3102,8 @@ static void ir_scan_obj_delete (ClientData clientData) tabs[0].obj = obj; tabs[1].tab = NULL; - ir_method (NULL, -1, NULL, tabs); - free (obj); + ir_tcl_method (NULL, -1, NULL, tabs, NULL); + xfree (obj); } /* @@ -3015,6 +3121,7 @@ static int ir_scan_obj_mk (ClientData clientData, Tcl_Interp *interp, interp->result = "wrong # args"; return TCL_ERROR; } + logf (LOG_DEBUG, "ir scan create %s", argv[1]); if (!Tcl_GetCommandInfo (interp, argv[2], &parent_info)) { interp->result = "No parent"; @@ -3027,7 +3134,7 @@ static int ir_scan_obj_mk (ClientData clientData, Tcl_Interp *interp, tabs[0].obj = obj; tabs[1].tab = NULL; - if (ir_method (interp, 0, NULL, tabs) == TCL_ERROR) + if (ir_tcl_method (interp, 0, NULL, tabs, NULL) == TCL_ERROR) return TCL_ERROR; Tcl_CreateCommand (interp, argv[1], ir_scan_obj_method, (ClientData) obj, ir_scan_obj_delete); @@ -3048,13 +3155,13 @@ static void ir_initResponse (void *obj, Z_InitResponse *initrs) get_referenceId (&p->set_inher.referenceId, initrs->referenceId); - free (p->targetImplementationId); + xfree (p->targetImplementationId); ir_tcl_strdup (p->interp, &p->targetImplementationId, initrs->implementationId); - free (p->targetImplementationName); + xfree (p->targetImplementationName); ir_tcl_strdup (p->interp, &p->targetImplementationName, initrs->implementationName); - free (p->targetImplementationVersion); + xfree (p->targetImplementationVersion); ir_tcl_strdup (p->interp, &p->targetImplementationVersion, initrs->implementationVersion); @@ -3064,7 +3171,7 @@ static void ir_initResponse (void *obj, Z_InitResponse *initrs) memcpy (&p->options, initrs->options, sizeof(initrs->options)); memcpy (&p->protocolVersion, initrs->protocolVersion, sizeof(initrs->protocolVersion)); - free (p->userInformationField); + xfree (p->userInformationField); p->userInformationField = NULL; if (initrs->userInformationField) { @@ -3088,8 +3195,8 @@ static void ir_deleteDiags (IrTcl_Diagnostic **dst_list, int *dst_num) { int i; for (i = 0; i<*dst_num; i++) - free (dst_list[i]->addinfo); - free (*dst_list); + xfree (dst_list[i]->addinfo); + xfree (*dst_list); *dst_list = NULL; *dst_num = 0; } @@ -3104,6 +3211,7 @@ static void ir_handleDiags (IrTcl_Diagnostic **dst_list, int *dst_num, *dst_list = ir_tcl_malloc (sizeof(**dst_list) * num); for (i = 0; iwhich) { case Z_DiagRec_defaultFormat: @@ -3112,6 +3220,9 @@ static void ir_handleDiags (IrTcl_Diagnostic **dst_list, int *dst_num, if (addinfo && ((*dst_list)[i].addinfo = ir_tcl_malloc (strlen(addinfo)+1))) strcpy ((*dst_list)[i].addinfo, addinfo); + cp = diagbib1_str ((*dst_list)[i].condition); + logf (LOG_DEBUG, "Diag %d %s %s", (*dst_list)[i].condition, + cp ? cp : "", addinfo ? addinfo : ""); break; default: (*dst_list)[i].addinfo = NULL; @@ -3190,7 +3301,7 @@ static void ir_handleRecords (void *o, Z_Records *zrs, IrTcl_SetObj *setobj, else if (rl->u.dbrec.type == VAL_GRS1 && oe->which == Z_External_grs1) { - ir_tcl_read_grs (oe->u.grs1, &rl->u.dbrec.u.grs1); + ir_tcl_grs_mk (oe->u.grs1, &rl->u.dbrec.u.grs1); rl->u.dbrec.buf = NULL; } else @@ -3238,7 +3349,7 @@ static void ir_searchResponse (void *o, Z_SearchResponse *searchrs, if (searchrs->nextResultSetPosition) setobj->nextResultSetPosition = *searchrs->nextResultSetPosition; - logf (LOG_DEBUG, "Search response %d, %d hits", + logf (LOG_DEBUG, "status %d hits %d", setobj->searchStatus, setobj->resultCount); if (zrs) { @@ -3302,7 +3413,7 @@ static void ir_scanResponse (void *o, Z_ScanResponse *scanrs, scanobj->positionOfTerm = -1; logf (LOG_DEBUG, "positionOfTerm=%d", scanobj->positionOfTerm); - free (scanobj->entries); + xfree (scanobj->entries); scanobj->entries = NULL; ir_deleteDiags (&scanobj->nonSurrogateDiagnosticList, @@ -3370,7 +3481,7 @@ static void ir_scanResponse (void *o, Z_ScanResponse *scanrs, /* * ir_select_read: handle incoming packages */ -void ir_select_read (ClientData clientData) +static void ir_select_read (ClientData clientData) { IrTcl_Obj *p = clientData; Z_APDU *apdu; @@ -3383,7 +3494,7 @@ void ir_select_read (ClientData clientData) logf(LOG_DEBUG, "Read handler fd=%d", cs_fileno(p->cs_link)); if (p->state == IR_TCL_R_Connecting) { - logf(LOG_DEBUG, "Connect handler"); + logf(LOG_DEBUG, "read: connect"); r = cs_rcvconnect (p->cs_link); if (r == 1) { @@ -3391,60 +3502,55 @@ void ir_select_read (ClientData clientData) return; } p->state = IR_TCL_R_Idle; -#if IRTCL_GENERIC_FILES - ir_select_remove_write (p->csFile, p); -#else + p->ref_count = 2; ir_select_remove_write (cs_fileno (p->cs_link), p); -#endif if (r < 0) { logf (LOG_DEBUG, "cs_rcvconnect error"); + ir_tcl_disconnect (p); if (p->failback) { p->failInfo = IR_TCL_FAIL_CONNECT; - IrTcl_eval (p->interp, p->failback); + ir_tcl_eval (p->interp, p->failback); } - do_disconnect (p, NULL, 2, NULL); + ir_obj_delete (p); return; } - p->state = IR_TCL_R_Idle; if (p->callback) - IrTcl_eval (p->interp, p->callback); - if (p->cs_link && p->request_queue && p->state == IR_TCL_R_Idle) + ir_tcl_eval (p->interp, p->callback); + if (p->ref_count == 2 && p->cs_link && p->request_queue + && p->state == IR_TCL_R_Idle) ir_tcl_send_q (p, p->request_queue, "x"); + ir_obj_delete (p); return; } do { - /* signal one more use of ir object - callbacks must not - release the ir memory (p pointer) */ p->state = IR_TCL_R_Reading; - ++(p->ref_count); /* read incoming APDU */ - if ((r=cs_get (p->cs_link, &p->buf_in, &p->len_in)) <= 0) + if ((r=cs_get (p->cs_link, &p->buf_in, &p->len_in)) == 1) + { + logf(LOG_DEBUG, "PDU Fraction read"); + return ; + } + /* signal one more use of ir object - callbacks must not + release the ir memory (p pointer) */ + p->ref_count = 2; + if (r <= 0) { logf (LOG_DEBUG, "cs_get failed, code %d", r); -#if IRTCL_GENERIC_FILES - ir_select_remove (p->csFile, p); -#else ir_select_remove (cs_fileno (p->cs_link), p); -#endif - do_disconnect (p, NULL, 2, NULL); + ir_tcl_disconnect (p); if (p->failback) { p->failInfo = IR_TCL_FAIL_READ; - IrTcl_eval (p->interp, p->failback); + ir_tcl_eval (p->interp, p->failback); } /* release ir object now if callback deleted it */ ir_obj_delete (p); return; } - if (r == 1) - { - logf(LOG_DEBUG, "PDU Fraction read"); - return ; - } /* got complete APDU. Now decode */ p->apduLen = r; p->apduOffset = -1; @@ -3453,19 +3559,18 @@ void ir_select_read (ClientData clientData) if (!z_APDU (p->odr_in, &apdu, 0)) { logf (LOG_DEBUG, "cs_get failed: %s", - odr_errmsg (odr_geterror (p->odr_in))); - do_disconnect (p, NULL, 2, NULL); + odr_errmsg (odr_geterror (p->odr_in))); + ir_tcl_disconnect (p); if (p->failback) { p->failInfo = IR_TCL_FAIL_IN_APDU; p->apduOffset = odr_offset (p->odr_in); - IrTcl_eval (p->interp, p->failback); + ir_tcl_eval (p->interp, p->failback); } /* release ir object now if failback deleted it */ ir_obj_delete (p); return; } - logf(LOG_DEBUG, "Decoded ok"); /* handle APDU and invoke callback */ rq = p->request_queue; if (!rq) @@ -3474,7 +3579,7 @@ void ir_select_read (ClientData clientData) exit (1); } object_name = rq->object_name; - logf (LOG_DEBUG, "getCommandInfo (%s)", object_name); + logf (LOG_DEBUG, "Object %s", object_name); apdu_call = NULL; if (Tcl_GetCommandInfo (p->interp, object_name, &cmd_info)) { @@ -3483,7 +3588,7 @@ void ir_select_read (ClientData clientData) case Z_APDU_initResponse: p->eventType = "init"; ir_initResponse (p, apdu->u.initResponse); - apdu_call = p->initResponse; + apdu_call = p->initResponse; break; case Z_APDU_searchResponse: p->eventType = "search"; @@ -3509,11 +3614,11 @@ void ir_select_read (ClientData clientData) default: logf (LOG_WARN, "Received unknown APDU type (%d)", apdu->which); - do_disconnect (p, NULL, 2, NULL); + ir_tcl_disconnect (p); if (p->failback) { p->failInfo = IR_TCL_FAIL_UNKNOWN_APDU; - IrTcl_eval (p->interp, p->failback); + ir_tcl_eval (p->interp, p->failback); } return; } @@ -3522,20 +3627,20 @@ void ir_select_read (ClientData clientData) p->state = IR_TCL_R_Idle; if (apdu_call) - IrTcl_eval (p->interp, apdu_call); + ir_tcl_eval (p->interp, apdu_call); else if (rq->callback) - IrTcl_eval (p->interp, rq->callback); - free (rq->buf_out); - free (rq->callback); - free (rq->object_name); - free (rq); + ir_tcl_eval (p->interp, rq->callback); + xfree (rq->buf_out); + xfree (rq->callback); + xfree (rq->object_name); + xfree (rq); odr_reset (p->odr_in); if (p->ref_count == 1) { ir_obj_delete (p); return; } - --(p->ref_count); + ir_obj_delete (p); } while (p->cs_link && cs_more (p->cs_link)); if (p->cs_link && p->request_queue && p->state == IR_TCL_R_Idle) ir_tcl_send_q (p, p->request_queue, "x"); @@ -3544,7 +3649,7 @@ void ir_select_read (ClientData clientData) /* * ir_select_write: handle outgoing packages - not yet written. */ -void ir_select_write (ClientData clientData) +static int ir_select_write (ClientData clientData) { IrTcl_Obj *p = clientData; int r; @@ -3553,64 +3658,73 @@ void ir_select_write (ClientData clientData) logf (LOG_DEBUG, "Write handler fd=%d", cs_fileno(p->cs_link)); if (p->state == IR_TCL_R_Connecting) { - logf(LOG_DEBUG, "Connect handler"); + logf(LOG_DEBUG, "write: connect"); r = cs_rcvconnect (p->cs_link); if (r == 1) - return; + { + logf (LOG_DEBUG, "cs_rcvconnect returned 1"); + return 2; + } p->state = IR_TCL_R_Idle; + p->ref_count = 2; + ir_select_remove_write (cs_fileno (p->cs_link), p); if (r < 0) { logf (LOG_DEBUG, "cs_rcvconnect error"); -#if IRTCL_GENERIC_FILES - ir_select_remove_write (p->csFile, p); -#else - ir_select_remove_write (cs_fileno (p->cs_link), p); -#endif + ir_tcl_disconnect (p); if (p->failback) { p->failInfo = IR_TCL_FAIL_CONNECT; - IrTcl_eval (p->interp, p->failback); + ir_tcl_eval (p->interp, p->failback); } - do_disconnect (p, NULL, 2, NULL); - return; + ir_obj_delete (p); + return 2; } -#if IRTCL_GENERIC_FILES - ir_select_remove_write (p->csFile, p); -#else - ir_select_remove_write (cs_fileno (p->cs_link), p); -#endif if (p->callback) - IrTcl_eval (p->interp, p->callback); - return; + ir_tcl_eval (p->interp, p->callback); + ir_obj_delete (p); + return 2; } rq = p->request_queue; if (!rq || !rq->buf_out) - return; + return 0; assert (rq); if ((r=cs_put (p->cs_link, rq->buf_out, rq->len_out)) < 0) { logf (LOG_DEBUG, "cs_put write fail"); + p->ref_count = 2; + xfree (rq->buf_out); + rq->buf_out = NULL; + ir_tcl_disconnect (p); if (p->failback) { p->failInfo = IR_TCL_FAIL_WRITE; - IrTcl_eval (p->interp, p->failback); + ir_tcl_eval (p->interp, p->failback); } - free (rq->buf_out); - rq->buf_out = NULL; - do_disconnect (p, NULL, 2, NULL); + ir_obj_delete (p); } else if (r == 0) /* remove select bit */ { - logf(LOG_DEBUG, "Write completed"); + logf (LOG_DEBUG, "Write completed"); p->state = IR_TCL_R_Waiting; -#if IRTCL_GENERIC_FILES - ir_select_remove_write (p->csFile, p); -#else ir_select_remove_write (cs_fileno (p->cs_link), p); -#endif - free (rq->buf_out); + xfree (rq->buf_out); rq->buf_out = NULL; } + return 1; +} + +static void ir_select_notify (ClientData clientData, int r, int w, int e) +{ + if (w) + { + if (!ir_select_write (clientData) && r) + ir_select_read (clientData); + } + else if (r) + { + ir_select_read (clientData); + } } /* ------------------------------------------------------- */