X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fcqltransform.c;h=3163775c593a06d4076ec095f5f04006dd5f99ef;hp=cd735e4d54d6e9f94aa751597cea2865eeff7653;hb=7dfff1f7b79d8a3cf5f5ed62c71f6e4c2a616072;hpb=b977948f73d07c0bf4478565f9af3497ffe862e7 diff --git a/src/cqltransform.c b/src/cqltransform.c index cd735e4..3163775 100644 --- a/src/cqltransform.c +++ b/src/cqltransform.c @@ -1,8 +1,7 @@ /* This file is part of the YAZ toolkit. - * Copyright (C) 1995-2008 Index Data + * Copyright (C) 1995-2011 Index Data * See the file LICENSE for details. */ - /** * \file cqltransform.c * \brief Implements CQL transform (CQL to RPN conversion). @@ -17,29 +16,27 @@ * index * relationModifier */ +#if HAVE_CONFIG_H +#include +#endif #include #include #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; + Z_AttributeList attr_list; struct cql_prop_entry *next; }; @@ -69,11 +66,13 @@ static int cql_transform_parse_tok_line(cql_transform_t ct, const char *pattern, yaz_tok_parse_t tp) { + int ae_num = 0; + Z_AttributeElement *ae[20]; int ret = 0; /* 0=OK, != 0 FAIL */ int t; t = yaz_tok_move(tp); - while (t == YAZ_TOK_STRING) + while (t == YAZ_TOK_STRING && ae_num < 20) { WRBUF type_str = wrbuf_alloc(); WRBUF set_str = 0; @@ -81,28 +80,9 @@ static int cql_transform_parse_tok_line(cql_transform_t ct, const char *value_str = 0; /* attset type=value OR type=value */ - elem = nmem_malloc(ct->nmem, sizeof(*elem)); + elem = (Z_AttributeElement *) 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 + ae[ae_num] = elem; wrbuf_puts(ct->w, yaz_tok_parse_string(tp)); wrbuf_puts(type_str, yaz_tok_parse_string(tp)); t = yaz_tok_move(tp); @@ -128,7 +108,7 @@ static int cql_transform_parse_tok_line(cql_transform_t ct, t = yaz_tok_move(tp); } elem->attributeType = nmem_intdup(ct->nmem, 0); - if (sscanf(wrbuf_cstr(type_str), "%d", elem->attributeType) + if (sscanf(wrbuf_cstr(type_str), ODR_INT_PRINTF, elem->attributeType) != 1) { wrbuf_destroy(type_str); @@ -157,7 +137,7 @@ static int cql_transform_parse_tok_line(cql_transform_t ct, break; } value_str = yaz_tok_parse_string(tp); - if (isdigit(*value_str)) + if (yaz_isdigit(*value_str)) { elem->which = Z_AttributeValue_numeric; elem->value.numeric = @@ -165,7 +145,8 @@ static int cql_transform_parse_tok_line(cql_transform_t ct, } else { - Z_ComplexAttribute *ca = nmem_malloc(ct->nmem, sizeof(*ca)); + Z_ComplexAttribute *ca = (Z_ComplexAttribute *) + nmem_malloc(ct->nmem, sizeof(*ca)); elem->which = Z_AttributeValue_complex; elem->value.complex = ca; ca->num_list = 1; @@ -182,6 +163,7 @@ static int cql_transform_parse_tok_line(cql_transform_t ct, wrbuf_puts(ct->w, yaz_tok_parse_string(tp)); t = yaz_tok_move(tp); wrbuf_puts(ct->w, " "); + ae_num++; } if (ret == 0) /* OK? */ { @@ -191,7 +173,29 @@ static int cql_transform_parse_tok_line(cql_transform_t ct, *pp = (struct cql_prop_entry *) xmalloc(sizeof(**pp)); (*pp)->pattern = xstrdup(pattern); (*pp)->value = xstrdup(wrbuf_cstr(ct->w)); + + (*pp)->attr_list.num_attributes = ae_num; + if (ae_num == 0) + (*pp)->attr_list.attributes = 0; + else + { + (*pp)->attr_list.attributes = (Z_AttributeElement **) + nmem_malloc(ct->nmem, + ae_num * sizeof(Z_AttributeElement *)); + memcpy((*pp)->attr_list.attributes, ae, + ae_num * sizeof(Z_AttributeElement *)); + } (*pp)->next = 0; + + if (0) + { + ODR pr = odr_createmem(ODR_PRINT); + Z_AttributeList *alp = &(*pp)->attr_list; + odr_setprint(pr, yaz_log_file()); + z_AttributeList(pr, &alp, 0, 0); + odr_setprint(pr, 0); + odr_destroy(pr); + } } return ret; } @@ -281,28 +285,75 @@ 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) +#if 0 +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 + +static int compare_attr(Z_AttributeElement *a, Z_AttributeElement *b) +{ + ODR odr_a = odr_createmem(ODR_ENCODE); + ODR odr_b = odr_createmem(ODR_ENCODE); + int len_a, len_b; + char *buf_a, *buf_b; + int ret; + + z_AttributeElement(odr_a, &a, 0, 0); + z_AttributeElement(odr_b, &b, 0, 0); + + buf_a = odr_getbuf(odr_a, &len_a, 0); + buf_b = odr_getbuf(odr_b, &len_b, 0); + + ret = yaz_memcmp(buf_a, buf_b, len_a, len_b); + + odr_destroy(odr_a); + odr_destroy(odr_b); + return ret; +} + +const char *cql_lookup_reverse(cql_transform_t ct, + const char *category, + Z_AttributeList *attributes) { struct cql_prop_entry *e; - size_t cat_len = strlen(category); - NMEM nmem = nmem_create(); + size_t clen = strlen(category); 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)) + if (!strncmp(e->pattern, category, clen)) { - char **attr_array; - int attr_num; - nmem_strsplit_blank(nmem, e->value, &attr_array, &attr_num); - nmem_reset(nmem); + /* category matches.. See if attributes in pattern value + are all listed in actual attributes */ + int i; + for (i = 0; i < e->attr_list.num_attributes; i++) + { + /* entry attribute */ + Z_AttributeElement *e_ae = e->attr_list.attributes[i]; + int j; + for (j = 0; j < attributes->num_attributes; j++) + { + /* actual attribute */ + Z_AttributeElement *a_ae = attributes->attributes[j]; + int r = compare_attr(e_ae, a_ae); + if (r == 0) + break; + } + if (j == attributes->num_attributes) + break; /* i was not found at all.. try next pattern */ + + } + if (i == e->attr_list.num_attributes) + return e->pattern + clen; } } - nmem_destroy(nmem); return 0; } @@ -385,7 +436,7 @@ int cql_pr_attr_uri(cql_transform_t ct, const char *category, int i; while (*cp1 && *cp1 != ' ') cp1++; - if (cp1 - cp0 >= sizeof(buf)) + if (cp1 - cp0 >= (ptrdiff_t) sizeof(buf)) break; memcpy(buf, cp0, cp1 - cp0); buf[cp1-cp0] = 0; @@ -557,11 +608,11 @@ static int has_modifier(struct cql_node *cn, const char *name) { } -void emit_term(cql_transform_t ct, - struct cql_node *cn, - const char *term, int length, - void (*pr)(const char *buf, void *client_data), - void *client_data) +static void emit_term(cql_transform_t ct, + struct cql_node *cn, + const char *term, int length, + void (*pr)(const char *buf, void *client_data), + void *client_data) { int i; const char *ns = cn->u.st.index_uri; @@ -683,7 +734,7 @@ void emit_term(cql_transform_t ct, } (*pr)("\"", client_data); - for (i = 0; iu.st.extra_terms; if (ne) @@ -726,11 +777,11 @@ void emit_terms(cql_transform_t ct, } } -void emit_wordlist(cql_transform_t ct, - struct cql_node *cn, - void (*pr)(const char *buf, void *client_data), - void *client_data, - const char *op) +static void emit_wordlist(cql_transform_t ct, + struct cql_node *cn, + void (*pr)(const char *buf, void *client_data), + void *client_data, + const char *op) { const char *cp0 = cn->u.st.term; const char *cp1; @@ -825,7 +876,9 @@ void cql_transform_r(cql_transform_t ct, cql_transform_r(ct, cn->u.boolean.left, pr, client_data); cql_transform_r(ct, cn->u.boolean.right, pr, client_data); break; - + case CQL_NODE_SORT: + cql_transform_r(ct, cn->u.sort.search, pr, client_data); + break; default: fprintf(stderr, "Fatal: impossible CQL node-type %d\n", cn->which); abort(); @@ -861,7 +914,8 @@ int cql_transform_FILE(cql_transform_t ct, struct cql_node *cn, FILE *f) return cql_transform(ct, cn, cql_fputs, f); } -int cql_transform_buf(cql_transform_t ct, struct cql_node *cn, char *out, int max) +int cql_transform_buf(cql_transform_t ct, struct cql_node *cn, + char *out, int max) { struct cql_buf_write_info info; int r; @@ -901,6 +955,7 @@ void cql_transform_set_error(cql_transform_t ct, int error, const char *addinfo) /* * Local variables: * c-basic-offset: 4 + * c-file-style: "Stroustrup" * indent-tabs-mode: nil * End: * vim: shiftwidth=4 tabstop=8 expandtab