+#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);
+ return TCL_ERROR;
+ }
+ ccl_pr_tree (rpn, stderr);
+ fprintf (stderr, "\n");
+ if (!(req->termListAndStartPoint = ccl_scan_query (rpn)))
+ return TCL_ERROR;
+#endif
+ req->stepSize = &obj->stepSize;
+ req->numberOfTermsRequested = &obj->numberOfTermsRequested;
+ req->preferredPositionInResponse = &obj->preferredPositionInResponse;
+ logf (LOG_DEBUG, "stepSize=%d", *req->stepSize);
+ logf (LOG_DEBUG, "numberOfTermsRequested=%d",
+ *req->numberOfTermsRequested);
+ logf (LOG_DEBUG, "preferredPositionInResponse=%d",
+ *req->preferredPositionInResponse);
+
+ return ir_tcl_send_APDU (interp, p, apdu, "scan", *argv);
+}
+
+/*
+ * do_scanResponse: add scan response handler
+ */
+static int do_scanResponse (void *o, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_ScanObj *obj = o;
+
+ if (argc == 0)
+ {
+ obj->scanResponse = NULL;
+ return TCL_OK;
+ }
+ else if (argc == -1)
+ return ir_tcl_strdel (interp, &obj->scanResponse);
+ if (argc == 3)
+ {
+ free (obj->scanResponse);
+ if (argv[2][0])
+ {
+ if (ir_tcl_strdup (interp, &obj->scanResponse, argv[2])
+ == TCL_ERROR)
+ return TCL_ERROR;
+ }
+ else
+ obj->scanResponse = NULL;
+ }
+ return TCL_OK;
+}
+
+/*
+ * do_stepSize: Set/get replace Step Size
+ */
+static int do_stepSize (void *obj, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_ScanObj *p = obj;
+ if (argc <= 0)
+ {
+ p->stepSize = 0;
+ return TCL_OK;
+ }
+ return get_set_int (&p->stepSize, interp, argc, argv);
+}
+
+/*
+ * do_numberOfTermsRequested: Set/get Number of Terms requested
+ */
+static int do_numberOfTermsRequested (void *obj, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_ScanObj *p = obj;
+
+ if (argc <= 0)
+ {
+ p->numberOfTermsRequested = 20;
+ return TCL_OK;
+ }
+ return get_set_int (&p->numberOfTermsRequested, interp, argc, argv);
+}
+
+
+/*
+ * do_preferredPositionInResponse: Set/get preferred Position
+ */
+static int do_preferredPositionInResponse (void *obj, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_ScanObj *p = obj;
+
+ if (argc <= 0)
+ {
+ p->preferredPositionInResponse = 1;
+ return TCL_OK;
+ }
+ return get_set_int (&p->preferredPositionInResponse, interp, argc, argv);
+}
+
+/*
+ * do_scanStatus: Get scan status
+ */
+static int do_scanStatus (void *obj, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_ScanObj *p = obj;
+
+ if (argc <= 0)
+ return TCL_OK;
+ return get_set_int (&p->scanStatus, interp, argc, argv);
+}
+
+/*
+ * do_numberOfEntriesReturned: Get number of Entries returned
+ */
+static int do_numberOfEntriesReturned (void *obj, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_ScanObj *p = obj;
+
+ if (argc <= 0)
+ return TCL_OK;
+ return get_set_int (&p->numberOfEntriesReturned, interp, argc, argv);
+}
+
+/*
+ * do_positionOfTerm: Get position of Term
+ */
+static int do_positionOfTerm (void *obj, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_ScanObj *p = obj;
+
+ if (argc <= 0)
+ return TCL_OK;
+ return get_set_int (&p->positionOfTerm, interp, argc, argv);
+}
+
+/*
+ * do_scanLine: get Scan Line (surrogate or normal) after response
+ */
+static int do_scanLine (void *obj, Tcl_Interp *interp, int argc, char **argv)
+{
+ IrTcl_ScanObj *p = obj;
+ int i;
+ char numstr[20];
+
+ if (argc == 0)
+ {
+ p->entries_flag = 0;
+ p->entries = NULL;
+ p->nonSurrogateDiagnosticNum = 0;
+ p->nonSurrogateDiagnosticList = 0;
+ return TCL_OK;
+ }
+ else if (argc == -1)
+ {
+ p->entries_flag = 0;
+ /* release entries */
+ p->entries = NULL;
+
+ ir_deleteDiags (&p->nonSurrogateDiagnosticList,
+ &p->nonSurrogateDiagnosticNum);
+ return TCL_OK;
+ }
+ if (argc != 3)
+ {
+ interp->result = "wrong # args";
+ return TCL_ERROR;
+ }
+ if (Tcl_GetInt (interp, argv[2], &i) == TCL_ERROR)
+ return TCL_ERROR;
+ if (!p->entries_flag || p->which != Z_ListEntries_entries || !p->entries
+ || i >= p->num_entries || i < 0)
+ return TCL_OK;
+ switch (p->entries[i].which)
+ {
+ case Z_Entry_termInfo:
+ Tcl_AppendElement (interp, "T");
+ if (p->entries[i].u.term.buf)
+ Tcl_AppendElement (interp, p->entries[i].u.term.buf);
+ else
+ Tcl_AppendElement (interp, "");
+ sprintf (numstr, "%d", p->entries[i].u.term.globalOccurrences);
+ Tcl_AppendElement (interp, numstr);
+ break;
+ case Z_Entry_surrogateDiagnostic:
+ Tcl_AppendElement (interp, "SD");
+ return ir_diagResult (interp, p->entries[i].u.diag.list,
+ p->entries[i].u.diag.num);
+ break;
+ }
+ return TCL_OK;
+}
+
+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}
+};
+
+/*
+ * ir_scan_obj_method: IR Scan Object methods
+ */
+static int ir_scan_obj_method (ClientData clientData, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ IrTcl_Methods tabs[2];
+
+ if (argc < 2)
+ {
+ interp->result = "wrong # args";
+ return TCL_ERROR;
+ }
+ tabs[0].tab = ir_scan_method_tab;
+ tabs[0].obj = clientData;
+ tabs[1].tab = NULL;
+
+ return ir_method (interp, argc, argv, tabs);
+}
+
+/*
+ * ir_scan_obj_delete: IR Scan Object disposal
+ */
+static void ir_scan_obj_delete (ClientData clientData)
+{
+ IrTcl_Methods tabs[2];
+ IrTcl_ScanObj *obj = clientData;
+
+ tabs[0].tab = ir_scan_method_tab;
+ tabs[0].obj = obj;
+ tabs[1].tab = NULL;
+
+ ir_method (NULL, -1, NULL, tabs);
+ free (obj);
+}
+
+/*
+ * ir_scan_obj_mk: IR Scan Object creation
+ */
+static int ir_scan_obj_mk (ClientData clientData, Tcl_Interp *interp,
+ int argc, char **argv)
+{
+ Tcl_CmdInfo parent_info;
+ IrTcl_ScanObj *obj;
+ IrTcl_Methods tabs[2];
+
+ if (argc != 3)
+ {
+ interp->result = "wrong # args";
+ return TCL_ERROR;
+ }
+ if (!Tcl_GetCommandInfo (interp, argv[2], &parent_info))
+ {
+ interp->result = "No parent";
+ return TCL_ERROR;
+ }
+ obj = ir_tcl_malloc (sizeof(*obj));
+ obj->parent = (IrTcl_Obj *) parent_info.clientData;
+
+ tabs[0].tab = ir_scan_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_scan_obj_method,
+ (ClientData) obj, ir_scan_obj_delete);
+ return TCL_OK;
+}
+
+/* ------------------------------------------------------- */
+
+static void ir_initResponse (void *obj, Z_InitResponse *initrs)
+{
+ IrTcl_Obj *p = obj;
+
+ p->initResult = *initrs->result ? 1 : 0;
+ if (!*initrs->result)
+ logf (LOG_DEBUG, "Connection rejected by target");
+ else
+ logf (LOG_DEBUG, "Connection accepted by target");
+
+ get_referenceId (&p->set_inher.referenceId, initrs->referenceId);
+
+ free (p->targetImplementationId);
+ ir_tcl_strdup (p->interp, &p->targetImplementationId,
+ initrs->implementationId);
+ free (p->targetImplementationName);
+ ir_tcl_strdup (p->interp, &p->targetImplementationName,
+ initrs->implementationName);
+ free (p->targetImplementationVersion);
+ ir_tcl_strdup (p->interp, &p->targetImplementationVersion,
+ initrs->implementationVersion);
+
+ p->maximumRecordSize = *initrs->maximumRecordSize;
+ p->preferredMessageSize = *initrs->preferredMessageSize;
+
+ memcpy (&p->options, initrs->options, sizeof(initrs->options));
+ memcpy (&p->protocolVersion, initrs->protocolVersion,
+ sizeof(initrs->protocolVersion));
+ free (p->userInformationField);
+ p->userInformationField = NULL;
+ if (initrs->userInformationField)
+ {
+ int len;
+
+ if (initrs->userInformationField->which == ODR_EXTERNAL_octet &&
+ (p->userInformationField =
+ ir_tcl_malloc ((len =
+ initrs->userInformationField->
+ u.octet_aligned->len) +1)))
+ {
+ memcpy (p->userInformationField,
+ initrs->userInformationField->u.octet_aligned->buf,
+ len);
+ (p->userInformationField)[len] = '\0';
+ }
+ }
+}
+
+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);
+ *dst_list = NULL;
+ *dst_num = 0;
+}
+
+static void ir_handleDiags (IrTcl_Diagnostic **dst_list, int *dst_num,
+ Z_DiagRec **list, int num)
+{
+ int i;
+ char *addinfo;
+
+ *dst_num = num;
+ *dst_list = ir_tcl_malloc (sizeof(**dst_list) * num);
+ for (i = 0; i<num; i++)
+ {
+ switch (list[i]->which)
+ {
+ case Z_DiagRec_defaultFormat:
+ (*dst_list)[i].condition = *list[i]->u.defaultFormat->condition;
+ addinfo = list[i]->u.defaultFormat->addinfo;
+ if (addinfo &&
+ ((*dst_list)[i].addinfo = ir_tcl_malloc (strlen(addinfo)+1)))
+ strcpy ((*dst_list)[i].addinfo, addinfo);
+ break;
+ default:
+ (*dst_list)[i].addinfo = NULL;
+ (*dst_list)[i].condition = 0;
+ }
+ }
+}
+
+static void ir_handleRecords (void *o, Z_Records *zrs, IrTcl_SetObj *setobj,
+ const char *elements)
+{
+ IrTcl_Obj *p = o;
+
+ int offset;
+ IrTcl_RecordList *rl;
+
+ setobj->which = zrs->which;
+ setobj->recordFlag = 1;
+
+ ir_deleteDiags (&setobj->nonSurrogateDiagnosticList,
+ &setobj->nonSurrogateDiagnosticNum);
+ if (zrs->which == Z_Records_DBOSD)
+ {
+ setobj->numberOfRecordsReturned =
+ zrs->u.databaseOrSurDiagnostics->num_records;
+ logf (LOG_DEBUG, "Got %d records", setobj->numberOfRecordsReturned);
+ for (offset = 0; offset<setobj->numberOfRecordsReturned; offset++)
+ {
+ rl = new_IR_record (setobj, setobj->start + offset,
+ zrs->u.databaseOrSurDiagnostics->
+ records[offset]->which,
+ elements);
+ if (rl->which == Z_NamePlusRecord_surrogateDiagnostic)
+ {
+ ir_handleDiags (&rl->u.surrogateDiagnostics.list,
+ &rl->u.surrogateDiagnostics.num,
+ &zrs->u.databaseOrSurDiagnostics->
+ records[offset]->u.surrogateDiagnostic,
+ 1);
+ }
+ else
+ {
+ Z_DatabaseRecord *zr;
+ Z_External *oe;
+ struct oident *ident;
+
+ zr = zrs->u.databaseOrSurDiagnostics->records[offset]
+ ->u.databaseRecord;
+ oe = (Z_External*) zr;
+ rl->u.dbrec.size = zr->u.octet_aligned->len;
+
+ if ((ident = oid_getentbyoid (oe->direct_reference)))
+ rl->u.dbrec.type = ident->value;