00001
00002
00003
00004
00015 #include <stdlib.h>
00016 #include <string.h>
00017
00018 #include "cclp.h"
00019
00020
00021 #define KIND (cclp->look_token->kind)
00022
00023
00024 #define ADVANCE cclp->look_token = cclp->look_token->next
00025
00033 static int qual_val_type(ccl_qualifier_t *qa, int type, int value,
00034 char **attset)
00035 {
00036 int i;
00037
00038 if (!qa)
00039 return 0;
00040 for (i = 0; qa[i]; i++)
00041 {
00042 struct ccl_rpn_attr *q = ccl_qual_get_attr(qa[i]);
00043 while (q)
00044 {
00045 if (q->type == type && q->kind == CCL_RPN_ATTR_NUMERIC &&
00046 q->value.numeric == value)
00047 {
00048 if (attset)
00049 *attset = q->set;
00050 return 1;
00051 }
00052 q = q->next;
00053 }
00054 }
00055 return 0;
00056 }
00057
00064 static void strxcat(char *n, const char *src, int len)
00065 {
00066 while (*n)
00067 n++;
00068 while (--len >= 0)
00069 *n++ = *src++;
00070 *n = '\0';
00071 }
00072
00078 static char *copy_token_name(struct ccl_token *tp)
00079 {
00080 char *str = (char *)xmalloc(tp->len + 1);
00081 ccl_assert(str);
00082 memcpy(str, tp->name, tp->len);
00083 str[tp->len] = '\0';
00084 return str;
00085 }
00086
00092 struct ccl_rpn_node *ccl_rpn_node_create(enum ccl_rpn_kind kind)
00093 {
00094 struct ccl_rpn_node *p;
00095 p = (struct ccl_rpn_node *)xmalloc(sizeof(*p));
00096 ccl_assert(p);
00097 p->kind = kind;
00098
00099 switch(kind)
00100 {
00101 case CCL_RPN_TERM:
00102 p->u.t.attr_list = 0;
00103 p->u.t.term = 0;
00104 p->u.t.qual = 0;
00105 break;
00106 default:
00107 break;
00108 }
00109 return p;
00110 }
00111
00116 void ccl_rpn_delete(struct ccl_rpn_node *rpn)
00117 {
00118 struct ccl_rpn_attr *attr, *attr1;
00119 if (!rpn)
00120 return;
00121 switch (rpn->kind)
00122 {
00123 case CCL_RPN_AND:
00124 case CCL_RPN_OR:
00125 case CCL_RPN_NOT:
00126 ccl_rpn_delete(rpn->u.p[0]);
00127 ccl_rpn_delete(rpn->u.p[1]);
00128 break;
00129 case CCL_RPN_TERM:
00130 xfree(rpn->u.t.term);
00131 xfree(rpn->u.t.qual);
00132 for (attr = rpn->u.t.attr_list; attr; attr = attr1)
00133 {
00134 attr1 = attr->next;
00135 if (attr->kind == CCL_RPN_ATTR_STRING)
00136 xfree(attr->value.str);
00137 if (attr->set)
00138 xfree(attr->set);
00139 xfree(attr);
00140 }
00141 break;
00142 case CCL_RPN_SET:
00143 xfree(rpn->u.setname);
00144 break;
00145 case CCL_RPN_PROX:
00146 ccl_rpn_delete(rpn->u.p[0]);
00147 ccl_rpn_delete(rpn->u.p[1]);
00148 ccl_rpn_delete(rpn->u.p[2]);
00149 break;
00150 }
00151 xfree(rpn);
00152 }
00153
00154 static struct ccl_rpn_node *find_spec(CCL_parser cclp, ccl_qualifier_t *qa);
00155
00156 static int is_term_ok(int look, int *list)
00157 {
00158 for (;*list >= 0; list++)
00159 if (look == *list)
00160 return 1;
00161 return 0;
00162 }
00163
00164 static struct ccl_rpn_node *search_terms(CCL_parser cclp, ccl_qualifier_t *qa);
00165
00166 static struct ccl_rpn_attr *add_attr_node(struct ccl_rpn_node *p,
00167 const char *set, int type)
00168 {
00169 struct ccl_rpn_attr *n;
00170
00171 n = (struct ccl_rpn_attr *)xmalloc(sizeof(*n));
00172 ccl_assert(n);
00173 if (set)
00174 n->set = xstrdup(set);
00175 else
00176 n->set = 0;
00177 n->type = type;
00178 n->next = p->u.t.attr_list;
00179 p->u.t.attr_list = n;
00180
00181 return n;
00182 }
00183
00191 void ccl_add_attr_numeric(struct ccl_rpn_node *p, const char *set,
00192 int type, int value)
00193 {
00194 struct ccl_rpn_attr *n;
00195
00196 n = add_attr_node(p, set, type);
00197 n->kind = CCL_RPN_ATTR_NUMERIC;
00198 n->value.numeric = value;
00199 }
00200
00201 void ccl_add_attr_string(struct ccl_rpn_node *p, const char *set,
00202 int type, char *value)
00203 {
00204 struct ccl_rpn_attr *n;
00205
00206 n = add_attr_node(p, set, type);
00207 n->kind = CCL_RPN_ATTR_STRING;
00208 n->value.str = xstrdup(value);
00209 }
00210
00211
00220 static struct ccl_rpn_node *search_term_x(CCL_parser cclp,
00221 ccl_qualifier_t *qa,
00222 int *term_list, int multi)
00223 {
00224 struct ccl_rpn_node *p_top = 0;
00225 struct ccl_token *lookahead = cclp->look_token;
00226 int and_list = 0;
00227 int or_list = 0;
00228 char *attset;
00229 const char **truncation_aliases;
00230 const char *t_default[2];
00231
00232 truncation_aliases =
00233 ccl_qual_search_special(cclp->bibset, "truncation");
00234 if (!truncation_aliases)
00235 {
00236 truncation_aliases = t_default;
00237 t_default[0] = "?";
00238 t_default[1] = 0;
00239 }
00240
00241 if (qual_val_type(qa, CCL_BIB1_STR, CCL_BIB1_STR_AND_LIST, 0))
00242 and_list = 1;
00243 if (qual_val_type(qa, CCL_BIB1_STR, CCL_BIB1_STR_OR_LIST, 0))
00244 or_list = 1;
00245 while (1)
00246 {
00247 struct ccl_rpn_node *p;
00248 size_t no, i;
00249 int no_spaces = 0;
00250 int left_trunc = 0;
00251 int right_trunc = 0;
00252 int mid_trunc = 0;
00253 int relation_value = -1;
00254 int position_value = -1;
00255 int structure_value = -1;
00256 int truncation_value = -1;
00257 int completeness_value = -1;
00258 int len = 0;
00259 size_t max = 200;
00260 if (and_list || or_list || !multi)
00261 max = 1;
00262
00263
00264 if (and_list && lookahead && lookahead->kind == CCL_TOK_COMMA)
00265 {
00266 lookahead = lookahead->next;
00267 ADVANCE;
00268 continue;
00269 }
00270
00271
00272
00273 for (no = 0; no < max && is_term_ok(lookahead->kind, term_list); no++)
00274 {
00275 for (i = 0; i<lookahead->len; i++)
00276 if (lookahead->name[i] == ' ')
00277 no_spaces++;
00278 else if (strchr(truncation_aliases[0], lookahead->name[i]))
00279 {
00280 if (no == 0 && i == 0 && lookahead->len >= 1)
00281 left_trunc = 1;
00282 else if (!is_term_ok(lookahead->next->kind, term_list) &&
00283 i == lookahead->len-1 && i >= 1)
00284 right_trunc = 1;
00285 else
00286 mid_trunc = 1;
00287 }
00288 len += 1+lookahead->len+lookahead->ws_prefix_len;
00289 lookahead = lookahead->next;
00290 }
00291
00292 if (len == 0)
00293 break;
00294
00295
00296 p = ccl_rpn_node_create(CCL_RPN_TERM);
00297 p->u.t.attr_list = NULL;
00298 p->u.t.term = NULL;
00299 if (qa && qa[0])
00300 {
00301 const char *n = ccl_qual_get_name(qa[0]);
00302 if (n)
00303 p->u.t.qual = xstrdup(n);
00304 }
00305
00306
00307 for (i=0; qa && qa[i]; i++)
00308 {
00309 struct ccl_rpn_attr *attr;
00310
00311 for (attr = ccl_qual_get_attr(qa[i]); attr; attr = attr->next)
00312 switch(attr->kind)
00313 {
00314 case CCL_RPN_ATTR_STRING:
00315 ccl_add_attr_string(p, attr->set, attr->type,
00316 attr->value.str);
00317 break;
00318 case CCL_RPN_ATTR_NUMERIC:
00319 if (attr->value.numeric > 0)
00320 {
00321 switch (attr->type)
00322 {
00323 case CCL_BIB1_REL:
00324 if (relation_value != -1)
00325 continue;
00326 relation_value = attr->value.numeric;
00327 break;
00328 case CCL_BIB1_POS:
00329 if (position_value != -1)
00330 continue;
00331 position_value = attr->value.numeric;
00332 break;
00333 case CCL_BIB1_STR:
00334 if (structure_value != -1)
00335 continue;
00336 structure_value = attr->value.numeric;
00337 break;
00338 case CCL_BIB1_TRU:
00339 if (truncation_value != -1)
00340 continue;
00341 truncation_value = attr->value.numeric;
00342 left_trunc = right_trunc = mid_trunc = 0;
00343 break;
00344 case CCL_BIB1_COM:
00345 if (completeness_value != -1)
00346 continue;
00347 completeness_value = attr->value.numeric;
00348 break;
00349 }
00350 ccl_add_attr_numeric(p, attr->set, attr->type,
00351 attr->value.numeric);
00352 }
00353 }
00354 }
00355
00356
00357
00358 if (structure_value == -1 &&
00359 qual_val_type(qa, CCL_BIB1_STR, CCL_BIB1_STR_WP, &attset))
00360 {
00361
00362 if (no == 1 && no_spaces == 0)
00363 ccl_add_attr_numeric(p, attset, CCL_BIB1_STR, 2);
00364 else
00365 ccl_add_attr_numeric(p, attset, CCL_BIB1_STR, 1);
00366 }
00367
00368
00369 p->u.t.term = (char *)xmalloc(len);
00370 ccl_assert(p->u.t.term);
00371 p->u.t.term[0] = '\0';
00372 for (i = 0; i<no; i++)
00373 {
00374 const char *src_str = cclp->look_token->name;
00375 size_t src_len = cclp->look_token->len;
00376
00377 if (i == 0 && left_trunc)
00378 {
00379 src_len--;
00380 src_str++;
00381 }
00382 if (i == no-1 && right_trunc)
00383 src_len--;
00384 if (p->u.t.term[0] && cclp->look_token->ws_prefix_len)
00385 {
00386 size_t len = strlen(p->u.t.term);
00387 memcpy(p->u.t.term + len, cclp->look_token->ws_prefix_buf,
00388 cclp->look_token->ws_prefix_len);
00389 p->u.t.term[len + cclp->look_token->ws_prefix_len] = '\0';
00390 }
00391 strxcat(p->u.t.term, src_str, src_len);
00392 ADVANCE;
00393 }
00394
00395
00396 if (p_top)
00397 {
00398 struct ccl_rpn_node *tmp;
00399
00400 if (or_list)
00401 tmp = ccl_rpn_node_create(CCL_RPN_OR);
00402 else if (and_list)
00403 tmp = ccl_rpn_node_create(CCL_RPN_AND);
00404 else
00405 tmp = ccl_rpn_node_create(CCL_RPN_AND);
00406 tmp->u.p[0] = p_top;
00407 tmp->u.p[1] = p;
00408
00409 p_top = tmp;
00410 }
00411 else
00412 p_top = p;
00413
00414
00415 if (left_trunc && right_trunc)
00416 {
00417 if (!qual_val_type(qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_BOTH,
00418 &attset))
00419 {
00420 cclp->error_code = CCL_ERR_TRUNC_NOT_BOTH;
00421 ccl_rpn_delete(p);
00422 return NULL;
00423 }
00424 ccl_add_attr_numeric(p, attset, CCL_BIB1_TRU, 3);
00425 }
00426 else if (right_trunc)
00427 {
00428 if (!qual_val_type(qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_RIGHT,
00429 &attset))
00430 {
00431 cclp->error_code = CCL_ERR_TRUNC_NOT_RIGHT;
00432 ccl_rpn_delete(p);
00433 return NULL;
00434 }
00435 ccl_add_attr_numeric(p, attset, CCL_BIB1_TRU, 1);
00436 }
00437 else if (left_trunc)
00438 {
00439 if (!qual_val_type(qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_LEFT,
00440 &attset))
00441 {
00442 cclp->error_code = CCL_ERR_TRUNC_NOT_LEFT;
00443 ccl_rpn_delete(p);
00444 return NULL;
00445 }
00446 ccl_add_attr_numeric(p, attset, CCL_BIB1_TRU, 2);
00447 }
00448 else
00449 {
00450 if (qual_val_type(qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_NONE,
00451 &attset))
00452 ccl_add_attr_numeric(p, attset, CCL_BIB1_TRU, 100);
00453 }
00454 if (!multi)
00455 break;
00456 }
00457 if (!p_top)
00458 cclp->error_code = CCL_ERR_TERM_EXPECTED;
00459 return p_top;
00460 }
00461
00462 static struct ccl_rpn_node *search_term(CCL_parser cclp, ccl_qualifier_t *qa)
00463 {
00464 static int list[] = {CCL_TOK_TERM, CCL_TOK_COMMA, -1};
00465 return search_term_x(cclp, qa, list, 0);
00466 }
00467
00468 static
00469 struct ccl_rpn_node *qualifiers_order(CCL_parser cclp,
00470 ccl_qualifier_t *ap, char *attset)
00471 {
00472 int rel = 0;
00473 struct ccl_rpn_node *p;
00474
00475 if (cclp->look_token->len == 1)
00476 {
00477 if (cclp->look_token->name[0] == '<')
00478 rel = 1;
00479 else if (cclp->look_token->name[0] == '=')
00480 rel = 3;
00481 else if (cclp->look_token->name[0] == '>')
00482 rel = 5;
00483 }
00484 else if (cclp->look_token->len == 2)
00485 {
00486 if (!memcmp(cclp->look_token->name, "<=", 2))
00487 rel = 2;
00488 else if (!memcmp(cclp->look_token->name, ">=", 2))
00489 rel = 4;
00490 else if (!memcmp(cclp->look_token->name, "<>", 2))
00491 rel = 6;
00492 }
00493 if (!rel)
00494 {
00495 cclp->error_code = CCL_ERR_BAD_RELATION;
00496 return NULL;
00497 }
00498 ADVANCE;
00499 if (rel == 3 &&
00500 qual_val_type(ap, CCL_BIB1_REL, CCL_BIB1_REL_PORDER, 0))
00501 {
00502
00503
00504 if (KIND == CCL_TOK_TERM)
00505 {
00506 size_t i;
00507 for (i = 0; i<cclp->look_token->len; i++)
00508 {
00509 if (cclp->look_token->name[i] == '-')
00510 break;
00511 }
00512
00513 if (cclp->look_token->len > 1 && i == 0)
00514 {
00515 struct ccl_token *ntoken = ccl_token_add(cclp->look_token);
00516
00517 ntoken->kind = CCL_TOK_TERM;
00518 ntoken->name = cclp->look_token->name + 1;
00519 ntoken->len = cclp->look_token->len - 1;
00520
00521 cclp->look_token->len = 1;
00522 cclp->look_token->name = "-";
00523 }
00524 else if (cclp->look_token->len > 1 && i == cclp->look_token->len-1)
00525 {
00526 struct ccl_token *ntoken = ccl_token_add(cclp->look_token);
00527
00528 ntoken->kind = CCL_TOK_TERM;
00529 ntoken->name = "-";
00530 ntoken->len = 1;
00531
00532 (cclp->look_token->len)--;
00533 }
00534 else if (cclp->look_token->len > 2 && i < cclp->look_token->len)
00535 {
00536 struct ccl_token *ntoken1 = ccl_token_add(cclp->look_token);
00537 struct ccl_token *ntoken2 = ccl_token_add(ntoken1);
00538
00539 ntoken1->kind = CCL_TOK_TERM;
00540 ntoken1->name = "-";
00541 ntoken1->len = 1;
00542
00543 ntoken2->kind = CCL_TOK_TERM;
00544 ntoken2->name = cclp->look_token->name + (i+1);
00545 ntoken2->len = cclp->look_token->len - (i+1);
00546
00547 cclp->look_token->len = i;
00548 }
00549 else if (i == cclp->look_token->len &&
00550 cclp->look_token->next &&
00551 cclp->look_token->next->kind == CCL_TOK_TERM &&
00552 cclp->look_token->next->len > 1 &&
00553 cclp->look_token->next->name[0] == '-')
00554
00555 {
00556
00557 struct ccl_token *ntoken = ccl_token_add(cclp->look_token);
00558
00559 ntoken->kind = CCL_TOK_TERM;
00560 ntoken->name = "-";
00561 ntoken->len = 1;
00562
00563 (ntoken->next->name)++;
00564 (ntoken->next->len)--;
00565 }
00566 }
00567 }
00568
00569 if (rel == 3 &&
00570 KIND == CCL_TOK_TERM &&
00571 cclp->look_token->next && cclp->look_token->next->len == 1 &&
00572 cclp->look_token->next->name[0] == '-')
00573 {
00574 struct ccl_rpn_node *p1;
00575 if (!(p1 = search_term(cclp, ap)))
00576 return NULL;
00577 ADVANCE;
00578 if (KIND == CCL_TOK_TERM)
00579 {
00580 struct ccl_rpn_node *p2;
00581
00582 if (!(p2 = search_term(cclp, ap)))
00583 {
00584 ccl_rpn_delete(p1);
00585 return NULL;
00586 }
00587 p = ccl_rpn_node_create(CCL_RPN_AND);
00588 p->u.p[0] = p1;
00589 ccl_add_attr_numeric(p1, attset, CCL_BIB1_REL, 4);
00590 p->u.p[1] = p2;
00591 ccl_add_attr_numeric(p2, attset, CCL_BIB1_REL, 2);
00592 return p;
00593 }
00594 else
00595 {
00596 ccl_add_attr_numeric(p1, attset, CCL_BIB1_REL, 4);
00597 return p1;
00598 }
00599 }
00600 else if (rel == 3 &&
00601 cclp->look_token->len == 1 &&
00602 cclp->look_token->name[0] == '-')
00603 {
00604 ADVANCE;
00605 if (!(p = search_term(cclp, ap)))
00606 return NULL;
00607 ccl_add_attr_numeric(p, attset, CCL_BIB1_REL, 2);
00608 return p;
00609 }
00610 else if (KIND == CCL_TOK_LP)
00611 {
00612 ADVANCE;
00613 if (!(p = find_spec(cclp, ap)))
00614 return NULL;
00615 if (KIND != CCL_TOK_RP)
00616 {
00617 cclp->error_code = CCL_ERR_RP_EXPECTED;
00618 ccl_rpn_delete(p);
00619 return NULL;
00620 }
00621 ADVANCE;
00622 return p;
00623 }
00624 else
00625 {
00626 if (!(p = search_terms(cclp, ap)))
00627 return NULL;
00628 ccl_add_attr_numeric(p, attset, CCL_BIB1_REL, rel);
00629 return p;
00630 }
00631 cclp->error_code = CCL_ERR_TERM_EXPECTED;
00632 return NULL;
00633 }
00634
00635 static
00636 struct ccl_rpn_node *qualifier_relation(CCL_parser cclp, ccl_qualifier_t *ap)
00637 {
00638 char *attset;
00639 struct ccl_rpn_node *p;
00640
00641 if (qual_val_type(ap, CCL_BIB1_REL, CCL_BIB1_REL_ORDER, &attset)
00642 || qual_val_type(ap, CCL_BIB1_REL, CCL_BIB1_REL_PORDER, &attset))
00643 return qualifiers_order(cclp, ap, attset);
00644
00645
00646 if (KIND != CCL_TOK_EQ)
00647 {
00648 cclp->error_code = CCL_ERR_EQ_EXPECTED;
00649 return NULL;
00650 }
00651 ADVANCE;
00652 if (KIND == CCL_TOK_LP)
00653 {
00654 ADVANCE;
00655 if (!(p = find_spec(cclp, ap)))
00656 {
00657 return NULL;
00658 }
00659 if (KIND != CCL_TOK_RP)
00660 {
00661 cclp->error_code = CCL_ERR_RP_EXPECTED;
00662 ccl_rpn_delete(p);
00663 return NULL;
00664 }
00665 ADVANCE;
00666 }
00667 else
00668 p = search_terms(cclp, ap);
00669 return p;
00670 }
00671
00679 static struct ccl_rpn_node *qualifier_list(CCL_parser cclp,
00680 struct ccl_token *la,
00681 ccl_qualifier_t *qa)
00682 {
00683 struct ccl_token *lookahead = cclp->look_token;
00684 struct ccl_token *look_start = cclp->look_token;
00685 ccl_qualifier_t *ap;
00686 struct ccl_rpn_node *node = 0;
00687 const char **field_str;
00688 int no = 0;
00689 int seq = 0;
00690 int i;
00691 int mode_merge = 1;
00692 #if 0
00693 if (qa)
00694 {
00695 cclp->error_code = CCL_ERR_DOUBLE_QUAL;
00696 return NULL;
00697 }
00698 #endif
00699 for (lookahead = cclp->look_token; lookahead != la;
00700 lookahead=lookahead->next)
00701 no++;
00702 if (qa)
00703 for (i=0; qa[i]; i++)
00704 no++;
00705 ap = (ccl_qualifier_t *)xmalloc((no ? (no+1) : 2) * sizeof(*ap));
00706 ccl_assert(ap);
00707
00708 field_str = ccl_qual_search_special(cclp->bibset, "field");
00709 if (field_str)
00710 {
00711 if (!strcmp(field_str[0], "or"))
00712 mode_merge = 0;
00713 else if (!strcmp(field_str[0], "merge"))
00714 mode_merge = 1;
00715 }
00716 if (!mode_merge)
00717 {
00718
00719 lookahead = look_start;
00720 while (lookahead != la)
00721 {
00722 ap[1] = 0;
00723 seq = 0;
00724 while ((ap[0] = ccl_qual_search(cclp, lookahead->name,
00725 lookahead->len, seq)) != 0)
00726 {
00727 struct ccl_rpn_node *node_sub;
00728 cclp->look_token = la;
00729
00730 node_sub = qualifier_relation(cclp, ap);
00731 if (!node_sub)
00732 {
00733 ccl_rpn_delete(node);
00734 xfree(ap);
00735 return 0;
00736 }
00737 if (node)
00738 {
00739 struct ccl_rpn_node *node_this =
00740 ccl_rpn_node_create(CCL_RPN_OR);
00741 node_this->u.p[0] = node;
00742 node_this->u.p[1] = node_sub;
00743 node = node_this;
00744 }
00745 else
00746 node = node_sub;
00747 seq++;
00748 }
00749 if (seq == 0)
00750 {
00751 cclp->look_token = lookahead;
00752 cclp->error_code = CCL_ERR_UNKNOWN_QUAL;
00753 xfree(ap);
00754 return NULL;
00755 }
00756 lookahead = lookahead->next;
00757 if (lookahead->kind == CCL_TOK_COMMA)
00758 lookahead = lookahead->next;
00759 }
00760 }
00761 else
00762 {
00763
00764 while (1)
00765 {
00766 struct ccl_rpn_node *node_sub;
00767 int found = 0;
00768 lookahead = look_start;
00769 for (i = 0; lookahead != la; i++)
00770 {
00771 ap[i] = ccl_qual_search(cclp, lookahead->name,
00772 lookahead->len, seq);
00773 if (ap[i])
00774 found++;
00775 if (!ap[i] && seq > 0)
00776 ap[i] = ccl_qual_search(cclp, lookahead->name,
00777 lookahead->len, 0);
00778 if (!ap[i])
00779 {
00780 cclp->look_token = lookahead;
00781 cclp->error_code = CCL_ERR_UNKNOWN_QUAL;
00782 xfree(ap);
00783 return NULL;
00784 }
00785 lookahead = lookahead->next;
00786 if (lookahead->kind == CCL_TOK_COMMA)
00787 lookahead = lookahead->next;
00788 }
00789 if (qa)
00790 {
00791 ccl_qualifier_t *qa0 = qa;
00792
00793 while (*qa0)
00794 ap[i++] = *qa0++;
00795 }
00796 ap[i] = NULL;
00797
00798 if (!found)
00799 break;
00800
00801 cclp->look_token = lookahead;
00802
00803 node_sub = qualifier_relation(cclp, ap);
00804 if (!node_sub)
00805 {
00806 ccl_rpn_delete(node);
00807 break;
00808 }
00809 if (node)
00810 {
00811 struct ccl_rpn_node *node_this =
00812 ccl_rpn_node_create(CCL_RPN_OR);
00813 node_this->u.p[0] = node;
00814 node_this->u.p[1] = node_sub;
00815 node = node_this;
00816 }
00817 else
00818 node = node_sub;
00819 seq++;
00820 }
00821 }
00822 xfree(ap);
00823 return node;
00824 }
00825
00826
00833 static struct ccl_rpn_node *search_terms(CCL_parser cclp, ccl_qualifier_t *qa)
00834 {
00835 static int list[] = {
00836 CCL_TOK_TERM, CCL_TOK_COMMA,CCL_TOK_EQ, CCL_TOK_REL, CCL_TOK_SET, -1};
00837 struct ccl_rpn_node *p1, *p2, *pn;
00838 p1 = search_term_x(cclp, qa, list, 1);
00839 if (!p1)
00840 return NULL;
00841 while (1)
00842 {
00843 if (KIND == CCL_TOK_PROX)
00844 {
00845 struct ccl_rpn_node *p_prox = 0;
00846
00847
00848 p_prox = ccl_rpn_node_create(CCL_RPN_TERM);
00849 p_prox->u.t.term = (char *) xmalloc(1 + cclp->look_token->len);
00850 memcpy(p_prox->u.t.term, cclp->look_token->name,
00851 cclp->look_token->len);
00852 p_prox->u.t.term[cclp->look_token->len] = 0;
00853 p_prox->u.t.attr_list = 0;
00854
00855 ADVANCE;
00856 p2 = search_term_x(cclp, qa, list, 1);
00857 if (!p2)
00858 {
00859 ccl_rpn_delete(p1);
00860 return NULL;
00861 }
00862 pn = ccl_rpn_node_create(CCL_RPN_PROX);
00863 pn->u.p[0] = p1;
00864 pn->u.p[1] = p2;
00865 pn->u.p[2] = p_prox;
00866 p1 = pn;
00867 }
00868 else if (is_term_ok(KIND, list))
00869 {
00870 p2 = search_term_x(cclp, qa, list, 1);
00871 if (!p2)
00872 {
00873 ccl_rpn_delete(p1);
00874 return NULL;
00875 }
00876 pn = ccl_rpn_node_create(CCL_RPN_PROX);
00877 pn->u.p[0] = p1;
00878 pn->u.p[1] = p2;
00879 pn->u.p[2] = 0;
00880 p1 = pn;
00881 }
00882 else
00883 break;
00884 }
00885 return p1;
00886 }
00887
00894 static struct ccl_rpn_node *search_elements(CCL_parser cclp,
00895 ccl_qualifier_t *qa)
00896 {
00897 struct ccl_rpn_node *p1;
00898 struct ccl_token *lookahead;
00899 if (KIND == CCL_TOK_LP)
00900 {
00901 ADVANCE;
00902 p1 = find_spec(cclp, qa);
00903 if (!p1)
00904 return NULL;
00905 if (KIND != CCL_TOK_RP)
00906 {
00907 cclp->error_code = CCL_ERR_RP_EXPECTED;
00908 ccl_rpn_delete(p1);
00909 return NULL;
00910 }
00911 ADVANCE;
00912 return p1;
00913 }
00914 else if (KIND == CCL_TOK_SET)
00915 {
00916 ADVANCE;
00917 if (KIND == CCL_TOK_EQ)
00918 ADVANCE;
00919 if (KIND != CCL_TOK_TERM)
00920 {
00921 cclp->error_code = CCL_ERR_SETNAME_EXPECTED;
00922 return NULL;
00923 }
00924 p1 = ccl_rpn_node_create(CCL_RPN_SET);
00925 p1->u.setname = copy_token_name(cclp->look_token);
00926 ADVANCE;
00927 return p1;
00928 }
00929 lookahead = cclp->look_token;
00930
00931 while (lookahead->kind==CCL_TOK_TERM)
00932 {
00933 lookahead = lookahead->next;
00934 if (lookahead->kind == CCL_TOK_REL || lookahead->kind == CCL_TOK_EQ)
00935 return qualifier_list(cclp, lookahead, qa);
00936 if (lookahead->kind != CCL_TOK_COMMA)
00937 break;
00938 lookahead = lookahead->next;
00939 }
00940 if (qa)
00941 return search_terms(cclp, qa);
00942 else
00943 {
00944 ccl_qualifier_t qa[2];
00945 struct ccl_rpn_node *node = 0;
00946 int seq;
00947 lookahead = cclp->look_token;
00948
00949 qa[1] = 0;
00950 for(seq = 0; ;seq++)
00951 {
00952 struct ccl_rpn_node *node_sub;
00953 qa[0] = ccl_qual_search(cclp, "term", 4, seq);
00954 if (!qa[0])
00955 break;
00956
00957 cclp->look_token = lookahead;
00958
00959 node_sub = search_terms(cclp, qa);
00960 if (!node_sub)
00961 {
00962 ccl_rpn_delete(node);
00963 return 0;
00964 }
00965 if (node)
00966 {
00967 struct ccl_rpn_node *node_this =
00968 ccl_rpn_node_create(CCL_RPN_OR);
00969 node_this->u.p[0] = node;
00970 node_this->u.p[1] = node_sub;
00971 node_this->u.p[2] = 0;
00972 node = node_this;
00973 }
00974 else
00975 node = node_sub;
00976 }
00977 if (!node)
00978 node = search_terms(cclp, 0);
00979 return node;
00980 }
00981 }
00982
00989 static struct ccl_rpn_node *find_spec(CCL_parser cclp, ccl_qualifier_t *qa)
00990 {
00991 struct ccl_rpn_node *p1, *p2, *pn;
00992 if (!(p1 = search_elements(cclp, qa)))
00993 return NULL;
00994 while (1)
00995 {
00996 switch (KIND)
00997 {
00998 case CCL_TOK_AND: