From 330271187bc05322c13e6e22483120ca8e5a20a1 Mon Sep 17 00:00:00 2001 From: Sebastian Hammer Date: Mon, 10 Apr 1995 10:28:16 +0000 Subject: [PATCH] Added copy of CCL. --- ccl/Makefile | 89 ++++++++ ccl/README | 15 ++ ccl/bib1 | 17 ++ ccl/cclerrms.c | 44 ++++ ccl/cclfind.c | 591 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ccl/cclptree.c | 79 +++++++ ccl/cclqual.c | 185 ++++++++++++++++ ccl/cclsh.c | 122 +++++++++++ ccl/ccltoken.c | 151 ++++++++++++++ include/ccl.h | 163 +++++++++++++++ include/marcdisp.h | 13 ++ 11 files changed, 1469 insertions(+) create mode 100644 ccl/Makefile create mode 100644 ccl/README create mode 100644 ccl/bib1 create mode 100644 ccl/cclerrms.c create mode 100644 ccl/cclfind.c create mode 100644 ccl/cclptree.c create mode 100644 ccl/cclqual.c create mode 100644 ccl/cclsh.c create mode 100644 ccl/ccltoken.c create mode 100644 include/ccl.h create mode 100644 include/marcdisp.h diff --git a/ccl/Makefile b/ccl/Makefile new file mode 100644 index 0000000..3186031 --- /dev/null +++ b/ccl/Makefile @@ -0,0 +1,89 @@ +# 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 + $(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 diff --git a/ccl/README b/ccl/README new file mode 100644 index 0000000..51a27c2 --- /dev/null +++ b/ccl/README @@ -0,0 +1,15 @@ +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. diff --git a/ccl/bib1 b/ccl/bib1 new file mode 100644 index 0000000..914e0e2 --- /dev/null +++ b/ccl/bib1 @@ -0,0 +1,17 @@ +# $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 diff --git a/ccl/cclerrms.c b/ccl/cclerrms.c new file mode 100644 index 0000000..9202e9f --- /dev/null +++ b/ccl/cclerrms.c @@ -0,0 +1,44 @@ +/* + * 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]; +} diff --git a/ccl/cclfind.c b/ccl/cclfind.c new file mode 100644 index 0000000..d0a71c9 --- /dev/null +++ b/ccl/cclfind.c @@ -0,0 +1,591 @@ +/* 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 +#include +#include +#include + +#include + +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; ilen; 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; iname; + 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; +} diff --git a/ccl/cclptree.c b/ccl/cclptree.c new file mode 100644 index 0000000..39abaf6 --- /dev/null +++ b/ccl/cclptree.c @@ -0,0 +1,79 @@ +/* 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 +#include +#include + +#include + +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); + } +} diff --git a/ccl/cclqual.c b/ccl/cclqual.c new file mode 100644 index 0000000..5ba4aa3 --- /dev/null +++ b/ccl/cclqual.c @@ -0,0 +1,185 @@ +/* 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 +#include +#include +#include + +#include + +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; + } + } + } +} diff --git a/ccl/cclsh.c b/ccl/cclsh.c new file mode 100644 index 0000000..acff48f --- /dev/null +++ b/ccl/cclsh.c @@ -0,0 +1,122 @@ +/* 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 +#include +#include + +#include + +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; +} diff --git a/ccl/ccltoken.c b/ccl/ccltoken.c new file mode 100644 index 0000000..cfdc8d1 --- /dev/null +++ b/ccl/ccltoken.c @@ -0,0 +1,151 @@ +/* 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 +#include +#include +#include + +#include + +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; +} diff --git a/include/ccl.h b/include/ccl.h new file mode 100644 index 0000000..a5651ca --- /dev/null +++ b/include/ccl.h @@ -0,0 +1,163 @@ +/* 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 + diff --git a/include/marcdisp.h b/include/marcdisp.h new file mode 100644 index 0000000..0efca23 --- /dev/null +++ b/include/marcdisp.h @@ -0,0 +1,13 @@ +/* + * 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); + -- 1.7.10.4