From b977948f73d07c0bf4478565f9af3497ffe862e7 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 22 Jul 2008 15:54:15 +0200 Subject: [PATCH] Added cql_transform_define_pattern. Renamed rpn2cql funcs. --- include/yaz/cql.h | 13 +++ include/yaz/rpn2cql.h | 24 ++++-- src/cqltransform.c | 222 ++++++++++++++++++++++++++++++++++++++++--------- src/rpn2cql.c | 51 +++++++++--- test/tst_rpn2cql.c | 2 +- util/cql2pqf.c | 3 +- 6 files changed, 258 insertions(+), 57 deletions(-) diff --git a/include/yaz/cql.h b/include/yaz/cql.h index 8cc3c85..fe3b7d4 100644 --- a/include/yaz/cql.h +++ b/include/yaz/cql.h @@ -250,6 +250,19 @@ cql_transform_t cql_transform_open_FILE (FILE *f); YAZ_EXPORT cql_transform_t cql_transform_open_fname(const char *fname); + +/** \brief defines CQL transform pattern + \param ct CQL transform handle + \param pattern pattern string + \param value pattern value + \returns 0 for succes; -1 for failure +*/ +YAZ_EXPORT +int cql_transform_define_pattern(cql_transform_t ct, const char *pattern, + const char *value); + + + /** \brief destroys a CQL transform handle \param ct CQL transform handle */ diff --git a/include/yaz/rpn2cql.h b/include/yaz/rpn2cql.h index 90798db..1eadae1 100644 --- a/include/yaz/rpn2cql.h +++ b/include/yaz/rpn2cql.h @@ -33,10 +33,11 @@ #define RPN2CQL_H_INCLUDED #include #include +#include YAZ_BEGIN_CDECL -/** \brief transforms PQF given a CQL tree (from FILE) +/** \brief transforms PQF given a CQL tree \param ct CQL transform handle \param pr print function \param client_data opaque data to be passed to print handler @@ -45,10 +46,23 @@ YAZ_BEGIN_CDECL \retval !=0 failure (error code) */ YAZ_EXPORT -int cql_transform_rpn2cql(cql_transform_t ct, - void (*pr)(const char *buf, void *client_data), - void *client_data, - Z_RPNQuery *q); +int cql_transform_rpn2cql_stream(cql_transform_t ct, + void (*pr)(const char *buf, void *client_data), + void *client_data, + Z_RPNQuery *q); + + +/** \brief transforms PQF given a CQL tree + \param ct CQL transform handle + \param w WRBUF handle for result + \param q RPN Query + \retval 0 success + \retval !=0 failure (error code) + */ +YAZ_EXPORT +int cql_transform_rpn2cql_wrbuf(cql_transform_t ct, + WRBUF w, + Z_RPNQuery *q); YAZ_END_CDECL diff --git a/src/cqltransform.c b/src/cqltransform.c index d350242..cd735e4 100644 --- a/src/cqltransform.c +++ b/src/cqltransform.c @@ -21,15 +21,25 @@ #include #include #include +#include #include #include #include #include #include +#include +#include +#include + +struct cql_rpn_value_entry { + Z_AttributeElement *elem; + struct cql_rpn_value_entry *next; +}; struct cql_prop_entry { char *pattern; char *value; + struct cql_rpn_value_entry *attr_values; struct cql_prop_entry *next; }; @@ -39,6 +49,7 @@ struct cql_transform_t_ { int error; char *addinfo; WRBUF w; + NMEM nmem; }; @@ -50,14 +61,156 @@ cql_transform_t cql_transform_create(void) ct->error = 0; ct->addinfo = 0; ct->entry = 0; + ct->nmem = nmem_create(); return ct; } +static int cql_transform_parse_tok_line(cql_transform_t ct, + const char *pattern, + yaz_tok_parse_t tp) +{ + int ret = 0; /* 0=OK, != 0 FAIL */ + int t; + t = yaz_tok_move(tp); + + while (t == YAZ_TOK_STRING) + { + WRBUF type_str = wrbuf_alloc(); + WRBUF set_str = 0; + Z_AttributeElement *elem = 0; + const char *value_str = 0; + /* attset type=value OR type=value */ + + elem = nmem_malloc(ct->nmem, sizeof(*elem)); + elem->attributeSet = 0; +#if 0 + struct Z_ComplexAttribute { + int num_list; + Z_StringOrNumeric **list; + int num_semanticAction; + int **semanticAction; /* OPT */ + }; + + struct Z_AttributeElement { + Z_AttributeSetId *attributeSet; /* OPT */ + int *attributeType; + int which; + union { + int *numeric; + Z_ComplexAttribute *complex; +#define Z_AttributeValue_numeric 1 +#define Z_AttributeValue_complex 2 + } value; + }; +#endif + wrbuf_puts(ct->w, yaz_tok_parse_string(tp)); + wrbuf_puts(type_str, yaz_tok_parse_string(tp)); + t = yaz_tok_move(tp); + if (t == YAZ_TOK_EOF) + { + wrbuf_destroy(type_str); + if (set_str) + wrbuf_destroy(set_str); + break; + } + if (t == YAZ_TOK_STRING) + { + wrbuf_puts(ct->w, " "); + wrbuf_puts(ct->w, yaz_tok_parse_string(tp)); + set_str = type_str; + + elem->attributeSet = + yaz_string_to_oid_nmem(yaz_oid_std(), CLASS_ATTSET, + wrbuf_cstr(set_str), ct->nmem); + + type_str = wrbuf_alloc(); + wrbuf_puts(type_str, yaz_tok_parse_string(tp)); + t = yaz_tok_move(tp); + } + elem->attributeType = nmem_intdup(ct->nmem, 0); + if (sscanf(wrbuf_cstr(type_str), "%d", elem->attributeType) + != 1) + { + wrbuf_destroy(type_str); + if (set_str) + wrbuf_destroy(set_str); + yaz_log(YLOG_WARN, "Expected numeric attribute type"); + ret = -1; + break; + } + + wrbuf_destroy(type_str); + if (set_str) + wrbuf_destroy(set_str); + + if (t != '=') + { + yaz_log(YLOG_WARN, "Expected = after after attribute type"); + ret = -1; + break; + } + t = yaz_tok_move(tp); + if (t != YAZ_TOK_STRING) /* value */ + { + yaz_log(YLOG_WARN, "Missing attribute value"); + ret = -1; + break; + } + value_str = yaz_tok_parse_string(tp); + if (isdigit(*value_str)) + { + elem->which = Z_AttributeValue_numeric; + elem->value.numeric = + nmem_intdup(ct->nmem, atoi(value_str)); + } + else + { + Z_ComplexAttribute *ca = nmem_malloc(ct->nmem, sizeof(*ca)); + elem->which = Z_AttributeValue_complex; + elem->value.complex = ca; + ca->num_list = 1; + ca->list = (Z_StringOrNumeric **) + nmem_malloc(ct->nmem, sizeof(Z_StringOrNumeric *)); + ca->list[0] = (Z_StringOrNumeric *) + nmem_malloc(ct->nmem, sizeof(Z_StringOrNumeric)); + ca->list[0]->which = Z_StringOrNumeric_string; + ca->list[0]->u.string = nmem_strdup(ct->nmem, value_str); + ca->num_semanticAction = 0; + ca->semanticAction = 0; + } + wrbuf_puts(ct->w, "="); + wrbuf_puts(ct->w, yaz_tok_parse_string(tp)); + t = yaz_tok_move(tp); + wrbuf_puts(ct->w, " "); + } + if (ret == 0) /* OK? */ + { + struct cql_prop_entry **pp = &ct->entry; + while (*pp) + pp = &(*pp)->next; + *pp = (struct cql_prop_entry *) xmalloc(sizeof(**pp)); + (*pp)->pattern = xstrdup(pattern); + (*pp)->value = xstrdup(wrbuf_cstr(ct->w)); + (*pp)->next = 0; + } + return ret; +} + +int cql_transform_define_pattern(cql_transform_t ct, const char *pattern, + const char *value) +{ + int r; + yaz_tok_parse_t tp = yaz_tok_parse_buf(ct->tok_cfg, value); + yaz_tok_cfg_single_tokens(ct->tok_cfg, "="); + r = cql_transform_parse_tok_line(ct, pattern, tp); + yaz_tok_parse_destroy(tp); + return r; +} + cql_transform_t cql_transform_open_FILE(FILE *f) { cql_transform_t ct = cql_transform_create(); char line[1024]; - struct cql_prop_entry **pp = &ct->entry; yaz_tok_cfg_single_tokens(ct->tok_cfg, "="); @@ -77,43 +230,13 @@ cql_transform_t cql_transform_open_FILE(FILE *f) cql_transform_close(ct); return 0; } - t = yaz_tok_move(tp); - - while (t == YAZ_TOK_STRING) + if (cql_transform_parse_tok_line(ct, pattern, tp)) { - /* attset type=value OR type=value */ - wrbuf_puts(ct->w, yaz_tok_parse_string(tp)); - t = yaz_tok_move(tp); - if (t == YAZ_TOK_EOF) - break; - if (t == YAZ_TOK_STRING) - { - wrbuf_puts(ct->w, " "); - wrbuf_puts(ct->w, yaz_tok_parse_string(tp)); - t = yaz_tok_move(tp); - } - if (t != '=') - { - yaz_tok_parse_destroy(tp); - cql_transform_close(ct); - return 0; - } - t = yaz_tok_move(tp); - if (t != YAZ_TOK_STRING) /* value */ - { - yaz_tok_parse_destroy(tp); - cql_transform_close(ct); - return 0; - } - wrbuf_puts(ct->w, "="); - wrbuf_puts(ct->w, yaz_tok_parse_string(tp)); - t = yaz_tok_move(tp); - wrbuf_puts(ct->w, " "); + yaz_tok_parse_destroy(tp); + cql_transform_close(ct); + return 0; } - *pp = (struct cql_prop_entry *) xmalloc(sizeof(**pp)); - (*pp)->pattern = pattern; - (*pp)->value = xstrdup(wrbuf_cstr(ct->w)); - pp = &(*pp)->next; + xfree(pattern); } else if (t != YAZ_TOK_EOF) { @@ -123,7 +246,6 @@ cql_transform_t cql_transform_open_FILE(FILE *f) } yaz_tok_parse_destroy(tp); } - *pp = 0; return ct; } @@ -144,6 +266,7 @@ void cql_transform_close(cql_transform_t ct) xfree(ct->addinfo); yaz_tok_cfg_destroy(ct->tok_cfg); wrbuf_destroy(ct->w); + nmem_destroy(ct->nmem); xfree(ct); } @@ -158,6 +281,31 @@ cql_transform_t cql_transform_open_fname(const char *fname) return ct; } +static const char *cql_lookup_reverse(cql_transform_t ct, + const char *category, + const char **attr_list, + int *matches) +{ + struct cql_prop_entry *e; + size_t cat_len = strlen(category); + NMEM nmem = nmem_create(); + for (e = ct->entry; e; e = e->next) + { + const char *dot_str = strchr(e->pattern, '.'); + int prefix_len = dot_str ? + prefix_len = dot_str - e->pattern : strlen(e->pattern); + if (cat_len == prefix_len && !memcmp(category, e->pattern, cat_len)) + { + char **attr_array; + int attr_num; + nmem_strsplit_blank(nmem, e->value, &attr_array, &attr_num); + nmem_reset(nmem); + } + } + nmem_destroy(nmem); + return 0; +} + static const char *cql_lookup_property(cql_transform_t ct, const char *pat1, const char *pat2, const char *pat3) diff --git a/src/rpn2cql.c b/src/rpn2cql.c index 3e581a4..108c0ec 100644 --- a/src/rpn2cql.c +++ b/src/rpn2cql.c @@ -27,10 +27,23 @@ #include #include +static int rpn2cql_attr(cql_transform_t ct, + void (*pr)(const char *buf, void *client_data), + void *client_data, + Z_AttributeList *attributes, WRBUF w) +{ + int i; + for (i = 0; i < attributes->num_attributes; i++) + { + Z_AttributeElement *elem = attributes->attributes[i]; + } + return 0; +} + static int rpn2cql_simple(cql_transform_t ct, void (*pr)(const char *buf, void *client_data), void *client_data, - Z_Operand *q) + Z_Operand *q, WRBUF w) { int ret = 0; if (q->which != Z_Operand_APT) @@ -42,8 +55,9 @@ static int rpn2cql_simple(cql_transform_t ct, { Z_AttributesPlusTerm *apt = q->u.attributesPlusTerm; Z_Term *term = apt->term; - Z_AttributeList *attributes = apt->attributes; - WRBUF w = wrbuf_alloc(); + + wrbuf_rewind(w); + ret = rpn2cql_attr(ct, pr, client_data, apt->attributes, w); switch(term->which) { @@ -62,7 +76,6 @@ static int rpn2cql_simple(cql_transform_t ct, } if (ret == 0) pr(wrbuf_cstr(w), client_data); - wrbuf_destroy(w); } return ret; } @@ -70,10 +83,11 @@ static int rpn2cql_simple(cql_transform_t ct, static int rpn2cql_structure(cql_transform_t ct, void (*pr)(const char *buf, void *client_data), void *client_data, - Z_RPNStructure *q, int nested) + Z_RPNStructure *q, int nested, + WRBUF w) { if (q->which == Z_RPNStructure_simple) - return rpn2cql_simple(ct, pr, client_data, q->u.simple); + return rpn2cql_simple(ct, pr, client_data, q->u.simple, w); else { Z_Operator *op = q->u.complex->roperator; @@ -82,7 +96,7 @@ static int rpn2cql_structure(cql_transform_t ct, if (nested) pr("(", client_data); - r = rpn2cql_structure(ct, pr, client_data, q->u.complex->s1, 1); + r = rpn2cql_structure(ct, pr, client_data, q->u.complex->s1, 1, w); if (r) return r; switch(op->which) @@ -100,23 +114,34 @@ static int rpn2cql_structure(cql_transform_t ct, cql_transform_set_error(ct, YAZ_BIB1_UNSUPP_SEARCH, 0); return -1; } - r = rpn2cql_structure(ct, pr, client_data, q->u.complex->s2, 1); + r = rpn2cql_structure(ct, pr, client_data, q->u.complex->s2, 1, w); if (nested) pr(")", client_data); return r; } } -int cql_transform_rpn2cql(cql_transform_t ct, - void (*pr)(const char *buf, void *client_data), - void *client_data, - Z_RPNQuery *q) +int cql_transform_rpn2cql_stream(cql_transform_t ct, + void (*pr)(const char *buf, void *client_data), + void *client_data, + Z_RPNQuery *q) { + int r; + WRBUF w = wrbuf_alloc(); cql_transform_set_error(ct, 0, 0); - return rpn2cql_structure(ct, pr, client_data, q->RPNStructure, 0); + r = rpn2cql_structure(ct, pr, client_data, q->RPNStructure, 0, w); + wrbuf_destroy(w); + return r; } +int cql_transform_rpn2cql_wrbuf(cql_transform_t ct, + WRBUF w, + Z_RPNQuery *q) +{ + return cql_transform_rpn2cql_stream(ct, wrbuf_vputs, w, q); +} + /* * Local variables: * c-basic-offset: 4 diff --git a/test/tst_rpn2cql.c b/test/tst_rpn2cql.c index bed3d66..2ef5d0e 100644 --- a/test/tst_rpn2cql.c +++ b/test/tst_rpn2cql.c @@ -21,7 +21,7 @@ static int compare(cql_transform_t ct, const char *pqf, const char *cql) if (q) { - int r = cql_transform_rpn2cql(ct, wrbuf_vputs, w, q); + int r = cql_transform_rpn2cql_wrbuf(ct, w, q); if (r != 0) { diff --git a/util/cql2pqf.c b/util/cql2pqf.c index 55bea5d..070e542 100644 --- a/util/cql2pqf.c +++ b/util/cql2pqf.c @@ -70,7 +70,8 @@ int main(int argc, char **argv) } else { - int ret = cql_transform_rpn2cql(ct, cql_fputs, stdout, rpn); + int ret = cql_transform_rpn2cql_stream(ct, cql_fputs, + stdout, rpn); if (ret) { -- 1.7.10.4