Improved handling of qualifiers. Aliases or reserved words.
authorAdam Dickmeiss <adam@indexdata.dk>
Mon, 17 Apr 1995 09:31:34 +0000 (09:31 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Mon, 17 Apr 1995 09:31:34 +0000 (09:31 +0000)
ccl/Makefile
ccl/bib1
ccl/cclerrms.c
ccl/cclfind.c
ccl/cclqfile.c [new file with mode: 0644]
ccl/cclqual.c
ccl/ccltoken.c

index 9df590b..841ec93 100644 (file)
@@ -2,7 +2,10 @@
 # Europagate, 1995
 #
 # $Log: Makefile,v $
-# Revision 1.8  1995/04/10 10:22:35  quinn
+# Revision 1.9  1995/04/17 09:31:34  adam
+# Improved handling of qualifiers. Aliases or reserved words.
+#
+# Revision 1.8  1995/04/10  10:22:35  quinn
 # Added ccl directory.
 #
 # Revision 1.7  1995/03/27  12:49:03  adam
@@ -28,7 +31,7 @@ INCLUDE=-I../include
 #CFLAGS=-g -Wall -pedantic -ansi
 TPROG1=cclsh
 LIB=../lib/ccl.a
-PO=cclfind.o ccltoken.o cclerrms.o cclqual.o cclptree.o
+PO=cclfind.o ccltoken.o cclerrms.o cclqual.o cclptree.o cclqfile.o
 CPP=$(CC) -E
 DEFS=$(INCLUDE)
 
@@ -48,39 +51,19 @@ $(LIB): $(PO)
 clean:
        rm -f *.log *.[oa] $(TPROG1) $(TPROG2) core mon.out gmon.out errlist *~
 
-depend: depend1
+depend: depend2
 
 depend1:
-       mv Makefile Makefile.tmp
-       sed '/^#Depend/q' <Makefile.tmp >Makefile
-       $(CPP) $(INCLUDE) -M *.c >>Makefile
-       -rm Makefile.tmp
+       sed '/^#Depend/q' <Makefile >Makefile.tmp
+       $(CPP) $(DEFS) -M *.c >>Makefile.tmp
+       mv -f Makefile.tmp Makefile
 
 depend2:
-       $(CPP) $(INCLUDE) -M *.c >.depend       
+       $(CPP) $(DEFS) -M *.c >.depend  
 
-#ifeq (.depend,$(wildcard .depend))
-#include .depend
-#endif
+#GNU make style depend
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
 
 #Depend --- DOT NOT DELETE THIS LINE
-cclerrms.o : cclerrms.c 
-cclfind.o : cclfind.c /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
-  /usr/include/libio.h /usr/include/_G_config.h /usr/include/stdlib.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h \
-  /usr/include/errno.h /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
-  /usr/include/alloca.h /usr/include/assert.h /usr/include/string.h ../include/ccl.h 
-cclptree.o : cclptree.c /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
-  /usr/include/libio.h /usr/include/_G_config.h /usr/include/assert.h /usr/include/string.h \
-  /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h ../include/ccl.h 
-cclqual.o : cclqual.c /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
-  /usr/include/libio.h /usr/include/_G_config.h /usr/include/stdlib.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h \
-  /usr/include/errno.h /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
-  /usr/include/alloca.h /usr/include/assert.h /usr/include/string.h ../include/ccl.h 
-cclsh.o : cclsh.c /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
-  /usr/include/libio.h /usr/include/_G_config.h /usr/include/stdlib.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h \
-  /usr/include/errno.h /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
-  /usr/include/alloca.h /usr/include/assert.h ../include/ccl.h 
-ccltoken.o : ccltoken.c /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
-  /usr/include/libio.h /usr/include/_G_config.h /usr/include/string.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/stddef.h \
-  /usr/include/stdlib.h /usr/include/errno.h /usr/include/linux/errno.h /usr/lib/gcc-lib/i486-linux/2.5.8/include/float.h \
-  /usr/include/alloca.h /usr/include/assert.h ../include/ccl.h 
index 9529a80..173e4e5 100644 (file)
--- a/ccl/bib1
+++ b/ccl/bib1
@@ -1,4 +1,4 @@
-# $Id: bib1,v 1.3 1995/02/23 08:31:59 adam Exp $
+# $Id: bib1,v 1.4 1995/04/17 09:31:38 adam Exp $
 # CCL qualifiers and their mapping to a bib-1 subset
 #
 term s=pw   t=l,r
@@ -8,10 +8,62 @@ isbn u=7
 issn u=8
 cc   u=20
 su   u=21   s=pw
-date u=30   r=o
+date u=30   r=o s=pw
 dp   u=31   r=o
 da   u=32   r=o
 la   u=54   s=pw
 ab   u=62   s=pw
 note u=63   s=pw
 af   u=1006 s=pw
+rel         s=9
+
+# Relation Attributes
+rel:lt      r=1
+rel:le      r=2
+rel:eq      r=3
+rel:ge      r=4
+rel:gt      r=5
+rel:ne      r=6
+rel:phon    r=100
+rel:stem    r=101
+rel:rele    r=102
+rel:alwa    r=103
+
+# Position Attributes
+pos:ff      p=1
+pos:fs      p=2
+pos:af      p=3
+
+# Structure Attributes
+str:wp      s=pw
+str:phrase  s=1
+str:word    s=2
+str:key     s=3
+str:year    s=4
+str:date    s=5
+str:wlist   s=6
+str:dateu   s=100
+str:daten   s=101
+str:nameu   s=102
+str:struc   s=103
+str:urx     s=104
+str:fft     s=105
+str:dt      s=106
+str:ln      s=107
+str:str     s=108
+str:num     s=109
+
+# Truncation Attributes
+tru:right   t=1
+tru:left    t=2
+tru:both    t=3
+tru:none    t=100
+tru:proh    t=101
+tru:re1     t=102
+tru:re2     t=103
+
+# Completeness Attributes
+com:is      c=1
+com:cs      c=2
+com:cf      c=3
+
index 2ffa907..4e8baf0 100644 (file)
@@ -2,7 +2,10 @@
  * Europagate, 1995
  *
  * $Log: cclerrms.c,v $
- * Revision 1.6  1995/02/23 08:31:59  adam
+ * Revision 1.7  1995/04/17 09:31:40  adam
+ * Improved handling of qualifiers. Aliases or reserved words.
+ *
+ * Revision 1.6  1995/02/23  08:31:59  adam
  * Changed header.
  *
  * Revision 1.4  1995/02/14  16:20:54  adam
@@ -35,6 +38,11 @@ char *err_msg_array[] = {
     "Right truncation not supported"
 };
 
+/*
+ * ccl_err_msg: return name of CCL error
+ * ccl_errno:   Error no.
+ * return:      Name of error.
+ */
 const char *ccl_err_msg (int ccl_errno)
 {
     return err_msg_array[ccl_errno];
index 3fac8e5..cbbe75d 100644 (file)
@@ -2,7 +2,10 @@
  * Europagate, 1995
  *
  * $Log: cclfind.c,v $
- * Revision 1.12  1995/03/20 15:27:43  adam
+ * Revision 1.13  1995/04/17 09:31:42  adam
+ * Improved handling of qualifiers. Aliases or reserved words.
+ *
+ * Revision 1.12  1995/03/20  15:27:43  adam
  * Minor changes.
  *
  * Revision 1.11  1995/02/23  08:31:59  adam
 
 #include <ccl.h>
 
+/* current lookahead token */
 static struct ccl_token *look_token;
+
+/* holds error no if error occur */
 static int ccl_error;
+
+/* current bibset */
 static CCL_bibset bibset;
 
+/* returns type of current lookahead */
 #define KIND (look_token->kind)
+
+/* move one token forward */
 #define ADVANCE look_token = look_token->next
-#define ADVX(x) x=(x)->next
 
-static struct ccl_rpn_attr *qual_val (struct ccl_rpn_attr *list, int type)
+/* 
+ * qual_val_range: search for attribute of type with range
+ * qa:     Attribute array
+ * type:   Type of attribute to search for
+ * vmin:   Lower bound of value to search for
+ * vmax:   Upper bound of value to search for
+ * return: Return pointer to integer of attribute value found; NULL
+ *         otherwise.
+ */
+static int *qual_val_range (struct ccl_rpn_attr **qa, int type,
+                            int vmin, int vmax)
 {
-    while (list)
-    {
-        if (list->type == type)
-            return list;
-        list = list->next;
-    }
+    int i;
+    struct ccl_rpn_attr *q;
+
+    if (!qa)
+        return NULL;
+    for (i = 0; (q=qa[i]); i++)
+        while (q)
+       {
+            if (q->type == type && q->value >= vmin && q->value <= vmax)
+               return &q->value;
+           q = q->next;
+       }
     return NULL;
 }
 
-static int qual_val_type (struct ccl_rpn_attr *list, int type, int value)
+/* 
+ * qual_val_type: test for existance of attribute type/value pair.
+ * qa:     Attribute array
+ * type:   Type of attribute to search for
+ * 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)
 {
-    while (list)
-    {
-        if (list->type == type && list->value == value)
-            return 1;
-        list = list->next;
-    }
+    int i;
+    struct ccl_rpn_attr *q;
+
+    if (!qa)
+        return 0;
+    for (i = 0;  (q=qa[i]); i++)
+        while (q)
+       {
+            if (q->type == type && q->value == value)
+               return 1;
+           q = q->next;
+       }
     return 0;
 }
 
+/*
+ * strxcat: concatenate strings.
+ * n:      Null-terminated Destination string 
+ * src:    Source string to be appended (not null-terminated)
+ * len:    Length of source string.
+ */
 static void strxcat (char *n, const char *src, int len)
 {
     while (*n)
@@ -85,6 +130,11 @@ static void strxcat (char *n, const char *src, int len)
     *n = '\0';
 }
 
+/*
+ * copy_token_name: Return copy of CCL token name
+ * tp:      Pointer to token info.
+ * return:  malloc(3) allocated copy of token name.
+ */
 static char *copy_token_name (struct ccl_token *tp)
 {
     char *str = malloc (tp->len + 1);
@@ -94,6 +144,11 @@ static char *copy_token_name (struct ccl_token *tp)
     return str;
 }
 
+/*
+ * mk_node: Create RPN node.
+ * kind:   Type of node.
+ * return: pointer to allocated node.
+ */
 static struct ccl_rpn_node *mk_node (enum rpn_node_kind kind)
 {
     struct ccl_rpn_node *p;
@@ -103,6 +158,10 @@ static struct ccl_rpn_node *mk_node (enum rpn_node_kind kind)
     return p;
 }
 
+/*
+ * ccl_rpn_delete: Delete RPN tree.
+ * rpn:   Pointer to tree.
+ */
 void ccl_rpn_delete (struct ccl_rpn_node *rpn)
 {
     struct ccl_rpn_attr *attr, *attr1;
@@ -138,6 +197,12 @@ void ccl_rpn_delete (struct ccl_rpn_node *rpn)
 static struct ccl_rpn_node *find_spec (struct ccl_rpn_attr **qa);
 static struct ccl_rpn_node *search_terms (struct ccl_rpn_attr **qa);
 
+/*
+ * add_attr: Add attribute (type/value) to RPN term node.
+ * p:     RPN node of type term.
+ * type:  Type of attribute
+ * value: Value of attribute
+ */
 static void add_attr (struct ccl_rpn_node *p, int type, int value)
 {
     struct ccl_rpn_attr *n;
@@ -150,26 +215,92 @@ static void add_attr (struct ccl_rpn_node *p, int type, int value)
     p->u.t.attr_list = n;
 }
 
+/*
+ * search_term: Parse CCL search term. 
+ * qa:     Qualifier attributes already applied.
+ * return: pointer to node(s); NULL on error.
+ */
 static struct ccl_rpn_node *search_term (struct ccl_rpn_attr **qa)
 {
     struct ccl_rpn_node *p;
-    struct ccl_rpn_attr *attr;
     struct ccl_token *lookahead = look_token;
     int len = 0;
     int no, i;
     int left_trunc = 0;
     int right_trunc = 0;
     int mid_trunc = 0;
+    int relation_value = -1;
+    int position_value = -1;
+    int structure_value = -1;
+    int truncation_value = -1;
+    int completeness_value = -1;
 
     if (KIND != CCL_TOK_TERM)
     {
         ccl_error = CCL_ERR_TERM_EXPECTED;
         return NULL;
     }
+    /* create the term node, but wait a moment before adding the term */
+    p = mk_node (CCL_RPN_TERM);
+    p->u.t.attr_list = NULL;
+    p->u.t.term = NULL;
+
+    if (!qa)
+    {
+        /* no qualifier(s) applied. Use 'term' if it is defined */
+
+        qa = malloc (2*sizeof(*qa));
+       assert (qa);
+       qa[0] = ccl_qual_search (bibset, "term", 4);
+       qa[1] = NULL;
+    }
+
+    /* 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 = qa[i]; attr; attr = attr->next)
+            if (attr->value > 0)
+           {   /* deal only with REAL attributes (positive) */
+               switch (attr->type)
+               {
+               case CCL_BIB1_REL:
+                   if (relation_value != -1)
+                       continue;
+                   relation_value = attr->value;
+                   break;
+               case CCL_BIB1_POS:
+                   if (position_value != -1)
+                       continue;
+                   position_value = attr->value;
+                   break;
+               case CCL_BIB1_STR:
+                   if (structure_value != -1)
+                       continue;
+                   structure_value = attr->value;
+                   break;
+               case CCL_BIB1_TRU:
+                   if (truncation_value != -1)
+                       continue;
+                   truncation_value = attr->value;
+                   break;
+               case CCL_BIB1_COM:
+                   if (completeness_value != -1)
+                       continue;
+                   completeness_value = attr->value;
+                   break;
+               }
+                add_attr (p, attr->type, attr->value);
+           }
+    }
+    /* go through each TERM token. If no truncation attribute is yet
+       met, then look for left/right truncation markers (?) and
+       set left_trunc/right_trunc/mid_trunc accordingly */
     for (no = 0; lookahead->kind == CCL_TOK_TERM; no++)
     {
         for (i = 0; i<lookahead->len; i++)
-            if (lookahead->name[i] == '?')
+            if (truncation_value == -1 && lookahead->name[i] == '?')
             {
                 if (no == 0 && i == 0 && lookahead->len >= 1)
                     left_trunc = 1;
@@ -182,10 +313,22 @@ static struct ccl_rpn_node *search_term (struct ccl_rpn_attr **qa)
         len += 1+lookahead->len;
        lookahead = lookahead->next;
     }
-    p = mk_node (CCL_RPN_TERM);
+    /* len now holds the number of characters in the RPN term */
+    /* 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))
+    {   /* no structure attribute met. Apply either structure attribute 
+           WORD or PHRASE depending on number of CCL tokens */
+        if (no == 1)
+            add_attr (p, CCL_BIB1_STR, 2);
+        else
+            add_attr (p, CCL_BIB1_STR, 1);
+    }
+
+    /* make the RPN token */
     p->u.t.term = malloc (len);
     assert (p->u.t.term);
-    p->u.t.attr_list = NULL;
     p->u.t.term[0] = '\0';
     for (i = 0; i<no; i++)
     {
@@ -204,35 +347,12 @@ static struct ccl_rpn_node *search_term (struct ccl_rpn_attr **qa)
        strxcat (p->u.t.term, src_str, src_len);
         ADVANCE;
     }
-    if (qa)
-    {
-        int i;
-        for (i=0; qa[i]; i++)
-        {
-            struct ccl_rpn_attr *attr;
-
-            for (attr = qa[i]; attr; attr = attr->next)
-                if (attr->value > 0)
-                    add_attr (p, attr->type, attr->value);
-        }
-        attr = qa[0];
-    }
-    else 
-        attr = ccl_qual_search (bibset, "term", 4);
-    if (attr && qual_val_type (attr, CCL_BIB1_STR, CCL_BIB1_STR_WP))
-    {
-        if (no == 1)
-            add_attr (p, CCL_BIB1_STR, 2);
-        else
-            add_attr (p, CCL_BIB1_STR, 1);
-    }
     if (left_trunc && right_trunc)
     {
-        if (attr && !qual_val_type (attr, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_BOTH))
+        if (!qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_BOTH))
         {
             ccl_error = CCL_ERR_TRUNC_NOT_BOTH;
-            if (qa)
-                free (qa);
+            free (qa);
             ccl_rpn_delete (p);
             return NULL;
         }
@@ -240,11 +360,10 @@ static struct ccl_rpn_node *search_term (struct ccl_rpn_attr **qa)
     }
     else if (right_trunc)
     {
-        if (attr && !qual_val_type (attr, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_RIGHT))
+        if (!qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_RIGHT))
         {
             ccl_error = CCL_ERR_TRUNC_NOT_RIGHT;
-            if (qa)
-                free (qa);
+            free (qa);
             ccl_rpn_delete (p);
             return NULL;
         }
@@ -252,11 +371,10 @@ static struct ccl_rpn_node *search_term (struct ccl_rpn_attr **qa)
     }
     else if (left_trunc)
     {
-        if (attr && !qual_val_type (attr, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_LEFT))
+        if (!qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_LEFT))
         {
             ccl_error = CCL_ERR_TRUNC_NOT_LEFT;
-            if (qa)
-                free (qa);
+            free (qa);
             ccl_rpn_delete (p);
             return NULL;
         }
@@ -264,31 +382,40 @@ static struct ccl_rpn_node *search_term (struct ccl_rpn_attr **qa)
     }
     else
     {
-        if (attr && qual_val_type (attr, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_NONE))
+        if (qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_NONE))
             add_attr (p, CCL_BIB1_TRU, 100);
     }
     return p;
 }
 
+/*
+ * qualifiers: Parse CCL qualifiers and search terms. 
+ * la:     Token pointer to RELATION token.
+ * qa:     Qualifier attributes already applied.
+ * return: pointer to node(s); NULL on error.
+ */
 static struct ccl_rpn_node *qualifiers (struct ccl_token *la,
                                         struct ccl_rpn_attr **qa)
 {
     struct ccl_token *lookahead = look_token;
     struct ccl_rpn_attr **ap;
-    int no = 1;
+    int no = 0;
     int i, rel;
-    struct ccl_rpn_attr *attr;
-
+#if 0
     if (qa)
     {
         ccl_error = CCL_ERR_DOUBLE_QUAL;
         return NULL;
     }
+#endif
     for (lookahead = look_token; lookahead != la; lookahead=lookahead->next)
         no++;
-    ap = malloc (no * sizeof(*ap));
+    if (qa)
+        for (i=0; qa[i]; i++)
+           no++;
+    ap = malloc ((no+1) * sizeof(*ap));
     assert (ap);
-    for (i=0; look_token != la; i++)
+    for (i = 0; look_token != la; i++)
     {
         ap[i] = ccl_qual_search (bibset, look_token->name, look_token->len);
         if (!ap[i])
@@ -301,9 +428,11 @@ static struct ccl_rpn_node *qualifiers (struct ccl_token *la,
         if (KIND == CCL_TOK_COMMA)
             ADVANCE;
     }
+    if (qa)
+        while (*qa)
+           ap[i++] = *qa++;
     ap[i] = NULL;
-    if (! (attr = qual_val (ap[0], CCL_BIB1_REL)) ||
-        attr->value != CCL_BIB1_REL_ORDER)
+    if (!qual_val_type (ap, CCL_BIB1_REL, CCL_BIB1_REL_ORDER))
     {                
         /* unordered relation */
         struct ccl_rpn_node *p;
@@ -362,36 +491,36 @@ static struct ccl_rpn_node *qualifiers (struct ccl_token *la,
         struct ccl_rpn_node *p;
 
         ADVANCE;                      /* skip relation */
-        if (KIND == CCL_TOK_TERM)
+        if (KIND == CCL_TOK_TERM && look_token->next->kind == CCL_TOK_MINUS)
         {
             struct ccl_rpn_node *p1;
-            p1 = search_term (ap);
-            if (KIND == CCL_TOK_MINUS)
+            if (!(p1 = search_term (ap)))
+           {
+               free (ap);
+               return NULL;
+           }
+            ADVANCE;                   /* skip '-' */
+            if (KIND == CCL_TOK_TERM)  /* = term - term  ? */
             {
-                ADVANCE;                   /* skip '-' */
-                if (KIND == CCL_TOK_TERM)  /* = term - term  ? */
-                {
-                    struct ccl_rpn_node *p2;
-                    
-                    p2 = search_term (ap);
-                    p = mk_node (CCL_RPN_AND);
-                    p->u.p[0] = p1;
-                    add_attr (p1, CCL_BIB1_REL, 4);
-                    p->u.p[1] = p2;
-                    add_attr (p2, CCL_BIB1_REL, 2);
-                    free (ap);
-                    return p;
-                }
-                else                       /* = term -    */
-                {
-                    add_attr (p1, CCL_BIB1_REL, 4);
-                    free (ap);
-                    return p1;
-                }
+                struct ccl_rpn_node *p2;
+                
+                if (!(p2 = search_term (ap)))
+               {
+                    ccl_rpn_delete (p1);
+                   free (ap);
+                   return NULL;
+               }
+                p = mk_node (CCL_RPN_AND);
+                p->u.p[0] = p1;
+                add_attr (p1, CCL_BIB1_REL, 4);
+                p->u.p[1] = p2;
+                add_attr (p2, CCL_BIB1_REL, 2);
+                free (ap);
+                return p;
             }
-            else
+            else                       /* = term -    */
             {
-                add_attr (p1, CCL_BIB1_REL, rel);
+                add_attr (p1, CCL_BIB1_REL, 4);
                 free (ap);
                 return p1;
             }
@@ -399,17 +528,56 @@ static struct ccl_rpn_node *qualifiers (struct ccl_token *la,
         else if (KIND == CCL_TOK_MINUS)   /* = - term  ? */
         {
             ADVANCE;
-            p = search_term (ap);
+            if (!(p = search_term (ap)))
+           {
+               free (ap);
+               return NULL;
+           }
             add_attr (p, CCL_BIB1_REL, 2);
             free (ap);
             return p;
         }
+       else if (KIND == CCL_TOK_LP)
+       {
+            ADVANCE;
+            if (!(p = find_spec (ap)))
+            {
+                free (ap);
+                return NULL;
+            }
+            if (KIND != CCL_TOK_RP)
+            {
+                ccl_error = CCL_ERR_RP_EXPECTED;
+                ccl_rpn_delete (p);
+                free (ap);
+                return NULL;
+            }
+            ADVANCE;
+           free (ap);
+           return p;
+       }
+       else
+       {
+            if (!(p = search_terms (ap)))
+           {
+               free (ap);
+               return NULL;
+           }
+            add_attr (p, CCL_BIB1_REL, rel);
+           free (ap);
+           return p;
+       }
         ccl_error = CCL_ERR_TERM_EXPECTED;
     }
     free (ap);
     return NULL;
 }
 
+/*
+ * search_terms: Parse CCL search terms - including proximity.
+ * qa:     Qualifier attributes already applied.
+ * return: pointer to node(s); NULL on error.
+ */
 static struct ccl_rpn_node *search_terms (struct ccl_rpn_attr **qa)
 {
     struct ccl_rpn_node *p1, *p2, *pn;
@@ -451,6 +619,11 @@ static struct ccl_rpn_node *search_terms (struct ccl_rpn_attr **qa)
     return p1;
 }
 
+/*
+ * search_elements: Parse CCL search elements
+ * qa:     Qualifier attributes already applied.
+ * return: pointer to node(s); NULL on error.
+ */
 static struct ccl_rpn_node *search_elements (struct ccl_rpn_attr **qa)
 {
     struct ccl_rpn_node *p1;
@@ -494,6 +667,11 @@ static struct ccl_rpn_node *search_elements (struct ccl_rpn_attr **qa)
     return search_terms (qa);
 }
 
+/*
+ * find_spec: Parse CCL find specification
+ * qa:     Qualifier attributes already applied.
+ * return: pointer to node(s); NULL on error.
+ */
 static struct ccl_rpn_node *find_spec (struct ccl_rpn_attr **qa)
 {
     struct ccl_rpn_node *p1, *p2, *pn;
@@ -548,6 +726,14 @@ static struct ccl_rpn_node *find_spec (struct ccl_rpn_attr **qa)
     return p1;
 }
 
+/*
+ * ccl_find: Parse CCL find - token representation
+ * abibset: Bibset to be used for the parsing
+ * list:    List of tokens
+ * error:   Pointer to integer. Holds error no. on completion.
+ * pos:     Pointer to char position. Holds approximate error position.
+ * return:  RPN tree on successful completion; NULL otherwise.
+ */
 struct ccl_rpn_node *ccl_find (CCL_bibset abibset, struct ccl_token *list,
                                int *error, const char **pos)
 {
@@ -573,6 +759,14 @@ struct ccl_rpn_node *ccl_find (CCL_bibset abibset, struct ccl_token *list,
     return p;
 }
 
+/*
+ * ccl_find_str: Parse CCL find - string representation
+ * bibset:  Bibset to be used for the parsing
+ * str:     String to be parsed
+ * error:   Pointer to integer. Holds error no. on completion.
+ * pos:     Pointer to char position. Holds approximate error position.
+ * return:  RPN tree on successful completion; NULL otherwise.
+ */
 struct ccl_rpn_node *ccl_find_str (CCL_bibset bibset, const char *str,
                                    int *error, int *pos)
 {
diff --git a/ccl/cclqfile.c b/ccl/cclqfile.c
new file mode 100644 (file)
index 0000000..dd6f63c
--- /dev/null
@@ -0,0 +1,110 @@
+/* CCL qualifiers
+ * Europagate, 1995
+ *
+ * $Log: cclqfile.c,v $
+ * Revision 1.1  1995/04/17 09:31:45  adam
+ * Improved handling of qualifiers. Aliases or reserved words.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include <ccl.h>
+
+/*
+ * ccl_qual_file: Read bibset definition from file.
+ * bibset:  Bibset
+ * inf:     FILE pointer.
+ *
+ * Each line format is:
+ *  <name> <t>=<v> <t>=<v> ....
+ *  Where <name> is name of qualifier;
+ *  <t>=<v> is a attribute definition pair where <t> is one of: 
+ *     u(use), r(relation), p(position), t(truncation), c(completeness) 
+ *     or plain integer.
+ *  <v> is an integer or special pseudo-value.
+ */
+void ccl_qual_file (CCL_bibset bibset, FILE *inf)
+{
+    char line[256];
+    char *cp;
+    char qual_name[128];
+    char qual_des[128];
+    int  no_scan;
+
+    while (fgets (line, 255, inf))
+    {
+        cp = line;
+        if (*cp == '#')
+            continue;        /* ignore lines starting with # */
+        if (sscanf (cp, "%s%n", qual_name, &no_scan) != 1)
+            continue;        /* also ignore empty lines */
+        cp += no_scan;
+        while (1)
+        {
+            int pair[2];
+            char *qual_type;
+            char *qual_value;
+            char *split;
+
+            if (sscanf (cp, "%s%n", qual_des, &no_scan) != 1)
+                break;
+
+            if (!(split = strchr (qual_des, '=')))
+                break;
+            cp += no_scan;
+
+            *split++ = '\0';
+            qual_type = qual_des;
+            qual_value = split;
+            while (1)
+            {
+                if ((split = strchr (qual_value, ',')))
+                    *split++ = '\0';
+                pair[1] = atoi (qual_value);
+                switch (qual_type[0])
+                {
+                case 'u':
+                    pair[0] = CCL_BIB1_USE;
+                    break;
+                case 'r':
+                    pair[0] = CCL_BIB1_REL;
+                    if (!strcmp (qual_value, "o"))
+                        pair[1] = CCL_BIB1_REL_ORDER;
+                    break;                
+                case 'p':
+                    pair[0] = CCL_BIB1_POS;
+                    break;
+                case 's':
+                    pair[0] = CCL_BIB1_STR;
+                    if (!strcmp (qual_value, "pw"))
+                        pair[1] = CCL_BIB1_STR_WP;
+                    break;                
+                case 't':
+                    pair[0] = CCL_BIB1_TRU;
+                    if (!strcmp (qual_value, "l"))
+                        pair[1] = CCL_BIB1_TRU_CAN_LEFT;
+                    else if (!strcmp (qual_value, "r"))
+                        pair[1] = CCL_BIB1_TRU_CAN_RIGHT;
+                    else if (!strcmp (qual_value, "b"))
+                        pair[1] = CCL_BIB1_TRU_CAN_BOTH;
+                    else if (!strcmp (qual_value, "n"))
+                        pair[1] = CCL_BIB1_TRU_CAN_NONE;
+                    break;                
+                case 'c':
+                    pair[0] = CCL_BIB1_COM;
+                    break;                
+                default:
+                    pair[0] = atoi (qual_type);
+                }
+                ccl_qual_add (bibset, qual_name, 1, pair);
+                if (!split)
+                    break;
+                qual_value = split;
+            }
+        }
+    }
+}
index 9180f9f..117702d 100644 (file)
@@ -2,7 +2,10 @@
  * Europagate, 1995
  *
  * $Log: cclqual.c,v $
- * Revision 1.6  1995/02/23 08:32:00  adam
+ * Revision 1.7  1995/04/17 09:31:46  adam
+ * Improved handling of qualifiers. Aliases or reserved words.
+ *
+ * Revision 1.6  1995/02/23  08:32:00  adam
  * Changed header.
  *
  * Revision 1.4  1995/02/14  19:55:12  adam
 
 #include <ccl.h>
 
+/* Definition of CCL_bibset pointer */
 struct ccl_qualifiers {
     struct ccl_qualifier *list;
 };
 
+/*
+ * ccl_qual_add: Add qualifier to Bibset. If qualifier already
+ *               exists, then attributes are appendend to old
+ *               definition.
+ * name:    name of qualifier
+ * no:      No of attribute type/value pairs.
+ * pairs:   Attributes. pairs[0] first type, pair[1] first value,
+ *          ... pair[2*no-2] last type, pair[2*no-1] last value.
+ */
 void ccl_qual_add (CCL_bibset b, const char *name, int no, int *pairs)
 {
     struct ccl_qualifier *q;
@@ -74,6 +87,10 @@ void ccl_qual_add (CCL_bibset b, const char *name, int no, int *pairs)
     *attrp = NULL;
 }
 
+/*
+ * ccl_qual_mk: Make new (empty) bibset.
+ * return:   empty bibset.
+ */
 CCL_bibset ccl_qual_mk (void)
 {
     CCL_bibset b = malloc (sizeof(*b));
@@ -82,12 +99,39 @@ CCL_bibset ccl_qual_mk (void)
     return b;
 }
 
+/*
+ * ccl_qual_rm: Delete bibset.
+ * b:        pointer to bibset
+ */
 void ccl_qual_rm (CCL_bibset *b)
 {
-    assert (*b);
+    struct ccl_qualifier *q, *q1;
+
+    if (!*b)
+        return;
+    for (q = (*b)->list; q; q = q1)
+    {
+        struct ccl_rpn_attr *attr, *attr1;
+
+        for (attr = q->attr_list; attr; attr = attr1)
+       {
+           attr1 = attr->next;
+           free (attr);
+       }
+        q1 = q->next;
+       free (q);
+    }
+    free (*b);
     *b = NULL;
 }
 
+/*
+ * ccl_qual_search: Search for qualifier in bibset.
+ * b:      Bibset
+ * name:   Name of qualifier to search for (need no null-termination)
+ * len:    Length of name.
+ * return: Attribute info. NULL if not found.
+ */
 struct ccl_rpn_attr *ccl_qual_search (CCL_bibset b, const char *name, int len)
 {
     struct ccl_qualifier *q;
@@ -99,84 +143,3 @@ struct ccl_rpn_attr *ccl_qual_search (CCL_bibset b, const char *name, int len)
     return NULL;
 }
 
-void ccl_qual_file (CCL_bibset bibset, FILE *inf)
-{
-    char line[256];
-    char *cp;
-    char qual_name[128];
-    char qual_des[128];
-    int  no_scan;
-
-    while (fgets (line, 255, inf))
-    {
-        cp = line;
-        if (*cp == '#')
-            continue;
-        if (sscanf (cp, "%s%n", qual_name, &no_scan) != 1)
-            continue;
-        cp += no_scan;
-        while (1)
-        {
-            int pair[2];
-            char *qual_type;
-            char *qual_value;
-            char *split;
-
-            if (sscanf (cp, "%s%n", qual_des, &no_scan) != 1)
-                break;
-
-            if (!(split = strchr (qual_des, '=')))
-                break;
-            cp += no_scan;
-
-            *split++ = '\0';
-            qual_type = qual_des;
-            qual_value = split;
-            while (1)
-            {
-                if ((split = strchr (qual_value, ',')))
-                    *split++ = '\0';
-                pair[1] = atoi (qual_value);
-                switch (qual_type[0])
-                {
-                case 'u':
-                    pair[0] = CCL_BIB1_USE;
-                    break;
-                case 'r':
-                    pair[0] = CCL_BIB1_REL;
-                    if (!strcmp (qual_value, "o"))
-                        pair[1] = CCL_BIB1_REL_ORDER;
-                    break;                
-                case 'p':
-                    pair[0] = CCL_BIB1_POS;
-                    break;
-                case 's':
-                    pair[0] = CCL_BIB1_STR;
-                    if (!strcmp (qual_value, "pw"))
-                        pair[1] = CCL_BIB1_STR_WP;
-                    break;                
-                case 't':
-                    pair[0] = CCL_BIB1_TRU;
-                    if (!strcmp (qual_value, "l"))
-                        pair[1] = CCL_BIB1_TRU_CAN_LEFT;
-                    else if (!strcmp (qual_value, "r"))
-                        pair[1] = CCL_BIB1_TRU_CAN_RIGHT;
-                    else if (!strcmp (qual_value, "b"))
-                        pair[1] = CCL_BIB1_TRU_CAN_BOTH;
-                    else if (!strcmp (qual_value, "n"))
-                        pair[1] = CCL_BIB1_TRU_CAN_NONE;
-                    break;                
-                case 'c':
-                    pair[0] = CCL_BIB1_COM;
-                    break;                
-                default:
-                    pair[0] = atoi (qual_type);
-                }
-                ccl_qual_add (bibset, qual_name, 1, pair);
-                if (!split)
-                    break;
-                qual_value = split;
-            }
-        }
-    }
-}
index e9cca4e..6930adf 100644 (file)
@@ -2,7 +2,10 @@
  * Europagate, 1995
  *
  * $Log: ccltoken.c,v $
- * Revision 1.5  1995/02/23 08:32:00  adam
+ * Revision 1.6  1995/04/17 09:31:48  adam
+ * Improved handling of qualifiers. Aliases or reserved words.
+ *
+ * Revision 1.5  1995/02/23  08:32:00  adam
  * Changed header.
  *
  * Revision 1.3  1995/02/15  17:42:16  adam
 
 #include <ccl.h>
 
-static int strin (const char *s, const char *cset)
+const char *ccl_token_and = "and";
+const char *ccl_token_or = "or";
+const char *ccl_token_not = "not andnot";
+const char *ccl_token_set = "set";
+
+/*
+ * token_cmp: Compare token with keyword(s)
+ * kw:     Keyword list. Each keyword is separated by space.
+ * token:  CCL token.
+ * return: 1 if token string matches one of the keywords in list;
+ *         0 otherwise.
+ */
+static int token_cmp (const char *kw, struct ccl_token *token)
 {
-    while (*cset)
+    const char *cp1 = kw;
+    const char *cp2;
+    while ((cp2 = strchr (cp1, ' ')))
     {
-       if (*cset++ == *s)
+        if (token->len == cp2-cp1 &&
+           !memcmp (cp1, token->name, token->len))
            return 1;
+       cp1 = cp2+1;
     }
-    return 0;
+    return token->len == strlen(cp1) 
+           && !memcmp (cp1, token->name, token->len);
 }
 
-const char *ccl_token_and = "and";
-const char *ccl_token_or = "or";
-const char *ccl_token_not = "not";
-const char *ccl_token_set = "set";
-
+/*
+ * ccl_tokenize: tokenize CCL command string.
+ * return: CCL token list.
+ */
 struct ccl_token *ccl_tokenize (const char *command)
 {
     const char *cp = command;
@@ -49,7 +68,7 @@ struct ccl_token *ccl_tokenize (const char *command)
 
     while (1)
     {
-       while (*cp && strin (cp, " \t\r\n"))
+       while (*cp && strchr (" \t\r\n", *cp))
        {
            cp++;
            continue;
@@ -123,23 +142,19 @@ struct ccl_token *ccl_tokenize (const char *command)
                cp++;
            break;
        default:
-           while (*cp && !strin (cp, "(),%!><=- \t\n\r"))
+           while (*cp && !strchr ("(),%!><=- \t\n\r", *cp))
            {
                cp++;
                ++ last->len;
            }
-           if (strlen (ccl_token_and)==last->len &&
-               !memcmp (ccl_token_and, last->name, last->len))
-               last->kind = CCL_TOK_AND;
-           else if (strlen (ccl_token_or)==last->len &&
-               !memcmp (ccl_token_or, last->name, last->len))
-               last->kind = CCL_TOK_OR;
-           else if (strlen (ccl_token_not)==last->len &&
-               !memcmp (ccl_token_not, last->name, last->len))
-               last->kind = CCL_TOK_NOT;
-           else if (strlen (ccl_token_set)==last->len &&
-               !memcmp (ccl_token_set, last->name, last->len))
-               last->kind = CCL_TOK_SET;
+           if (token_cmp (ccl_token_and, last))
+               last->kind = CCL_TOK_AND;
+           else if (token_cmp (ccl_token_or, last))
+               last->kind = CCL_TOK_OR;
+            else if (token_cmp (ccl_token_not, last))
+               last->kind = CCL_TOK_NOT;
+           else if (token_cmp (ccl_token_set, last))
+               last->kind = CCL_TOK_SET;
            else
                last->kind = CCL_TOK_TERM;
        }