--- /dev/null
+# Makefile for Email gateway CCL
+# Europagate, 1995
+#
+# $Log: Makefile,v $
+# Revision 1.1 1995-04-10 10:28:16 quinn
+# Added copy of CCL.
+#
+# Revision 1.8 1995/04/10 10:22:35 quinn
+# Added ccl directory.
+#
+# Revision 1.7 1995/03/27 12:49:03 adam
+# Removed CFLAGS def.
+#
+# Revision 1.6 1995/02/23 08:31:58 adam
+# Changed header.
+#
+# Revision 1.4 1995/02/22 08:50:28 adam
+# Definition of CPP changed.
+#
+# Revision 1.3 1995/02/14 10:25:55 adam
+# The constructions 'qualifier rel term ...' implemented.
+#
+# Revision 1.2 1995/02/13 15:15:06 adam
+# Added handling of qualifiers. Not finished yet.
+#
+# Revision 1.1 1995/02/13 12:35:20 adam
+# First version of CCL. Qualifiers aren't handled yet.
+#
+SHELL=/bin/sh
+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
+CPP=$(CC) -E
+DEFS=$(INCLUDE)
+
+all: $(LIB)
+
+$(TPROG1): $(TPROG1).o $(LIB)
+ $(CC) $(CFLAGS) -o $(TPROG1) $(TPROG1).o $(LIB)
+
+$(LIB): $(PO)
+ rm -f $(LIB)
+ ar qc $(LIB) $(PO)
+ ranlib $(LIB)
+
+.c.o:
+ $(CC) -c $(DEFS) $(CFLAGS) $<
+
+clean:
+ rm -f *.log *.[oa] $(TPROG1) $(TPROG2) core mon.out gmon.out errlist *~
+
+depend: depend1
+
+depend1:
+ mv Makefile Makefile.tmp
+ sed '/^#Depend/q' <Makefile.tmp >Makefile
+ $(CPP) $(INCLUDE) -M *.c >>Makefile
+ -rm Makefile.tmp
+
+depend2:
+ $(CPP) $(INCLUDE) -M *.c >.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
--- /dev/null
+CCL test module
+
+This module is required to parse the queries given to the 'cli'
+test program. It is *not* a part of the YAZ module, and it is
+distributed under a different license.
+
+Eventually, the products of the EUROPAGATE will be made available to
+the general public, free of charge (the exact nature of the license is
+unknown at this point). Until then, you should *NOT* distribute copies
+of this software to organisations that are not partners in EUROPAGATE.
+
+If you need to distribute copies of YAZ to organisations which are not
+partners in EUROPAGATE, you should remove this module, and, if
+necessary, modify yazlib/tst.c to work wihout it. The test program is
+not essential to the general working of YAS.
--- /dev/null
+# $Id: bib1,v 1.1 1995-04-10 10:28:17 quinn Exp $
+# CCL qualifiers and their mapping to a bib-1 subset
+#
+term s=pw t=l,r
+au u=1 s=pw
+ti u=4 s=pw
+isbn u=7
+issn u=8
+cc u=20
+su u=21 s=pw
+date u=30 r=o
+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
--- /dev/null
+/*
+ * Europagate, 1995
+ *
+ * $Log: cclerrms.c,v $
+ * Revision 1.1 1995-04-10 10:28:18 quinn
+ * Added copy of CCL.
+ *
+ * Revision 1.6 1995/02/23 08:31:59 adam
+ * Changed header.
+ *
+ * Revision 1.4 1995/02/14 16:20:54 adam
+ * Qualifiers are read from a file now.
+ *
+ * Revision 1.3 1995/02/14 10:25:56 adam
+ * The constructions 'qualifier rel term ...' implemented.
+ *
+ * Revision 1.2 1995/02/13 15:15:06 adam
+ * Added handling of qualifiers. Not finished yet.
+ *
+ * Revision 1.1 1995/02/13 12:35:20 adam
+ * First version of CCL. Qualifiers aren't handled yet.
+ *
+ */
+
+char *err_msg_array[] = {
+ "Ok",
+ "Search word expected",
+ "')' expected",
+ "Set name expected",
+ "Operator expected",
+ "Unbalanced ')'",
+ "Unknown qualifier",
+ "Qualifiers applied twice",
+ "'=' expected",
+ "Bad relation",
+ "Left truncation not supported",
+ "Both left - and right truncation not supported",
+ "Right truncation not supported"
+};
+
+const char *ccl_err_msg (int ccl_errno)
+{
+ return err_msg_array[ccl_errno];
+}
--- /dev/null
+/* CCL find (to rpn conversion)
+ * Europagate, 1995
+ *
+ * $Log: cclfind.c,v $
+ * Revision 1.1 1995-04-10 10:28:19 quinn
+ * Added copy of CCL.
+ *
+ * Revision 1.12 1995/03/20 15:27:43 adam
+ * Minor changes.
+ *
+ * Revision 1.11 1995/02/23 08:31:59 adam
+ * Changed header.
+ *
+ * Revision 1.9 1995/02/16 13:20:06 adam
+ * Spell fix.
+ *
+ * Revision 1.8 1995/02/14 19:59:42 adam
+ * Removed a syntax error.
+ *
+ * Revision 1.7 1995/02/14 19:55:10 adam
+ * Header files ccl.h/cclp.h are gone! They have been merged an
+ * moved to ../include/ccl.h.
+ * Node kind(s) in ccl_rpn_node have changed names.
+ *
+ * Revision 1.6 1995/02/14 16:20:55 adam
+ * Qualifiers are read from a file now.
+ *
+ * Revision 1.5 1995/02/14 14:12:41 adam
+ * Ranges for ordered qualfiers implemented (e.g. pd=1980-1990).
+ *
+ * Revision 1.4 1995/02/14 13:16:29 adam
+ * Left and/or right truncation implemented.
+ *
+ * Revision 1.3 1995/02/14 10:25:56 adam
+ * The constructions 'qualifier rel term ...' implemented.
+ *
+ * Revision 1.2 1995/02/13 15:15:07 adam
+ * Added handling of qualifiers. Not finished yet.
+ *
+ * Revision 1.1 1995/02/13 12:35:20 adam
+ * First version of CCL. Qualifiers aren't handled yet.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include <ccl.h>
+
+static struct ccl_token *look_token;
+static int ccl_error;
+static CCL_bibset bibset;
+
+#define KIND (look_token->kind)
+#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)
+{
+ while (list)
+ {
+ if (list->type == type)
+ return list;
+ list = list->next;
+ }
+ return NULL;
+}
+
+static int qual_val_type (struct ccl_rpn_attr *list, int type, int value)
+{
+ while (list)
+ {
+ if (list->type == type && list->value == value)
+ return 1;
+ list = list->next;
+ }
+ return 0;
+}
+
+static void strxcat (char *n, const char *src, int len)
+{
+ while (*n)
+ n++;
+ while (--len >= 0)
+ *n++ = *src++;
+ *n = '\0';
+}
+
+static char *copy_token_name (struct ccl_token *tp)
+{
+ char *str = malloc (tp->len + 1);
+ assert (str);
+ memcpy (str, tp->name, tp->len);
+ str[tp->len] = '\0';
+ return str;
+}
+
+static struct ccl_rpn_node *mk_node (enum rpn_node_kind kind)
+{
+ struct ccl_rpn_node *p;
+ p = malloc (sizeof(*p));
+ assert (p);
+ p->kind = kind;
+ return p;
+}
+
+void ccl_rpn_delete (struct ccl_rpn_node *rpn)
+{
+ struct ccl_rpn_attr *attr, *attr1;
+ if (!rpn)
+ return;
+ switch (rpn->kind)
+ {
+ 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]);
+ break;
+ case CCL_RPN_TERM:
+ free (rpn->u.t.term);
+ for (attr = rpn->u.t.attr_list; attr; attr = attr1)
+ {
+ attr1 = attr->next;
+ free (attr);
+ }
+ break;
+ case CCL_RPN_SET:
+ free (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);
+}
+
+static struct ccl_rpn_node *find_spec (struct ccl_rpn_attr **qa);
+static struct ccl_rpn_node *search_terms (struct ccl_rpn_attr **qa);
+
+static void add_attr (struct ccl_rpn_node *p, int type, int value)
+{
+ struct ccl_rpn_attr *n;
+
+ n = malloc (sizeof(*n));
+ assert (n);
+ n->type = type;
+ n->value = value;
+ n->next = p->u.t.attr_list;
+ p->u.t.attr_list = n;
+}
+
+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;
+
+ if (KIND != CCL_TOK_TERM)
+ {
+ ccl_error = CCL_ERR_TERM_EXPECTED;
+ return NULL;
+ }
+ for (no = 0; lookahead->kind == CCL_TOK_TERM; no++)
+ {
+ for (i = 0; i<lookahead->len; i++)
+ if (lookahead->name[i] == '?')
+ {
+ if (no == 0 && i == 0 && lookahead->len >= 1)
+ left_trunc = 1;
+ else if (lookahead->next->kind != CCL_TOK_TERM &&
+ i == lookahead->len-1 && i >= 1)
+ right_trunc = 1;
+ else
+ mid_trunc = 1;
+ }
+ len += 1+lookahead->len;
+ lookahead = lookahead->next;
+ }
+ p = mk_node (CCL_RPN_TERM);
+ 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++)
+ {
+ const char *src_str = look_token->name;
+ int src_len = look_token->len;
+
+ if (i == 0 && left_trunc)
+ {
+ src_len--;
+ src_str++;
+ }
+ else if (i == no-1 && right_trunc)
+ src_len--;
+ if (i)
+ strcat (p->u.t.term, " ");
+ 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))
+ {
+ ccl_error = CCL_ERR_TRUNC_NOT_BOTH;
+ if (qa)
+ free (qa);
+ ccl_rpn_delete (p);
+ return NULL;
+ }
+ add_attr (p, CCL_BIB1_TRU, 3);
+ }
+ else if (right_trunc)
+ {
+ if (attr && !qual_val_type (attr, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_RIGHT))
+ {
+ ccl_error = CCL_ERR_TRUNC_NOT_RIGHT;
+ if (qa)
+ free (qa);
+ ccl_rpn_delete (p);
+ return NULL;
+ }
+ add_attr (p, CCL_BIB1_TRU, 1);
+ }
+ else if (left_trunc)
+ {
+ if (attr && !qual_val_type (attr, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_LEFT))
+ {
+ ccl_error = CCL_ERR_TRUNC_NOT_LEFT;
+ if (qa)
+ free (qa);
+ ccl_rpn_delete (p);
+ return NULL;
+ }
+ add_attr (p, CCL_BIB1_TRU, 2);
+ }
+ else
+ {
+ if (attr && qual_val_type (attr, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_NONE))
+ add_attr (p, CCL_BIB1_TRU, 100);
+ }
+ return p;
+}
+
+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 i, rel;
+ struct ccl_rpn_attr *attr;
+
+ if (qa)
+ {
+ ccl_error = CCL_ERR_DOUBLE_QUAL;
+ return NULL;
+ }
+ for (lookahead = look_token; lookahead != la; lookahead=lookahead->next)
+ no++;
+ ap = malloc (no * sizeof(*ap));
+ assert (ap);
+ for (i=0; look_token != la; i++)
+ {
+ ap[i] = ccl_qual_search (bibset, look_token->name, look_token->len);
+ if (!ap[i])
+ {
+ ccl_error = CCL_ERR_UNKNOWN_QUAL;
+ free (ap);
+ return NULL;
+ }
+ ADVANCE;
+ if (KIND == CCL_TOK_COMMA)
+ ADVANCE;
+ }
+ ap[i] = NULL;
+ if (! (attr = qual_val (ap[0], CCL_BIB1_REL)) ||
+ attr->value != CCL_BIB1_REL_ORDER)
+ {
+ /* unordered relation */
+ struct ccl_rpn_node *p;
+ if (KIND != CCL_TOK_EQ)
+ {
+ ccl_error = CCL_ERR_EQ_EXPECTED;
+ free (ap);
+ return NULL;
+ }
+ ADVANCE;
+ 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;
+ }
+ else
+ p = search_terms (ap);
+ free (ap);
+ return p;
+ }
+ rel = 0;
+ if (look_token->len == 1)
+ {
+ if (look_token->name[0] == '<')
+ rel = 1;
+ else if (look_token->name[0] == '=')
+ rel = 3;
+ else if (look_token->name[0] == '>')
+ rel = 5;
+ }
+ else if (look_token->len == 2)
+ {
+ if (!memcmp (look_token->name, "<=", 2))
+ rel = 2;
+ else if (!memcmp (look_token->name, ">=", 2))
+ rel = 4;
+ else if (!memcmp (look_token->name, "<>", 2))
+ rel = 6;
+ }
+ if (!rel)
+ ccl_error = CCL_ERR_BAD_RELATION;
+ else
+ {
+ struct ccl_rpn_node *p;
+
+ ADVANCE; /* skip relation */
+ if (KIND == CCL_TOK_TERM)
+ {
+ struct ccl_rpn_node *p1;
+ p1 = search_term (ap);
+ if (KIND == CCL_TOK_MINUS)
+ {
+ 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;
+ }
+ }
+ else
+ {
+ add_attr (p1, CCL_BIB1_REL, rel);
+ free (ap);
+ return p1;
+ }
+ }
+ else if (KIND == CCL_TOK_MINUS) /* = - term ? */
+ {
+ ADVANCE;
+ p = search_term (ap);
+ add_attr (p, CCL_BIB1_REL, 2);
+ free (ap);
+ return p;
+ }
+ ccl_error = CCL_ERR_TERM_EXPECTED;
+ }
+ free (ap);
+ return NULL;
+}
+
+static struct ccl_rpn_node *search_terms (struct ccl_rpn_attr **qa)
+{
+ struct ccl_rpn_node *p1, *p2, *pn;
+ p1 = search_term (qa);
+ if (!p1)
+ return NULL;
+ while (1)
+ {
+ if (KIND == CCL_TOK_PROX)
+ {
+ ADVANCE;
+ p2 = search_term (qa);
+ if (!p2)
+ {
+ ccl_rpn_delete (p1);
+ return NULL;
+ }
+ pn = mk_node (CCL_RPN_PROX);
+ pn->u.p[0] = p1;
+ pn->u.p[1] = p2;
+ p1 = pn;
+ }
+ else if (KIND == CCL_TOK_TERM)
+ {
+ p2 = search_term (qa);
+ if (!p2)
+ {
+ ccl_rpn_delete (p1);
+ return NULL;
+ }
+ pn = mk_node (CCL_RPN_PROX);
+ pn->u.p[0] = p1;
+ pn->u.p[1] = p2;
+ p1 = pn;
+ }
+ else
+ break;
+ }
+ return p1;
+}
+
+static struct ccl_rpn_node *search_elements (struct ccl_rpn_attr **qa)
+{
+ struct ccl_rpn_node *p1;
+ struct ccl_token *lookahead;
+ if (KIND == CCL_TOK_LP)
+ {
+ ADVANCE;
+ p1 = find_spec (qa);
+ if (!p1)
+ return NULL;
+ if (KIND != CCL_TOK_RP)
+ {
+ ccl_error = CCL_ERR_RP_EXPECTED;
+ ccl_rpn_delete (p1);
+ return NULL;
+ }
+ ADVANCE;
+ return p1;
+ }
+ else if (KIND == CCL_TOK_SET)
+ {
+ ADVANCE;
+ if (KIND == CCL_TOK_EQ)
+ ADVANCE;
+ if (KIND != CCL_TOK_TERM)
+ {
+ ccl_error = CCL_ERR_SETNAME_EXPECTED;
+ return NULL;
+ }
+ p1 = mk_node (CCL_RPN_SET);
+ p1->u.setname = copy_token_name (look_token);
+ ADVANCE;
+ return p1;
+ }
+ lookahead = look_token;
+
+ while (lookahead->kind==CCL_TOK_TERM || lookahead->kind==CCL_TOK_COMMA)
+ lookahead = lookahead->next;
+ if (lookahead->kind == CCL_TOK_REL || lookahead->kind == CCL_TOK_EQ)
+ return qualifiers (lookahead, qa);
+ return search_terms (qa);
+}
+
+static struct ccl_rpn_node *find_spec (struct ccl_rpn_attr **qa)
+{
+ struct ccl_rpn_node *p1, *p2, *pn;
+ if (!(p1 = search_elements (qa)))
+ return NULL;
+ while (1)
+ {
+ switch (KIND)
+ {
+ case CCL_TOK_AND:
+ ADVANCE;
+ p2 = search_elements (qa);
+ if (!p2)
+ {
+ ccl_rpn_delete (p1);
+ return NULL;
+ }
+ pn = mk_node (CCL_RPN_AND);
+ pn->u.p[0] = p1;
+ pn->u.p[1] = p2;
+ p1 = pn;
+ continue;
+ case CCL_TOK_OR:
+ ADVANCE;
+ p2 = search_elements (qa);
+ if (!p2)
+ {
+ ccl_rpn_delete (p1);
+ return NULL;
+ }
+ pn = mk_node (CCL_RPN_OR);
+ pn->u.p[0] = p1;
+ pn->u.p[1] = p2;
+ p1 = pn;
+ continue;
+ case CCL_TOK_NOT:
+ ADVANCE;
+ p2 = search_elements (qa);
+ if (!p2)
+ {
+ ccl_rpn_delete (p1);
+ return NULL;
+ }
+ pn = mk_node (CCL_RPN_NOT);
+ pn->u.p[0] = p1;
+ pn->u.p[1] = p2;
+ p1 = pn;
+ continue;
+ }
+ break;
+ }
+ return p1;
+}
+
+struct ccl_rpn_node *ccl_find (CCL_bibset abibset, struct ccl_token *list,
+ int *error, const char **pos)
+{
+ struct ccl_rpn_node *p;
+
+ look_token = list;
+ bibset = abibset;
+ p = find_spec (NULL);
+ if (p && KIND != CCL_TOK_EOL)
+ {
+ if (KIND == CCL_TOK_RP)
+ ccl_error = CCL_ERR_BAD_RP;
+ else
+ ccl_error = CCL_ERR_OP_EXPECTED;
+ ccl_rpn_delete (p);
+ p = NULL;
+ }
+ *pos = look_token->name;
+ if (p)
+ *error = CCL_ERR_OK;
+ else
+ *error = ccl_error;
+ return p;
+}
+
+struct ccl_rpn_node *ccl_find_str (CCL_bibset bibset, const char *str,
+ int *error, int *pos)
+{
+ struct ccl_token *list;
+ struct ccl_rpn_node *rpn;
+ const char *char_pos;
+
+ list = ccl_tokenize (str);
+ rpn = ccl_find (bibset, list, error, &char_pos);
+ if (*error)
+ *pos = char_pos - str;
+ return rpn;
+}
--- /dev/null
+/* CCL print rpn tree - infix notation
+ * Europagate, 1995
+ *
+ * $Log: cclptree.c,v $
+ * Revision 1.1 1995-04-10 10:28:20 quinn
+ * Added copy of CCL.
+ *
+ * Revision 1.5 1995/02/23 08:31:59 adam
+ * Changed header.
+ *
+ * Revision 1.3 1995/02/15 17:42:16 adam
+ * Minor changes of the api of this module. FILE* argument added
+ * to ccl_pr_tree.
+ *
+ * Revision 1.2 1995/02/14 19:55:11 adam
+ * Header files ccl.h/cclp.h are gone! They have been merged an
+ * moved to ../include/ccl.h.
+ * Node kind(s) in ccl_rpn_node have changed names.
+ *
+ * Revision 1.1 1995/02/14 10:25:56 adam
+ * The constructions 'qualifier rel term ...' implemented.
+ *
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+#include <ccl.h>
+
+void ccl_pr_tree (struct ccl_rpn_node *rpn, FILE *fd_out)
+{
+
+ switch (rpn->kind)
+ {
+ case CCL_RPN_TERM:
+ fprintf (fd_out, "\"%s\"", rpn->u.t.term);
+ if (rpn->u.t.attr_list)
+ {
+ struct ccl_rpn_attr *attr;
+ for (attr = rpn->u.t.attr_list; attr; attr = attr->next)
+ fprintf (fd_out, " %d=%d", attr->type, attr->value);
+ }
+ break;
+ case CCL_RPN_AND:
+ fprintf (fd_out, "(");
+ ccl_pr_tree (rpn->u.p[0], fd_out);
+ fprintf (fd_out, ") and (");
+ ccl_pr_tree (rpn->u.p[1], fd_out);
+ fprintf (fd_out, ")");
+ break;
+ case CCL_RPN_OR:
+ fprintf (fd_out, "(");
+ ccl_pr_tree (rpn->u.p[0], fd_out);
+ fprintf (fd_out, ") or (");
+ ccl_pr_tree (rpn->u.p[1], fd_out);
+ fprintf (fd_out, ")");
+ break;
+ case CCL_RPN_NOT:
+ fprintf (fd_out, "(");
+ ccl_pr_tree (rpn->u.p[0], fd_out);
+ fprintf (fd_out, ") not (");
+ ccl_pr_tree (rpn->u.p[1], fd_out);
+ fprintf (fd_out, ")");
+ break;
+ case CCL_RPN_SET:
+ fprintf (fd_out, "set=%s", rpn->u.setname);
+ break;
+ case CCL_RPN_PROX:
+ fprintf (fd_out, "(");
+ ccl_pr_tree (rpn->u.p[0], fd_out);
+ fprintf (fd_out, ") prox (");
+ ccl_pr_tree (rpn->u.p[1], fd_out);
+ fprintf (fd_out, ")");
+ break;
+ default:
+ assert (0);
+ }
+}
--- /dev/null
+/* CCL qualifiers
+ * Europagate, 1995
+ *
+ * $Log: cclqual.c,v $
+ * Revision 1.1 1995-04-10 10:28:20 quinn
+ * Added copy of CCL.
+ *
+ * Revision 1.6 1995/02/23 08:32:00 adam
+ * Changed header.
+ *
+ * Revision 1.4 1995/02/14 19:55:12 adam
+ * Header files ccl.h/cclp.h are gone! They have been merged an
+ * moved to ../include/ccl.h.
+ * Node kind(s) in ccl_rpn_node have changed names.
+ *
+ * Revision 1.3 1995/02/14 16:20:56 adam
+ * Qualifiers are read from a file now.
+ *
+ * Revision 1.2 1995/02/14 10:25:56 adam
+ * The constructions 'qualifier rel term ...' implemented.
+ *
+ * Revision 1.1 1995/02/13 15:15:07 adam
+ * Added handling of qualifiers. Not finished yet.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include <ccl.h>
+
+struct ccl_qualifiers {
+ struct ccl_qualifier *list;
+};
+
+void ccl_qual_add (CCL_bibset b, const char *name, int no, int *pairs)
+{
+ struct ccl_qualifier *q;
+ struct ccl_rpn_attr **attrp;
+
+ assert (b);
+ for (q = b->list; q; q = q->next)
+ if (!strcmp (name, q->name))
+ break;
+ if (!q)
+ {
+ struct ccl_qualifier *new_qual = malloc (sizeof(*new_qual));
+ assert (new_qual);
+
+ new_qual->next = b->list;
+ b->list = new_qual;
+
+ new_qual->name = malloc (strlen(name)+1);
+ assert (new_qual->name);
+ strcpy (new_qual->name, name);
+ attrp = &new_qual->attr_list;
+ }
+ else
+ {
+ attrp = &q->attr_list;
+ while (*attrp)
+ attrp = &(*attrp)->next;
+ }
+ while (--no >= 0)
+ {
+ struct ccl_rpn_attr *attr;
+
+ attr = malloc (sizeof(*attr));
+ assert (attr);
+ attr->type = *pairs++;
+ attr->value = *pairs++;
+ *attrp = attr;
+ attrp = &attr->next;
+ }
+ *attrp = NULL;
+}
+
+CCL_bibset ccl_qual_mk (void)
+{
+ CCL_bibset b = malloc (sizeof(*b));
+ assert (b);
+ b->list = NULL;
+ return b;
+}
+
+void ccl_qual_rm (CCL_bibset *b)
+{
+ assert (*b);
+ *b = NULL;
+}
+
+struct ccl_rpn_attr *ccl_qual_search (CCL_bibset b, const char *name, int len)
+{
+ struct ccl_qualifier *q;
+
+ assert (b);
+ for (q = b->list; q; q = q->next)
+ if (strlen(q->name) == len && !memcmp (name, q->name, len))
+ return q->attr_list;
+ 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;
+ }
+ }
+ }
+}
--- /dev/null
+/* CCL shell.
+ * Europagate 1995
+ *
+ * $Log: cclsh.c,v $
+ * Revision 1.1 1995-04-10 10:28:21 quinn
+ * Added copy of CCL.
+ *
+ * Revision 1.9 1995/02/23 08:32:00 adam
+ * Changed header.
+ *
+ * Revision 1.7 1995/02/15 17:42:16 adam
+ * Minor changes of the api of this module. FILE* argument added
+ * to ccl_pr_tree.
+ *
+ * Revision 1.6 1995/02/14 19:55:13 adam
+ * Header files ccl.h/cclp.h are gone! They have been merged an
+ * moved to ../include/ccl.h.
+ * Node kind(s) in ccl_rpn_node have changed names.
+ *
+ * Revision 1.5 1995/02/14 16:20:57 adam
+ * Qualifiers are read from a file now.
+ *
+ * Revision 1.4 1995/02/14 14:12:42 adam
+ * Ranges for ordered qualfiers implemented (e.g. pd=1980-1990).
+ *
+ * Revision 1.3 1995/02/14 10:25:57 adam
+ * The constructions 'qualifier rel term ...' implemented.
+ *
+ * Revision 1.2 1995/02/13 15:15:07 adam
+ * Added handling of qualifiers. Not finished yet.
+ *
+ * Revision 1.1 1995/02/13 12:35:21 adam
+ * First version of CCL. Qualifiers aren't handled yet.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <ccl.h>
+
+static int debug = 0;
+static char *prog;
+
+int main (int argc, char **argv)
+{
+ CCL_bibset bibset;
+ FILE *bib_inf;
+ char *bib_fname;
+
+ prog = *argv;
+ bibset = ccl_qual_mk ();
+ while (--argc > 0)
+ {
+ if (**++argv == '-')
+ {
+ switch (argv[0][1])
+ {
+ case 'd':
+ debug = 1;
+ break;
+ case 'b':
+ if (argv[0][2])
+ bib_fname = argv[0]+2;
+ else if (argc > 0)
+ {
+ --argc;
+ bib_fname = *++argv;
+ }
+ else
+ {
+ fprintf (stderr, "%s: missing bib filename\n", prog);
+ exit (1);
+ }
+ bib_inf = fopen (bib_fname, "r");
+ if (!bib_inf)
+ {
+ fprintf (stderr, "%s: cannot open %s\n", prog,
+ bib_fname);
+ exit (1);
+ }
+ ccl_qual_file (bibset, bib_inf);
+ fclose (bib_inf);
+ break;
+ default:
+ fprintf (stderr, "%s: unknown option '%s'\n",
+ prog, *argv);
+ exit (1);
+ }
+ }
+ else
+ {
+ fprintf (stderr, "%s: no filenames, please\n", prog);
+ exit (1);
+ }
+ }
+ while (1)
+ {
+ char buf[80];
+ int error, pos;
+ struct ccl_rpn_node *rpn;
+
+ printf ("CCLSH>"); fflush (stdout);
+ if (!fgets (buf, 79, stdin))
+ break;
+ rpn = ccl_find_str (bibset, buf, &error, &pos);
+ if (error)
+ {
+ printf ("%*s^ - ", 6+pos, " ");
+ printf ("%s\n", ccl_err_msg (error));
+ }
+ else
+ {
+ assert (rpn);
+ ccl_pr_tree (rpn, stdout);
+ putchar ('\n');
+ }
+ }
+ putchar ('\n');
+ return 0;
+}
--- /dev/null
+/* CCL - lexical analysis
+ * Europagate, 1995
+ *
+ * $Log: ccltoken.c,v $
+ * Revision 1.1 1995-04-10 10:28:22 quinn
+ * Added copy of CCL.
+ *
+ * Revision 1.5 1995/02/23 08:32:00 adam
+ * Changed header.
+ *
+ * Revision 1.3 1995/02/15 17:42:16 adam
+ * Minor changes of the api of this module. FILE* argument added
+ * to ccl_pr_tree.
+ *
+ * Revision 1.2 1995/02/14 19:55:13 adam
+ * Header files ccl.h/cclp.h are gone! They have been merged an
+ * moved to ../include/ccl.h.
+ * Node kind(s) in ccl_rpn_node have changed names.
+ *
+ * Revision 1.1 1995/02/13 12:35:21 adam
+ * First version of CCL. Qualifiers aren't handled yet.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <ccl.h>
+
+static int strin (const char *s, const char *cset)
+{
+ while (*cset)
+ {
+ if (*cset++ == *s)
+ return 1;
+ }
+ return 0;
+}
+
+const char *ccl_token_and = "and";
+const char *ccl_token_or = "or";
+const char *ccl_token_not = "not";
+const char *ccl_token_set = "set";
+
+struct ccl_token *ccl_tokenize (const char *command)
+{
+ const char *cp = command;
+ struct ccl_token *first = NULL;
+ struct ccl_token *last = NULL;
+
+ while (1)
+ {
+ while (*cp && strin (cp, " \t\r\n"))
+ {
+ cp++;
+ continue;
+ }
+ if (!first)
+ {
+ first = last = malloc (sizeof (*first));
+ assert (first);
+ last->prev = NULL;
+ }
+ else
+ {
+ last->next = malloc (sizeof(*first));
+ assert (last->next);
+ last->next->prev = last;
+ last = last->next;
+ }
+ last->next = NULL;
+ last->name = cp;
+ last->len = 1;
+ switch (*cp++)
+ {
+ case '\0':
+ last->kind = CCL_TOK_EOL;
+ return first;
+ case '(':
+ last->kind = CCL_TOK_LP;
+ break;
+ case ')':
+ last->kind = CCL_TOK_RP;
+ break;
+ case ',':
+ last->kind = CCL_TOK_COMMA;
+ break;
+ case '%':
+ case '!':
+ last->kind = CCL_TOK_PROX;
+ while (*cp == '%' || *cp == '!')
+ {
+ ++ last->len;
+ cp++;
+ }
+ break;
+ case '>':
+ case '<':
+ case '=':
+ if (*cp == '=' || *cp == '<' || *cp == '>')
+ {
+ cp++;
+ last->kind = CCL_TOK_REL;
+ ++ last->len;
+ }
+ else if (cp[-1] == '=')
+ last->kind = CCL_TOK_EQ;
+ else
+ last->kind = CCL_TOK_REL;
+ break;
+ case '-':
+ last->kind = CCL_TOK_MINUS;
+ break;
+ case '\"':
+ last->kind = CCL_TOK_TERM;
+ last->name = cp;
+ last->len = 0;
+ while (*cp && *cp != '\"')
+ {
+ cp++;
+ ++ last->len;
+ }
+ if (*cp == '\"')
+ cp++;
+ break;
+ default:
+ while (*cp && !strin (cp, "(),%!><=- \t\n\r"))
+ {
+ 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;
+ else
+ last->kind = CCL_TOK_TERM;
+ }
+ }
+ return first;
+}
--- /dev/null
+/* CCL - header file
+ * Europagate, 1995
+ *
+ * $Log: ccl.h,v $
+ * Revision 1.1 1995-04-10 10:28:27 quinn
+ * Added copy of CCL.
+ *
+ * Revision 1.5 1995/02/23 08:32:11 adam
+ * Changed header.
+ *
+ * Revision 1.3 1995/02/16 13:20:10 adam
+ * Spell fix.
+ *
+ * Revision 1.2 1995/02/15 17:43:08 adam
+ * Minor changes to the ccl interface. Bug fix in iso2709 module.
+ *
+ * Revision 1.1 1995/02/14 19:55:21 adam
+ * Header files ccl.h/cclp.h are gone! They have been merged an
+ * moved to ../include/ccl.h.
+ *
+ */
+
+#ifndef CCL_H
+#define CCL_H
+
+/* CCL error numbers */
+#define CCL_ERR_OK 0
+#define CCL_ERR_TERM_EXPECTED 1
+#define CCL_ERR_RP_EXPECTED 2
+#define CCL_ERR_SETNAME_EXPECTED 3
+#define CCL_ERR_OP_EXPECTED 4
+#define CCL_ERR_BAD_RP 5
+#define CCL_ERR_UNKNOWN_QUAL 6
+#define CCL_ERR_DOUBLE_QUAL 7
+#define CCL_ERR_EQ_EXPECTED 8
+#define CCL_ERR_BAD_RELATION 9
+#define CCL_ERR_TRUNC_NOT_LEFT 10
+#define CCL_ERR_TRUNC_NOT_BOTH 11
+#define CCL_ERR_TRUNC_NOT_RIGHT 12
+
+/* attribute pair (type, value) */
+struct ccl_rpn_attr {
+ struct ccl_rpn_attr *next;
+ int type;
+ int value;
+};
+
+/* RPN tree structure */
+struct ccl_rpn_node {
+ enum rpn_node_kind {
+ CCL_RPN_AND, CCL_RPN_OR, CCL_RPN_NOT,
+ CCL_RPN_TERM,
+ CCL_RPN_SET,
+ CCL_RPN_PROX
+ } kind;
+ union {
+ struct ccl_rpn_node *p[2];
+ struct {
+ char *term;
+ struct ccl_rpn_attr *attr_list;
+ } t;
+ char *setname;
+ } u;
+};
+
+typedef struct ccl_qualifiers *CCL_bibset;
+
+/* use (1)
+
+ relation (2)
+ -1 none
+ 0 ordered
+ 1-6 relation (<, <=, =, >=, >, <>)
+
+ position (3)
+ -1 none
+ 1 first in field
+ 2 first in sub field
+ 3 any position in field
+ structure (4)
+ -1 none
+ 0 word/phrase auto select
+ 1 phrase
+ 2 word
+ 3 key
+ 4 year
+ 5 date (normalized)
+ 6 word list
+ 100 date (un-normalized)
+ 101 name (normalized)
+ 102 name (un-normalized)
+ truncation (5)
+ completeness (6)
+*/
+
+#define CCL_BIB1_USE 1
+#define CCL_BIB1_REL 2
+#define CCL_BIB1_POS 3
+#define CCL_BIB1_STR 4
+#define CCL_BIB1_TRU 5
+#define CCL_BIB1_COM 6
+
+#define CCL_BIB1_STR_WP (-1)
+#define CCL_BIB1_REL_ORDER (-1)
+
+#define CCL_BIB1_TRU_CAN_LEFT (-1)
+#define CCL_BIB1_TRU_CAN_RIGHT (-2)
+#define CCL_BIB1_TRU_CAN_BOTH (-3)
+#define CCL_BIB1_TRU_CAN_NONE (-4)
+
+#define CCL_TOK_EOL 0
+#define CCL_TOK_TERM 1
+#define CCL_TOK_REL 2
+#define CCL_TOK_EQ 3
+#define CCL_TOK_PROX 4
+#define CCL_TOK_LP 5
+#define CCL_TOK_RP 6
+#define CCL_TOK_COMMA 7
+#define CCL_TOK_AND 8
+#define CCL_TOK_OR 7
+#define CCL_TOK_NOT 9
+#define CCL_TOK_MINUS 10
+#define CCL_TOK_SET 11
+
+struct ccl_token {
+ char kind;
+ char len;
+ const char *name;
+ struct ccl_token *next;
+ struct ccl_token *prev;
+};
+
+struct ccl_qualifier {
+ char *name;
+ struct ccl_rpn_attr *attr_list;
+ struct ccl_qualifier *next;
+};
+
+struct ccl_token *ccl_tokenize (const char *command);
+
+struct ccl_rpn_node *ccl_find_str (CCL_bibset bibset,
+ const char *str, int *error, int *pos);
+
+struct ccl_rpn_node *ccl_find (CCL_bibset abibset, struct ccl_token *list,
+ int *error, const char **pos);
+char *ccl_err_msg (int ccl_errno);
+void ccl_rpn_delete (struct ccl_rpn_node *rpn);
+void ccl_pr_tree (struct ccl_rpn_node *rpn, FILE *fd_out);
+
+void ccl_qual_add (CCL_bibset b, const char *name, int no, int *attr);
+void ccl_qual_file (CCL_bibset bibset, FILE *inf);
+CCL_bibset ccl_qual_mk (void);
+void ccl_qual_rm (CCL_bibset *b);
+
+extern const char *ccl_token_and;
+extern const char *ccl_token_or;
+extern const char *ccl_token_not;
+extern const char *ccl_token_set;
+
+
+struct ccl_rpn_attr *ccl_qual_search (CCL_bibset b, const char *name, int len);
+#endif
+
--- /dev/null
+/*
+ * Copyright (C) 1994, Index Data I/S
+ * All rights reserved.
+ * Sebastian Hammer, Adam Dickmeiss
+ *
+ * $Log: marcdisp.h,v $
+ * Revision 1.1 1995-04-10 10:28:28 quinn
+ * Added copy of CCL.
+ *
+ */
+
+int marc_display (const char *buf, FILE *outf);
+