+ Tcl_AppendResult (interp, "No Diagnostic record at #", argv[2], NULL);
+ return TCL_ERROR;
+ }
+ return ir_diagResult (interp, rl->u.surrogateDiagnostics.list,
+ rl->u.surrogateDiagnostics.num);
+}
+
+/*
+ * do_getMarc: Get ISO2709 Record lines/fields
+ */
+static int do_getMarc (void *o, Tcl_Interp *interp, int argc, char **argv)
+{
+ IrTcl_SetObj *obj = o;
+ int offset;
+ IrTcl_RecordList *rl;
+
+ if (argc <= 0)
+ return TCL_OK;
+ if (argc < 7)
+ {
+ sprintf (interp->result, "wrong # args");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetInt (interp, argv[2], &offset)==TCL_ERROR)
+ return TCL_ERROR;
+ rl = find_IR_record (obj, offset);
+ if (!rl)
+ {
+ Tcl_AppendResult (interp, "No record at #", argv[2], NULL);
+ return TCL_ERROR;
+ }
+ if (rl->which != Z_NamePlusRecord_databaseRecord)
+ {
+ Tcl_AppendResult (interp, "No DB record at #", argv[2], NULL);
+ return TCL_ERROR;
+ }
+ return ir_tcl_get_marc (interp, rl->u.dbrec.buf, argc, argv);
+}
+
+/*
+ * do_getSutrs: Get SUTRS Record
+ */
+static int do_getSutrs (void *o, Tcl_Interp *interp, int argc, char **argv)
+{
+ IrTcl_SetObj *obj = o;
+ int offset;
+ IrTcl_RecordList *rl;
+
+ if (argc <= 0)
+ return TCL_OK;
+ if (argc < 3)
+ {
+ sprintf (interp->result, "wrong # args");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetInt (interp, argv[2], &offset)==TCL_ERROR)
+ return TCL_ERROR;
+ rl = find_IR_record (obj, offset);
+ if (!rl)
+ {
+ Tcl_AppendResult (interp, "No record at #", argv[2], NULL);
+ return TCL_ERROR;
+ }
+ if (rl->which != Z_NamePlusRecord_databaseRecord)
+ {
+ Tcl_AppendResult (interp, "No DB record at #", argv[2], NULL);
+ return TCL_ERROR;
+ }
+ if (rl->u.dbrec.type != VAL_SUTRS)
+ return TCL_OK;
+ Tcl_AppendElement (interp, rl->u.dbrec.buf);
+ return TCL_OK;
+}
+
+
+/*
+ * do_responseStatus: Return response status (present or search)
+ */
+static int do_responseStatus (void *o, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_SetObj *obj = o;
+
+ if (argc == 0)
+ {
+ obj->recordFlag = 0;
+ obj->nonSurrogateDiagnosticNum = 0;
+ obj->nonSurrogateDiagnosticList = NULL;
+ return TCL_OK;
+ }
+ else if (argc == -1)
+ {
+ ir_deleteDiags (&obj->nonSurrogateDiagnosticList,
+ &obj->nonSurrogateDiagnosticNum);
+ return TCL_OK;
+ }
+ if (!obj->recordFlag)
+ {
+ Tcl_AppendElement (interp, "OK");
+ return TCL_OK;
+ }
+ switch (obj->which)
+ {
+ case Z_Records_DBOSD:
+ Tcl_AppendElement (interp, "DBOSD");
+ break;
+ case Z_Records_NSD:
+ Tcl_AppendElement (interp, "NSD");
+ return ir_diagResult (interp, obj->nonSurrogateDiagnosticList,
+ obj->nonSurrogateDiagnosticNum);
+ }
+ return TCL_OK;
+}
+
+/*
+ * do_present: Perform Present Request
+ */
+
+static int do_present (void *o, Tcl_Interp *interp, int argc, char **argv)
+{
+ IrTcl_SetObj *obj = o;
+ IrTcl_Obj *p;
+ Z_APDU *apdu;
+ Z_PresentRequest *req;
+ int start;
+ int number;
+
+ if (argc <= 0)
+ return TCL_OK;
+ if (argc >= 3)
+ {
+ if (Tcl_GetInt (interp, argv[2], &start) == TCL_ERROR)
+ return TCL_ERROR;
+ }
+ else
+ start = 1;
+ if (argc >= 4)
+ {
+ if (Tcl_GetInt (interp, argv[3], &number) == TCL_ERROR)
+ return TCL_ERROR;
+ }
+ else
+ number = 10;
+ p = obj->parent;
+ if (!p->cs_link)
+ {
+ interp->result = "present: not connected";
+ return TCL_ERROR;
+ }
+
+ obj->start = start;
+ obj->number = number;
+
+ apdu = zget_APDU (p->odr_out, Z_APDU_presentRequest);
+ req = apdu->u.presentRequest;
+
+ set_referenceId (p->odr_out, &req->referenceId,
+ obj->set_inher.referenceId);
+
+ req->resultSetId = obj->setName ? obj->setName : "Default";
+
+ req->resultSetStartPoint = &start;
+ req->numberOfRecordsRequested = &number;
+ if (obj->set_inher.preferredRecordSyntax)
+ {
+ struct oident ident;
+
+ ident.proto = p->protocol_type;
+ ident.class = CLASS_RECSYN;
+ ident.value = *obj->set_inher.preferredRecordSyntax;
+ logf (LOG_DEBUG, "Preferred record syntax is %d", ident.value);
+ req->preferredRecordSyntax = odr_oiddup (p->odr_out,
+ oid_getoidbyent (&ident));
+ }
+ else
+ req->preferredRecordSyntax = 0;
+
+ return ir_tcl_send_APDU (interp, p, apdu, "present", argv[0]);
+}
+
+/*
+ * do_loadFile: Load result set from file
+ */
+
+static int do_loadFile (void *o, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_SetObj *setobj = o;
+ FILE *inf;
+ size_t size;
+ int no = 1;
+ char *buf;
+
+ if (argc <= 0)
+ return TCL_OK;
+ if (argc < 3)
+ {
+ interp->result = "wrong # args";
+ return TCL_ERROR;
+ }
+ inf = fopen (argv[2], "r");
+ if (!inf)
+ {
+ Tcl_AppendResult (interp, "Cannot open ", argv[2], NULL);
+ return TCL_ERROR;
+ }
+ while ((buf = ir_tcl_fread_marc (inf, &size)))
+ {
+ IrTcl_RecordList *rl;
+
+ rl = new_IR_record (setobj, no, Z_NamePlusRecord_databaseRecord);
+ rl->u.dbrec.type = VAL_USMARC;
+ rl->u.dbrec.buf = buf;
+ rl->u.dbrec.size = size;
+ no++;
+ }
+ setobj->numberOfRecordsReturned = no-1;
+ fclose (inf);
+ return TCL_OK;
+}
+
+static IrTcl_Method ir_set_method_tab[] = {
+ { 0, "search", do_search },
+ { 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, "recordType", do_recordType },
+ { 0, "diag", do_diag },
+ { 0, "responseStatus", do_responseStatus },
+ { 0, "loadFile", do_loadFile },
+ { 0, NULL, NULL}
+};
+
+/*
+ * ir_set_obj_method: IR Set Object methods
+ */
+static int ir_set_obj_method (ClientData clientData, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_Methods tabs[3];
+ IrTcl_SetObj *p = clientData;
+
+ if (argc < 2)
+ {
+ interp->result = "wrong # args";
+ return TCL_ERROR;
+ }
+ tabs[0].tab = ir_set_method_tab;
+ tabs[0].obj = p;
+ tabs[1].tab = ir_set_c_method_tab;
+ tabs[1].obj = &p->set_inher;
+ tabs[2].tab = NULL;
+
+ return ir_method (interp, argc, argv, tabs);
+}
+
+/*
+ * ir_set_obj_delete: IR Set Object disposal
+ */
+static void ir_set_obj_delete (ClientData clientData)
+{
+ IrTcl_Methods tabs[3];
+ IrTcl_SetObj *p = clientData;
+
+ logf (LOG_DEBUG, "ir set delete");
+
+ tabs[0].tab = ir_set_method_tab;
+ tabs[0].obj = p;
+ tabs[1].tab = ir_set_c_method_tab;
+ tabs[1].obj = &p->set_inher;
+ tabs[2].tab = NULL;
+
+ ir_method (NULL, -1, NULL, tabs);
+
+ free (p);
+}
+
+/*
+ * ir_set_obj_mk: IR Set Object creation
+ */
+static int ir_set_obj_mk (ClientData clientData, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_Methods tabs[3];
+ IrTcl_SetObj *obj;
+
+ if (argc < 2 || argc > 3)
+ {
+ interp->result = "wrong # args";
+ return TCL_ERROR;
+ }
+ obj = ir_tcl_malloc (sizeof(*obj));
+ logf (LOG_DEBUG, "ir set create");
+ if (argc == 3)
+ {
+ 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;
+
+ dst = &obj->set_inher;
+ src = &obj->parent->set_inher;
+
+ dst->num_databaseNames = src->num_databaseNames;
+ dst->databaseNames =
+ ir_tcl_malloc (sizeof (*dst->databaseNames)
+ * 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;
+ }
+ if (ir_tcl_strdup (interp, &dst->queryType, src->queryType)
+ == TCL_ERROR)
+ return TCL_ERROR;
+
+ if (ir_tcl_strdup (interp, &dst->referenceId, src->referenceId)
+ == TCL_ERROR)
+ return TCL_ERROR;
+
+ if (src->preferredRecordSyntax &&
+ (dst->preferredRecordSyntax
+ = ir_tcl_malloc (sizeof(*dst->preferredRecordSyntax))))
+ *dst->preferredRecordSyntax = *src->preferredRecordSyntax;
+ else
+ dst->preferredRecordSyntax = NULL;
+ dst->replaceIndicator = src->replaceIndicator;
+ dst->smallSetUpperBound = src->smallSetUpperBound;
+ dst->largeSetLowerBound = src->largeSetLowerBound;
+ dst->mediumSetPresentNumber = src->mediumSetPresentNumber;
+ }
+ else
+ obj->parent = NULL;
+
+ tabs[0].tab = ir_set_method_tab;
+ tabs[0].obj = obj;
+ tabs[1].tab = NULL;
+
+ if (ir_method (interp, 0, NULL, tabs) == TCL_ERROR)
+ return TCL_ERROR;
+
+ Tcl_CreateCommand (interp, argv[1], ir_set_obj_method,
+ (ClientData) obj, ir_set_obj_delete);
+ return TCL_OK;
+}
+
+/* ------------------------------------------------------- */
+
+/*
+ * do_scan: Perform scan
+ */
+static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv)
+{
+ Z_ScanRequest *req;
+ Z_APDU *apdu;
+ IrTcl_ScanObj *obj = o;
+ IrTcl_Obj *p = obj->parent;
+ oident bib1;
+#if CCL2RPN
+ struct ccl_rpn_node *rpn;
+ int pos;
+#endif
+
+ if (argc <= 0)
+ return TCL_OK;
+ if (argc != 3)
+ {
+ interp->result = "wrong # args";
+ return TCL_ERROR;
+ }
+ if (!p->set_inher.num_databaseNames)
+ {
+ interp->result = "no databaseNames";
+ return TCL_ERROR;
+ }
+ if (!p->cs_link)
+ {
+ interp->result = "scan: not connected";
+ return TCL_ERROR;
+ }
+
+ bib1.proto = p->protocol_type;
+ bib1.class = 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])))
+ {
+ Tcl_AppendResult (interp, "Syntax error in query", NULL);
+ return TCL_ERROR;
+ }
+#else
+ rpn = ccl_find_str(p->bibset, argv[2], &r, &pos);
+ if (r)
+ {
+ Tcl_AppendResult (interp, "CCL error: ", ccl_err_msg (r), NULL);