X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fcqltransform.c;h=dbdd8aad59794820180698fb60577c6ed11f8c2b;hp=59b74b9e32288c65360bb8794c4d60355e46ca15;hb=8e9d2cec97def1cd8b89b1fe427f1a232661ec6f;hpb=1bd4b1c686ba63f685fc0195fa76ada49680d219 diff --git a/src/cqltransform.c b/src/cqltransform.c index 59b74b9..dbdd8aa 100644 --- a/src/cqltransform.c +++ b/src/cqltransform.c @@ -21,79 +21,232 @@ #include #include #include +#include #include #include #include +#include +#include +#include +#include +#include struct cql_prop_entry { char *pattern; char *value; + Z_AttributeList attr_list; struct cql_prop_entry *next; }; struct cql_transform_t_ { struct cql_prop_entry *entry; + yaz_tok_cfg_t tok_cfg; int error; char *addinfo; + WRBUF w; + NMEM nmem; }; -cql_transform_t cql_transform_open_FILE(FILE *f) + +cql_transform_t cql_transform_create(void) { - char line[1024]; cql_transform_t ct = (cql_transform_t) xmalloc(sizeof(*ct)); - struct cql_prop_entry **pp = &ct->entry; - + ct->tok_cfg = yaz_tok_cfg_create(); + ct->w = wrbuf_alloc(); ct->error = 0; ct->addinfo = 0; - while (fgets(line, sizeof(line)-1, f)) + 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 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 && ae_num < 20) { - const char *cp_value_start; - const char *cp_value_end; - const char *cp_pattern_start; - const char *cp_pattern_end; - const char *cp = line; - - while (*cp && strchr(" \t", *cp)) - cp++; - cp_pattern_start = cp; + 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; + 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); + 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); - while (*cp && !strchr(" \t\r\n=#", *cp)) - cp++; - cp_pattern_end = cp; - if (cp == cp_pattern_start) - continue; - while (*cp && strchr(" \t", *cp)) - cp++; - if (*cp != '=') + 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, " "); + ae_num++; + } + 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)->attr_list.num_attributes = ae_num; + if (ae_num == 0) + (*pp)->attr_list.attributes = 0; + else + { + (*pp)->attr_list.attributes = + 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) { - *pp = 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; +} + +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]; + + yaz_tok_cfg_single_tokens(ct->tok_cfg, "="); + + while (fgets(line, sizeof(line)-1, f)) + { + yaz_tok_parse_t tp = yaz_tok_parse_buf(ct->tok_cfg, line); + int t; + wrbuf_rewind(ct->w); + t = yaz_tok_move(tp); + if (t == YAZ_TOK_STRING) + { + char * pattern = xstrdup(yaz_tok_parse_string(tp)); + t = yaz_tok_move(tp); + if (t != '=') + { + yaz_tok_parse_destroy(tp); + cql_transform_close(ct); + return 0; + } + if (cql_transform_parse_tok_line(ct, pattern, tp)) + { + yaz_tok_parse_destroy(tp); + cql_transform_close(ct); + return 0; + } + xfree(pattern); + } + else if (t != YAZ_TOK_EOF) + { + yaz_tok_parse_destroy(tp); cql_transform_close(ct); return 0; } - cp++; - while (*cp && strchr(" \t\r\n", *cp)) - cp++; - cp_value_start = cp; - cp_value_end = strchr(cp, '#'); - if (!cp_value_end) - cp_value_end = strlen(line) + line; - - if (cp_value_end != cp_value_start && - strchr(" \t\r\n", cp_value_end[-1])) - cp_value_end--; - *pp = (struct cql_prop_entry *) xmalloc(sizeof(**pp)); - (*pp)->pattern = (char *) xmalloc(cp_pattern_end-cp_pattern_start + 1); - memcpy((*pp)->pattern, cp_pattern_start, - cp_pattern_end-cp_pattern_start); - (*pp)->pattern[cp_pattern_end-cp_pattern_start] = '\0'; - - (*pp)->value = (char *) xmalloc(cp_value_end-cp_value_start + 1); - if (cp_value_start != cp_value_end) - memcpy((*pp)->value, cp_value_start, cp_value_end-cp_value_start); - (*pp)->value[cp_value_end - cp_value_start] = '\0'; - pp = &(*pp)->next; + yaz_tok_parse_destroy(tp); } - *pp = 0; return ct; } @@ -112,6 +265,9 @@ void cql_transform_close(cql_transform_t ct) pe = pe_next; } xfree(ct->addinfo); + yaz_tok_cfg_destroy(ct->tok_cfg); + wrbuf_destroy(ct->w); + nmem_destroy(ct->nmem); xfree(ct); } @@ -126,6 +282,78 @@ cql_transform_t cql_transform_open_fname(const char *fname) return ct; } +#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 clen = strlen(category); + for (e = ct->entry; e; e = e->next) + { + if (!strncmp(e->pattern, category, clen)) + { + /* 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; + } + } + return 0; +} + static const char *cql_lookup_property(cql_transform_t ct, const char *pat1, const char *pat2, const char *pat3) @@ -710,6 +938,14 @@ int cql_transform_error(cql_transform_t ct, const char **addinfo) *addinfo = ct->addinfo; return ct->error; } + +void cql_transform_set_error(cql_transform_t ct, int error, const char *addinfo) +{ + xfree(ct->addinfo); + ct->addinfo = addinfo ? xstrdup(addinfo) : 0; + ct->error = error; +} + /* * Local variables: * c-basic-offset: 4