From 5921175c5859c16c2ba411999831b8aaf64917b4 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Sat, 6 Jun 2015 19:50:44 +0200 Subject: [PATCH] CCL: split-list deals with multiple use attr YAZ-844 --- src/cclfind.c | 88 +++++++++++++++++++++++++++++++------------------------ test/test_ccl.c | 19 ++++++++++++ 2 files changed, 68 insertions(+), 39 deletions(-) diff --git a/src/cclfind.c b/src/cclfind.c index c03bdd3..13714d6 100644 --- a/src/cclfind.c +++ b/src/cclfind.c @@ -582,6 +582,49 @@ static struct ccl_rpn_node *ccl_term_one_use(CCL_parser cclp, return p; } +static struct ccl_rpn_node *ccl_term_multi_use(CCL_parser cclp, + struct ccl_token *lookahead0, + ccl_qualifier_t *qa, + size_t no, + int is_phrase, + int auto_group) +{ + struct ccl_rpn_node *p = 0; + int i; + for (i = 0; qa && qa[i]; i++) + { + struct ccl_rpn_attr *attr; + for (attr = ccl_qual_get_attr(qa[i]); attr; attr = attr->next) + if (attr->type == 1 && i == 0) + { + struct ccl_rpn_node *tmp2; + tmp2 = ccl_term_one_use(cclp, lookahead0, + attr, qa, no, + is_phrase, auto_group); + if (!tmp2) + { + ccl_rpn_delete(p); + return 0; + } + if (!p) + p = tmp2; + else + { + struct ccl_rpn_node *tmp1; + tmp1 = ccl_rpn_node_create(CCL_RPN_OR); + tmp1->u.p[0] = p; + tmp1->u.p[1] = tmp2; + p = tmp1; + } + } + } + if (!p) + p = ccl_term_one_use(cclp, lookahead0, + 0 /* attr: no use */, qa, no, + is_phrase, auto_group); + return p; +} + static struct ccl_rpn_node *split_recur(CCL_parser cclp, ccl_qualifier_t *qa, struct ccl_rpn_node *parent, struct ccl_token **ar, size_t sz) @@ -592,11 +635,10 @@ static struct ccl_rpn_node *split_recur(CCL_parser cclp, ccl_qualifier_t *qa, for (l = 1; l <= sz; l++) { struct ccl_rpn_node *p1; - struct ccl_rpn_node *p2 = ccl_term_one_use(cclp, ar[0], - /* attr_use */0, - qa, l, - l > 1, - /* auto_group */0); + struct ccl_rpn_node *p2 = ccl_term_multi_use(cclp, ar[0], + qa, l, + l > 1, + /* auto_group */0); if (!p2) return 0; if (parent) @@ -716,40 +758,8 @@ static struct ccl_rpn_node *search_term_x(CCL_parser cclp, if (no == 0) break; /* no more terms . stop . */ - - /* go through all attributes and add them to the attribute list */ - for (i = 0; qa && qa[i]; i++) - { - struct ccl_rpn_attr *attr; - - for (attr = ccl_qual_get_attr(qa[i]); attr; attr = attr->next) - if (attr->type == 1 && i == 0) - { - struct ccl_rpn_node *tmp2; - tmp2 = ccl_term_one_use(cclp, cclp->look_token, - attr, qa, no, - is_phrase, auto_group); - if (!tmp2) - { - ccl_rpn_delete(p); - return 0; - } - if (!p) - p = tmp2; - else - { - struct ccl_rpn_node *tmp1; - tmp1 = ccl_rpn_node_create(CCL_RPN_OR); - tmp1->u.p[0] = p; - tmp1->u.p[1] = tmp2; - p = tmp1; - } - } - } - if (!p) - p = ccl_term_one_use(cclp, cclp->look_token, - 0 /* attr: no use */, qa, no, - is_phrase, auto_group); + p = ccl_term_multi_use(cclp, cclp->look_token, qa, no, + is_phrase, auto_group); for (i = 0; i < no; i++) ADVANCE; if (!p) diff --git a/test/test_ccl.c b/test/test_ccl.c index 3881b4b..2cfc545 100644 --- a/test/test_ccl.c +++ b/test/test_ccl.c @@ -88,6 +88,7 @@ void tst1(int pass) ccl_qual_fitem(bibset, "dc.title", "title"); ccl_qual_fitem(bibset, "s=ag", "ag"); ccl_qual_fitem(bibset, "s=sl u=2", "splitlist"); + ccl_qual_fitem(bibset, "s=sl u=2 u=3", "s2"); break; case 1: strcpy(tstline, "ti u=4 s=pw t=l,r"); @@ -122,6 +123,9 @@ void tst1(int pass) strcpy(tstline, "splitlist s=sl u=2"); ccl_qual_line(bibset, tstline); + + strcpy(tstline, "s2 s=sl u=2 u=3"); + ccl_qual_line(bibset, tstline); break; case 2: ccl_qual_buf(bibset, "ti u=4 s=pw t=l,r\n" @@ -136,6 +140,7 @@ void tst1(int pass) "comb term dc.title\n" "ag s=ag\n" "splitlist s=sl u=2\n" + "s2 s=sl u=2 u=3\n" ); break; case 3: @@ -186,6 +191,11 @@ void tst1(int pass) " \n" " \n" " \n" + " \n" + " \n" + " \n" + " \n" + " \n" "\n"; doc = xmlParseMemory(xml_str, strlen(xml_str)); @@ -445,6 +455,15 @@ void tst1(int pass) "@and @attr 1=2 a @attr 1=2 \"b c\" " "@and @attr 1=2 \"a b\" @attr 1=2 c " "@attr 1=2 \"a b c\" ")); + + YAZ_CHECK(tst_ccl_query(bibset, "s2=a", "@or @attr 1=2 a @attr 1=3 a ")); + + YAZ_CHECK(tst_ccl_query(bibset, "s2=a b", "@or " + "@and " "@or @attr 1=2 a @attr 1=3 a " + "@or @attr 1=2 b @attr 1=3 b " + "@or @attr 1=2 \"a b\" @attr 1=3 \"a b\" ")); + + ccl_qual_rm(&bibset); } -- 1.7.10.4