From 98a49f6636e01e87e867688f4fb8a3b696a847ff Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Mon, 13 Feb 1995 15:15:06 +0000 Subject: [PATCH] Added handling of qualifiers. Not finished yet. --- ccl/Makefile | 7 ++- ccl/ccl.h | 71 +++++++++++++++++++++++- ccl/cclerrms.c | 13 ++++- ccl/cclfind.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++-------- ccl/cclp.h | 33 ++++++----- ccl/cclqual.c | 72 ++++++++++++++++++++++++ ccl/cclsh.c | 17 +++++- 7 files changed, 331 insertions(+), 48 deletions(-) create mode 100644 ccl/cclqual.c diff --git a/ccl/Makefile b/ccl/Makefile index 20984f1..8932443 100644 --- a/ccl/Makefile +++ b/ccl/Makefile @@ -2,7 +2,10 @@ # Europagate, 1995 # # $Log: Makefile,v $ -# Revision 1.1 1995/02/13 12:35:20 adam +# 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 @@ -11,7 +14,7 @@ CFLAGS=-g -Wall -pedantic -ansi CC=gcc TPROG1=cclsh LIB=../lib/ccl.a -PO=cclfind.o ccltoken.o cclerrms.o +PO=cclfind.o ccltoken.o cclerrms.o cclqual.o CPP=cc -E DEFS=$(INCLUDE) diff --git a/ccl/ccl.h b/ccl/ccl.h index 444575e..0b319a0 100644 --- a/ccl/ccl.h +++ b/ccl/ccl.h @@ -2,7 +2,10 @@ * Europagate, 1995 * * $Log: ccl.h,v $ - * Revision 1.1 1995/02/13 12:35:20 adam + * 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. * */ @@ -13,7 +16,71 @@ #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_DOBBLE_QUAL 7 +#define CCL_ERR_EQ_EXPECTED 8 + +struct ccl_rpn_attr { + struct ccl_rpn_attr *next; + int type; + int value; +}; + +struct ccl_rpn_node { + enum rpn_node_kind { AND, OR, NOT, TERM, SET, 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; -void ccl_find_str (const char *str, int *error, int *pos); +struct ccl_rpn_node *ccl_find_str (CCL_bibset bibset, + const char *str, int *error, int *pos); char *ccl_err_msg (int ccl_errno); +void ccl_rpn_delete (struct ccl_rpn_node *rpn); +void ccl_qual_add (CCL_bibset b, + const char *name, + int nuse, int *use, + int relation, +/* -1 none + 0 ordered + 1-6 relation (<, <=, =, >=, >, <>) + */ + int position, +/* -1 none + 1 first in field + 2 first in sub field + 3 any position in field + */ + int structure, +/* -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) + */ + int truncation, + int completeness); +CCL_bibset ccl_qual_mk (void); +void ccl_qual_rm (CCL_bibset *b); + +#define CCL_TRUNC_L 1 +#define CCL_TRUNC_R 2 +#define CCL_TRUNC_LR 4 +#define CCL_TRUNC_NONE 8 +#define CCL_TRUNC_HASH 16 +#define CCL_TRUNC_REG 32 + diff --git a/ccl/cclerrms.c b/ccl/cclerrms.c index 85a4ce6..992140d 100644 --- a/ccl/cclerrms.c +++ b/ccl/cclerrms.c @@ -2,7 +2,10 @@ * Europagate, 1995 * * $Log: cclerrms.c,v $ - * Revision 1.1 1995/02/13 12:35:20 adam + * 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. * */ @@ -10,10 +13,14 @@ char *err_msg_array[] = { "Ok", "Search word expected", - ") expected", + "')' expected", "Set name expected", "Operator expected", - "Unbalanced )" + "Unbalanced ')'", + "Unknown qualifier", + "Qualifiers applied twice", + "'=' expected" + }; const char *ccl_err_msg (int ccl_errno) diff --git a/ccl/cclfind.c b/ccl/cclfind.c index b663666..c100640 100644 --- a/ccl/cclfind.c +++ b/ccl/cclfind.c @@ -2,7 +2,10 @@ * Europagate, 1995 * * $Log: cclfind.c,v $ - * Revision 1.1 1995/02/13 12:35:20 adam + * 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. * */ @@ -16,6 +19,7 @@ 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 @@ -33,6 +37,7 @@ static void strxcat (char *n, const char *src, int len) 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; @@ -49,6 +54,7 @@ static struct ccl_rpn_node *mk_node (enum rpn_node_kind kind) void ccl_rpn_delete (struct ccl_rpn_node *rpn) { + struct ccl_rpn_attr *attr, *attr1; if (!rpn) return; switch (rpn->kind) @@ -61,7 +67,11 @@ void ccl_rpn_delete (struct ccl_rpn_node *rpn) break; case TERM: free (rpn->u.t.term); - /* attr list */ + for (attr = rpn->u.t.attr_list; attr; attr = attr1) + { + attr1 = attr->next; + free (attr); + } break; case SET: free (rpn->u.setname); @@ -74,13 +84,27 @@ void ccl_rpn_delete (struct ccl_rpn_node *rpn) free (rpn); } -static struct ccl_rpn_node *find_spec (void); +static struct ccl_rpn_node *find_spec (struct ccl_qualifier **qa); +static struct ccl_rpn_node *search_terms (struct ccl_qualifier **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 (void) +static struct ccl_rpn_node *search_term (struct ccl_qualifier **qa) { struct ccl_rpn_node *p; struct ccl_token *lookahead = look_token; int len = 0; + int no = 0; if (KIND != CCL_TOK_TERM) { @@ -89,6 +113,7 @@ static struct ccl_rpn_node *search_term (void) } while (lookahead->kind == CCL_TOK_TERM) { + no++; len += 1+lookahead->len; lookahead = lookahead->next; } @@ -105,19 +130,104 @@ static struct ccl_rpn_node *search_term (void) strxcat (p->u.t.term, look_token->name, look_token->len); ADVANCE; } + if (qa) + { + int i; + /* use ... */ + for (i=0; qa[i]; i++) + { + int j; + for (j=0; jnuse; j++) + add_attr (p, 1, qa[i]->use[j]); + } + /* structure ... */ + if (qa[0]->structure == 0) + { + if (no == 1) + add_attr (p, 4, 2); + else + add_attr (p, 4, 1); + } + else if (qa[0]->structure > 0) + add_attr (p, 4, qa[0]->structure); + } return p; } -static struct ccl_rpn_node *qualifiers (struct ccl_token *la) +static struct ccl_rpn_node *qualifiers (struct ccl_token *la, + struct ccl_qualifier **qa) { + struct ccl_token *lookahead = look_token; + struct ccl_qualifier **ap; + int no = 1; + int i; + + if (qa) + { + ccl_error = CCL_ERR_DOBBLE_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, lookahead->name); + if (!ap[i]) + { + ccl_error = CCL_ERR_UNKNOWN_QUAL; + free (ap); + return NULL; + } + ADVANCE; + if (KIND == CCL_TOK_COMMA) + ADVANCE; + } + ap[i] = NULL; + if (ap[0]->relation != 0) + { + /* 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; + } + /* ordered relation ... */ assert (0); + free (ap); return NULL; } -static struct ccl_rpn_node *search_terms (void) +static struct ccl_rpn_node *search_terms (struct ccl_qualifier **qa) { struct ccl_rpn_node *p1, *p2, *pn; - p1 = search_term (); + p1 = search_term (qa); if (!p1) return NULL; while (1) @@ -125,7 +235,7 @@ static struct ccl_rpn_node *search_terms (void) if (KIND == CCL_TOK_PROX) { ADVANCE; - p2 = search_term (); + p2 = search_term (qa); if (!p2) { ccl_rpn_delete (p1); @@ -138,7 +248,7 @@ static struct ccl_rpn_node *search_terms (void) } else if (KIND == CCL_TOK_TERM) { - p2 = search_term (); + p2 = search_term (qa); if (!p2) { ccl_rpn_delete (p1); @@ -155,14 +265,14 @@ static struct ccl_rpn_node *search_terms (void) return p1; } -static struct ccl_rpn_node *search_elements (void) +static struct ccl_rpn_node *search_elements (struct ccl_qualifier **qa) { struct ccl_rpn_node *p1; struct ccl_token *lookahead; if (KIND == CCL_TOK_LP) { ADVANCE; - p1 = find_spec (); + p1 = find_spec (qa); if (!p1) return NULL; if (KIND != CCL_TOK_RP) @@ -192,14 +302,14 @@ static struct ccl_rpn_node *search_elements (void) 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); - return search_terms (); + return qualifiers (lookahead, qa); + return search_terms (qa); } -static struct ccl_rpn_node *find_spec (void) +static struct ccl_rpn_node *find_spec (struct ccl_qualifier **qa) { struct ccl_rpn_node *p1, *p2, *pn; - if (!(p1 = search_elements ())) + if (!(p1 = search_elements (qa))) return NULL; while (1) { @@ -207,7 +317,7 @@ static struct ccl_rpn_node *find_spec (void) { case CCL_TOK_AND: ADVANCE; - p2 = search_elements (); + p2 = search_elements (qa); if (!p2) { ccl_rpn_delete (p1); @@ -220,7 +330,7 @@ static struct ccl_rpn_node *find_spec (void) continue; case CCL_TOK_OR: ADVANCE; - p2 = search_elements (); + p2 = search_elements (qa); if (!p2) { ccl_rpn_delete (p1); @@ -233,7 +343,7 @@ static struct ccl_rpn_node *find_spec (void) continue; case CCL_TOK_NOT: ADVANCE; - p2 = search_elements (); + p2 = search_elements (qa); if (!p2) { ccl_rpn_delete (p1); @@ -250,13 +360,14 @@ static struct ccl_rpn_node *find_spec (void) return p1; } -struct ccl_rpn_node *ccl_find (struct ccl_token *list, +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; - p = find_spec (); + bibset = abibset; + p = find_spec (NULL); if (p && KIND != CCL_TOK_EOL) { if (KIND == CCL_TOK_RP) @@ -276,10 +387,19 @@ struct ccl_rpn_node *ccl_find (struct ccl_token *list, static void pr_tree (struct ccl_rpn_node *rpn) { + switch (rpn->kind) { case TERM: printf ("\"%s\"", rpn->u.t.term); + if (rpn->u.t.attr_list) + { + struct ccl_rpn_attr *attr; + printf ("[ "); + for (attr = rpn->u.t.attr_list; attr; attr = attr->next) + printf ("%d=%d ", attr->type, attr->value); + printf ("] "); + } break; case AND: printf ("("); @@ -317,7 +437,8 @@ static void pr_tree (struct ccl_rpn_node *rpn) } } -void ccl_find_str (const char *str, int *error, int *pos) +struct ccl_rpn_node *ccl_find_str (CCL_bibset bibset, const char *str, + int *error, int *pos) { struct ccl_token *list, *li; struct ccl_rpn_node *rpn; @@ -328,7 +449,7 @@ void ccl_find_str (const char *str, int *error, int *pos) for (li = list; li; li = li->next) printf ("kind=%d, str='%.*s'\n", li->kind, li->len, li->name); #endif - rpn = ccl_find (list, error, &char_pos); + rpn = ccl_find (bibset, list, error, &char_pos); if (! *error) { pr_tree (rpn); @@ -338,4 +459,5 @@ void ccl_find_str (const char *str, int *error, int *pos) { *pos = char_pos - str; } + return rpn; } diff --git a/ccl/cclp.h b/ccl/cclp.h index d8aa138..d9565ce 100644 --- a/ccl/cclp.h +++ b/ccl/cclp.h @@ -2,7 +2,10 @@ * Europagate, 1995 * * $Log: cclp.h,v $ - * Revision 1.1 1995/02/13 12:35:20 adam + * 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. * */ @@ -31,23 +34,19 @@ struct ccl_token { struct ccl_token *prev; }; -struct ccl_rpn_attr { - struct ccl_rpn_attr *next; - int name; - int value; +struct ccl_qualifier { + char *name; + int nuse; + int *use; + int relation; + int position; + int structure; + int truncation; + int completeness; + struct ccl_qualifier *next; }; -struct ccl_rpn_node { - enum rpn_node_kind { AND, OR, NOT, TERM, SET, PROX } kind; - union { - struct ccl_rpn_node *p[2]; - struct { - char *term; - struct ccl_rpn_attr *attr_list; - } t; - char *setname; - } u; -}; struct ccl_token *ccl_tokenize (const char *command); -void ccl_rpn_delete (struct ccl_rpn_node *rpn); +struct ccl_qualifier *ccl_qual_search (CCL_bibset b, const char *name); + diff --git a/ccl/cclqual.c b/ccl/cclqual.c new file mode 100644 index 0000000..4dff9cb --- /dev/null +++ b/ccl/cclqual.c @@ -0,0 +1,72 @@ +/* CCL qualifiers + * Europagate, 1995 + * + * $Log: cclqual.c,v $ + * Revision 1.1 1995/02/13 15:15:07 adam + * Added handling of qualifiers. Not finished yet. + * + */ + +#include +#include +#include +#include + +#include "cclp.h" + +struct ccl_qualifiers { + struct ccl_qualifier *list; +}; + +void ccl_qual_add (CCL_bibset b, + const char *name, int nuse, int *use, int relation, + int position, int structure, int truncation, + int completeness) +{ + struct ccl_qualifier *new_qual; + + assert (b); + 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); + new_qual->nuse = nuse; + new_qual->use = malloc (sizeof(int)*nuse); + assert (new_qual->use); + memcpy (new_qual->use, use, sizeof(int)*nuse); + new_qual->relation = relation; + new_qual->position = position; + new_qual->structure = structure; + new_qual->truncation = truncation; + new_qual->completeness = completeness; +} + +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_qualifier *ccl_qual_search (CCL_bibset b, const char *name) +{ + struct ccl_qualifier *q; + + assert (b); + for (q = b->list; q; q = q->next) + if (strcmp (name, q->name)) + return q; + return NULL; +} diff --git a/ccl/cclsh.c b/ccl/cclsh.c index 24c4520..f6dd236 100644 --- a/ccl/cclsh.c +++ b/ccl/cclsh.c @@ -2,7 +2,10 @@ * Europagate 1995 * * $Log: cclsh.c,v $ - * Revision 1.1 1995/02/13 12:35:21 adam + * 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. * */ @@ -17,7 +20,11 @@ static char *prog; int main (int argc, char **argv) { + CCL_bibset bibset; + static int uses[10]; + prog = *argv; + bibset = ccl_qual_mk (); while (--argc > 0) { ++argv; @@ -40,6 +47,12 @@ int main (int argc, char **argv) exit (1); } } + uses[0] = 5; + ccl_qual_add (bibset, "ti", 1, uses, -1, -1, + 0, -1, -1); + uses[0] = 1; + ccl_qual_add (bibset, "au", 1, uses, -1, -1, + 0, -1, -1); while (1) { char buf[80]; @@ -48,7 +61,7 @@ int main (int argc, char **argv) printf ("CCLSH>"); fflush (stdout); if (!fgets (buf, 79, stdin)) break; - ccl_find_str (buf, &error, &pos); + ccl_find_str (bibset, buf, &error, &pos); if (error) { printf ("%*s^ - ", 6+pos, " "); -- 1.7.10.4