+ if ((term_tmp - term_dict) > IT_MAX_WORD)
+ break;
+ }
+ for (i = 0; term_component[i]; )
+ string_rel_add_char(&term_tmp, term_component, &i);
+ *term_tmp++ = ')';
+ *term_tmp = '\0';
+ break;
+ case 5:
+ if (!term_100 (zh->reg->zebra_maps, reg_type,
+ term_sub, term_component, space_split, term_dst))
+ return 0;
+ yaz_log(log_level_rpn, "Relation >");
+
+ *term_tmp++ = '(';
+ for (i = 0; term_component[i];)
+ {
+ int j = 0;
+
+ while (j < i)
+ string_rel_add_char(&term_tmp, term_component, &j);
+ *term_tmp++ = '[';
+
+ *term_tmp++ = '^';
+ *term_tmp++ = '-';
+ string_rel_add_char(&term_tmp, term_component, &i);
+
+ *term_tmp++ = ']';
+ *term_tmp++ = '.';
+ *term_tmp++ = '*';
+
+ *term_tmp++ = '|';
+
+ if ((term_tmp - term_dict) > IT_MAX_WORD)
+ break;
+ }
+ for (i = 0; term_component[i];)
+ string_rel_add_char(&term_tmp, term_component, &i);
+ *term_tmp++ = '.';
+ *term_tmp++ = '+';
+ *term_tmp++ = ')';
+ *term_tmp = '\0';
+ break;
+ case 4:
+ if (!term_100(zh->reg->zebra_maps, reg_type, term_sub,
+ term_component, space_split, term_dst))
+ return 0;
+ yaz_log(log_level_rpn, "Relation >=");
+
+ *term_tmp++ = '(';
+ for (i = 0; term_component[i];)
+ {
+ int j = 0;
+
+ if (i)
+ *term_tmp++ = '|';
+ while (j < i)
+ string_rel_add_char(&term_tmp, term_component, &j);
+ *term_tmp++ = '[';
+
+ if (term_component[i+1])
+ {
+ *term_tmp++ = '^';
+ *term_tmp++ = '-';
+ string_rel_add_char(&term_tmp, term_component, &i);
+ }
+ else
+ {
+ string_rel_add_char(&term_tmp, term_component, &i);
+ *term_tmp++ = '-';
+ }
+ *term_tmp++ = ']';
+ *term_tmp++ = '.';
+ *term_tmp++ = '*';
+
+ if ((term_tmp - term_dict) > IT_MAX_WORD)
+ break;
+ }
+ *term_tmp++ = ')';
+ *term_tmp = '\0';
+ break;
+ case 3:
+ case 102:
+ case -1:
+ yaz_log(log_level_rpn, "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, ")");
+ break;
+ default:
+ *error_code = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
+ return 0;
+ }
+ return 1;
+}
+
+static ZEBRA_RES 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,
+ struct ord_list **ol);
+
+static ZEBRA_RES term_limits_APT(ZebraHandle zh,
+ Z_AttributesPlusTerm *zapt,
+ zint *hits_limit_value,
+ const char **term_ref_id_str,
+ NMEM nmem)
+{
+ AttrType term_ref_id_attr;
+ AttrType hits_limit_attr;
+ int term_ref_id_int;
+
+ attr_init(&hits_limit_attr, zapt, 9);
+ *hits_limit_value = attr_find(&hits_limit_attr, NULL);
+
+ attr_init(&term_ref_id_attr, zapt, 10);
+ term_ref_id_int = attr_find_ex(&term_ref_id_attr, NULL, term_ref_id_str);
+ if (term_ref_id_int != -1)
+ {
+ char *res = nmem_malloc(nmem, 20);
+ sprintf(res, "%d", term_ref_id_int);
+ *term_ref_id_str = res;
+ }
+
+ /* no limit given ? */
+ if (*hits_limit_value == -1)
+ {
+ if (*term_ref_id_str)
+ {
+ /* use global if term_ref is present */
+ *hits_limit_value = zh->approx_limit;
+ }
+ else
+ {
+ /* no counting if term_ref is not present */
+ *hits_limit_value = 0;
+ }
+ }
+ else if (*hits_limit_value == 0)
+ {
+ /* 0 is the same as global limit */
+ *hits_limit_value = zh->approx_limit;
+ }
+ yaz_log(YLOG_DEBUG, "term_limits_APT ref_id=%s limit=" ZINT_FORMAT,
+ *term_ref_id_str ? *term_ref_id_str : "none",
+ *hits_limit_value);
+ return ZEBRA_OK;
+}
+
+static ZEBRA_RES 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,
+ RSET *rset,
+ struct rset_key_control *kc)
+{
+ ZEBRA_RES res;
+ struct ord_list *ol;
+ zint hits_limit_value;
+ const char *term_ref_id_str = 0;
+ *rset = 0;
+
+ term_limits_APT(zh, zapt, &hits_limit_value, &term_ref_id_str,
+ stream);
+ grep_info->isam_p_indx = 0;
+ res = string_term(zh, zapt, term_sub, attributeSet, stream, grep_info,
+ reg_type, complete_flag, num_bases, basenames,
+ term_dst, xpath_use, &ol);
+ if (res != ZEBRA_OK)
+ return res;
+ if (!*term_sub) /* no more terms ? */
+ return res;
+ yaz_log(log_level_rpn, "term: %s", term_dst);
+ *rset = 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,
+ kc, kc->scope, ol, reg_type, hits_limit_value,
+ term_ref_id_str);
+ if (!*rset)
+ return ZEBRA_FAIL;
+ return ZEBRA_OK;
+}
+
+static ZEBRA_RES 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,
+ struct ord_list **ol)
+{
+ 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 */
+
+ *ol = ord_list_create(stream);
+
+ rpn_char_map_prepare (zh->reg, reg_type, &rcmi);
+ attr_init(&use, zapt, 1);
+ use_value = attr_find_ex(&use, &curAttributeSet, &use_string);
+ yaz_log(log_level_rpn, "string_term, use value %d", use_value);
+ attr_init(&truncation, zapt, 5);
+ truncation_value = attr_find(&truncation, NULL);
+ yaz_log(log_level_rpn, "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++)
+ {
+ int ord = -1;
+ int attr_ok = 0;
+ int regex_range = 0;
+ int init_pos = 0;
+ attent attp;
+ data1_local_attribute id_xpath_attr;