From de80462103c0fc554c8fa40827894f92fa9d8fe6 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 25 Apr 2007 20:52:18 +0000 Subject: [PATCH] Clean-up the CCL API. Moved some internal structures from ccl.h to private header cclp.h. Changed ccl_parser_create so that a Bibset must be supplied. Removed tokenize API from ccl.h - including ccl_parser_find. This is replaced by ccl_parser_find_str which takes a string instead. --- NEWS | 5 +++ include/yaz/ccl.h | 113 +++++------------------------------------------------ src/Makefile.am | 4 +- src/cclfind.c | 52 ++++++++---------------- src/cclp.h | 95 ++++++++++++++++++++++++++++++++++++++++++++ src/cclqfile.c | 19 ++++----- src/cclqual.c | 14 ++++++- src/ccltoken.c | 28 ++++++------- test/tstccl.c | 11 ++---- util/cclsh.c | 41 +++++-------------- 10 files changed, 176 insertions(+), 206 deletions(-) create mode 100644 src/cclp.h diff --git a/NEWS b/NEWS index 1c5d0a6..bd9a2f8 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +Clean-up the CCL API. Moved some internal structures from ccl.h to +private header cclp.h. Changed ccl_parser_create so that a Bibset must +be supplied. Removed tokenize API from ccl.h - including ccl_parser_find. +This is replaced by ccl_parser_find_str which takes a string instead. + Split YAZ library into two libs : libyaz.la and libyaz_server.la. libyaz.la is the core of YAZ except the generic frontend server and does not depend on POSIX threads anymore. libyaz_server.la is the diff --git a/include/yaz/ccl.h b/include/yaz/ccl.h index 6296864..a132f86 100644 --- a/include/yaz/ccl.h +++ b/include/yaz/ccl.h @@ -49,7 +49,7 @@ /* * CCL - header file * - * $Id: ccl.h,v 1.23 2005-06-25 15:46:01 adam Exp $ + * $Id: ccl.h,v 1.24 2007-04-25 20:52:18 adam Exp $ * * Old Europagate Log: * @@ -203,95 +203,9 @@ typedef struct ccl_qualifiers *CCL_bibset; #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 9 -#define CCL_TOK_NOT 10 -#define CCL_TOK_SET 11 - -/** CCL token */ -struct ccl_token { - char kind; - size_t len; /* length of name below */ - const char *name; /* string / name of token */ - struct ccl_token *next; - struct ccl_token *prev; - const char *ws_prefix_buf; /* leading white space buf */ - size_t ws_prefix_len; /* leading white space len */ -}; - -/** CCL Qualifier */ -struct ccl_qualifier { - char *name; - int no_sub; - struct ccl_qualifier **sub; - struct ccl_rpn_attr *attr_list; - struct ccl_qualifier *next; -}; - -/** CCL parser structure */ -struct ccl_parser { - /** current lookahead token */ - struct ccl_token *look_token; - - /** holds error code if error occur */ - int error_code; - /** if error occurs, this holds position (starting from 0). */ - const char *error_pos; - - /** current bibset */ - CCL_bibset bibset; - - /** names of and operator */ - char *ccl_token_and; - /** names of or operator */ - char *ccl_token_or; - /** names of not operator */ - char *ccl_token_not; - /** names of set operator */ - char *ccl_token_set; - /** 1=CCL parser is case sensitive, 0=case insensitive */ - int ccl_case_sensitive; -}; - typedef struct ccl_parser *CCL_parser; /** - * Splits CCL command string into individual tokens using - * a CCL parser. - */ -YAZ_EXPORT -struct ccl_token *ccl_parser_tokenize (CCL_parser cclp, const char *command); - -/** - * Splits CCL command string into tokens using temporary parser. - * - * Use ccl_parser_tokenize instead and provide a parser - it is - * more flexible and efficient. - */ -YAZ_EXPORT -struct ccl_token *ccl_tokenize (const char *command); - -/** - * Deletes token list - */ -YAZ_EXPORT -void ccl_token_del (struct ccl_token *list); - -/** - * Add single token after a given onde. - */ -YAZ_EXPORT -struct ccl_token *ccl_token_add (struct ccl_token *at); - -/** * Parses a CCL Find command in a simple C string. Returns CCL parse * tree node describing RPN if parsing is successful. If parsing is * unsuccesful, NULL is returned and error and pos is set accordingly. @@ -300,20 +214,8 @@ YAZ_EXPORT struct ccl_rpn_node *ccl_find_str (CCL_bibset bibset, const char *str, int *error, int *pos); -/** - * Parses CCL Find command from a list of CCL tokens. Otherwise similar to - * ccl_find_str. - */ YAZ_EXPORT -struct ccl_rpn_node *ccl_find (CCL_bibset abibset, struct ccl_token *list, - int *error, const char **pos); - -/** - * Parses a CCL Find command from a list of CCL tokens and given a CCL - * parser. Otherwise similar to ccl_find_str. - */ -YAZ_EXPORT -struct ccl_rpn_node *ccl_parser_find (CCL_parser cclp, struct ccl_token *list); +struct ccl_rpn_node *ccl_parser_find_str(CCL_parser cclp, const char *str); /** Set names for AND operator in parser */ YAZ_EXPORT @@ -411,7 +313,7 @@ struct ccl_rpn_attr *ccl_qual_search (CCL_parser cclp, const char *name, /** Create CCL parser */ YAZ_EXPORT -CCL_parser ccl_parser_create (void); +CCL_parser ccl_parser_create (CCL_bibset bibset); /** Destroy CCL parser */ YAZ_EXPORT @@ -423,12 +325,17 @@ char *ccl_strdup (const char *str); /** Search for special qualifier */ YAZ_EXPORT -const char *ccl_qual_search_special (CCL_bibset b, - const char *name); +const char *ccl_qual_search_special (CCL_bibset b, const char *name); /** Pretty-print CCL RPN node tree to WRBUF */ YAZ_EXPORT void ccl_pquery (WRBUF w, struct ccl_rpn_node *p); +YAZ_EXPORT +CCL_bibset ccl_parser_get_bibset(CCL_parser cclp); + +YAZ_EXPORT +int ccl_parser_get_error(CCL_parser cclp, int *pos); + #ifndef ccl_assert #define ccl_assert(x) ; #endif diff --git a/src/Makefile.am b/src/Makefile.am index b9ec18b..780d0b5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ ## This file is part of the YAZ toolkit. ## Copyright (C) 1995-2007, Index Data, All rights reserved. -## $Id: Makefile.am,v 1.63 2007-04-18 08:08:02 adam Exp $ +## $Id: Makefile.am,v 1.64 2007-04-25 20:52:19 adam Exp $ YAZ_VERSION_INFO=3:0:0 @@ -85,7 +85,7 @@ libyaz_la_SOURCES=version.c options.c log.c \ otherinfo.c pquery.c sortspec.c charneg.c initopt.c \ zoom-c.c zoom-socket.c zoom-opt.c zoom-p.h \ grs1disp.c zgdu.c soap.c srw.c srwutil.c \ - opacdisp.c cclfind.c ccltoken.c cclerrms.c cclqual.c cclptree.c \ + opacdisp.c cclfind.c ccltoken.c cclerrms.c cclqual.c cclptree.c cclp.h \ cclqfile.c cclstr.c cclxmlconfig.c \ cql.y cqlstdio.c cqltransform.c cqlutil.c xcqlutil.c cqlstring.c \ cqlstrer.c querytowrbuf.c \ diff --git a/src/cclfind.c b/src/cclfind.c index 72f1aa6..f03de85 100644 --- a/src/cclfind.c +++ b/src/cclfind.c @@ -56,7 +56,7 @@ /* CCL find (to rpn conversion) * Europagate, 1995 * - * $Id: cclfind.c,v 1.8 2005-06-25 15:46:03 adam Exp $ + * $Id: cclfind.c,v 1.9 2007-04-25 20:52:19 adam Exp $ * * Old Europagate log: * @@ -113,7 +113,7 @@ #include #include -#include +#include "cclp.h" /* returns type of current lookahead */ #define KIND (cclp->look_token->kind) @@ -1121,7 +1121,17 @@ static struct ccl_rpn_node *find_spec (CCL_parser cclp, return p1; } -struct ccl_rpn_node *ccl_parser_find (CCL_parser cclp, struct ccl_token *list) +struct ccl_rpn_node *ccl_parser_find_str(CCL_parser cclp, const char *str) +{ + struct ccl_rpn_node *p; + struct ccl_token *list = ccl_parser_tokenize(cclp, str); + p = ccl_parser_find_token(cclp, list); + ccl_token_del(list); + return p; +} + +struct ccl_rpn_node *ccl_parser_find_token(CCL_parser cclp, + struct ccl_token *list) { struct ccl_rpn_node *p; @@ -1145,32 +1155,6 @@ struct ccl_rpn_node *ccl_parser_find (CCL_parser cclp, struct ccl_token *list) } /** - * ccl_find: Parse CCL find - token representation - * bibset: 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 bibset, struct ccl_token *list, - int *error, const char **pos) -{ - struct ccl_rpn_node *p; - CCL_parser cclp = ccl_parser_create (); - - cclp->bibset = bibset; - - p = ccl_parser_find (cclp, list); - - *error = cclp->error_code; - *pos = cclp->error_pos; - - ccl_parser_destroy (cclp); - - return p; -} - -/** * ccl_find_str: Parse CCL find - string representation * bibset: Bibset to be used for the parsing * str: String to be parsed @@ -1178,17 +1162,15 @@ struct ccl_rpn_node *ccl_find (CCL_bibset bibset, struct ccl_token *list, * 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) +struct ccl_rpn_node *ccl_find_str(CCL_bibset bibset, const char *str, + int *error, int *pos) { - CCL_parser cclp = ccl_parser_create (); + CCL_parser cclp = ccl_parser_create (bibset); struct ccl_token *list; struct ccl_rpn_node *p; - cclp->bibset = bibset; - list = ccl_parser_tokenize (cclp, str); - p = ccl_parser_find (cclp, list); + p = ccl_parser_find_token(cclp, list); *error = cclp->error_code; if (*error) diff --git a/src/cclp.h b/src/cclp.h new file mode 100644 index 0000000..a45052d --- /dev/null +++ b/src/cclp.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 1995-2005, Index Data ApS + * See the file LICENSE for details. + * + * $Id: cclp.h,v 1.1 2007-04-25 20:52:19 adam Exp $ + */ + +#include + +#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 9 +#define CCL_TOK_NOT 10 +#define CCL_TOK_SET 11 + + +/** CCL token */ +struct ccl_token { + char kind; + size_t len; /* length of name below */ + const char *name; /* string / name of token */ + struct ccl_token *next; + struct ccl_token *prev; + const char *ws_prefix_buf; /* leading white space buf */ + size_t ws_prefix_len; /* leading white space len */ +}; + +/** CCL parser structure */ +struct ccl_parser { + /** current lookahead token */ + struct ccl_token *look_token; + + /** holds error code if error occur */ + int error_code; + /** start of CCL string buffer */ + const char *start_pos; + /** if error occurs, this holds position (starting from 0). */ + const char *error_pos; + + /** current bibset */ + CCL_bibset bibset; + + /** names of and operator */ + char *ccl_token_and; + /** names of or operator */ + char *ccl_token_or; + /** names of not operator */ + char *ccl_token_not; + /** names of set operator */ + char *ccl_token_set; + /** 1=CCL parser is case sensitive, 0=case insensitive */ + int ccl_case_sensitive; +}; + +/** + * Splits CCL command string into individual tokens using + * a CCL parser. + */ +YAZ_EXPORT +struct ccl_token *ccl_parser_tokenize (CCL_parser cclp, const char *command); + +/** + * Deletes token list + */ +YAZ_EXPORT +void ccl_token_del (struct ccl_token *list); + +/** + * Add single token after a given onde. + */ +YAZ_EXPORT +struct ccl_token *ccl_token_add (struct ccl_token *at); + + +YAZ_EXPORT +struct ccl_rpn_node *ccl_parser_find_token(CCL_parser cclp, + struct ccl_token *list); + + + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/cclqfile.c b/src/cclqfile.c index 210be93..9d34229 100644 --- a/src/cclqfile.c +++ b/src/cclqfile.c @@ -48,7 +48,7 @@ /* CCL qualifiers * Europagate, 1995 * - * $Id: cclqfile.c,v 1.7 2005-06-25 15:46:03 adam Exp $ + * $Id: cclqfile.c,v 1.8 2007-04-25 20:52:19 adam Exp $ * * Old Europagate Log: * @@ -71,16 +71,18 @@ #include +#define MAX_QUAL 128 + void ccl_qual_field (CCL_bibset bibset, const char *cp, const char *qual_name) { char qual_spec[128]; - int type_ar[128]; - int value_ar[128]; - char *svalue_ar[128]; - char *attsets[128]; + int type_ar[MAX_QUAL]; + int value_ar[MAX_QUAL]; + char *svalue_ar[MAX_QUAL]; + char *attsets[MAX_QUAL]; int pair_no = 0; - while (pair_no < 128) + while (pair_no < MAX_QUAL) { char *qual_value, *qual_type; char *split, *setp; @@ -116,7 +118,7 @@ void ccl_qual_field (CCL_bibset bibset, const char *cp, const char *qual_name) /* type=value ... */ qual_type = qual_spec; } - while (pair_no < 128) + while (pair_no < MAX_QUAL) { int type, value; @@ -198,8 +200,7 @@ void ccl_qual_field (CCL_bibset bibset, const char *cp, const char *qual_name) } if (setp) { - attsets[pair_no] = (char*) xmalloc (strlen(qual_spec)+1); - strcpy (attsets[pair_no], qual_spec); + attsets[pair_no] = xstrdup (qual_spec); } else attsets[pair_no] = 0; diff --git a/src/cclqual.c b/src/cclqual.c index 24ea31c..287836c 100644 --- a/src/cclqual.c +++ b/src/cclqual.c @@ -48,7 +48,7 @@ /* CCL qualifiers * Europagate, 1995 * - * $Id: cclqual.c,v 1.3 2005-06-25 15:46:03 adam Exp $ + * $Id: cclqual.c,v 1.4 2007-04-25 20:52:19 adam Exp $ * * Old Europagate Log: * @@ -86,7 +86,17 @@ #include #include -#include +#include "cclp.h" + +/** CCL Qualifier */ +struct ccl_qualifier { + char *name; + int no_sub; + struct ccl_qualifier **sub; + struct ccl_rpn_attr *attr_list; + struct ccl_qualifier *next; +}; + /** Definition of CCL_bibset pointer */ struct ccl_qualifiers { diff --git a/src/ccltoken.c b/src/ccltoken.c index 1288071..35b03ed 100644 --- a/src/ccltoken.c +++ b/src/ccltoken.c @@ -48,7 +48,7 @@ /* CCL - lexical analysis * Europagate, 1995 * - * $Id: ccltoken.c,v 1.9 2005-08-22 20:34:21 adam Exp $ + * $Id: ccltoken.c,v 1.10 2007-04-25 20:52:19 adam Exp $ * * Old Europagate Log: * @@ -91,7 +91,7 @@ #include #include -#include +#include "cclp.h" /* * token_cmp: Compare token with keyword(s) @@ -146,6 +146,7 @@ struct ccl_token *ccl_parser_tokenize (CCL_parser cclp, const char *command) const unsigned char *cp = (const unsigned char *) command; struct ccl_token *first = NULL; struct ccl_token *last = NULL; + cclp->start_pos = command; while (1) { @@ -277,17 +278,6 @@ struct ccl_token *ccl_token_add (struct ccl_token *at) return n; } -struct ccl_token *ccl_tokenize (const char *command) -{ - CCL_parser cclp = ccl_parser_create (); - struct ccl_token *list; - - list = ccl_parser_tokenize (cclp, command); - - ccl_parser_destroy (cclp); - return list; -} - /* * ccl_token_del: delete CCL tokens */ @@ -311,7 +301,7 @@ char *ccl_strdup (const char *str) return p; } -CCL_parser ccl_parser_create (void) +CCL_parser ccl_parser_create (CCL_bibset bibset) { CCL_parser p = (CCL_parser)xmalloc (sizeof(*p)); if (!p) @@ -319,7 +309,7 @@ CCL_parser ccl_parser_create (void) p->look_token = NULL; p->error_code = 0; p->error_pos = NULL; - p->bibset = NULL; + p->bibset = bibset; p->ccl_token_and = ccl_strdup("and"); p->ccl_token_or = ccl_strdup("or"); @@ -384,6 +374,14 @@ void ccl_parser_set_case (CCL_parser p, int case_sensitivity_flag) if (p) p->ccl_case_sensitive = case_sensitivity_flag; } + +int ccl_parser_get_error(CCL_parser cclp, int *pos) +{ + if (pos && cclp->error_code) + *pos = cclp->error_pos - cclp->start_pos; + return cclp->error_code; +} + /* * Local variables: * c-basic-offset: 4 diff --git a/test/tstccl.c b/test/tstccl.c index f5aac60..6b3ff05 100644 --- a/test/tstccl.c +++ b/test/tstccl.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2007, Index Data ApS * See the file LICENSE for details. * - * $Id: tstccl.c,v 1.15 2007-03-19 22:17:41 adam Exp $ + * $Id: tstccl.c,v 1.16 2007-04-25 20:52:19 adam Exp $ */ /* CCL test */ @@ -16,19 +16,14 @@ static int tst_ccl_query(CCL_bibset bibset, const char *query, const char *result) { - CCL_parser parser = ccl_parser_create(); + CCL_parser parser = ccl_parser_create(bibset); int ret = 0; if (parser && bibset) { - struct ccl_token *token_list; struct ccl_rpn_node *rpn; - parser->bibset = bibset; - - token_list = ccl_parser_tokenize(parser, query); - rpn = ccl_parser_find(parser, token_list); - ccl_token_del(token_list); + rpn = ccl_parser_find_str(parser, query); if (rpn) { /* parse ok. check that result is there and match */ diff --git a/util/cclsh.c b/util/cclsh.c index 0d89350..6882ce2 100644 --- a/util/cclsh.c +++ b/util/cclsh.c @@ -44,7 +44,7 @@ /* CCL shell. * Europagate 1995 * - * $Id: cclsh.c,v 1.5 2007-01-08 10:48:08 adam Exp $ + * $Id: cclsh.c,v 1.6 2007-04-25 20:52:20 adam Exp $ * * Old Europagate Log: * @@ -172,17 +172,13 @@ int main (int argc, char **argv) } if (q_wrbuf) { - CCL_parser cclp = ccl_parser_create (); - struct ccl_token *list; + CCL_parser cclp = ccl_parser_create(bibset); int error; struct ccl_rpn_node *rpn; - cclp->bibset = bibset; + rpn = ccl_parser_find_str (cclp, wrbuf_cstr(q_wrbuf)); - list = ccl_parser_tokenize (cclp, wrbuf_cstr(q_wrbuf)); - rpn = ccl_parser_find (cclp, list); - - error = cclp->error_code; + error = ccl_parser_get_error(cclp, 0); if (error) { @@ -196,13 +192,6 @@ int main (int argc, char **argv) printf ("\n"); } } - if (debug) - { - struct ccl_token *lp; - for (lp = list; lp; lp = lp->next) - printf ("%d %.*s\n", lp->kind, (int) (lp->len), lp->name); - } - ccl_token_del (list); ccl_parser_destroy (cclp); if (rpn) ccl_rpn_delete(rpn); @@ -212,7 +201,7 @@ int main (int argc, char **argv) while (1) { char buf[1000]; - int i, error, pos; + int i, error; struct ccl_rpn_node *rpn; #if HAVE_READLINE_READLINE_H @@ -238,17 +227,12 @@ int main (int argc, char **argv) for (i = 0; i<1; i++) { - CCL_parser cclp = ccl_parser_create (); - struct ccl_token *list; - - cclp->bibset = bibset; + CCL_parser cclp = ccl_parser_create(bibset); + int pos; - list = ccl_parser_tokenize (cclp, buf); - rpn = ccl_parser_find (cclp, list); + rpn = ccl_parser_find_str(cclp, buf); - error = cclp->error_code; - if (error) - pos = cclp->error_pos - buf; + error = ccl_parser_get_error(cclp, &pos); if (error) { @@ -263,13 +247,6 @@ int main (int argc, char **argv) printf ("\n"); } } - if (debug) - { - struct ccl_token *lp; - for (lp = list; lp; lp = lp->next) - printf ("%d %.*s\n", lp->kind, (int) (lp->len), lp->name); - } - ccl_token_del (list); ccl_parser_destroy (cclp); if (rpn) ccl_rpn_delete(rpn); -- 1.7.10.4