+ Z_Term *term = zapt->term;
+ char **map;
+ char *cp = (char*) term->u.general->buf;
+ const char *cp_end = cp + term->u.general->len;
+ const char *src;
+ int i = 0;
+ int prev_space = 0;
+ int len;
+
+ while ((len = (cp_end - cp)) > 0)
+ {
+ map = map_chrs_input (&cp, len);
+ if (**map == *CHR_SPACE)
+ {
+ if (prev_space)
+ continue;
+ prev_space = 1;
+ }
+ else
+ prev_space = 0;
+ for (src = *map; *src; src++)
+ termz[i++] = *src;
+ }
+ termz[i] = '\0';
+}
+
+static RSET rpn_search_APT_relevance (ZServerInfo *zi,
+ Z_AttributesPlusTerm *zapt,
+ oid_value attributeSet,
+ int num_bases, char **basenames)
+{
+ rset_relevance_parms parms;
+ char termz[IT_MAX_WORD+1];
+ char *termp = termz;
+ struct grep_info grep_info;
+ RSET result;
+ int term_index = 0;
+ int r;
+
+ parms.key_size = sizeof(struct it_key);
+ parms.max_rec = 100;
+ parms.cmp = key_compare;
+ parms.is = zi->isam;
+ parms.isc = zi->isamc;
+ parms.no_terms = 0;
+
+ if (zapt->term->which != Z_Term_general)
+ {
+ zi->errCode = 124;
+ return NULL;
+ }
+ trans_term (zi, zapt, termz);
+
+#ifdef TERM_COUNT
+ grep_info.term_no = 0;
+#endif
+ grep_info.isam_p_indx = 0;
+ grep_info.isam_p_size = 0;
+ grep_info.isam_p_buf = NULL;
+ while (1)
+ {
+ r = field_term (zi, zapt, &termp, 'w', attributeSet, &grep_info,
+ num_bases, basenames);
+ if (r <= 0)
+ break;
+#ifdef TERM_COUNT
+ for (; term_index < grep_info.isam_p_indx; term_index++)
+ grep_info.term_no[term_index] = parms.no_terms;
+ parms.no_terms++;
+#endif
+ }
+ parms.term_no = grep_info.term_no;
+ parms.isam_positions = grep_info.isam_p_buf;
+ parms.no_isam_positions = grep_info.isam_p_indx;
+ if (grep_info.isam_p_indx > 0)
+ result = rset_create (rset_kind_relevance, &parms);
+ else
+ result = rset_create (rset_kind_null, NULL);
+#ifdef TERM_COUNT
+ xfree(grep_info.term_no);
+#endif
+ xfree (grep_info.isam_p_buf);
+ return result;
+}
+
+static RSET rpn_search_APT_cphrase (ZServerInfo *zi,
+ Z_AttributesPlusTerm *zapt,
+ oid_value attributeSet,
+ int num_bases, char **basenames)
+{
+ char termz[IT_MAX_WORD+1];
+ struct grep_info grep_info;
+ RSET result;
+ char *termp = termz;
+ int r;
+
+ if (zapt->term->which != Z_Term_general)
+ {
+ zi->errCode = 124;
+ return NULL;
+ }
+ trans_term (zi, zapt, termz);
+
+#ifdef TERM_COUNT
+ grep_info.term_no = 0;
+#endif
+ grep_info.isam_p_indx = 0;
+ grep_info.isam_p_size = 0;
+ grep_info.isam_p_buf = NULL;
+
+ r = field_term (zi, zapt, &termp, 'p', attributeSet, &grep_info,
+ num_bases, basenames);
+ result = rset_trunc (zi, grep_info.isam_p_buf, grep_info.isam_p_indx);
+#ifdef TERM_COUNT
+ xfree(grep_info.term_no);
+#endif
+ xfree (grep_info.isam_p_buf);
+ return result;
+}
+
+static RSET rpn_prox (RSET *rset, int rset_no)
+{
+ int i;
+ RSFD *rsfd;
+ int *more;
+ struct it_key **buf;
+ RSFD rsfd_result;
+ RSET result;
+ rset_temp_parms parms;
+
+ rsfd = xmalloc (sizeof(*rsfd)*rset_no);
+ more = xmalloc (sizeof(*more)*rset_no);
+ buf = xmalloc (sizeof(*buf)*rset_no);
+
+ for (i = 0; i<rset_no; i++)
+ {
+ buf[i] = xmalloc (sizeof(**buf));
+ rsfd[i] = rset_open (rset[i], RSETF_READ|RSETF_SORT_SYSNO);
+ if (!(more[i] = rset_read (rset[i], rsfd[i], buf[i])))
+ {
+ while (i >= 0)
+ {
+ rset_close (rset[i], rsfd[i]);
+ xfree (buf[i]);
+ --i;
+ }
+ xfree (rsfd);
+ xfree (more);
+ xfree (buf);
+ return rset_create (rset_kind_null, NULL);
+ }
+ }
+ parms.key_size = sizeof (struct it_key);
+ result = rset_create (rset_kind_temp, &parms);
+ rsfd_result = rset_open (result, RSETF_WRITE|RSETF_SORT_SYSNO);
+
+ while (*more)
+ {
+ for (i = 1; i<rset_no; i++)
+ {
+ int cmp;
+
+ if (!more[i])
+ {
+ *more = 0;
+ break;
+ }
+ cmp = key_compare (buf[i], buf[i-1]);
+ if (cmp > 1)
+ {
+ more[i-1] = rset_read (rset[i-1], rsfd[i-1], buf[i-1]);
+ break;
+ }
+ else if (cmp == 1)
+ {
+ if (buf[i-1]->seqno+1 != buf[i]->seqno)
+ {
+ more[i-1] = rset_read (rset[i-1], rsfd[i-1], buf[i-1]);
+ break;
+ }
+ }
+ else
+ {
+ more[i] = rset_read (rset[i], rsfd[i], buf[i]);
+ break;
+ }
+ }
+ if (i == rset_no)
+ {
+ rset_write (result, rsfd_result, buf[0]);
+ more[0] = rset_read (*rset, *rsfd, *buf);
+ }
+ }
+
+ for (i = 0; i<rset_no; i++)
+ {
+ rset_close (rset[i], rsfd[i]);
+ xfree (buf[i]);
+ }
+ rset_close (result, rsfd_result);
+ xfree (buf);
+ xfree (more);
+ xfree (rsfd);
+ return result;
+}
+
+static RSET rpn_search_APT_phrase (ZServerInfo *zi,
+ Z_AttributesPlusTerm *zapt,
+ oid_value attributeSet,
+ int num_bases, char **basenames)
+{
+ char termz[IT_MAX_WORD+1];
+ char *termp = termz;
+ RSET rset[60], result;
+ int i, r, rset_no = 0;
+ struct grep_info grep_info;
+
+ if (zapt->term->which != Z_Term_general)
+ {
+ zi->errCode = 124;
+ return NULL;
+ }
+ trans_term (zi, zapt, termz);
+
+#ifdef TERM_COUNT
+ grep_info.term_no = 0;
+#endif
+ grep_info.isam_p_size = 0;
+ grep_info.isam_p_buf = NULL;
+
+ while (1)
+ {
+ grep_info.isam_p_indx = 0;
+ r = field_term (zi, zapt, &termp, 'w', attributeSet, &grep_info,
+ num_bases, basenames);
+ if (r < 1)
+ break;
+ rset[rset_no] = rset_trunc (zi, grep_info.isam_p_buf,
+ grep_info.isam_p_indx);
+ assert (rset[rset_no]);
+ if (++rset_no >= sizeof(rset)/sizeof(*rset))
+ break;
+ }
+#ifdef TERM_COUNT
+ xfree(grep_info.term_no);
+#endif
+ xfree (grep_info.isam_p_buf);
+ if (rset_no == 0)
+ return rset_create (rset_kind_null, NULL);
+ else if (rset_no == 1)
+ return (rset[0]);
+ result = rpn_prox (rset, rset_no);
+ for (i = 0; i<rset_no; i++)
+ rset_delete (rset[i]);
+ return result;
+}
+
+static RSET rpn_search_APT_local (ZServerInfo *zi, Z_AttributesPlusTerm *zapt,
+ oid_value attributeSet)
+{
+ RSET result;
+ RSFD rsfd;
+ struct it_key key;
+ rset_temp_parms parms;
+ char termz[IT_MAX_WORD+1];
+
+ if (zapt->term->which != Z_Term_general)
+ {
+ zi->errCode = 124;
+ return NULL;
+ }
+ parms.key_size = sizeof (struct it_key);
+ result = rset_create (rset_kind_temp, &parms);
+ rsfd = rset_open (result, RSETF_WRITE|RSETF_SORT_SYSNO);
+
+ trans_term (zi, zapt, termz);
+
+ key.sysno = atoi (termz);
+ if (key.sysno <= 0)
+ key.sysno = 1;
+ rset_write (result, rsfd, &key);
+ rset_close (result, rsfd);
+ return result;
+}
+
+static RSET rpn_search_APT (ZServerInfo *zi, Z_AttributesPlusTerm *zapt,
+ oid_value attributeSet,
+ int num_bases, char **basenames)
+{
+ AttrType relation;
+ AttrType structure;
+ AttrType completeness;
+ int relation_value, structure_value, completeness_value;
+
+ attr_init (&relation, zapt, 2);
+ attr_init (&structure, zapt, 4);
+ attr_init (&completeness, zapt, 6);
+
+ relation_value = attr_find (&relation, NULL);
+ structure_value = attr_find (&structure, NULL);
+ completeness_value = attr_find (&completeness, NULL);
+ switch (structure_value)
+ {
+ case -1:
+ if (relation_value == 102) /* relevance relation */
+ return rpn_search_APT_relevance (zi, zapt, attributeSet,
+ num_bases, basenames);
+ if (completeness_value == 2 || completeness_value == 3)
+ return rpn_search_APT_cphrase (zi, zapt, attributeSet,
+ num_bases, basenames);
+ return rpn_search_APT_phrase (zi, zapt, attributeSet,
+ num_bases, basenames);
+ case 1: /* phrase */
+ if (relation_value == 102) /* relevance relation */
+ return rpn_search_APT_relevance (zi, zapt, attributeSet,
+ num_bases, basenames);
+ if (completeness_value == 2 || completeness_value == 3)
+ return rpn_search_APT_cphrase (zi, zapt, attributeSet,
+ num_bases, basenames);
+ return rpn_search_APT_phrase (zi, zapt, attributeSet,
+ num_bases, basenames);
+ break;
+ case 2: /* word */
+ if (relation_value == 102) /* relevance relation */
+ return rpn_search_APT_relevance (zi, zapt, attributeSet,
+ num_bases, basenames);
+ if (completeness_value == 2 || completeness_value == 3)
+ return rpn_search_APT_cphrase (zi, zapt, attributeSet,
+ num_bases, basenames);
+ return rpn_search_APT_phrase (zi, zapt, attributeSet,
+ num_bases, basenames);
+ case 3: /* key */
+ break;
+ case 4: /* year */
+ break;
+ case 5: /* date - normalized */
+ break;
+ case 6: /* word list */
+ return rpn_search_APT_relevance (zi, zapt, attributeSet,
+ num_bases, basenames);
+ case 100: /* date - un-normalized */
+ break;
+ case 101: /* name - normalized */
+ break;
+ case 102: /* date - un-normalized */
+ break;
+ case 103: /* structure */
+ break;
+ case 104: /* urx */
+ break;
+ case 105: /* free-form-text */
+ return rpn_search_APT_relevance (zi, zapt, attributeSet,
+ num_bases, basenames);
+ case 106: /* document-text */
+ return rpn_search_APT_relevance (zi, zapt, attributeSet,
+ num_bases, basenames);
+ case 107: /* local-number */
+ return rpn_search_APT_local (zi, zapt, attributeSet);
+ case 108: /* string */
+ return rpn_search_APT_phrase (zi, zapt, attributeSet,
+ num_bases, basenames);
+ case 109: /* numeric string */
+ break;
+ }
+ zi->errCode = 118;