/* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2012 Index Data
+ * Copyright (C) Index Data
* See the file LICENSE for details.
*/
/**
yaz_tok_cfg_t tok_cfg;
int error;
char *addinfo;
- WRBUF w;
NMEM nmem;
};
{
cql_transform_t ct = (cql_transform_t) xmalloc(sizeof(*ct));
ct->tok_cfg = yaz_tok_cfg_create();
- ct->w = wrbuf_alloc();
ct->error = 0;
ct->addinfo = 0;
ct->entry = 0;
Z_AttributeElement *ae[20];
int ret = 0; /* 0=OK, != 0 FAIL */
int t;
+ WRBUF w = wrbuf_alloc();
+
t = yaz_tok_move(tp);
while (t == YAZ_TOK_STRING && ae_num < 20)
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(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)
}
if (t == YAZ_TOK_STRING)
{
- wrbuf_puts(ct->w, " ");
- wrbuf_puts(ct->w, yaz_tok_parse_string(tp));
+ wrbuf_puts(w, " ");
+ wrbuf_puts(w, yaz_tok_parse_string(tp));
set_str = type_str;
elem->attributeSet =
ca->num_semanticAction = 0;
ca->semanticAction = 0;
}
- wrbuf_puts(ct->w, "=");
- wrbuf_puts(ct->w, yaz_tok_parse_string(tp));
+ wrbuf_puts(w, "=");
+ wrbuf_puts(w, yaz_tok_parse_string(tp));
t = yaz_tok_move(tp);
- wrbuf_puts(ct->w, " ");
+ wrbuf_puts(w, " ");
ae_num++;
}
if (ret == 0) /* OK? */
pp = &(*pp)->next;
*pp = (struct cql_prop_entry *) xmalloc(sizeof(**pp));
(*pp)->pattern = xstrdup(pattern);
- (*pp)->value = xstrdup(wrbuf_cstr(ct->w));
+ (*pp)->value = xstrdup(wrbuf_cstr(w));
(*pp)->attr_list.num_attributes = ae_num;
if (ae_num == 0)
odr_destroy(pr);
}
}
+ wrbuf_destroy(w);
return ret;
}
{
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)
{
}
xfree(ct->addinfo);
yaz_tok_cfg_destroy(ct->tok_cfg);
- wrbuf_destroy(ct->w);
nmem_destroy(ct->nmem);
xfree(ct);
}
return 1;
}
-/* Returns location of first wildcard character in the `length'
- * characters starting at `term', or a null pointer of there are
- * none -- like memchr().
- */
-static const char *wcchar(int start, const char *term, int length)
-{
- while (length > 0)
- {
- if (start || term[-1] != '\\')
- if (strchr("*?", *term))
- return term;
- term++;
- length--;
- start = 0;
- }
- return 0;
-}
-
-
/* ### checks for CQL relation-name rather than Type-1 attribute */
static int has_modifier(struct cql_node *cn, const char *name) {
struct cql_node *mod;
return 0;
}
-
static void emit_term(cql_transform_t ct,
struct cql_node *cn,
const char *term, int length,
if (has_modifier(cn, "regexp"))
process_term = 0;
+ else if (has_modifier(cn, "unmasked"))
+ process_term = 0;
else if (cql_lookup_property(ct, "truncation", 0, "cql"))
{
process_term = 0;
}
assert(cn->which == CQL_NODE_ST);
- if (process_term && length > 0)
- {
- if (length > 1 && term[0] == '^' && term[length-1] == '^')
+ if (process_term)
+ { /* convert term via truncation.things */
+ unsigned anchor = 0;
+ unsigned trunc = 0;
+ for (i = 0; i < length; i++)
+ {
+ if (term[i] == '\\' && i < length - 1)
+ i++;
+ else
+ {
+ switch (term[i])
+ {
+ case '^':
+ if (i == 0)
+ anchor |= 1;
+ else if (i == length - 1)
+ anchor |= 2;
+ break;
+ case '*':
+ if (i == 0)
+ trunc |= 1;
+ else if (i == length - 1)
+ trunc |= 2;
+ else
+ z3958_mode = 1;
+ break;
+ case '?':
+ z3958_mode = 1;
+ break;
+ }
+ }
+ }
+ if (anchor == 3)
{
cql_pr_attr(ct, "position", "firstAndLast", 0,
pr, client_data, YAZ_SRW_ANCHORING_CHAR_IN_UNSUPP_POSITION);
term++;
length -= 2;
}
- else if (term[0] == '^')
+ else if (anchor == 1)
{
cql_pr_attr(ct, "position", "first", 0,
pr, client_data, YAZ_SRW_ANCHORING_CHAR_IN_UNSUPP_POSITION);
term++;
length--;
}
- else if (term[length-1] == '^')
+ else if (anchor == 2)
{
cql_pr_attr(ct, "position", "last", 0,
pr, client_data, YAZ_SRW_ANCHORING_CHAR_IN_UNSUPP_POSITION);
cql_pr_attr(ct, "position", "any", 0,
pr, client_data, YAZ_SRW_ANCHORING_CHAR_IN_UNSUPP_POSITION);
}
- }
-
- if (process_term && length > 0)
- {
- const char *first_wc = wcchar(1, term, length);
- const char *second_wc = first_wc ?
- wcchar(0, first_wc+1, length-(first_wc-term)-1) : 0;
-
- /* Check for well-known globbing patterns that represent
- * simple truncation attributes as expected by, for example,
- * Bath-compliant server. If we find such a pattern but
- * there's no mapping for it, that's fine: we just use a
- * general pattern-matching attribute.
- */
- if (first_wc == term && second_wc == term + length-1
- && *first_wc == '*' && *second_wc == '*'
- && cql_pr_attr(ct, "truncation", "both", 0, pr, client_data, 0))
- {
- term++;
- length -= 2;
- }
- else if (first_wc == term && second_wc == 0 && *first_wc == '*'
- && cql_pr_attr(ct, "truncation", "left", 0,
- pr, client_data, 0))
- {
- term++;
- length--;
- }
- else if (first_wc == term + length-1 && second_wc == 0
- && *first_wc == '*'
- && cql_pr_attr(ct, "truncation", "right", 0,
- pr, client_data, 0))
+ if (z3958_mode == 0)
{
- length--;
+ if (trunc == 3 && cql_pr_attr(ct, "truncation",
+ "both", 0, pr, client_data, 0))
+ {
+ term++;
+ length -= 2;
+ }
+ else if (trunc == 1 && cql_pr_attr(ct, "truncation",
+ "left", 0, pr, client_data, 0))
+ {
+ term++;
+ length--;
+ }
+ else if (trunc == 2 && cql_pr_attr(ct, "truncation", "right", 0,
+ pr, client_data, 0))
+ {
+ length--;
+ }
+ else if (trunc)
+ z3958_mode = 1;
+ else
+ cql_pr_attr(ct, "truncation", "none", 0,
+ pr, client_data, 0);
}
- else if (first_wc)
- {
- z3958_mode = 1;
+ if (z3958_mode)
cql_pr_attr(ct, "truncation", "z3958", 0,
pr, client_data, YAZ_SRW_MASKING_CHAR_UNSUPP);
- }
- else
- {
- /* No masking characters. Use "truncation.none" if given. */
- cql_pr_attr(ct, "truncation", "none", 0,
- pr, client_data, 0);
- }
}
if (ns) {
cql_pr_attr_uri(ct, "index", ns,
pr, client_data, YAZ_SRW_UNSUPP_RELATION_MODIFIER);
}
}
-
- /* produce only \-sequences if:
- 1) the output is a Z39.58-trunc reserved character
- 2) the output is a PQF reserved character (\\, \")
- */
(*pr)("\"", client_data);
- for (i = 0; i < length; i++)
- {
- char x[3]; /* temp buffer */
- if (i > 0 && term[i-1] == '\\')
+ if (process_term)
+ for (i = 0; i < length; i++)
{
- if (term[i] == '\"' || term[i] == '\\')
- pr("\\", client_data);
- if (z3958_mode && strchr("#?", term[i]))
- pr("\\\\", client_data); /* double \\ to survive PQF parse */
- x[0] = term[i];
- x[1] = '\0';
- pr(x, client_data);
+ char x[2]; /* temp buffer */
+ if (term[i] == '\\' && i < length - 1)
+ {
+ i++;
+ if (strchr("\"\\", term[i]))
+ pr("\\", client_data);
+ if (z3958_mode && strchr("#?", term[i]))
+ pr("\\\\", client_data); /* double \\ to survive PQF parse */
+ x[0] = term[i];
+ x[1] = '\0';
+ pr(x, client_data);
+ }
+ else if (z3958_mode && term[i] == '*')
+ {
+ pr("?", client_data);
+ if (i < length - 1 && yaz_isdigit(term[i+1]))
+ pr("\\\\", client_data); /* dbl \\ to survive PQF parse */
+ }
+ else if (z3958_mode && term[i] == '?')
+ {
+ pr("#", client_data);
+ }
+ else
+ {
+ if (term[i] == '\"')
+ pr("\\", client_data);
+ if (z3958_mode && strchr("#?", term[i]))
+ pr("\\\\", client_data); /* dbl \\ to survive PQF parse */
+ x[0] = term[i];
+ x[1] = '\0';
+ pr(x, client_data);
+ }
}
- else if (z3958_mode && term[i] == '*')
- {
- pr("?", client_data);
- /* avoid ?n sequences output (n=[0-9]) because that has
- different semantics than just a single ? in Z39.58
- */
- if (i < length - 1 && yaz_isdigit(term[i+1]))
- pr("\\\\", client_data); /* double \\ to survive PQF parse */
- }
- else if (z3958_mode && term[i] == '?')
- pr("#", client_data);
- else if (term[i] != '\\')
+ else
+ {
+ for (i = 0; i < length; i++)
{
- if (term[i] == '\"')
- pr("\\", client_data);
- if (z3958_mode && strchr("#?", term[i]))
- pr("\\\\", client_data); /* double \\ to survive PQF parse */
+ char x[2];
x[0] = term[i];
x[1] = '\0';
pr(x, client_data);