+ }
+ *term_tmp++ = ')';
+ *term_tmp = '\0';
+ break;
+ case 3:
+ default:
+ logf (LOG_DEBUG, "Relation =");
+ if (!term_100 (zh->reg->zebra_maps, reg_type, term_sub,
+ term_component, space_split, term_dst))
+ return 0;
+ strcat (term_tmp, "(");
+ strcat (term_tmp, term_component);
+ strcat (term_tmp, ")");
+ }
+ return 1;
+}
+
+static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt,
+ const char **term_sub,
+ oid_value attributeSet, NMEM stream,
+ struct grep_info *grep_info,
+ int reg_type, int complete_flag,
+ int num_bases, char **basenames,
+ char *term_dst, int xpath_use);
+
+static RSET term_trunc (ZebraHandle zh, Z_AttributesPlusTerm *zapt,
+ const char **term_sub,
+ oid_value attributeSet, NMEM stream,
+ struct grep_info *grep_info,
+ int reg_type, int complete_flag,
+ int num_bases, char **basenames,
+ char *term_dst,
+ const char *rank_type, int xpath_use,
+ NMEM rset_nmem)
+{
+ int r;
+ grep_info->isam_p_indx = 0;
+ r = string_term (zh, zapt, term_sub, attributeSet, stream, grep_info,
+ reg_type, complete_flag, num_bases, basenames,
+ term_dst, xpath_use);
+ if (r < 1)
+ return 0;
+ logf (LOG_DEBUG, "term: %s", term_dst);
+ return rset_trunc (zh, grep_info->isam_p_buf,
+ grep_info->isam_p_indx, term_dst,
+ strlen(term_dst), rank_type, 1 /* preserve pos */,
+ zapt->term->which, rset_nmem,key_it_ctrl);
+}
+
+
+static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt,
+ const char **term_sub,
+ oid_value attributeSet, NMEM stream,
+ struct grep_info *grep_info,
+ int reg_type, int complete_flag,
+ int num_bases, char **basenames,
+ char *term_dst, int xpath_use)
+{
+ char term_dict[2*IT_MAX_WORD+4000];
+ int j, r, base_no;
+ AttrType truncation;
+ int truncation_value;
+ AttrType use;
+ int use_value;
+ const char *use_string = 0;
+ oid_value curAttributeSet = attributeSet;
+ const char *termp;
+ struct rpn_char_map_info rcmi;
+ int space_split = complete_flag ? 0 : 1;
+
+ int bases_ok = 0; /* no of databases with OK attribute */
+ int errCode = 0; /* err code (if any is not OK) */
+ char *errString = 0; /* addinfo */
+
+ rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
+ attr_init (&use, zapt, 1);
+ use_value = attr_find_ex (&use, &curAttributeSet, &use_string);
+ logf (LOG_DEBUG, "string_term, use value %d", use_value);
+ attr_init (&truncation, zapt, 5);
+ truncation_value = attr_find (&truncation, NULL);
+ logf (LOG_DEBUG, "truncation value %d", truncation_value);
+
+ if (use_value == -1) /* no attribute - assumy "any" */
+ use_value = 1016;
+ for (base_no = 0; base_no < num_bases; base_no++)
+ {
+ attent attp;
+ data1_local_attribute id_xpath_attr;
+ data1_local_attribute *local_attr;
+ int max_pos, prefix_len = 0;
+
+ termp = *term_sub;
+
+ if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
+ {
+ zh->errCode = 109; /* Database unavailable */
+ zh->errString = basenames[base_no];
+ return -1;
+ }
+ if (xpath_use > 0 && use_value == -2)
+ {
+ use_value = xpath_use;
+ attp.local_attributes = &id_xpath_attr;
+ attp.attset_ordinal = VAL_IDXPATH;
+ id_xpath_attr.next = 0;
+ id_xpath_attr.local = use_value;
+ }
+ else if (curAttributeSet == VAL_IDXPATH)
+ {
+ attp.local_attributes = &id_xpath_attr;
+ attp.attset_ordinal = VAL_IDXPATH;
+ id_xpath_attr.next = 0;
+ id_xpath_attr.local = use_value;
+ }
+ else
+ {
+ if ((r=att_getentbyatt (zh, &attp, curAttributeSet, use_value,
+ use_string)))
+ {
+ logf (LOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
+ curAttributeSet, use_value, r);
+ if (r == -1)
+ {
+ /* set was found, but value wasn't defined */
+ errCode = 114;
+ if (use_string)
+ errString = nmem_strdup(stream, use_string);
+ else
+ {
+ char val_str[32];
+ sprintf (val_str, "%d", use_value);
+ errString = nmem_strdup (stream, val_str);
+ }
+ }
+ else
+ {
+ int oid[OID_SIZE];
+ struct oident oident;
+
+ oident.proto = PROTO_Z3950;
+ oident.oclass = CLASS_ATTSET;
+ oident.value = curAttributeSet;
+ oid_ent_to_oid (&oident, oid);
+
+ errCode = 121;
+ errString = nmem_strdup (stream, oident.desc);
+ }
+ continue;
+ }
+ }
+ for (local_attr = attp.local_attributes; local_attr;
+ local_attr = local_attr->next)
+ {
+ int ord;
+ char ord_buf[32];
+ int i, ord_len;
+
+ ord = zebraExplain_lookupSU (zh->reg->zei, attp.attset_ordinal,
+ local_attr->local);
+ if (ord < 0)
+ continue;
+ if (prefix_len)
+ term_dict[prefix_len++] = '|';
+ else
+ term_dict[prefix_len++] = '(';
+
+ ord_len = key_SU_encode (ord, ord_buf);
+ for (i = 0; i<ord_len; i++)
+ {
+ term_dict[prefix_len++] = 1;
+ term_dict[prefix_len++] = ord_buf[i];
+ }
+ }
+ if (!prefix_len)
+ {
+#if 1
+ bases_ok++;
+#else
+ char val_str[32];
+ sprintf (val_str, "%d", use_value);
+ errCode = 114;
+ errString = nmem_strdup (stream, val_str);
+#endif
+ continue;
+ }
+ bases_ok++; /* this has OK attributes */
+
+ term_dict[prefix_len++] = ')';
+ term_dict[prefix_len++] = 1;
+ term_dict[prefix_len++] = reg_type;
+ logf (LOG_DEBUG, "reg_type = %d", term_dict[prefix_len-1]);
+ term_dict[prefix_len] = '\0';
+ j = prefix_len;
+ switch (truncation_value)
+ {
+ case -1: /* not specified */
+ case 100: /* do not truncate */
+ if (!string_relation (zh, zapt, &termp, term_dict,
+ attributeSet,
+ reg_type, space_split, term_dst))
+ return 0;
+ logf (LOG_LOG, "dict_lookup_grep: %s", term_dict+prefix_len);
+ r = dict_lookup_grep (zh->reg->dict, term_dict, 0,
+ grep_info, &max_pos, 0, grep_handle);
+ if (r)
+ logf (LOG_WARN, "dict_lookup_grep fail %d", r);
+ break;
+ case 1: /* right truncation */
+ term_dict[j++] = '(';
+ if (!term_100 (zh->reg->zebra_maps, reg_type,
+ &termp, term_dict + j, space_split, term_dst))
+ return 0;
+ strcat (term_dict, ".*)");
+ dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info,
+ &max_pos, 0, grep_handle);
+ break;
+ case 2: /* keft truncation */
+ term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
+ if (!term_100 (zh->reg->zebra_maps, reg_type,
+ &termp, term_dict + j, space_split, term_dst))
+ return 0;
+ strcat (term_dict, ")");
+ dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info,
+ &max_pos, 0, grep_handle);
+ break;
+ case 3: /* left&right truncation */
+ term_dict[j++] = '('; term_dict[j++] = '.'; term_dict[j++] = '*';
+ if (!term_100 (zh->reg->zebra_maps, reg_type,
+ &termp, term_dict + j, space_split, term_dst))
+ return 0;
+ strcat (term_dict, ".*)");
+ dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info,
+ &max_pos, 0, grep_handle);
+ break;
+ zh->errCode = 120;
+ return -1;
+ case 101: /* process # in term */
+ term_dict[j++] = '(';
+ if (!term_101 (zh->reg->zebra_maps, reg_type,
+ &termp, term_dict + j, space_split, term_dst))
+ return 0;
+ strcat (term_dict, ")");
+ r = dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info,
+ &max_pos, 0, grep_handle);
+ if (r)
+ logf (LOG_WARN, "dict_lookup_grep err, trunc=#: %d", r);
+ break;
+ case 102: /* Regexp-1 */
+ term_dict[j++] = '(';
+ if (!term_102 (zh->reg->zebra_maps, reg_type,
+ &termp, term_dict + j, space_split, term_dst))
+ return 0;
+ strcat (term_dict, ")");
+ logf (LOG_DEBUG, "Regexp-1 tolerance=%d", r);
+ r = dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info,
+ &max_pos, 0, grep_handle);
+ if (r)
+ logf (LOG_WARN, "dict_lookup_grep err, trunc=regular: %d",
+ r);
+ break;
+ case 103: /* Regexp-2 */
+ r = 1;
+ term_dict[j++] = '(';
+ if (!term_103 (zh->reg->zebra_maps, reg_type,
+ &termp, term_dict + j, &r, space_split, term_dst))
+ return 0;
+ strcat (term_dict, ")");
+ logf (LOG_DEBUG, "Regexp-2 tolerance=%d", r);
+ r = dict_lookup_grep (zh->reg->dict, term_dict, r, grep_info,
+ &max_pos, 2, grep_handle);
+ if (r)
+ logf (LOG_WARN, "dict_lookup_grep err, trunc=eregular: %d",
+ r);
+ break;
+ case 104: /* process # and ! in term */
+ term_dict[j++] = '(';
+ if (!term_104 (zh->reg->zebra_maps, reg_type,
+ &termp, term_dict + j, space_split, term_dst))
+ return 0;
+ strcat (term_dict, ")");
+ r = dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info,
+ &max_pos, 0, grep_handle);
+ if (r)
+ logf (LOG_WARN, "dict_lookup_grep err, trunc=#/!: %d", r);
+ break;
+ case 105: /* process * and ! in term */
+ term_dict[j++] = '(';
+ if (!term_105 (zh->reg->zebra_maps, reg_type,
+ &termp, term_dict + j, space_split, term_dst, 1))
+ return 0;
+ strcat (term_dict, ")");
+ r = dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info,
+ &max_pos, 0, grep_handle);
+ if (r)
+ logf (LOG_WARN, "dict_lookup_grep err, trunc=*/!: %d", r);
+ break;
+ case 106: /* process * and ! in term */
+ term_dict[j++] = '(';
+ if (!term_105 (zh->reg->zebra_maps, reg_type,
+ &termp, term_dict + j, space_split, term_dst, 0))
+ return 0;
+ strcat (term_dict, ")");
+ r = dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info,
+ &max_pos, 0, grep_handle);
+ if (r)
+ logf (LOG_WARN, "dict_lookup_grep err, trunc=*/!: %d", r);
+ break;
+ }
+ }
+ if (!bases_ok)
+ {
+ zh->errCode = errCode;
+ zh->errString = errString;
+ return -1;
+ }
+ *term_sub = termp;
+ logf (LOG_DEBUG, "%d positions", grep_info->isam_p_indx);
+ return 1;
+}
+
+
+/* convert APT search term to UTF8 */
+static int zapt_term_to_utf8 (ZebraHandle zh, Z_AttributesPlusTerm *zapt,
+ char *termz)
+{
+ size_t sizez;
+ Z_Term *term = zapt->term;
+
+ switch (term->which)
+ {
+ case Z_Term_general:
+ if (zh->iconv_to_utf8 != 0)
+ {
+ char *inbuf = term->u.general->buf;
+ size_t inleft = term->u.general->len;
+ char *outbuf = termz;
+ size_t outleft = IT_MAX_WORD-1;
+ size_t ret;
+
+ ret = yaz_iconv(zh->iconv_to_utf8, &inbuf, &inleft,
+ &outbuf, &outleft);
+ if (ret == (size_t)(-1))
+ {
+ ret = yaz_iconv(zh->iconv_to_utf8, 0, 0, 0, 0);
+ zh->errCode = 125;
+ return -1;
+ }
+ *outbuf = 0;
+ }
+ else
+ {
+ sizez = term->u.general->len;
+ if (sizez > IT_MAX_WORD-1)
+ sizez = IT_MAX_WORD-1;
+ memcpy (termz, term->u.general->buf, sizez);
+ termz[sizez] = '\0';
+ }
+ break;
+ case Z_Term_characterString:
+ sizez = strlen(term->u.characterString);
+ if (sizez > IT_MAX_WORD-1)
+ sizez = IT_MAX_WORD-1;
+ memcpy (termz, term->u.characterString, sizez);
+ termz[sizez] = '\0';
+ break;
+ default:
+ zh->errCode = 124;
+ return -1;
+ }
+ return 0;
+}
+
+/* convert APT SCAN term to internal cmap */
+static int trans_scan_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt,
+ char *termz, int reg_type)
+{
+ char termz0[IT_MAX_WORD];
+
+ if (zapt_term_to_utf8(zh, zapt, termz0))
+ return -1; /* error */
+ else
+ {
+ const char **map;
+ const char *cp = (const char *) termz0;
+ const char *cp_end = cp + strlen(cp);
+ const char *src;
+ int i = 0;
+ const char *space_map = NULL;
+ int len;
+
+ while ((len = (cp_end - cp)) > 0)
+ {
+ map = zebra_maps_input (zh->reg->zebra_maps, reg_type, &cp, len);
+ if (**map == *CHR_SPACE)
+ space_map = *map;
+ else
+ {
+ if (i && space_map)
+ for (src = space_map; *src; src++)
+ termz[i++] = *src;
+ space_map = NULL;
+ for (src = *map; *src; src++)
+ termz[i++] = *src;
+ }
+ }
+ termz[i] = '\0';
+ }
+ return 0;
+}
+
+char *normalize_term(ZebraHandle zh, Z_AttributesPlusTerm *zapt,
+ const char *termz, NMEM stream, unsigned reg_id)
+{
+ WRBUF wrbuf = 0;
+ AttrType truncation;
+ int truncation_value;
+ char *ex_list = 0;
+
+ attr_init (&truncation, zapt, 5);
+ truncation_value = attr_find (&truncation, NULL);
+
+ switch (truncation_value)
+ {
+ default:
+ ex_list = "";
+ break;
+ case 101:
+ ex_list = "#";
+ break;
+ case 102:
+ case 103:
+ ex_list = 0;
+ break;
+ case 104:
+ ex_list = "!#";
+ break;
+ case 105:
+ ex_list = "!*";
+ break;
+ }
+ if (ex_list)
+ wrbuf = zebra_replace(zh->reg->zebra_maps, reg_id, ex_list,
+ termz, strlen(termz));
+ if (!wrbuf)
+ return nmem_strdup(stream, termz);
+ else
+ {
+ char *buf = (char*) nmem_malloc (stream, wrbuf_len(wrbuf)+1);
+ memcpy (buf, wrbuf_buf(wrbuf), wrbuf_len(wrbuf));
+ buf[wrbuf_len(wrbuf)] = '\0';
+ return buf;
+ }
+}
+
+static void grep_info_delete (struct grep_info *grep_info)
+{
+#ifdef TERM_COUNT
+ xfree(grep_info->term_no);
+#endif
+ xfree (grep_info->isam_p_buf);
+}
+
+static int grep_info_prepare (ZebraHandle zh,
+ Z_AttributesPlusTerm *zapt,
+ struct grep_info *grep_info,
+ int reg_type,
+ NMEM stream)
+{
+ AttrType termset;
+ int termset_value_numeric;
+ const char *termset_value_string;
+
+#ifdef TERM_COUNT
+ grep_info->term_no = 0;
+#endif
+ grep_info->isam_p_size = 0;
+ grep_info->isam_p_buf = NULL;
+ grep_info->zh = zh;
+ grep_info->reg_type = reg_type;
+ grep_info->termset = 0;
+
+ if (!zapt)
+ return 0;
+ attr_init (&termset, zapt, 8);
+ termset_value_numeric =
+ attr_find_ex (&termset, NULL, &termset_value_string);
+ if (termset_value_numeric != -1)
+ {
+ char resname[32];
+ const char *termset_name = 0;
+ if (termset_value_numeric != -2)
+ {
+
+ sprintf (resname, "%d", termset_value_numeric);
+ termset_name = resname;
+ }
+ else
+ termset_name = termset_value_string;
+ logf (LOG_LOG, "creating termset set %s", termset_name);
+ grep_info->termset = resultSetAdd (zh, termset_name, 1);
+ if (!grep_info->termset)
+ {
+ zh->errCode = 128;
+ zh->errString = nmem_strdup (stream, termset_name);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+static RSET rpn_search_APT_phrase (ZebraHandle zh,
+ Z_AttributesPlusTerm *zapt,
+ const char *termz_org,
+ oid_value attributeSet,
+ NMEM stream,
+ int reg_type, int complete_flag,
+ const char *rank_type, int xpath_use,
+ int num_bases, char **basenames,
+ NMEM rset_nmem)
+{
+ char term_dst[IT_MAX_WORD+1];
+ RSET rset[60], result;
+ int rset_no = 0;
+ struct grep_info grep_info;
+ char *termz = normalize_term(zh, zapt, termz_org, stream, reg_type);
+ const char *termp = termz;
+
+ *term_dst = 0;
+ if (grep_info_prepare (zh, zapt, &grep_info, reg_type, stream))
+ return 0;
+ while (1)
+ {
+ logf (LOG_DEBUG, "APT_phrase termp=%s", termp);
+ rset[rset_no] = term_trunc (zh, zapt, &termp, attributeSet,
+ stream, &grep_info,
+ reg_type, complete_flag,
+ num_bases, basenames,
+ term_dst, rank_type,
+ xpath_use,rset_nmem);
+ if (!rset[rset_no])
+ break;
+ if (++rset_no >= (int) (sizeof(rset)/sizeof(*rset)))
+ break;
+ }
+ grep_info_delete (&grep_info);
+ if (rset_no == 0)
+ return rsnull_create (rset_nmem,key_it_ctrl);
+ else if (rset_no == 1)
+ return (rset[0]);
+ else
+ result = rsprox_create( rset_nmem, key_it_ctrl,
+ rset_no, rset,
+ 1 /* ordered */, 0 /* exclusion */,
+ 3 /* relation */, 1 /* distance */);
+ return result;
+}
+
+static RSET rpn_search_APT_or_list (ZebraHandle zh,
+ Z_AttributesPlusTerm *zapt,
+ const char *termz_org,
+ oid_value attributeSet,
+ NMEM stream,
+ int reg_type, int complete_flag,
+ const char *rank_type,
+ int xpath_use,
+ int num_bases, char **basenames,
+ NMEM rset_nmem)
+{
+ char term_dst[IT_MAX_WORD+1];
+ RSET rset[60];
+ int rset_no = 0;
+ struct grep_info grep_info;
+ char *termz = normalize_term(zh, zapt, termz_org, stream, reg_type);
+ const char *termp = termz;
+
+ if (grep_info_prepare (zh, zapt, &grep_info, reg_type, stream))
+ return 0;
+ while (1)
+ {
+ logf (LOG_DEBUG, "APT_or_list termp=%s", termp);
+ rset[rset_no] = term_trunc (zh, zapt, &termp, attributeSet,
+ stream, &grep_info,
+ reg_type, complete_flag,
+ num_bases, basenames,
+ term_dst, rank_type,
+ xpath_use,rset_nmem);
+ if (!rset[rset_no])
+ break;
+ if (++rset_no >= (int) (sizeof(rset)/sizeof(*rset)))
+ break;
+ }
+ grep_info_delete (&grep_info);
+ if (rset_no == 0)
+ return rsnull_create (rset_nmem,key_it_ctrl);
+ return rsmultior_create(rset_nmem, key_it_ctrl,
+ rset_no, rset);
+}
+
+static RSET rpn_search_APT_and_list (ZebraHandle zh,
+ Z_AttributesPlusTerm *zapt,
+ const char *termz_org,
+ oid_value attributeSet,
+ NMEM stream,
+ int reg_type, int complete_flag,
+ const char *rank_type,
+ int xpath_use,
+ int num_bases, char **basenames,
+ NMEM rset_nmem)
+{
+ char term_dst[IT_MAX_WORD+1];
+ RSET rset[60], result;
+ int i, rset_no = 0;
+ struct grep_info grep_info;
+ char *termz = normalize_term(zh, zapt, termz_org, stream, reg_type);
+ const char *termp = termz;
+
+ if (grep_info_prepare (zh, zapt, &grep_info, reg_type, stream))
+ return 0;
+ while (1)
+ {
+ logf (LOG_DEBUG, "APT_and_list termp=%s", termp);
+ rset[rset_no] = term_trunc (zh, zapt, &termp, attributeSet,
+ stream, &grep_info,
+ reg_type, complete_flag,
+ num_bases, basenames,
+ term_dst, rank_type,
+ xpath_use, rset_nmem);
+ if (!rset[rset_no])
+ break;
+ assert (rset[rset_no]);
+ if (++rset_no >= (int) (sizeof(rset)/sizeof(*rset)))
+ break;
+ }
+ grep_info_delete (&grep_info);
+ if (rset_no == 0)
+ return rsnull_create (rset_nmem,key_it_ctrl);
+ result = rset[0];
+ /* FIXME - Use a proper rsmultiand */
+ for (i = 1; i<rset_no; i++)
+ result= rsbool_create_and(rset_nmem,key_it_ctrl,
+ result, rset[i] );
+ return result;
+}
+
+static int numeric_relation (ZebraHandle zh, Z_AttributesPlusTerm *zapt,
+ const char **term_sub,
+ char *term_dict,
+ oid_value attributeSet,
+ struct grep_info *grep_info,
+ int *max_pos,
+ int reg_type,
+ char *term_dst)
+{
+ AttrType relation;
+ int relation_value;
+ int term_value;
+ int r;
+ char *term_tmp = term_dict + strlen(term_dict);
+
+ attr_init (&relation, zapt, 2);
+ relation_value = attr_find (&relation, NULL);
+
+ logf (LOG_DEBUG, "numeric relation value=%d", relation_value);
+
+ if (!term_100 (zh->reg->zebra_maps, reg_type, term_sub, term_tmp, 1,
+ term_dst))
+ return 0;
+ term_value = atoi (term_tmp);
+ switch (relation_value)
+ {
+ case 1:
+ logf (LOG_DEBUG, "Relation <");
+ gen_regular_rel (term_tmp, term_value-1, 1);
+ break;
+ case 2:
+ logf (LOG_DEBUG, "Relation <=");
+ gen_regular_rel (term_tmp, term_value, 1);
+ break;
+ case 4:
+ logf (LOG_DEBUG, "Relation >=");
+ gen_regular_rel (term_tmp, term_value, 0);
+ break;
+ case 5:
+ logf (LOG_DEBUG, "Relation >");
+ gen_regular_rel (term_tmp, term_value+1, 0);
+ break;
+ case 3:
+ default:
+ logf (LOG_DEBUG, "Relation =");
+ sprintf (term_tmp, "(0*%d)", term_value);
+ }
+ logf (LOG_DEBUG, "dict_lookup_grep: %s", term_tmp);
+ r = dict_lookup_grep (zh->reg->dict, term_dict, 0, grep_info, max_pos,
+ 0, grep_handle);
+ if (r)
+ logf (LOG_WARN, "dict_lookup_grep fail, rel=gt: %d", r);
+ logf (LOG_DEBUG, "%d positions", grep_info->isam_p_indx);
+ return 1;
+}
+
+static int numeric_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt,
+ const char **term_sub,
+ oid_value attributeSet, struct grep_info *grep_info,
+ int reg_type, int complete_flag,
+ int num_bases, char **basenames,
+ char *term_dst, int xpath_use, NMEM stream)
+{
+ char term_dict[2*IT_MAX_WORD+2];
+ int r, base_no;
+ AttrType use;
+ int use_value;
+ const char *use_string = 0;
+ oid_value curAttributeSet = attributeSet;
+ const char *termp;
+ struct rpn_char_map_info rcmi;
+
+ int bases_ok = 0; /* no of databases with OK attribute */
+ int errCode = 0; /* err code (if any is not OK) */
+ char *errString = 0; /* addinfo */
+
+ rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
+ attr_init (&use, zapt, 1);
+ use_value = attr_find_ex (&use, &curAttributeSet, &use_string);
+
+ if (use_value == -1)
+ use_value = 1016;
+
+ for (base_no = 0; base_no < num_bases; base_no++)
+ {
+ attent attp;
+ data1_local_attribute id_xpath_attr;
+ data1_local_attribute *local_attr;
+ int max_pos, prefix_len = 0;
+
+ termp = *term_sub;
+ if (use_value == -2) /* string attribute (assume IDXPATH/any) */
+ {
+ use_value = xpath_use;
+ attp.local_attributes = &id_xpath_attr;
+ attp.attset_ordinal = VAL_IDXPATH;
+ id_xpath_attr.next = 0;
+ id_xpath_attr.local = use_value;
+ }
+ else if (curAttributeSet == VAL_IDXPATH)
+ {
+ attp.local_attributes = &id_xpath_attr;
+ attp.attset_ordinal = VAL_IDXPATH;
+ id_xpath_attr.next = 0;
+ id_xpath_attr.local = use_value;
+ }
+ else
+ {
+ if ((r=att_getentbyatt (zh, &attp, curAttributeSet, use_value,
+ use_string)))
+ {
+ logf (LOG_DEBUG, "att_getentbyatt fail. set=%d use=%d r=%d",
+ curAttributeSet, use_value, r);
+ if (r == -1)
+ {
+ char val_str[32];
+ sprintf (val_str, "%d", use_value);
+ errString = nmem_strdup (stream, val_str);
+ errCode = 114;
+ }
+ else
+ errCode = 121;
+ continue;
+ }
+ }
+ if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no]))
+ {
+ zh->errCode = 109; /* Database unavailable */
+ zh->errString = basenames[base_no];
+ return -1;
+ }
+ for (local_attr = attp.local_attributes; local_attr;
+ local_attr = local_attr->next)
+ {
+ int ord;
+ char ord_buf[32];
+ int i, ord_len;
+
+ ord = zebraExplain_lookupSU (zh->reg->zei, attp.attset_ordinal,
+ local_attr->local);
+ if (ord < 0)
+ continue;
+ if (prefix_len)
+ term_dict[prefix_len++] = '|';
+ else
+ term_dict[prefix_len++] = '(';
+
+ ord_len = key_SU_encode (ord, ord_buf);
+ for (i = 0; i<ord_len; i++)
+ {
+ term_dict[prefix_len++] = 1;
+ term_dict[prefix_len++] = ord_buf[i];