X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=ccl%2Fcclfind.c;h=8153a0e3a1e4c2060538b3b42194f4c987af2705;hb=6b3cf0738c53080781fedd852e26b299224af3c3;hp=579491e522482aaa1ac85cc091ad759bc4226098;hpb=c4d8d77293c838ebb69fc2dbafe12a0d39599d1b;p=yaz-moved-to-github.git diff --git a/ccl/cclfind.c b/ccl/cclfind.c index 579491e..8153a0e 100644 --- a/ccl/cclfind.c +++ b/ccl/cclfind.c @@ -44,7 +44,7 @@ /* CCL find (to rpn conversion) * Europagate, 1995 * - * $Id: cclfind.c,v 1.29 2002-03-18 18:14:34 adam Exp $ + * $Id: cclfind.c,v 1.33 2003-02-14 18:49:22 adam Exp $ * * Old Europagate log: * @@ -160,7 +160,7 @@ static void strxcat (char *n, const char *src, int len) */ static char *copy_token_name (struct ccl_token *tp) { - char *str = (char *)malloc (tp->len + 1); + char *str = (char *)xmalloc (tp->len + 1); ccl_assert (str); memcpy (str, tp->name, tp->len); str[tp->len] = '\0'; @@ -175,7 +175,7 @@ static char *copy_token_name (struct ccl_token *tp) static struct ccl_rpn_node *mk_node (int kind) { struct ccl_rpn_node *p; - p = (struct ccl_rpn_node *)malloc (sizeof(*p)); + p = (struct ccl_rpn_node *)xmalloc (sizeof(*p)); ccl_assert (p); p->kind = kind; return p; @@ -199,24 +199,24 @@ void ccl_rpn_delete (struct ccl_rpn_node *rpn) ccl_rpn_delete (rpn->u.p[1]); break; case CCL_RPN_TERM: - free (rpn->u.t.term); + xfree (rpn->u.t.term); for (attr = rpn->u.t.attr_list; attr; attr = attr1) { attr1 = attr->next; if (attr->set) - free (attr->set); - free (attr); + xfree (attr->set); + xfree (attr); } break; case CCL_RPN_SET: - free (rpn->u.setname); + xfree (rpn->u.setname); break; case CCL_RPN_PROX: ccl_rpn_delete (rpn->u.p[0]); ccl_rpn_delete (rpn->u.p[1]); break; } - free (rpn); + xfree (rpn); } static struct ccl_rpn_node *find_spec (CCL_parser cclp, @@ -245,11 +245,11 @@ static void add_attr (struct ccl_rpn_node *p, const char *set, { struct ccl_rpn_attr *n; - n = (struct ccl_rpn_attr *)malloc (sizeof(*n)); + n = (struct ccl_rpn_attr *)xmalloc (sizeof(*n)); ccl_assert (n); if (set) { - n->set = (char*) malloc (strlen(set)+1); + n->set = (char*) xmalloc (strlen(set)+1); strcpy (n->set, set); } else @@ -417,7 +417,7 @@ static struct ccl_rpn_node *search_term_x (CCL_parser cclp, } /* make the RPN token */ - p->u.t.term = (char *)malloc (len); + p->u.t.term = (char *)xmalloc (len); ccl_assert (p->u.t.term); p->u.t.term[0] = '\0'; for (i = 0; ilook_token; struct ccl_token *look_start = cclp->look_token; struct ccl_rpn_attr **ap; struct ccl_rpn_node *node = 0; + const char *field_str; int no = 0; int seq = 0; int i; + int mode_merge = 1; #if 0 if (qa) { @@ -656,62 +658,122 @@ static struct ccl_rpn_node *qualifiers (CCL_parser cclp, struct ccl_token *la, if (qa) for (i=0; qa[i]; i++) no++; - ap = (struct ccl_rpn_attr **)malloc ((no+1) * sizeof(*ap)); + ap = (struct ccl_rpn_attr **)xmalloc ((no ? (no+1) : 2) * sizeof(*ap)); ccl_assert (ap); - while (1) + field_str = ccl_qual_search_special(cclp->bibset, "field"); + if (field_str) + { + if (!strcmp (field_str, "or")) + mode_merge = 0; + else if (!strcmp (field_str, "merge")) + mode_merge = 1; + } + if (!mode_merge) { - struct ccl_rpn_node *node_sub; - int found = 0; + /* consider each field separately and OR */ lookahead = look_start; - for (i = 0; lookahead != la; i++) + while (lookahead != la) { - ap[i] = ccl_qual_search (cclp, lookahead->name, - lookahead->len, seq); - if (ap[i]) - found++; - if (!ap[i] && seq > 0) - ap[i] = ccl_qual_search (cclp, lookahead->name, - lookahead->len, 0); - if (!ap[i]) + ap[1] = 0; + seq = 0; + while ((ap[0] = ccl_qual_search (cclp, lookahead->name, + lookahead->len, seq)) != 0) + { + struct ccl_rpn_node *node_sub; + cclp->look_token = la; + + node_sub = qualifiers2(cclp, ap); + if (!node_sub) + { + ccl_rpn_delete (node); + xfree (ap); + return 0; + } + if (node) + { + struct ccl_rpn_node *node_this = mk_node(CCL_RPN_OR); + node_this->u.p[0] = node; + node_this->u.p[1] = node_sub; + node = node_this; + } + else + node = node_sub; + seq++; + } + if (seq == 0) { cclp->look_token = lookahead; cclp->error_code = CCL_ERR_UNKNOWN_QUAL; - free (ap); + xfree (ap); return NULL; } lookahead = lookahead->next; if (lookahead->kind == CCL_TOK_COMMA) lookahead = lookahead->next; } - if (qa) - while (*qa) - ap[i++] = *qa++; - ap[i] = NULL; - - if (!found) - break; - - cclp->look_token = lookahead; - - node_sub = qualifiers2(cclp, ap); - if (!node_sub) - { - ccl_rpn_delete (node); - break; - } - if (node) + } + else + { + /* merge attributes from ALL fields - including inherited ones */ + while (1) { - struct ccl_rpn_node *node_this = mk_node(CCL_RPN_OR); - node_this->u.p[0] = node; - node_this->u.p[1] = node_sub; - node = node_this; + struct ccl_rpn_node *node_sub; + int found = 0; + lookahead = look_start; + for (i = 0; lookahead != la; i++) + { + ap[i] = ccl_qual_search (cclp, lookahead->name, + lookahead->len, seq); + if (ap[i]) + found++; + if (!ap[i] && seq > 0) + ap[i] = ccl_qual_search (cclp, lookahead->name, + lookahead->len, 0); + if (!ap[i]) + { + cclp->look_token = lookahead; + cclp->error_code = CCL_ERR_UNKNOWN_QUAL; + xfree (ap); + return NULL; + } + lookahead = lookahead->next; + if (lookahead->kind == CCL_TOK_COMMA) + lookahead = lookahead->next; + } + if (qa) + { + struct ccl_rpn_attr **qa0 = qa; + + while (*qa0) + ap[i++] = *qa0++; + } + ap[i] = NULL; + + if (!found) + break; + + cclp->look_token = lookahead; + + node_sub = qualifiers2(cclp, ap); + if (!node_sub) + { + ccl_rpn_delete (node); + break; + } + if (node) + { + struct ccl_rpn_node *node_this = mk_node(CCL_RPN_OR); + node_this->u.p[0] = node; + node_this->u.p[1] = node_sub; + node = node_this; + } + else + node = node_sub; + seq++; } - else - node = node_sub; - seq++; } - free (ap); + xfree (ap); return node; } @@ -735,6 +797,16 @@ static struct ccl_rpn_node *search_terms (CCL_parser cclp, { if (KIND == CCL_TOK_PROX) { + struct ccl_rpn_node *p_prox = 0; + /* ! word order specified */ + /* % word order not specified */ + p_prox = mk_node(CCL_RPN_TERM); + p_prox->u.t.term = (char *) xmalloc(cclp->look_token->len); + memcpy(p_prox->u.t.term, cclp->look_token->name, + cclp->look_token->len); + p_prox->u.t.term[cclp->look_token->len] = 0; + p_prox->u.t.attr_list = 0; + ADVANCE; p2 = search_term_x (cclp, qa, list, 1); if (!p2) @@ -745,6 +817,7 @@ static struct ccl_rpn_node *search_terms (CCL_parser cclp, pn = mk_node (CCL_RPN_PROX); pn->u.p[0] = p1; pn->u.p[1] = p2; + pn->u.p[2] = p_prox; p1 = pn; } else if (is_term_ok(KIND, list)) @@ -758,6 +831,7 @@ static struct ccl_rpn_node *search_terms (CCL_parser cclp, pn = mk_node (CCL_RPN_PROX); pn->u.p[0] = p1; pn->u.p[1] = p2; + pn->u.p[2] = 0; p1 = pn; } else @@ -813,7 +887,7 @@ static struct ccl_rpn_node *search_elements (CCL_parser cclp, { lookahead = lookahead->next; if (lookahead->kind == CCL_TOK_REL || lookahead->kind == CCL_TOK_EQ) - return qualifiers (cclp, lookahead, qa); + return qualifiers1 (cclp, lookahead, qa); if (lookahead->kind != CCL_TOK_COMMA) break; lookahead = lookahead->next; @@ -848,6 +922,7 @@ static struct ccl_rpn_node *search_elements (CCL_parser cclp, struct ccl_rpn_node *node_this = mk_node(CCL_RPN_OR); node_this->u.p[0] = node; node_this->u.p[1] = node_sub; + node_this->u.p[2] = 0; node = node_this; } else @@ -886,6 +961,7 @@ static struct ccl_rpn_node *find_spec (CCL_parser cclp, pn = mk_node (CCL_RPN_AND); pn->u.p[0] = p1; pn->u.p[1] = p2; + pn->u.p[2] = 0; p1 = pn; continue; case CCL_TOK_OR: @@ -899,6 +975,7 @@ static struct ccl_rpn_node *find_spec (CCL_parser cclp, pn = mk_node (CCL_RPN_OR); pn->u.p[0] = p1; pn->u.p[1] = p2; + pn->u.p[2] = 0; p1 = pn; continue; case CCL_TOK_NOT: @@ -912,6 +989,7 @@ static struct ccl_rpn_node *find_spec (CCL_parser cclp, pn = mk_node (CCL_RPN_NOT); pn->u.p[0] = p1; pn->u.p[1] = p2; + pn->u.p[2] = 0; p1 = pn; continue; }