+ elem = (Z_AttributeElement *) 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), ODR_INT_PRINTF, 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 (yaz_isdigit(*value_str))
+ {
+ elem->which = Z_AttributeValue_numeric;
+ elem->value.numeric =
+ nmem_intdup(ct->nmem, atoi(value_str));
+ }
+ else
+ {
+ Z_ComplexAttribute *ca = (Z_ComplexAttribute *)
+ 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 = (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;
+}
+
+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);