Restructure qualifier handling so we can have more rules per-field -
authorAdam Dickmeiss <adam@indexdata.dk>
Mon, 30 Apr 2007 11:33:49 +0000 (11:33 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Mon, 30 Apr 2007 11:33:49 +0000 (11:33 +0000)
such as stop word handling.

include/yaz/ccl.h
src/cclfind.c
src/cclp.h
src/cclqual.c

index 7772cff..65d2ffd 100644 (file)
@@ -49,7 +49,7 @@
 /*
  * CCL - header file
  *
- * $Id: ccl.h,v 1.26 2007-04-26 21:45:16 adam Exp $
+ * $Id: ccl.h,v 1.27 2007-04-30 11:33:49 adam Exp $
  *
  * Old Europagate Log:
  *
@@ -274,11 +274,6 @@ int ccl_stricmp(const char *s1, const char *s2);
 YAZ_EXPORT
 int ccl_memicmp(const char *s1, const char *s2, size_t n);
 
-/** Search for qualifier 'name' in set 'b'. */
-YAZ_EXPORT
-struct ccl_rpn_attr *ccl_qual_search(CCL_parser cclp, const char *name,
-                                      size_t len, int seq);
-
 /** Create CCL parser */
 YAZ_EXPORT
 CCL_parser ccl_parser_create(CCL_bibset bibset);
index fc67b80..2ebd11f 100644 (file)
@@ -56,7 +56,7 @@
 /* CCL find (to rpn conversion)
  * Europagate, 1995
  *
- * $Id: cclfind.c,v 1.11 2007-04-26 21:45:17 adam Exp $
+ * $Id: cclfind.c,v 1.12 2007-04-30 11:33:49 adam Exp $
  *
  * Old Europagate log:
  *
  * value:  Value of attribute to seach for
  * return: 1 if found; 0 otherwise.
  */
-static int qual_val_type (struct ccl_rpn_attr **qa, int type, int value,
-                           char **attset)
+static int qual_val_type(ccl_qualifier_t *qa, int type, int value,
+                         char **attset)
 {
     int i;
-    struct ccl_rpn_attr *q;
 
     if (!qa)
         return 0;
-    for (i = 0;  (q=qa[i]); i++)
+    for (i = 0; qa[i]; i++)
+    {
+        struct ccl_rpn_attr *q = ccl_qual_get_attr(qa[i]);
         while (q)
         {
             if (q->type == type && q->kind == CCL_RPN_ATTR_NUMERIC &&
@@ -148,6 +149,7 @@ static int qual_val_type (struct ccl_rpn_attr **qa, int type, int value,
             }
             q = q->next;
         }
+    }
     return 0;
 }
 
@@ -157,7 +159,7 @@ static int qual_val_type (struct ccl_rpn_attr **qa, int type, int value,
  * src:    Source string to be appended (not null-terminated)
  * len:    Length of source string.
  */
-static void strxcat (char *n, const char *src, int len)
+static void strxcat(char *n, const char *src, int len)
 {
     while (*n)
         n++;
@@ -171,11 +173,11 @@ static void strxcat (char *n, const char *src, int len)
  * tp:      Pointer to token info.
  * return:  malloc(3) allocated copy of token name.
  */
-static char *copy_token_name (struct ccl_token *tp)
+static char *copy_token_name(struct ccl_token *tp)
 {
-    char *str = (char *)xmalloc (tp->len + 1);
-    ccl_assert (str);
-    memcpy (str, tp->name, tp->len);
+    char *str = (char *)xmalloc(tp->len + 1);
+    ccl_assert(str);
+    memcpy(str, tp->name, tp->len);
     str[tp->len] = '\0';
     return str;
 }
@@ -188,8 +190,8 @@ static char *copy_token_name (struct ccl_token *tp)
 struct ccl_rpn_node *ccl_rpn_node_create(enum ccl_rpn_kind kind)
 {
     struct ccl_rpn_node *p;
-    p = (struct ccl_rpn_node *)xmalloc (sizeof(*p));
-    ccl_assert (p);
+    p = (struct ccl_rpn_node *)xmalloc(sizeof(*p));
+    ccl_assert(p);
     p->kind = kind;
 
     switch(kind)
@@ -208,7 +210,7 @@ struct ccl_rpn_node *ccl_rpn_node_create(enum ccl_rpn_kind kind)
  * ccl_rpn_delete: Delete RPN tree.
  * rpn:   Pointer to tree.
  */
-void ccl_rpn_delete (struct ccl_rpn_node *rpn)
+void ccl_rpn_delete(struct ccl_rpn_node *rpn)
 {
     struct ccl_rpn_attr *attr, *attr1;
     if (!rpn)
@@ -218,37 +220,36 @@ void ccl_rpn_delete (struct ccl_rpn_node *rpn)
     case CCL_RPN_AND:
     case CCL_RPN_OR:
     case CCL_RPN_NOT:
-        ccl_rpn_delete (rpn->u.p[0]);
-        ccl_rpn_delete (rpn->u.p[1]);
+        ccl_rpn_delete(rpn->u.p[0]);
+        ccl_rpn_delete(rpn->u.p[1]);
         break;
     case CCL_RPN_TERM:
-        xfree (rpn->u.t.term);
+        xfree(rpn->u.t.term);
         for (attr = rpn->u.t.attr_list; attr; attr = attr1)
         {
             attr1 = attr->next;
             if (attr->kind == CCL_RPN_ATTR_STRING)
                 xfree(attr->value.str);
             if (attr->set)
-                xfree (attr->set);
-            xfree (attr);
+                xfree(attr->set);
+            xfree(attr);
         }
         break;
     case CCL_RPN_SET:
-        xfree (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]);
-        ccl_rpn_delete (rpn->u.p[2]);
+        ccl_rpn_delete(rpn->u.p[0]);
+        ccl_rpn_delete(rpn->u.p[1]);
+        ccl_rpn_delete(rpn->u.p[2]);
         break;
     }
-    xfree (rpn);
+    xfree(rpn);
 }
 
-static struct ccl_rpn_node *find_spec (CCL_parser cclp,
-                                       struct ccl_rpn_attr **qa);
+static struct ccl_rpn_node *find_spec(CCL_parser cclp, ccl_qualifier_t *qa);
 
-static int is_term_ok (int look, int *list)
+static int is_term_ok(int look, int *list)
 {
     for (;*list >= 0; list++)
         if (look == *list)
@@ -256,16 +257,15 @@ static int is_term_ok (int look, int *list)
     return 0;
 }
 
-static struct ccl_rpn_node *search_terms (CCL_parser cclp,
-                                          struct ccl_rpn_attr **qa);
+static struct ccl_rpn_node *search_terms(CCL_parser cclp, ccl_qualifier_t *qa);
 
-static struct ccl_rpn_attr *add_attr_node (struct ccl_rpn_node *p,
+static struct ccl_rpn_attr *add_attr_node(struct ccl_rpn_node *p,
                                            const char *set, int type)
 {
     struct ccl_rpn_attr *n;
     
-    n = (struct ccl_rpn_attr *)xmalloc (sizeof(*n));
-    ccl_assert (n);
+    n = (struct ccl_rpn_attr *)xmalloc(sizeof(*n));
+    ccl_assert(n);
     if (set)
         n->set = xstrdup(set);
     else
@@ -313,9 +313,9 @@ void ccl_add_attr_string(struct ccl_rpn_node *p, const char *set,
  * multi:  whether we accept "multiple" tokens
  * return: pointer to node(s); NULL on error.
  */
-static struct ccl_rpn_node *search_term_x (CCL_parser cclp,
-                                           struct ccl_rpn_attr **qa,
-                                           int *term_list, int multi)
+static struct ccl_rpn_node *search_term_x(CCL_parser cclp,
+                                          ccl_qualifier_t *qa,
+                                          int *term_list, int multi)
 {
     struct ccl_rpn_node *p_top = 0;
     struct ccl_token *lookahead = cclp->look_token;
@@ -329,9 +329,9 @@ static struct ccl_rpn_node *search_term_x (CCL_parser cclp,
     if (!truncation_aliases)
         truncation_aliases = "?";
 
-    if (qual_val_type (qa, CCL_BIB1_STR, CCL_BIB1_STR_AND_LIST, 0))
+    if (qual_val_type(qa, CCL_BIB1_STR, CCL_BIB1_STR_AND_LIST, 0))
         and_list = 1;
-    if (qual_val_type (qa, CCL_BIB1_STR, CCL_BIB1_STR_OR_LIST, 0))
+    if (qual_val_type(qa, CCL_BIB1_STR, CCL_BIB1_STR_OR_LIST, 0))
         or_list = 1;
     while (1)
     {
@@ -413,7 +413,7 @@ static struct ccl_rpn_node *search_term_x (CCL_parser cclp,
         {
             struct ccl_rpn_attr *attr;
             
-            for (attr = qa[i]; attr; attr = attr->next)
+            for (attr = ccl_qual_get_attr(qa[i]); attr; attr = attr->next)
                 switch(attr->kind)
                 {
                 case CCL_RPN_ATTR_STRING:
@@ -461,7 +461,7 @@ static struct ccl_rpn_node *search_term_x (CCL_parser cclp,
         /* no holds the number of CCL tokens (1 or more) */
         
         if (structure_value == -1 && 
-            qual_val_type (qa, CCL_BIB1_STR, CCL_BIB1_STR_WP, &attset))
+            qual_val_type(qa, CCL_BIB1_STR, CCL_BIB1_STR_WP, &attset))
         {   /* no structure attribute met. Apply either structure attribute 
                WORD or PHRASE depending on number of CCL tokens */
             if (no == 1 && no_spaces == 0)
@@ -471,8 +471,8 @@ static struct ccl_rpn_node *search_term_x (CCL_parser cclp,
         }
 
         /* make the RPN token */
-        p->u.t.term = (char *)xmalloc (len);
-        ccl_assert (p->u.t.term);
+        p->u.t.term = (char *)xmalloc(len);
+        ccl_assert(p->u.t.term);
         p->u.t.term[0] = '\0';
         for (i = 0; i<no; i++)
         {
@@ -486,6 +486,10 @@ static struct ccl_rpn_node *search_term_x (CCL_parser cclp,
             }
             if (i == no-1 && right_trunc)
                 src_len--;
+#if 0
+            fprintf(stderr, "[%s %.*s]",
+                    ccl_qual_get_name(qa[0]), src_len, src_str);
+#endif
             if (i && cclp->look_token->ws_prefix_len)
             {
                 size_t len = strlen(p->u.t.term);
@@ -493,45 +497,45 @@ static struct ccl_rpn_node *search_term_x (CCL_parser cclp,
                                 cclp->look_token->ws_prefix_len);
                 p->u.t.term[len + cclp->look_token->ws_prefix_len] = '\0';
             }
-            strxcat (p->u.t.term, src_str, src_len);
+            strxcat(p->u.t.term, src_str, src_len);
             ADVANCE;
         }
         if (left_trunc && right_trunc)
         {
-            if (!qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_BOTH,
+            if (!qual_val_type(qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_BOTH,
                                 &attset))
             {
                 cclp->error_code = CCL_ERR_TRUNC_NOT_BOTH;
-                ccl_rpn_delete (p);
+                ccl_rpn_delete(p);
                 return NULL;
             }
             ccl_add_attr_numeric(p, attset, CCL_BIB1_TRU, 3);
         }
         else if (right_trunc)
         {
-            if (!qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_RIGHT,
+            if (!qual_val_type(qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_RIGHT,
                                  &attset))
             {
                 cclp->error_code = CCL_ERR_TRUNC_NOT_RIGHT;
-                ccl_rpn_delete (p);
+                ccl_rpn_delete(p);
                 return NULL;
             }
             ccl_add_attr_numeric(p, attset, CCL_BIB1_TRU, 1);
         }
         else if (left_trunc)
         {
-            if (!qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_LEFT,
+            if (!qual_val_type(qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_LEFT,
                                 &attset))
             {
                 cclp->error_code = CCL_ERR_TRUNC_NOT_LEFT;
-                ccl_rpn_delete (p);
+                ccl_rpn_delete(p);
                 return NULL;
             }
             ccl_add_attr_numeric(p, attset, CCL_BIB1_TRU, 2);
         }
         else
         {
-            if (qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_NONE,
+            if (qual_val_type(qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_NONE,
                                &attset))
                 ccl_add_attr_numeric(p, attset, CCL_BIB1_TRU, 100);
         }
@@ -543,16 +547,15 @@ static struct ccl_rpn_node *search_term_x (CCL_parser cclp,
     return p_top;
 }
 
-static struct ccl_rpn_node *search_term (CCL_parser cclp,
-                                         struct ccl_rpn_attr **qa)
+static struct ccl_rpn_node *search_term(CCL_parser cclp, ccl_qualifier_t *qa)
 {
     static int list[] = {CCL_TOK_TERM, CCL_TOK_COMMA, -1};
     return search_term_x(cclp, qa, list, 0);
 }
 
 static
-struct ccl_rpn_node *qualifiers_order (CCL_parser cclp,
-                                       struct ccl_rpn_attr **ap, char *attset)
+struct ccl_rpn_node *qualifiers_order(CCL_parser cclp,
+                                      ccl_qualifier_t *ap, char *attset)
 {
     int rel = 0;
     struct ccl_rpn_node *p;
@@ -568,11 +571,11 @@ struct ccl_rpn_node *qualifiers_order (CCL_parser cclp,
     }
     else if (cclp->look_token->len == 2)
     {
-        if (!memcmp (cclp->look_token->name, "<=", 2))
+        if (!memcmp(cclp->look_token->name, "<=", 2))
             rel = 2;
-        else if (!memcmp (cclp->look_token->name, ">=", 2))
+        else if (!memcmp(cclp->look_token->name, ">=", 2))
             rel = 4;
-        else if (!memcmp (cclp->look_token->name, "<>", 2))
+        else if (!memcmp(cclp->look_token->name, "<>", 2))
             rel = 6;
     }
     if (!rel)
@@ -597,7 +600,7 @@ struct ccl_rpn_node *qualifiers_order (CCL_parser cclp,
             
             if (cclp->look_token->len > 1 && i == 0)
             {   /*  -xx*/
-                struct ccl_token *ntoken = ccl_token_add (cclp->look_token);
+                struct ccl_token *ntoken = ccl_token_add(cclp->look_token);
 
                 ntoken->kind = CCL_TOK_TERM;
                 ntoken->name = cclp->look_token->name + 1;
@@ -608,7 +611,7 @@ struct ccl_rpn_node *qualifiers_order (CCL_parser cclp,
             }
             else if (cclp->look_token->len > 1 && i == cclp->look_token->len-1)
             {   /* xx- */
-                struct ccl_token *ntoken = ccl_token_add (cclp->look_token);
+                struct ccl_token *ntoken = ccl_token_add(cclp->look_token);
 
                 ntoken->kind = CCL_TOK_TERM;
                 ntoken->name = "-";
@@ -618,8 +621,8 @@ struct ccl_rpn_node *qualifiers_order (CCL_parser cclp,
             }
             else if (cclp->look_token->len > 2 && i < cclp->look_token->len)
             {   /* xx-yy */
-                struct ccl_token *ntoken1 = ccl_token_add (cclp->look_token);
-                struct ccl_token *ntoken2 = ccl_token_add (ntoken1);
+                struct ccl_token *ntoken1 = ccl_token_add(cclp->look_token);
+                struct ccl_token *ntoken2 = ccl_token_add(ntoken1);
 
                 ntoken1->kind = CCL_TOK_TERM;  /* generate - */
                 ntoken1->name = "-";
@@ -639,7 +642,7 @@ struct ccl_rpn_node *qualifiers_order (CCL_parser cclp,
                      
             {   /* xx -yy */
                 /* we _know_ that xx does not have - in it */
-                struct ccl_token *ntoken = ccl_token_add (cclp->look_token);
+                struct ccl_token *ntoken = ccl_token_add(cclp->look_token);
 
                 ntoken->kind = CCL_TOK_TERM;    /* generate - */
                 ntoken->name = "-";
@@ -657,16 +660,16 @@ struct ccl_rpn_node *qualifiers_order (CCL_parser cclp,
         cclp->look_token->next->name[0] == '-')
     {
         struct ccl_rpn_node *p1;
-        if (!(p1 = search_term (cclp, ap)))
+        if (!(p1 = search_term(cclp, ap)))
             return NULL;
         ADVANCE;                   /* skip '-' */
         if (KIND == CCL_TOK_TERM)  /* = term - term  ? */
         {
             struct ccl_rpn_node *p2;
             
-            if (!(p2 = search_term (cclp, ap)))
+            if (!(p2 = search_term(cclp, ap)))
             {
-                ccl_rpn_delete (p1);
+                ccl_rpn_delete(p1);
                 return NULL;
             }
             p = ccl_rpn_node_create(CCL_RPN_AND);
@@ -687,7 +690,7 @@ struct ccl_rpn_node *qualifiers_order (CCL_parser cclp,
              cclp->look_token->name[0] == '-')   /* = - term  ? */
     {
         ADVANCE;
-        if (!(p = search_term (cclp, ap)))
+        if (!(p = search_term(cclp, ap)))
             return NULL;
         ccl_add_attr_numeric(p, attset, CCL_BIB1_REL, 2);
         return p;
@@ -695,12 +698,12 @@ struct ccl_rpn_node *qualifiers_order (CCL_parser cclp,
     else if (KIND == CCL_TOK_LP)
     {
         ADVANCE;
-        if (!(p = find_spec (cclp, ap)))
+        if (!(p = find_spec(cclp, ap)))
             return NULL;
         if (KIND != CCL_TOK_RP)
         {
             cclp->error_code = CCL_ERR_RP_EXPECTED;
-            ccl_rpn_delete (p);
+            ccl_rpn_delete(p);
             return NULL;
         }
         ADVANCE;
@@ -708,7 +711,7 @@ struct ccl_rpn_node *qualifiers_order (CCL_parser cclp,
     }
     else
     {
-        if (!(p = search_terms (cclp, ap)))
+        if (!(p = search_terms(cclp, ap)))
             return NULL;
         ccl_add_attr_numeric(p, attset, CCL_BIB1_REL, rel);
         return p;
@@ -718,7 +721,7 @@ struct ccl_rpn_node *qualifiers_order (CCL_parser cclp,
 }
 
 static
-struct ccl_rpn_node *qualifiers2 (CCL_parser cclp, struct ccl_rpn_attr **ap)
+struct ccl_rpn_node *qualifier_relation(CCL_parser cclp, ccl_qualifier_t *ap)
 {
     char *attset;
     struct ccl_rpn_node *p;
@@ -737,36 +740,36 @@ struct ccl_rpn_node *qualifiers2 (CCL_parser cclp, struct ccl_rpn_attr **ap)
     if (KIND == CCL_TOK_LP)
     {
         ADVANCE;
-        if (!(p = find_spec (cclp, ap)))
+        if (!(p = find_spec(cclp, ap)))
         {
             return NULL;
         }
         if (KIND != CCL_TOK_RP)
         {
             cclp->error_code = CCL_ERR_RP_EXPECTED;
-            ccl_rpn_delete (p);
+            ccl_rpn_delete(p);
             return NULL;
         }
         ADVANCE;
     }
     else
-        p = search_terms (cclp, ap);
+        p = search_terms(cclp, ap);
     return p;
 }
 
 /**
- * qualifiers1: Parse CCL qualifiers and search terms. 
+ * qualifier_list: Parse CCL qualifiers and search terms. 
  * cclp:   CCL Parser
  * la:     Token pointer to RELATION token.
  * qa:     Qualifier attributes already applied.
  * return: pointer to node(s); NULL on error.
  */
-static struct ccl_rpn_node *qualifiers1 (CCL_parser cclp, struct ccl_token *la,
-                                         struct ccl_rpn_attr **qa)
+static struct ccl_rpn_node *qualifier_list(CCL_parser cclp, struct ccl_token *la,
+                                        ccl_qualifier_t *qa)
 {
     struct ccl_token *lookahead = cclp->look_token;
     struct ccl_token *look_start = cclp->look_token;
-    struct ccl_rpn_attr **ap;
+    ccl_qualifier_t *ap;
     struct ccl_rpn_node *node = 0;
     const char *field_str;
     int no = 0;
@@ -786,15 +789,15 @@ static struct ccl_rpn_node *qualifiers1 (CCL_parser cclp, struct ccl_token *la,
     if (qa)
         for (i=0; qa[i]; i++)
             no++;
-    ap = (struct ccl_rpn_attr **)xmalloc ((no ? (no+1) : 2) * sizeof(*ap));
-    ccl_assert (ap);
+    ap = (ccl_qualifier_t *)xmalloc((no ? (no+1) : 2) * sizeof(*ap));
+    ccl_assert(ap);
 
     field_str = ccl_qual_search_special(cclp->bibset, "field");
     if (field_str)
     {
-        if (!strcmp (field_str, "or"))
+        if (!strcmp(field_str, "or"))
             mode_merge = 0;
-        else if (!strcmp (field_str, "merge"))
+        else if (!strcmp(field_str, "merge"))
             mode_merge = 1;
     }
     if (!mode_merge)
@@ -805,17 +808,17 @@ static struct ccl_rpn_node *qualifiers1 (CCL_parser cclp, struct ccl_token *la,
         {
             ap[1] = 0;
             seq = 0;
-            while ((ap[0] = ccl_qual_search (cclp, lookahead->name,
-                                             lookahead->len, 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);
+                node_sub = qualifier_relation(cclp, ap);
                 if (!node_sub)
                 {
-                    ccl_rpn_delete (node);
-                    xfree (ap);
+                    ccl_rpn_delete(node);
+                    xfree(ap);
                     return 0;
                 }
                 if (node)
@@ -834,7 +837,7 @@ static struct ccl_rpn_node *qualifiers1 (CCL_parser cclp, struct ccl_token *la,
             {
                 cclp->look_token = lookahead;
                 cclp->error_code = CCL_ERR_UNKNOWN_QUAL;
-                xfree (ap);
+                xfree(ap);
                 return NULL;
             }
             lookahead = lookahead->next;
@@ -852,18 +855,18 @@ static struct ccl_rpn_node *qualifiers1 (CCL_parser cclp, struct ccl_token *la,
             lookahead = look_start;
             for (i = 0; lookahead != la; i++)
             {
-                ap[i] = ccl_qual_search (cclp, lookahead->name,
+                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,
+                    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);
+                    xfree(ap);
                     return NULL;
                 }
                 lookahead = lookahead->next;
@@ -872,7 +875,7 @@ static struct ccl_rpn_node *qualifiers1 (CCL_parser cclp, struct ccl_token *la,
             }
             if (qa)
             {
-                struct ccl_rpn_attr **qa0 = qa;
+                ccl_qualifier_t *qa0 = qa;
                 
                 while (*qa0)
                     ap[i++] = *qa0++;
@@ -884,10 +887,10 @@ static struct ccl_rpn_node *qualifiers1 (CCL_parser cclp, struct ccl_token *la,
             
             cclp->look_token = lookahead;
             
-            node_sub = qualifiers2(cclp, ap);
+            node_sub = qualifier_relation(cclp, ap);
             if (!node_sub)
             {
-                ccl_rpn_delete (node);
+                ccl_rpn_delete(node);
                 break;
             }
             if (node)
@@ -903,7 +906,7 @@ static struct ccl_rpn_node *qualifiers1 (CCL_parser cclp, struct ccl_token *la,
             seq++;
         }
     }
-    xfree (ap);
+    xfree(ap);
     return node;
 }
 
@@ -914,13 +917,12 @@ static struct ccl_rpn_node *qualifiers1 (CCL_parser cclp, struct ccl_token *la,
  * qa:     Qualifier attributes already applied.
  * return: pointer to node(s); NULL on error.
  */
-static struct ccl_rpn_node *search_terms (CCL_parser cclp,
-                                          struct ccl_rpn_attr **qa)
+static struct ccl_rpn_node *search_terms(CCL_parser cclp, ccl_qualifier_t *qa)
 {
     static int list[] = {
         CCL_TOK_TERM, CCL_TOK_COMMA,CCL_TOK_EQ, CCL_TOK_REL, CCL_TOK_SET, -1};
     struct ccl_rpn_node *p1, *p2, *pn;
-    p1 = search_term_x (cclp, qa, list, 1);
+    p1 = search_term_x(cclp, qa, list, 1);
     if (!p1)
         return NULL;
     while (1)
@@ -938,10 +940,10 @@ static struct ccl_rpn_node *search_terms (CCL_parser cclp,
             p_prox->u.t.attr_list = 0;
 
             ADVANCE;
-            p2 = search_term_x (cclp, qa, list, 1);
+            p2 = search_term_x(cclp, qa, list, 1);
             if (!p2)
             {
-                ccl_rpn_delete (p1);
+                ccl_rpn_delete(p1);
                 return NULL;
             }
             pn = ccl_rpn_node_create(CCL_RPN_PROX);
@@ -952,10 +954,10 @@ static struct ccl_rpn_node *search_terms (CCL_parser cclp,
         }
         else if (is_term_ok(KIND, list))
         {
-            p2 = search_term_x (cclp, qa, list, 1);
+            p2 = search_term_x(cclp, qa, list, 1);
             if (!p2)
             {
-                ccl_rpn_delete (p1);
+                ccl_rpn_delete(p1);
                 return NULL;
             }
             pn = ccl_rpn_node_create(CCL_RPN_PROX);
@@ -976,21 +978,21 @@ static struct ccl_rpn_node *search_terms (CCL_parser cclp,
  * qa:     Qualifier attributes already applied.
  * return: pointer to node(s); NULL on error.
  */
-static struct ccl_rpn_node *search_elements (CCL_parser cclp,
-                                             struct ccl_rpn_attr **qa)
+static struct ccl_rpn_node *search_elements(CCL_parser cclp,
+                                            ccl_qualifier_t *qa)
 {
     struct ccl_rpn_node *p1;
     struct ccl_token *lookahead;
     if (KIND == CCL_TOK_LP)
     {
         ADVANCE;
-        p1 = find_spec (cclp, qa);
+        p1 = find_spec(cclp, qa);
         if (!p1)
             return NULL;
         if (KIND != CCL_TOK_RP)
         {
             cclp->error_code = CCL_ERR_RP_EXPECTED;
-            ccl_rpn_delete (p1);
+            ccl_rpn_delete(p1);
             return NULL;
         }
         ADVANCE;
@@ -1007,7 +1009,7 @@ static struct ccl_rpn_node *search_elements (CCL_parser cclp,
             return NULL;
         }
         p1 = ccl_rpn_node_create(CCL_RPN_SET);
-        p1->u.setname = copy_token_name (cclp->look_token);
+        p1->u.setname = copy_token_name(cclp->look_token);
         ADVANCE;
         return p1;
     }
@@ -1017,16 +1019,16 @@ 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 qualifiers1 (cclp, lookahead, qa);
+            return qualifier_list(cclp, lookahead, qa);
         if (lookahead->kind != CCL_TOK_COMMA)
             break;
         lookahead = lookahead->next;
     }
     if (qa)
-        return search_terms (cclp, qa);
+        return search_terms(cclp, qa);
     else
     {
-        struct ccl_rpn_attr *qa[2];
+        ccl_qualifier_t qa[2];
         struct ccl_rpn_node *node = 0;
         int seq;
         lookahead = cclp->look_token;
@@ -1041,10 +1043,10 @@ static struct ccl_rpn_node *search_elements (CCL_parser cclp,
 
             cclp->look_token = lookahead;
 
-            node_sub = search_terms (cclp, qa);
+            node_sub = search_terms(cclp, qa);
             if (!node_sub)
             {
-                ccl_rpn_delete (node);
+                ccl_rpn_delete(node);
                 return 0;
             }
             if (node)
@@ -1060,7 +1062,7 @@ static struct ccl_rpn_node *search_elements (CCL_parser cclp,
                 node = node_sub;
         }
         if (!node)
-            node = search_terms (cclp, 0);
+            node = search_terms(cclp, 0);
         return node;
     }
 }
@@ -1071,11 +1073,10 @@ static struct ccl_rpn_node *search_elements (CCL_parser cclp,
  * qa:     Qualifier attributes already applied.
  * return: pointer to node(s); NULL on error.
  */
-static struct ccl_rpn_node *find_spec (CCL_parser cclp,
-                                       struct ccl_rpn_attr **qa)
+static struct ccl_rpn_node *find_spec(CCL_parser cclp, ccl_qualifier_t *qa)
 {
     struct ccl_rpn_node *p1, *p2, *pn;
-    if (!(p1 = search_elements (cclp, qa)))
+    if (!(p1 = search_elements(cclp, qa)))
         return NULL;
     while (1)
     {
@@ -1083,10 +1084,10 @@ static struct ccl_rpn_node *find_spec (CCL_parser cclp,
         {
         case CCL_TOK_AND:
             ADVANCE;
-            p2 = search_elements (cclp, qa);
+            p2 = search_elements(cclp, qa);
             if (!p2)
             {
-                ccl_rpn_delete (p1);
+                ccl_rpn_delete(p1);
                 return NULL;
             }
             pn = ccl_rpn_node_create(CCL_RPN_AND);
@@ -1097,10 +1098,10 @@ static struct ccl_rpn_node *find_spec (CCL_parser cclp,
             continue;
         case CCL_TOK_OR:
             ADVANCE;
-            p2 = search_elements (cclp, qa);
+            p2 = search_elements(cclp, qa);
             if (!p2)
             {
-                ccl_rpn_delete (p1);
+                ccl_rpn_delete(p1);
                 return NULL;
             }
             pn = ccl_rpn_node_create(CCL_RPN_OR);
@@ -1111,10 +1112,10 @@ static struct ccl_rpn_node *find_spec (CCL_parser cclp,
             continue;
         case CCL_TOK_NOT:
             ADVANCE;
-            p2 = search_elements (cclp, qa);
+            p2 = search_elements(cclp, qa);
             if (!p2)
             {
-                ccl_rpn_delete (p1);
+                ccl_rpn_delete(p1);
                 return NULL;
             }
             pn = ccl_rpn_node_create(CCL_RPN_NOT);
@@ -1144,14 +1145,14 @@ struct ccl_rpn_node *ccl_parser_find_token(CCL_parser cclp,
     struct ccl_rpn_node *p;
 
     cclp->look_token = list;
-    p = find_spec (cclp, NULL);
+    p = find_spec(cclp, NULL);
     if (p && KIND != CCL_TOK_EOL)
     {
         if (KIND == CCL_TOK_RP)
             cclp->error_code = CCL_ERR_BAD_RP;
         else
             cclp->error_code = CCL_ERR_OP_EXPECTED;
-        ccl_rpn_delete (p);
+        ccl_rpn_delete(p);
         p = NULL;
     }
     cclp->error_pos = cclp->look_token->name;
@@ -1173,18 +1174,18 @@ struct ccl_rpn_node *ccl_parser_find_token(CCL_parser cclp,
 struct ccl_rpn_node *ccl_find_str(CCL_bibset bibset, const char *str,
                                   int *error, int *pos)
 {
-    CCL_parser cclp = ccl_parser_create (bibset);
+    CCL_parser cclp = ccl_parser_create(bibset);
     struct ccl_token *list;
     struct ccl_rpn_node *p;
 
-    list = ccl_parser_tokenize (cclp, str);
+    list = ccl_parser_tokenize(cclp, str);
     p = ccl_parser_find_token(cclp, list);
 
     *error = cclp->error_code;
     if (*error)
         *pos = cclp->error_pos - str;
-    ccl_parser_destroy (cclp);
-    ccl_token_del (list);
+    ccl_parser_destroy(cclp);
+    ccl_token_del(list);
     return p;
 }
 /*
index 0cc5b5b..1f59728 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2005, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: cclp.h,v 1.2 2007-04-27 09:50:35 adam Exp $
+ * $Id: cclp.h,v 1.3 2007-04-30 11:33:49 adam Exp $
  */
 
 /** 
@@ -24,6 +24,7 @@
 #define CCL_TOK_NOT   10
 #define CCL_TOK_SET   11
 
+typedef struct ccl_qualifier *ccl_qualifier_t;
 
 /** CCL token */
 struct ccl_token {
@@ -88,6 +89,15 @@ struct ccl_rpn_node *ccl_parser_find_token(CCL_parser cclp,
                                            struct ccl_token *list);
 
 
+YAZ_EXPORT
+ccl_qualifier_t ccl_qual_search(CCL_parser cclp, const char *name, 
+                                size_t name_len, int seq);
+
+YAZ_EXPORT
+struct ccl_rpn_attr *ccl_qual_get_attr(ccl_qualifier_t q);
+
+YAZ_EXPORT
+const char *ccl_qual_get_name(ccl_qualifier_t q);
 
 /*
  * Local variables:
index f187c5e..1c2dc1e 100644 (file)
@@ -48,7 +48,7 @@
 /* CCL qualifiers
  * Europagate, 1995
  *
- * $Id: cclqual.c,v 1.7 2007-04-26 22:11:32 adam Exp $
+ * $Id: cclqual.c,v 1.8 2007-04-30 11:33:49 adam Exp $
  *
  * Old Europagate Log:
  *
@@ -327,52 +327,58 @@ void ccl_qual_rm(CCL_bibset *b)
     *b = NULL;
 }
 
-/** \brief searches for qualifier attributes
-    \param cclp CCL parser
-    \param name qualifier name to for search (length given by len)
-    \param len length of name
-    \param seq attribute index (0=first, 1=second, ..)
-    \returns attribute or NULL if none is found
-*/
-struct ccl_rpn_attr *ccl_qual_search(CCL_parser cclp, const char *name, 
-                                     size_t len, int seq)
+ccl_qualifier_t ccl_qual_search(CCL_parser cclp, const char *name, 
+                                size_t name_len, int seq)
 {
-    struct ccl_qualifier *q;
+    struct ccl_qualifier *q = 0;
     const char *aliases;
     int case_sensitive = cclp->ccl_case_sensitive;
 
     ccl_assert(cclp);
     if (!cclp->bibset)
-        return NULL;
+        return 0;
 
     aliases = ccl_qual_search_special(cclp->bibset, "case");
     if (aliases)
         case_sensitive = atoi(aliases);
 
     for (q = cclp->bibset->list; q; q = q->next)
-        if (strlen(q->name) == len)
+        if (strlen(q->name) == name_len)
         {
             if (case_sensitive)
             {
-                if (!memcmp(name, q->name, len))
+                if (!memcmp(name, q->name, name_len))
                     break;
             }
             else
             {
-                if (!ccl_memicmp(name, q->name, len))
+                if (!ccl_memicmp(name, q->name, name_len))
                     break;
             }
         }
     if (q)
     {
-        if (q->attr_list && seq == 0)
-            return q->attr_list;
-        if (seq < q->no_sub && q->sub[seq])
+        if (q->no_sub)
         {
-            return q->sub[seq]->attr_list;
+            if (seq < q->no_sub)
+                q = q->sub[seq];
+            else
+                q = 0;
         }
+        else if (seq)
+            q = 0;
     }
-    return 0;
+    return q;
+}
+
+struct ccl_rpn_attr *ccl_qual_get_attr(ccl_qualifier_t q)
+{
+    return q->attr_list;
+}
+
+const char *ccl_qual_get_name(ccl_qualifier_t q)
+{
+    return q->name;
 }
 
 const char *ccl_qual_search_special(CCL_bibset b, const char *name)