+ IRSetObj *obj = o;
+
+ sprintf (interp->result, "%d", obj->resultCount);
+ return TCL_OK;
+}
+
+/*
+ * do_numberOfRecordsReturned: Get number of records returned
+ */
+static int do_numberOfRecordsReturned (void *o, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IRSetObj *obj = o;
+
+ sprintf (interp->result, "%d", obj->numberOfRecordsReturned);
+ return TCL_OK;
+}
+
+static int marc_cmp (const char *field, const char *pattern)
+{
+ if (*pattern == '*')
+ return 0;
+ for (; *field && *pattern; field++, pattern++)
+ {
+ if (*pattern == '?')
+ continue;
+ if (*pattern != *field)
+ break;
+ }
+ return *field - *pattern;
+}
+
+static int get_marc_fields(Tcl_Interp *interp, Iso2709Rec rec,
+ int argc, char **argv)
+{
+ struct iso2709_dir *dir;
+ struct iso2709_field *field;
+
+ for (dir = rec->directory; dir; dir = dir->next)
+ {
+ if (argc > 4 && marc_cmp (dir->tag, argv[4]))
+ continue;
+ if (argc > 5 && marc_cmp (dir->indicator, argv[5]))
+ continue;
+ for (field = dir->fields; field; field = field->next)
+ {
+ if (argc > 6 && marc_cmp (field->identifier, argv[6]))
+ continue;
+ Tcl_AppendElement (interp, field->data);
+ }
+ }
+ return TCL_OK;
+}
+
+static int get_marc_lines (Tcl_Interp *interp, Iso2709Rec rec,
+ int argc, char **argv)
+{
+ struct iso2709_dir *dir;
+ struct iso2709_field *field;
+
+ for (dir = rec->directory; dir; dir = dir->next)
+ {
+ if (argc > 4 && marc_cmp (dir->tag, argv[4]))
+ continue;
+ if (!dir->indicator)
+ Tcl_AppendResult (interp, "{", dir->tag, " {} {", NULL);
+ else
+ {
+ if (argc > 5 && marc_cmp (dir->indicator, argv[5]))
+ continue;
+ Tcl_AppendResult (interp, "{", dir->tag, " {", dir->indicator,
+ "} {", NULL);
+ }
+ for (field = dir->fields; field; field = field->next)
+ {
+ if (!field->identifier)
+ Tcl_AppendResult (interp, "{{} ", NULL);
+ else
+ {
+ if (argc > 6 && marc_cmp (field->identifier, argv[6]))
+ continue;
+ Tcl_AppendResult (interp, "{", field->identifier, " ", NULL);
+ }
+ Tcl_AppendResult (interp, "{", field->data, "}", NULL);
+ Tcl_AppendResult (interp, "} ", NULL);
+ }
+ Tcl_AppendResult (interp, "}} ", NULL);
+ }
+ return TCL_OK;
+}
+
+/*
+ * do_recordType: Return record type (if any) at position.
+ */
+static int do_recordType (void *o, Tcl_Interp *interp, int argc, char **argv)
+{
+ IRSetObj *obj = o;
+ int offset;
+ IRRecordList *rl;
+
+ if (argc < 3)
+ {
+ sprintf (interp->result, "wrong # args");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetInt (interp, argv[2], &offset)==TCL_ERROR)
+ return TCL_ERROR;
+ for (rl = obj->record_list; rl; rl = rl->next)
+ {
+ if (rl->no == offset)
+ break;
+ }
+ if (!rl)
+ return TCL_OK;
+ switch (rl->which)
+ {
+ case Z_NamePlusRecord_databaseRecord:
+ interp->result = "databaseRecord";
+ break;
+ case Z_NamePlusRecord_surrogateDiagnostic:
+ interp->result = "surrogateDiagnostic";
+ break;
+ default:
+ interp->result = "unknown";
+ break;
+ }
+ return TCL_OK;
+}
+
+/*
+ * do_recordDiag: Return diagnostic record info
+ */
+static int do_recordDiag (void *o, Tcl_Interp *interp, int argc, char **argv)
+{
+ IRSetObj *obj = o;
+ int offset;
+ IRRecordList *rl;
+ char buf[20];
+
+ if (argc < 3)
+ {
+ sprintf (interp->result, "wrong # args");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetInt (interp, argv[2], &offset)==TCL_ERROR)
+ return TCL_ERROR;
+ for (rl = obj->record_list; rl; rl = rl->next)
+ {
+ if (rl->no == offset)
+ break;
+ }
+ if (!rl)
+ {
+ Tcl_AppendResult (interp, "No record at #", argv[2], NULL);
+ return TCL_ERROR;
+ }
+ if (rl->which != Z_NamePlusRecord_surrogateDiagnostic)
+ {
+ Tcl_AppendResult (interp, "No Diagnostic record at #", argv[2], NULL);
+ return TCL_ERROR;
+ }
+ sprintf (buf, "%d ", rl->u.diag.code);
+ Tcl_AppendResult (interp, buf, NULL);
+ if (rl->u.diag.add_info)
+ Tcl_AppendElement (interp, rl->u.diag.add_info);
+ else
+ Tcl_AppendElement (interp, "");
+ return TCL_OK;
+}
+
+/*
+ * do_recordMarc: Get ISO2709 Record lines/fields
+ */
+static int do_recordMarc (void *o, Tcl_Interp *interp, int argc, char **argv)
+{
+ IRSetObj *obj = o;
+ int offset;
+ IRRecordList *rl;
+
+ if (argc < 4)
+ {
+ sprintf (interp->result, "wrong # args");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetInt (interp, argv[2], &offset)==TCL_ERROR)
+ return TCL_ERROR;
+ for (rl = obj->record_list; rl; rl = rl->next)
+ if (rl->no == offset)
+ break;
+ if (!rl)
+ {
+ Tcl_AppendResult (interp, "No record at #", argv[2], NULL);
+ return TCL_ERROR;
+ }
+ if (rl->which != Z_NamePlusRecord_databaseRecord)
+ {
+ Tcl_AppendResult (interp, "No MARC record at #", argv[2], NULL);
+ return TCL_ERROR;
+ }
+ if (!strcmp (argv[3], "field"))
+ return get_marc_fields (interp, rl->u.marc.rec, argc, argv);
+ else if (!strcmp (argv[3], "line"))
+ return get_marc_lines (interp, rl->u.marc.rec, argc, argv);
+ else
+ {
+ Tcl_AppendResult (interp, "field/line expected", NULL);
+ return TCL_ERROR;
+ }
+}
+
+/*
+ * do_present: Perform Present Request
+ */
+
+static int do_present (void *o, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IRSetObj *obj = o;
+ IRObj *p = obj->parent;
+ Z_APDU apdu, *apdup;
+ Z_PresentRequest req;
+ int start;
+ int number;
+ char *sbuf;
+ int slen;
+
+ 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;
+ obj->start = start;
+ obj->number = number;
+
+ apdup = &apdu;
+ apdu.which = Z_APDU_presentRequest;
+ apdu.u.presentRequest = &req;
+ req.referenceId = 0;
+ /* sprintf(setstring, "%d", setnumber); */
+ req.resultSetId = "Default";
+ req.resultSetStartPoint = &start;
+ req.numberOfRecordsRequested = &number;
+ req.elementSetNames = 0;
+ req.preferredRecordSyntax = 0;
+
+ if (!z_APDU (p->odr_out, &apdup, 0))
+ {
+ interp->result = odr_errlist [odr_geterror (p->odr_out)];
+ odr_reset (p->odr_out);
+ return TCL_ERROR;
+ }
+ sbuf = odr_getbuf (p->odr_out, &slen);
+ if (cs_put (p->cs_link, sbuf, slen) < 0)
+ {
+ interp->result = "cs_put failed in init";
+ return TCL_ERROR;
+ }
+ printf ("Present request, start=%d, num=%d\n", start, number);
+ return TCL_OK;
+}
+
+/*
+ * do_loadFile: Load result set from file
+ */
+
+static int do_loadFile (void *o, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IRSetObj *setobj = o;
+ FILE *inf;
+ int no = 1;
+ const char *buf;
+
+ 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 = iso2709_read (inf)))
+ {
+ IRRecordList *rl;
+ Iso2709Rec rec;
+
+ rec = iso2709_cvt (buf);
+ if (!rec)
+ break;
+ for (rl = setobj->record_list; rl; rl = rl->next)
+ {
+ if (no == rl->no)
+ {
+ if (rl->which == Z_NamePlusRecord_databaseRecord)
+ iso2709_rm (rl->u.marc.rec);
+ break;
+ }
+ }
+ if (!rl)
+ {
+ rl = malloc (sizeof(*rl));
+ assert (rl);
+ rl->next = setobj->record_list;
+ rl->no = no;
+ setobj->record_list = rl;
+ }
+ rl->which = Z_NamePlusRecord_databaseRecord;
+ rl->u.marc.rec = rec;
+ no++;
+ }
+ setobj->numberOfRecordsReturned = no-1;
+ fclose (inf);