X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=index%2Fzrpn.c;h=80d66c76b4f31362d946d2a526ac1670c625fb06;hb=cefaccf49b16e9ae79f53d963a03ad40f332de0f;hp=88dbefcdcbc924e2ebe3ee245ff900128d990759;hpb=47ea1fc957c7b97bb30a26698f072109cae275e4;p=idzebra-moved-to-github.git diff --git a/index/zrpn.c b/index/zrpn.c index 88dbefc..80d66c7 100644 --- a/index/zrpn.c +++ b/index/zrpn.c @@ -1,10 +1,26 @@ -/* - * Copyright (C) 1995-2002, Index Data - * All rights reserved. - * Sebastian Hammer, Adam Dickmeiss - * - * $Id: zrpn.c,v 1.117 2002-07-25 13:06:43 adam Exp $ - */ +/* $Id: zrpn.c,v 1.125 2002-10-03 10:16:23 adam Exp $ + Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002 + Index Data Aps + +This file is part of the Zebra server. + +Zebra is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +Zebra is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Zebra; see the file LICENSE.zebra. If not, write to the +Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. +*/ + + #include #include #ifdef WIN32 @@ -30,7 +46,20 @@ struct rpn_char_map_info { static const char **rpn_char_map_handler (void *vp, const char **from, int len) { struct rpn_char_map_info *p = (struct rpn_char_map_info *) vp; - return zebra_maps_input (p->zm, p->reg_type, from, len); + const char **out = zebra_maps_input (p->zm, p->reg_type, from, len); +#if 0 + if (out && *out) + { + const char *outp = *out; + yaz_log (LOG_LOG, "---"); + while (*outp) + { + yaz_log (LOG_LOG, "%02X", *outp); + outp++; + } + } +#endif + return out; } static void rpn_char_map_prepare (struct zebra_register *reg, int reg_type, @@ -151,17 +180,18 @@ struct grep_info { static void term_untrans (ZebraHandle zh, int reg_type, char *dst, const char *src) { + int len = 0; while (*src) { const char *cp = zebra_maps_output (zh->reg->zebra_maps, reg_type, &src); - if (!cp) - *dst++ = *src++; + if (!cp && len < IT_MAX_WORD-1) + dst[len++] = *src++; else - while (*cp) - *dst++ = *cp++; + while (*cp && len < IT_MAX_WORD-1) + dst[len++] = *cp++; } - *dst = '\0'; + dst[len] = '\0'; } static void add_isam_p (const char *name, const char *info, @@ -204,7 +234,7 @@ static void add_isam_p (const char *name, const char *info, { const char *db; int set, use; - char term_tmp[512]; + char term_tmp[IT_MAX_WORD]; int su_code = 0; int len = key_SU_decode (&su_code, name); @@ -250,7 +280,7 @@ static int term_pre (ZebraMaps zebra_maps, int reg_type, const char **src, return *s0; } -#define REGEX_CHARS "[]()|.*+!" +#define REGEX_CHARS " []()|.*+?!" /* term_100: handle term, where trunc=none (no operators at all) */ static int term_100 (ZebraMaps zebra_maps, int reg_type, @@ -805,7 +835,7 @@ static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, struct grep_info *grep_info, int reg_type, int complete_flag, int num_bases, char **basenames, - char *term_dst); + char *term_dst, int xpath_use); static RSET term_trunc (ZebraHandle zh, Z_AttributesPlusTerm *zapt, const char **term_sub, @@ -814,13 +844,13 @@ static RSET term_trunc (ZebraHandle zh, Z_AttributesPlusTerm *zapt, int reg_type, int complete_flag, int num_bases, char **basenames, char *term_dst, - const char *rank_type) + const char *rank_type, int xpath_use) { 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); + term_dst, xpath_use); if (r < 1) return 0; logf (LOG_DEBUG, "term: %s", term_dst); @@ -837,7 +867,7 @@ static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, struct grep_info *grep_info, int reg_type, int complete_flag, int num_bases, char **basenames, - char *term_dst) + char *term_dst, int xpath_use) { char term_dict[2*IT_MAX_WORD+4000]; int j, r, base_no; @@ -861,9 +891,6 @@ static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, if (use_value == -1) /* no attribute - assumy "any" */ use_value = 1016; - if (use_value == -2) /* string attribute - assumy "any" */ - use_value = 1016; - for (base_no = 0; base_no < num_bases; base_no++) { attent attp; @@ -879,10 +906,18 @@ static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, zh->errString = basenames[base_no]; return -1; } - if (curAttributeSet == VAL_IDXPATH) + 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 = curAttributeSet; + attp.attset_ordinal = VAL_IDXPATH; id_xpath_attr.next = 0; id_xpath_attr.local = use_value; } @@ -896,7 +931,7 @@ static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, { /* set was found, but value wasn't defined */ char val_str[32]; - sprintf (val_str, "%d", use_value); + sprintf (val_str, "%d (1)", use_value); zh->errCode = 114; zh->errString = nmem_strdup (stream, val_str); } @@ -942,7 +977,7 @@ static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, if (!prefix_len) { char val_str[32]; - sprintf (val_str, "%d", use_value); + sprintf (val_str, "%d (2)", use_value); zh->errCode = 114; zh->errString = nmem_strdup (stream, val_str); return -1; @@ -961,11 +996,11 @@ static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, attributeSet, reg_type, space_split, term_dst)) return 0; - logf (LOG_DEBUG, "dict_lookup_grep: %s", term_dict+prefix_len); + 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, rel=gt: %d", r); + logf (LOG_WARN, "dict_lookup_grep fail %d", r); break; case 1: /* right truncation */ term_dict[j++] = '('; @@ -1075,8 +1110,9 @@ static int string_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, } -static int trans_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, - char *termz) +/* 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; @@ -1084,8 +1120,7 @@ static int trans_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, switch (term->which) { case Z_Term_general: -#if HAVE_ICONV_H - if (zh->iconv_to_utf8 != (iconv_t)(-1)) + if (zh->iconv_to_utf8 != 0) { char *inbuf = term->u.general->buf; size_t inleft = term->u.general->len; @@ -1093,24 +1128,24 @@ static int trans_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, size_t outleft = IT_MAX_WORD-1; size_t ret; - yaz_log (LOG_DEBUG, "converting general from ISO-8859-1"); - ret = iconv(zh->iconv_to_utf8, &inbuf, &inleft, + ret = yaz_iconv(zh->iconv_to_utf8, &inbuf, &inleft, &outbuf, &outleft); if (ret == (size_t)(-1)) { - ret = iconv(zh->iconv_to_utf8, 0, 0, 0, 0); + ret = yaz_iconv(zh->iconv_to_utf8, 0, 0, 0, 0); zh->errCode = 125; return -1; } *outbuf = 0; - return 0; } -#endif - 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'; + 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); @@ -1121,38 +1156,47 @@ static int trans_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, break; default: zh->errCode = 124; + return -1; } return 0; } -static void trans_scan_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, - char *termz, int reg_type) +/* convert APT SCAN term to internal cmap */ +static int trans_scan_term (ZebraHandle zh, Z_AttributesPlusTerm *zapt, + char *termz, int reg_type) { - Z_Term *term = zapt->term; - const char **map; - const char *cp = (const char *) term->u.general->buf; - const char *cp_end = cp + term->u.general->len; - const char *src; - int i = 0; - const char *space_map = NULL; - int len; - - while ((len = (cp_end - cp)) > 0) + char termz0[IT_MAX_WORD]; + + if (zapt_term_to_utf8(zh, zapt, termz0)) + return -1; /* error */ + else { - map = zebra_maps_input (zh->reg->zebra_maps, reg_type, &cp, len); - if (**map == *CHR_SPACE) - space_map = *map; - 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) { - if (i && space_map) - for (src = space_map; *src; src++) + 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; - space_map = NULL; - for (src = *map; *src; src++) - termz[i++] = *src; + } } + termz[i] = '\0'; } - termz[i] = '\0'; + return 0; } static RSET rpn_prox (ZebraHandle zh, RSET *rset, int rset_no, @@ -1457,6 +1501,8 @@ static int grep_info_prepare (ZebraHandle 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); @@ -1491,7 +1537,7 @@ static RSET rpn_search_APT_phrase (ZebraHandle zh, oid_value attributeSet, NMEM stream, int reg_type, int complete_flag, - const char *rank_type, + const char *rank_type, int xpath_use, int num_bases, char **basenames) { char term_dst[IT_MAX_WORD+1]; @@ -1511,7 +1557,8 @@ static RSET rpn_search_APT_phrase (ZebraHandle zh, stream, &grep_info, reg_type, complete_flag, num_bases, basenames, - term_dst, rank_type); + term_dst, rank_type, + xpath_use); if (!rset[rset_no]) break; if (++rset_no >= (int) (sizeof(rset)/sizeof(*rset))) @@ -1541,6 +1588,7 @@ static RSET rpn_search_APT_or_list (ZebraHandle zh, NMEM stream, int reg_type, int complete_flag, const char *rank_type, + int xpath_use, int num_bases, char **basenames) { char term_dst[IT_MAX_WORD+1]; @@ -1559,7 +1607,8 @@ static RSET rpn_search_APT_or_list (ZebraHandle zh, stream, &grep_info, reg_type, complete_flag, num_bases, basenames, - term_dst, rank_type); + term_dst, rank_type, + xpath_use); if (!rset[rset_no]) break; if (++rset_no >= (int) (sizeof(rset)/sizeof(*rset))) @@ -1594,7 +1643,8 @@ static RSET rpn_search_APT_and_list (ZebraHandle zh, oid_value attributeSet, NMEM stream, int reg_type, int complete_flag, - const char *rank_type, + const char *rank_type, + int xpath_use, int num_bases, char **basenames) { char term_dst[IT_MAX_WORD+1]; @@ -1613,7 +1663,8 @@ static RSET rpn_search_APT_and_list (ZebraHandle zh, stream, &grep_info, reg_type, complete_flag, num_bases, basenames, - term_dst, rank_type); + term_dst, rank_type, + xpath_use); if (!rset[rset_no]) break; assert (rset[rset_no]); @@ -1977,131 +2028,324 @@ static RSET rpn_sort_spec (ZebraHandle zh, Z_AttributesPlusTerm *zapt, return rset_create (rset_kind_null, &parms); } -static RSET rpn_search_xpath (ZebraHandle zh, Z_AttributesPlusTerm *zapt, - oid_value attributeSet, - int num_bases, char **basenames, - NMEM stream, const char *rank_type, RSET rset) +struct xpath_predicate { + int which; + union { +#define XPATH_PREDICATE_RELATION 1 + struct { + char *name; + char *op; + char *value; + } relation; +#define XPATH_PREDICATE_BOOLEAN 2 + struct { + const char *op; + struct xpath_predicate *left; + struct xpath_predicate *right; + } boolean; + } u; +}; + +struct xpath_location_step { + char *part; + struct xpath_predicate *predicate; +}; + +static int parse_xpath(ZebraHandle zh, Z_AttributesPlusTerm *zapt, + oid_value attributeSet, + struct xpath_location_step *xpath, NMEM mem) { + oid_value curAttributeSet = attributeSet; AttrType use; const char *use_string = 0; - oid_value curAttributeSet = attributeSet; - char term_dict[2048]; - int base_no; - int reg_type = '0'; - struct grep_info grep_info; - - yaz_log (LOG_LOG, "rpn_search_xpath 1"); + const char *cp; + int no = 0; + attr_init (&use, zapt, 1); attr_find_ex (&use, &curAttributeSet, &use_string); - if (curAttributeSet != VAL_IDXPATH) + if (!use_string || *use_string != '/') + return -1; + cp = use_string; + while (*cp) { - yaz_log (LOG_LOG, "rpn_search_xpath - not 1"); - return rset; + int i = 0; + while (*cp && !strchr("/[",*cp)) + { + i++; + cp++; + } + xpath[no].predicate = 0; + xpath[no].part = nmem_malloc (mem, i+1); + memcpy (xpath[no].part, cp - i, i); + xpath[no].part[i] = 0; + + if (*cp == '[') + { + struct xpath_predicate *p = xpath[no].predicate = + nmem_malloc (mem, sizeof(struct xpath_predicate)); + + p->which = XPATH_PREDICATE_RELATION; + cp++; + while (*cp == ' ') + cp++; + + for (i = 0; *cp && !strchr("><=] ", *cp); i++) + cp++; + p->u.relation.name = nmem_malloc (mem, i+1); + memcpy (p->u.relation.name, cp - i, i); + p->u.relation.name[i] = 0; + while (*cp == ' ') + cp++; + if (*cp != ']') + { + for (i = 0; *cp && strchr(">=u.relation.op = nmem_malloc (mem, i+1); + if (i) + memcpy (p->u.relation.op, cp - i, i); + p->u.relation.op[i] = 0; + + while (*cp == ' ') + cp++; + + if (strchr("\"'", *cp)) + { + cp++; + for (i = 0; *cp && !strchr("\"'", *cp); i++) + cp++; + + p->u.relation.value = nmem_malloc (mem, i+1); + if (i) + memcpy (p->u.relation.value, cp - i, i); + p->u.relation.value[i] = 0; + yaz_log (LOG_LOG, "value=%s", p->u.relation.value); + + cp++; + } + else + { + for (i = 0; *cp && !strchr(" ]", *cp); i++) + cp++; + p->u.relation.value = nmem_malloc (mem, i+1); + if (i) + memcpy (p->u.relation.value, cp - i, i); + p->u.relation.value[i] = 0; + } + while (*cp == ' ') + cp++; + } + if (*cp == ']') + cp++; + } /* end of ] predicate */ + no++; + if (*cp != '/') + break; + cp++; + } + return no; +} + + +static RSET xpath_trunc(ZebraHandle zh, NMEM stream, + int reg_type, const char *term, int use, + oid_value curAttributeSet) +{ + RSET rset; + struct grep_info grep_info; + char term_dict[2048]; + char ord_buf[32]; + int prefix_len = 0; + int ord = zebraExplain_lookupSU (zh->reg->zei, curAttributeSet, use); + int ord_len, i, r, max_pos; + int term_type = Z_Term_characterString; + const char *flags = "void"; + + if (grep_info_prepare (zh, 0 /* zapt */, &grep_info, '0', stream)) + { + rset_null_parms parms; + + parms.rset_term = rset_term_create (term, strlen(term), + flags, term_type); + parms.rset_term->nn = 0; + return rset_create (rset_kind_null, &parms); } - if (!use_string) + + if (ord < 0) { - yaz_log (LOG_LOG, "rpn_search_xpath - not 2"); + rset_null_parms parms; + + parms.rset_term = rset_term_create (term, strlen(term), + flags, term_type); + parms.rset_term->nn = 0; + return rset_create (rset_kind_null, &parms); + } + if (prefix_len) + term_dict[prefix_len++] = '|'; + else + term_dict[prefix_len++] = '('; + + ord_len = key_SU_encode (ord, ord_buf); + for (i = 0; ireg->dict, term_dict, 0, + &grep_info, &max_pos, 0, grep_handle); + yaz_log (LOG_LOG, "%s %d positions", term, + grep_info.isam_p_indx); + rset = rset_trunc (zh, grep_info.isam_p_buf, + grep_info.isam_p_indx, term, strlen(term), + flags, 1, term_type); + grep_info_delete (&grep_info); + return rset; +} + +static RSET rpn_search_xpath (ZebraHandle zh, + oid_value attributeSet, + int num_bases, char **basenames, + NMEM stream, const char *rank_type, RSET rset, + int xpath_len, struct xpath_location_step *xpath) +{ + oid_value curAttributeSet = attributeSet; + int base_no; + int i; + + if (xpath_len < 0) return rset; + + yaz_log (LOG_LOG, "len=%d", xpath_len); + for (i = 0; i a/.* + //a/b -> b/a/.* + /a -> a/ + /a/b -> b/a/ + + / -> none + + a[@attr=value]/b[@other=othervalue] + + /e/@a val range(e/,range(@a,freetext(w,1015,val),@a),e/) + /a/b val range(b/a/,freetext(w,1016,val),b/a/) + /a/b/@c val range(b/a/,range(@c,freetext(w,1016,val),@c),b/a/) + /a/b[@c=y] val range(b/a/,freetext(w,1016,val),b/a/,@c=y) + /a[@c=y]/b val range(a/,range(b/a/,freetext(w,1016,val),b/a/),a/,@c=y) + /a[@c=x]/b[@c=y] range(a/,range(b/a/,freetext(w,1016,val),b/a/,@c=y),a/,@c=x) + + */ + dict_grep_cmap (zh->reg->dict, 0, 0); - if (grep_info_prepare (zh, zapt, &grep_info, reg_type, stream)) - return 0; - yaz_log (LOG_LOG, "rpn_search_xpath 2"); for (base_no = 0; base_no < num_bases; base_no++) { - const char *termp = use_string; - rset_between_parms parms; - RSET rset_start_tag, rset_end_tag; - int ord, ord_len, i, r, max_pos; - int prefix_len ; - char ord_buf[32]; + int level = xpath_len; + int first_path = 1; + if (zebraExplain_curDatabase (zh->reg->zei, basenames[base_no])) { zh->errCode = 109; /* Database unavailable */ zh->errString = basenames[base_no]; return rset; } - - prefix_len = 0; - ord = zebraExplain_lookupSU (zh->reg->zei, curAttributeSet, 1); - 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; ireg->dict, term_dict, 0, - &grep_info, &max_pos, 0, grep_handle); - yaz_log (LOG_LOG, "%s %d positions", use_string, - grep_info.isam_p_indx); - rset_start_tag = - rset_trunc (zh, grep_info.isam_p_buf, - grep_info.isam_p_indx, use_string, strlen(use_string), - rank_type, 1, zapt->term->which); - - prefix_len = 0; - ord = zebraExplain_lookupSU (zh->reg->zei, curAttributeSet, 2); - 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= 0) { - term_dict[prefix_len++] = 1; - term_dict[prefix_len++] = ord_buf[i]; - } - term_dict[prefix_len++] = ')'; - term_dict[prefix_len++] = 1; - term_dict[prefix_len++] = reg_type; - - termp = use_string; - - strcpy (term_dict+prefix_len, use_string); - - grep_info.isam_p_indx = 0; - r = dict_lookup_grep (zh->reg->dict, term_dict, 0, - &grep_info, &max_pos, 0, grep_handle); + char xpath_rev[128]; + int i, len; + rset_between_parms parms; + RSET rset_start_tag = 0, rset_end_tag = 0, rset_attr = 0; + + *xpath_rev = 0; + len = 0; + for (i = level; i >= 1; --i) + { + const char *cp = xpath[i].part; + if (*cp) + { + for (;*cp; cp++) + if (*cp == '*') + { + memcpy (xpath_rev + len, "[^/]*", 5); + len += 5; + } + else if (*cp == ' ') + { + + xpath_rev[len++] = 1; + xpath_rev[len++] = ' '; + } + + else + xpath_rev[len++] = *cp; + xpath_rev[len++] = '/'; + } + else if (i == 1) /* // case */ + { + xpath_rev[len++] = '.'; + xpath_rev[len++] = '*'; + } + } + xpath_rev[len] = 0; - yaz_log (LOG_LOG, "%s %d positions", use_string, - grep_info.isam_p_indx); - rset_end_tag = - rset_trunc (zh, grep_info.isam_p_buf, - grep_info.isam_p_indx, use_string, strlen(use_string), - rank_type, 1, zapt->term->which); + if (xpath[level].predicate && + xpath[level].predicate->which == XPATH_PREDICATE_RELATION && + xpath[level].predicate->u.relation.name[0]) + { + char predicate_str[128]; - parms.key_size = sizeof(struct it_key); - parms.cmp = key_compare_it; - parms.rset_l = rset_start_tag; - parms.rset_m = rset; - parms.rset_r = rset_end_tag; - parms.printer = key_print_it; - yaz_log (LOG_LOG, "rpn_search_xpath 4"); - rset = rset_create (rset_kind_between, &parms); + strcpy (predicate_str, + xpath[level].predicate->u.relation.name+1); + if (xpath[level].predicate->u.relation.value) + { + strcat (predicate_str, "="); + strcat (predicate_str, + xpath[level].predicate->u.relation.value); + } + rset_attr = xpath_trunc ( + zh, stream, '0', predicate_str, 3, curAttributeSet); + } + else + { + if (!first_path) + continue; + } + yaz_log (LOG_LOG, "xpath_rev (%d) = %s", level, xpath_rev); + if (strlen(xpath_rev)) + { + rset_start_tag = xpath_trunc(zh, stream, + '0', xpath_rev, 1, curAttributeSet); + + rset_end_tag = xpath_trunc(zh, stream, + '0', xpath_rev, 2, curAttributeSet); + + parms.key_size = sizeof(struct it_key); + parms.cmp = key_compare_it; + parms.rset_l = rset_start_tag; + parms.rset_m = rset; + parms.rset_r = rset_end_tag; + parms.rset_attr = rset_attr; + parms.printer = key_print_it; + rset = rset_create (rset_kind_between, &parms); + } + first_path = 0; + } } - grep_info_delete (&grep_info); return rset; } @@ -2120,6 +2364,9 @@ static RSET rpn_search_APT (ZebraHandle zh, Z_AttributesPlusTerm *zapt, int sort_flag; char termz[IT_MAX_WORD+1]; RSET rset = 0; + int xpath_len; + int xpath_use = 0; + struct xpath_location_step xpath[10]; zebra_maps_attr (zh->reg->zebra_maps, zapt, ®_id, &search_type, rank_type, &complete_flag, &sort_flag); @@ -2129,29 +2376,39 @@ static RSET rpn_search_APT (ZebraHandle zh, Z_AttributesPlusTerm *zapt, logf (LOG_DEBUG, "search_type=%s", search_type); logf (LOG_DEBUG, "rank_type=%s", rank_type); - if (trans_term (zh, zapt, termz)) + if (zapt_term_to_utf8(zh, zapt, termz)) return 0; if (sort_flag) return rpn_sort_spec (zh, zapt, attributeSet, stream, sort_sequence, rank_type); + xpath_len = parse_xpath(zh, zapt, attributeSet, xpath, stream); + if (xpath_len >= 0) + { + xpath_use = 1016; + if (xpath[xpath_len-1].part[0] == '@') + xpath_use = 1015; + } if (!strcmp (search_type, "phrase")) { rset = rpn_search_APT_phrase (zh, zapt, termz, attributeSet, stream, reg_id, complete_flag, rank_type, + xpath_use, num_bases, basenames); } else if (!strcmp (search_type, "and-list")) { rset = rpn_search_APT_and_list (zh, zapt, termz, attributeSet, stream, reg_id, complete_flag, rank_type, + xpath_use, num_bases, basenames); } else if (!strcmp (search_type, "or-list")) { rset = rpn_search_APT_or_list (zh, zapt, termz, attributeSet, stream, reg_id, complete_flag, rank_type, + xpath_use, num_bases, basenames); } else if (!strcmp (search_type, "local")) @@ -2165,10 +2422,14 @@ static RSET rpn_search_APT (ZebraHandle zh, Z_AttributesPlusTerm *zapt, reg_id, complete_flag, rank_type, num_bases, basenames); } + else if (!strcmp (search_type, "always")) + { + rset = 0; + } else zh->errCode = 118; - return rpn_search_xpath (zh, zapt, attributeSet, num_bases, basenames, - stream, rank_type, rset); + return rpn_search_xpath (zh, attributeSet, num_bases, basenames, + stream, rank_type, rset, xpath_len, xpath); } static RSET rpn_search_structure (ZebraHandle zh, Z_RPNStructure *zs, @@ -2390,12 +2651,33 @@ static int scan_handle (char *name, const char *info, int pos, void *client) static void scan_term_untrans (ZebraHandle zh, NMEM stream, int reg_type, char **dst, const char *src) { - char term_dst[1024]; + char term_src[IT_MAX_WORD]; + char term_dst[IT_MAX_WORD]; - term_untrans (zh, reg_type, term_dst, src); - - *dst = (char *) nmem_malloc (stream, strlen(term_dst)+1); - strcpy (*dst, term_dst); + term_untrans (zh, reg_type, term_src, src); + + if (zh->iconv_from_utf8 != 0) + { + int len; + char *inbuf = term_src; + size_t inleft = strlen(term_src); + char *outbuf = term_dst; + size_t outleft = sizeof(term_dst)-1; + size_t ret; + + ret = yaz_iconv (zh->iconv_from_utf8, &inbuf, &inleft, + &outbuf, &outleft); + if (ret == (size_t)(-1)) + len = 0; + else + len = outbuf - term_dst; + *dst = nmem_malloc (stream, len + 1); + if (len > 0) + memcpy (*dst, term_dst, len); + (*dst)[len] = '\0'; + } + else + *dst = nmem_strdup (stream, term_src); } static void count_set (RSET r, int *count) @@ -2539,7 +2821,8 @@ void rpn_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, termz[prefix_len] = 0; strcpy (scan_info->prefix, termz); - trans_scan_term (zh, zapt, termz+prefix_len, reg_id); + if (trans_scan_term (zh, zapt, termz+prefix_len, reg_id)) + return ; dict_scan (zh->reg->dict, termz, &before_tmp, &after_tmp, scan_info, scan_handle);