+ char term_dict[2*IT_MAX_WORD+2];
+ int i, j;
+ const char *info;
+ AttrType truncation;
+ int truncation_value;
+ AttrType use;
+ int use_value;
+
+ attr_init (&use, zapt, 1);
+ use_value = attr_find (&use);
+ logf (LOG_DEBUG, "use value %d", use_value);
+ attr_init (&truncation, zapt, 5);
+ truncation_value = attr_find (&truncation);
+ logf (LOG_DEBUG, "truncation value %d", truncation_value);
+
+ if (use_value == -1)
+ use_value = 1016;
+ i = index_word_prefix (term_dict, 1, use_value);
+
+ switch (truncation_value)
+ {
+ case -1: /* not specified */
+ case 100: /* do not truncate */
+ strcat (term_dict, term_sub);
+ logf (LOG_DEBUG, "dict_lookup: %s", term_dict);
+ if ((info = dict_lookup (zi->wordDict, term_dict)))
+ add_isam_p (info);
+ break;
+ case 1: /* right truncation */
+ strcat (term_dict, term_sub);
+ strcat (term_dict, ".*");
+ dict_lookup_grep (zi->wordDict, term_dict, 0, grep_handle);
+ break;
+ case 2: /* left truncation */
+ case 3: /* left&right truncation */
+ zi->errCode = 120;
+ return -1;
+ case 101: /* process # in term */
+ for (j = strlen(term_dict), i = 0; term_sub[i] && i < 2; i++)
+ term_dict[j++] = term_sub[i];
+ for (; term_sub[i]; i++)
+ if (term_sub[i] == '#')
+ {
+ term_dict[j++] = '.';
+ term_dict[j++] = '*';
+ }
+ else
+ term_dict[j++] = term_sub[i];
+ term_dict[j] = '\0';
+ dict_lookup_grep (zi->wordDict, term_dict, 0, grep_handle);
+ break;
+ case 102: /* regular expression */
+ strcat (term_dict, term_sub);
+ dict_lookup_grep (zi->wordDict, term_dict, 0, grep_handle);
+ break;
+ }
+ *isam_ps = isam_p_buf;
+ logf (LOG_DEBUG, "%d positions", isam_p_indx);
+ return 0;
+}
+
+static void trans_term (ZServerInfo *zi, Z_AttributesPlusTerm *zapt,
+ char *termz)
+{
+ size_t i, sizez;
+ Z_Term *term = zapt->term;
+
+ sizez = term->u.general->len;
+ if (sizez > IT_MAX_WORD)
+ sizez = IT_MAX_WORD;
+ for (i = 0; i < sizez; i++)
+ termz[i] = index_char_cvt (term->u.general->buf[i]);
+ termz[i] = '\0';
+}
+
+static RSET rpn_search_APT_relevance (ZServerInfo *zi,
+ Z_AttributesPlusTerm *zapt)
+{
+ rset_relevance_parms parms;
+ char termz[IT_MAX_WORD+1];
+ char term_sub[IT_MAX_WORD+1];
+ char *p0 = termz, *p1 = NULL;
+ Z_Term *term = zapt->term;
+
+ parms.key_size = sizeof(struct it_key);
+ parms.max_rec = 100;
+ parms.cmp = key_compare;
+ parms.is = zi->wordIsam;
+
+ if (term->which != Z_Term_general)
+ {
+ zi->errCode = 124;
+ return NULL;
+ }
+ trans_term (zi, zapt, termz);
+ isam_p_indx = 0; /* global, set by trunc_term - see below */
+ while (1)
+ {
+ if ((p1 = strchr (p0, ' ')))
+ {
+ memcpy (term_sub, p0, p1-p0);
+ term_sub[p1-p0] = '\0';
+ }
+ else
+ strcpy (term_sub, p0);
+ if (trunc_term (zi, zapt, term_sub, &parms.isam_positions))
+ return NULL;
+ if (!p1)
+ break;
+ p0 = p1+1;
+ }
+ parms.no_isam_positions = isam_p_indx;
+ if (isam_p_indx > 0)
+ return rset_create (rset_kind_relevance, &parms);
+ else
+ return rset_create (rset_kind_null, NULL);
+}
+
+static RSET rpn_search_APT_word (ZServerInfo *zi,
+ Z_AttributesPlusTerm *zapt)
+{
+ ISAM_P *isam_positions;
+ rset_isam_parms parms;
+
+ char termz[IT_MAX_WORD+1];
+ Z_Term *term = zapt->term;
+
+ if (term->which != Z_Term_general)
+ {
+ zi->errCode = 124;
+ return NULL;
+ }
+ trans_term (zi, zapt, termz);
+ isam_p_indx = 0; /* global, set by trunc_term - see below */
+ if (trunc_term (zi, zapt, termz, &isam_positions))
+ return NULL;
+ if (isam_p_indx < 1)
+ return rset_create (rset_kind_null, NULL);
+ else if (isam_p_indx == 1)
+ {
+ parms.is = zi->wordIsam;
+ parms.pos = *isam_positions;
+ return rset_create (rset_kind_isam, &parms);
+ }
+ else
+ return rset_trunc (zi->wordIsam, isam_positions, 0, isam_p_indx, 400);
+}
+
+static RSET rpn_search_APT_phrase (ZServerInfo *zi,
+ Z_AttributesPlusTerm *zapt)
+{
+ ISAM_P *isam_positions;
+ rset_isam_parms parms;
+
+ char termz[IT_MAX_WORD+1];
+ Z_Term *term = zapt->term;
+
+ if (term->which != Z_Term_general)
+ {
+ zi->errCode = 124;
+ return NULL;
+ }
+ trans_term (zi, zapt, termz);
+ isam_p_indx = 0; /* global, set by trunc_term - see below */
+ if (trunc_term (zi, zapt, termz, &isam_positions))
+ return NULL;
+ if (isam_p_indx != 1)
+ return rset_create (rset_kind_null, NULL);
+ parms.is = zi->wordIsam;
+ parms.pos = *isam_positions;
+ return rset_create (rset_kind_isam, &parms);
+}
+
+static RSET rpn_search_APT (ZServerInfo *zi, Z_AttributesPlusTerm *zapt)
+{
+ AttrType relation;
+ AttrType structure;
+ int relation_value, structure_value;
+
+ attr_init (&relation, zapt, 2);
+ attr_init (&structure, zapt, 4);
+
+ relation_value = attr_find (&relation);
+ structure_value = attr_find (&structure);
+ switch (structure_value)
+ {
+ case -1:
+ if (relation_value == 102) /* relevance relation */
+ return rpn_search_APT_relevance (zi, zapt);
+ return rpn_search_APT_word (zi, zapt);
+ case 1: /* phrase */
+ if (relation_value == 102) /* relevance relation */
+ return rpn_search_APT_relevance (zi, zapt);
+ return rpn_search_APT_phrase (zi, zapt);
+ break;
+ case 2: /* word */
+ if (relation_value == 102) /* relevance relation */
+ return rpn_search_APT_relevance (zi, zapt);
+ return rpn_search_APT_word (zi, zapt);
+ case 3: /* key */
+ break;
+ case 4: /* year */
+ break;
+ case 5: /* date - normalized */
+ break;
+ case 6: /* word list */
+ return rpn_search_APT_relevance (zi, zapt);
+ 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);
+ case 106: /* document-text */
+ return rpn_search_APT_relevance (zi, zapt);
+ case 107: /* local-number */
+ break;
+ case 108: /* string */
+ return rpn_search_APT_word (zi, zapt);
+ case 109: /* numeric string */
+ break;
+ }
+ zi->errCode = 118;