Possible compatibility problems with earlier versions marked with '*'.
+String value attributes for CCL parser.
+
--- 2.0.3 2003/06/20
Fix CCL directive @case handling so that it affects string match for
-## $Id: Makefile.am,v 1.9 2002-06-06 13:02:01 adam Exp $
+## $Id: Makefile.am,v 1.10 2003-06-23 10:22:21 adam Exp $
noinst_LTLIBRARIES = libccl.la
noinst_PROGRAMS = cclsh
+check_PROGRAMS = tstccl
+
+TESTS = $(check_PROGRAMS)
+
EXTRA_DIST = bib1
AM_CPPFLAGS=-I$(top_srcdir)/include
libccl_la_SOURCES = cclfind.c ccltoken.c cclerrms.c cclqual.c cclptree.c \
cclqfile.c cclstr.c
+
cclsh_SOURCES=cclsh.c
cclsh_LDADD = libccl.la ../util/libutil.la $(READLINE_LIBS)
+
+tstccl_SOURCES = tstccl.c
+tstccl_LDADD = libccl.la ../util/libutil.la
+
-# $Id: bib1,v 1.12 2002-10-14 19:45:36 adam Exp $
+# $Id: bib1,v 1.13 2003-06-23 10:22:21 adam Exp $
# CCL qualifiers and their mappings
#
# Each line takes the form:
forfatter au
# tiau=x is equivalent to ti=x or ti=x
tiau ti au
+#
+# string atributes
+dc.title 1=/my/title
/* CCL find (to rpn conversion)
* Europagate, 1995
*
- * $Id: cclfind.c,v 1.33 2003-02-14 18:49:22 adam Exp $
+ * $Id: cclfind.c,v 1.34 2003-06-23 10:22:21 adam Exp $
*
* Old Europagate log:
*
for (i = 0; (q=qa[i]); i++)
while (q)
{
- if (q->type == type && q->value == value)
+ if (q->type == type && q->kind == CCL_RPN_ATTR_NUMERIC &&
+ q->value.numeric == value)
{
if (attset)
*attset = q->set;
for (attr = rpn->u.t.attr_list; attr; attr = attr1)
{
attr1 = attr->next;
+ if (attr->kind == CCL_RPN_ATTR_STRING)
+ xfree(attr->value.str);
if (attr->set)
xfree (attr->set);
xfree (attr);
static struct ccl_rpn_node *search_terms (CCL_parser cclp,
struct ccl_rpn_attr **qa);
-/*
- * add_attr: Add attribute (type/value) to RPN term node.
- * p: RPN node of type term.
- * type: Type of attribute
- * value: Value of attribute
- * set: Attribute set name
- */
-static void add_attr (struct ccl_rpn_node *p, const char *set,
- int type, int value)
+static struct ccl_rpn_attr *add_attr_node (struct ccl_rpn_node *p,
+ const char *set, int type)
{
struct ccl_rpn_attr *n;
-
+
n = (struct ccl_rpn_attr *)xmalloc (sizeof(*n));
ccl_assert (n);
if (set)
else
n->set = 0;
n->type = type;
- n->value = value;
n->next = p->u.t.attr_list;
p->u.t.attr_list = n;
+
+ n->kind = CCL_RPN_ATTR_NUMERIC;
+ n->value.numeric = 0;
+ return n;
}
/*
+ * add_attr_numeric: Add attribute (type/value) to RPN term node.
+ * p: RPN node of type term.
+ * type: Type of attribute
+ * value: Value of attribute
+ * set: Attribute set name
+ */
+static void add_attr_numeric (struct ccl_rpn_node *p, const char *set,
+ int type, int value)
+{
+ struct ccl_rpn_attr *n;
+
+ n = add_attr_node(p, set, type);
+ n->kind = CCL_RPN_ATTR_NUMERIC;
+ n->value.numeric = value;
+}
+
+static void add_attr_string (struct ccl_rpn_node *p, const char *set,
+ int type, char *value)
+{
+ struct ccl_rpn_attr *n;
+
+ n = add_attr_node(p, set, type);
+ n->kind = CCL_RPN_ATTR_STRING;
+ n->value.str = xstrdup(value);
+}
+
+
+/*
* search_term: Parse CCL search term.
* cclp: CCL Parser
* qa: Qualifier attributes already applied.
struct ccl_rpn_attr *attr;
for (attr = qa[i]; attr; attr = attr->next)
- if (attr->value > 0)
- { /* deal only with REAL attributes (positive) */
- switch (attr->type)
- {
- case CCL_BIB1_REL:
- if (relation_value != -1)
- continue;
- relation_value = attr->value;
- break;
- case CCL_BIB1_POS:
- if (position_value != -1)
- continue;
- position_value = attr->value;
- break;
- case CCL_BIB1_STR:
- if (structure_value != -1)
- continue;
- structure_value = attr->value;
- break;
- case CCL_BIB1_TRU:
- if (truncation_value != -1)
- continue;
- truncation_value = attr->value;
- left_trunc = right_trunc = mid_trunc = 0;
- break;
- case CCL_BIB1_COM:
- if (completeness_value != -1)
- continue;
- completeness_value = attr->value;
- break;
- }
- add_attr (p, attr->set, attr->type, attr->value);
- }
+ switch(attr->kind)
+ {
+ case CCL_RPN_ATTR_STRING:
+ add_attr_string(p, attr->set, attr->type,
+ attr->value.str);
+ break;
+ case CCL_RPN_ATTR_NUMERIC:
+ if (attr->value.numeric > 0)
+ { /* deal only with REAL attributes (positive) */
+ switch (attr->type)
+ {
+ case CCL_BIB1_REL:
+ if (relation_value != -1)
+ continue;
+ relation_value = attr->value.numeric;
+ break;
+ case CCL_BIB1_POS:
+ if (position_value != -1)
+ continue;
+ position_value = attr->value.numeric;
+ break;
+ case CCL_BIB1_STR:
+ if (structure_value != -1)
+ continue;
+ structure_value = attr->value.numeric;
+ break;
+ case CCL_BIB1_TRU:
+ if (truncation_value != -1)
+ continue;
+ truncation_value = attr->value.numeric;
+ left_trunc = right_trunc = mid_trunc = 0;
+ break;
+ case CCL_BIB1_COM:
+ if (completeness_value != -1)
+ continue;
+ completeness_value = attr->value.numeric;
+ break;
+ }
+ add_attr_numeric(p, attr->set, attr->type,
+ attr->value.numeric);
+ }
+ }
}
/* len now holds the number of characters in the RPN term */
/* no holds the number of CCL tokens (1 or more) */
{ /* no structure attribute met. Apply either structure attribute
WORD or PHRASE depending on number of CCL tokens */
if (no == 1 && no_spaces == 0)
- add_attr (p, attset, CCL_BIB1_STR, 2);
+ add_attr_numeric (p, attset, CCL_BIB1_STR, 2);
else
- add_attr (p, attset, CCL_BIB1_STR, 1);
+ add_attr_numeric (p, attset, CCL_BIB1_STR, 1);
}
/* make the RPN token */
ccl_rpn_delete (p);
return NULL;
}
- add_attr (p, attset, CCL_BIB1_TRU, 3);
+ add_attr_numeric (p, attset, CCL_BIB1_TRU, 3);
}
else if (right_trunc)
{
ccl_rpn_delete (p);
return NULL;
}
- add_attr (p, attset, CCL_BIB1_TRU, 1);
+ add_attr_numeric (p, attset, CCL_BIB1_TRU, 1);
}
else if (left_trunc)
{
ccl_rpn_delete (p);
return NULL;
}
- add_attr (p, attset, CCL_BIB1_TRU, 2);
+ add_attr_numeric (p, attset, CCL_BIB1_TRU, 2);
}
else
{
if (qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_NONE,
&attset))
- add_attr (p, attset, CCL_BIB1_TRU, 100);
+ add_attr_numeric (p, attset, CCL_BIB1_TRU, 100);
}
if (!multi)
break;
}
p = mk_node (CCL_RPN_AND);
p->u.p[0] = p1;
- add_attr (p1, attset, CCL_BIB1_REL, 4);
+ add_attr_numeric (p1, attset, CCL_BIB1_REL, 4);
p->u.p[1] = p2;
- add_attr (p2, attset, CCL_BIB1_REL, 2);
+ add_attr_numeric (p2, attset, CCL_BIB1_REL, 2);
return p;
}
else /* = term - */
{
- add_attr (p1, attset, CCL_BIB1_REL, 4);
+ add_attr_numeric (p1, attset, CCL_BIB1_REL, 4);
return p1;
}
}
ADVANCE;
if (!(p = search_term (cclp, ap)))
return NULL;
- add_attr (p, attset, CCL_BIB1_REL, 2);
+ add_attr_numeric (p, attset, CCL_BIB1_REL, 2);
return p;
}
else if (KIND == CCL_TOK_LP)
{
if (!(p = search_terms (cclp, ap)))
return NULL;
- add_attr (p, attset, CCL_BIB1_REL, rel);
+ add_attr_numeric (p, attset, CCL_BIB1_REL, rel);
return p;
}
cclp->error_code = CCL_ERR_TERM_EXPECTED;
/* CCL print rpn tree - infix notation
* Europagate, 1995
*
- * $Id: cclptree.c,v 1.12 2003-02-14 18:49:23 adam Exp $
+ * $Id: cclptree.c,v 1.13 2003-06-23 10:22:21 adam Exp $
*
* Old Europagate Log:
*
{
struct ccl_rpn_attr *attr;
for (attr = rpn->u.t.attr_list; attr; attr = attr->next)
- if (attr->set)
- fprintf (fd_out, "@attr %s %d=%d ", attr->set, attr->type,
- attr->value);
- else
- fprintf (fd_out, "@attr %d=%d ", attr->type, attr->value);
+ {
+ if (attr->set)
+ fprintf(fd_out, "@attr %s", attr->set);
+ else
+ fprintf(fd_out, "@attr ");
+ switch(attr->kind)
+ {
+ case CCL_RPN_ATTR_NUMERIC:
+ fprintf (fd_out, "%d=%d ", attr->type,
+ attr->value.numeric);
+ break;
+ case CCL_RPN_ATTR_STRING:
+ fprintf (fd_out, "%d=%s ", attr->type,
+ attr->value.str);
+ }
+ }
}
fprintf (fd_out, "\"%s\"\n", rpn->u.t.term);
break;
/* CCL qualifiers
* Europagate, 1995
*
- * $Id: cclqfile.c,v 1.13 2002-06-06 12:54:24 adam Exp $
+ * $Id: cclqfile.c,v 1.14 2003-06-23 10:22:21 adam Exp $
*
* Old Europagate Log:
*
void ccl_qual_field (CCL_bibset bibset, const char *cp, const char *qual_name)
{
char qual_spec[128];
- int pair[256];
+ int type_ar[128];
+ int value_ar[128];
+ char *svalue_ar[128];
char *attsets[128];
int pair_no = 0;
if (!(split = strchr (qual_spec, '=')))
{
+ /* alias specification .. */
if (pair_no == 0)
{
ccl_qual_add_combi (bibset, qual_name, cp);
}
break;
}
+ /* [set,]type=value ... */
cp += no_scan;
*split++ = '\0';
setp = strchr (qual_spec, ',');
if (setp)
{
+ /* set,type=value ... */
*setp++ = '\0';
qual_type = setp;
}
else
+ {
+ /* type=value ... */
qual_type = qual_spec;
+ }
while (pair_no < 128)
{
int type, value;
qual_value = split;
if ((split = strchr (qual_value, ',')))
*split++ = '\0';
- value = atoi (qual_value);
+
+ value = 0;
switch (qual_type[0])
{
case 'u':
default:
type = atoi (qual_type);
}
- pair[pair_no*2] = type;
- pair[pair_no*2+1] = value;
+
+ type_ar[pair_no] = type;
+
+ if (value)
+ {
+ value_ar[pair_no] = value;
+ svalue_ar[pair_no] = 0;
+ }
+ else if (*qual_value >= '0' && *qual_value <= '9')
+ {
+ value_ar[pair_no] = atoi (qual_value);
+ svalue_ar[pair_no] = 0;
+ }
+ else
+ {
+ size_t len;
+ if (split)
+ len = split - qual_value;
+ else
+ len = strlen(qual_value);
+ svalue_ar[pair_no] = xmalloc(len+1);
+ memcpy(svalue_ar[pair_no], qual_value, len);
+ svalue_ar[pair_no][len] = '\0';
+ }
if (setp)
{
attsets[pair_no] = (char*) xmalloc (strlen(qual_spec)+1);
break;
}
}
- ccl_qual_add_set (bibset, qual_name, pair_no, pair, attsets);
+ ccl_qual_add_set (bibset, qual_name, pair_no, type_ar, value_ar, svalue_ar,
+ attsets);
}
void ccl_qual_fitem (CCL_bibset bibset, const char *cp, const char *qual_name)
/* CCL qualifiers
* Europagate, 1995
*
- * $Id: cclqual.c,v 1.18 2003-06-19 19:51:40 adam Exp $
+ * $Id: cclqual.c,v 1.19 2003-06-23 10:22:21 adam Exp $
*
* Old Europagate Log:
*
* pairs: Attributes. pairs[0] first type, pair[1] first value,
* ... pair[2*no-2] last type, pair[2*no-1] last value.
*/
-void ccl_qual_add_set (CCL_bibset b, const char *name, int no, int *pairs,
+
+void ccl_qual_add_set (CCL_bibset b, const char *name, int no,
+ int *type_ar, int *value_ar, char **svalue_ar,
char **attsets)
{
struct ccl_qualifier *q;
}
else
{
- if (q->sub)
+ if (q->sub) /* suspect.. */
xfree (q->sub);
attrp = &q->attr_list;
while (*attrp)
attr = (struct ccl_rpn_attr *)xmalloc (sizeof(*attr));
ccl_assert (attr);
attr->set = *attsets++;
- attr->type = *pairs++;
- attr->value = *pairs++;
+ attr->type = *type_ar++;
+ if (*svalue_ar)
+ {
+ attr->kind = CCL_RPN_ATTR_STRING;
+ attr->value.str = *svalue_ar;
+ }
+ else
+ {
+ attr->kind = CCL_RPN_ATTR_NUMERIC;
+ attr->value.numeric = *value_ar;
+ }
+ svalue_ar++;
+ value_ar++;
*attrp = attr;
attrp = &attr->next;
}
{
attr1 = attr->next;
if (attr->set)
- xfree (attr->set);
+ xfree(attr->set);
+ if (attr->kind == CCL_RPN_ATTR_STRING)
+ xfree(attr->value.str);
xfree (attr);
}
q1 = q->next;
--- /dev/null
+/*
+ * Copyright (c) 2002-2003, Index Data
+ * See the file LICENSE for details.
+ *
+ * $Id: tstccl.c,v 1.1 2003-06-23 10:22:21 adam Exp $
+ */
+
+/* CCL test */
+
+#include <yaz/ccl.h>
+
+static char *query_str[] = {
+ "x1",
+ "x1 and x2",
+ "ti=x3",
+ "dc.title=x4",
+ 0
+};
+
+void tst1(void)
+{
+ CCL_parser parser = ccl_parser_create ();
+ CCL_bibset bibset = ccl_qual_mk();
+ int i;
+
+ ccl_qual_fitem(bibset, "u=4 s=pw t=l,r", "ti");
+ ccl_qual_fitem(bibset, "1=1016 s=al,pw", "term");
+ ccl_qual_fitem(bibset, "1=/my/title", "dc.title");
+
+ parser->bibset = bibset;
+
+ for (i = 0; query_str[i]; i++)
+ {
+ struct ccl_token *token_list =
+ ccl_parser_tokenize(parser, query_str[i]);
+ struct ccl_rpn_node *rpn = ccl_parser_find(parser, token_list);
+ ccl_token_del (token_list);
+ if (rpn)
+ {
+ ccl_rpn_delete(rpn);
+ }
+ else
+ {
+ printf ("failed %s\n", query_str[i]);
+ exit(1+i);
+ }
+ }
+ ccl_parser_destroy (parser);
+ ccl_qual_rm(&bibset);
+}
+
+int main(int argc, char **argv)
+{
+ tst1();
+ exit(0);
+}
/*
* CCL - header file
*
- * $Id: ccl.h,v 1.13 2002-12-28 12:13:03 adam Exp $
+ * $Id: ccl.h,v 1.14 2003-06-23 10:22:21 adam Exp $
*
* Old Europagate Log:
*
struct ccl_rpn_attr *next;
char *set;
int type;
- int value;
+ int kind;
+#define CCL_RPN_ATTR_NUMERIC 1
+#define CCL_RPN_ATTR_STRING 2
+ union {
+ int numeric;
+ char *str;
+ } value;
};
#define CCL_RPN_AND 1
int *attr);
YAZ_EXPORT void ccl_qual_add_set (CCL_bibset b, const char *name, int no,
- int *attr, char **attsets);
+ int *type, int *value, char **svalue,
+ char **attsets);
YAZ_EXPORT void ccl_qual_add_special (CCL_bibset bibset,
const char *n, const char *v);
* Copyright (c) 2002-2003, Index Data
* See the file LICENSE for details.
*
- * $Id: tstwrbuf.c,v 1.1 2003-05-06 10:07:33 adam Exp $
+ * $Id: tstwrbuf.c,v 1.2 2003-06-23 10:22:21 adam Exp $
*/
#include <stdio.h>
{
if (cp[k] != i+1)
{
- printf ("tstwrbuf 2 %d k=%d\n", k);
+ printf ("tstwrbuf 2 %d k=%d\n", step, k);
exit(1);
}
k++;
* Copyright (c) 1996-2003, Index Data.
* See the file LICENSE for details.
*
- * $Id: yaz-ccl.c,v 1.19 2003-02-12 15:06:44 adam Exp $
+ * $Id: yaz-ccl.c,v 1.20 2003-06-23 10:22:21 adam Exp $
*/
#include <stdio.h>
wrbuf_puts (w, att->set);
wrbuf_puts (w, " ");
}
- sprintf(tmpattr, "%d=%d ", att->type, att->value);
- wrbuf_puts (w, tmpattr);
+ switch(att->kind)
+ {
+ case CCL_RPN_ATTR_NUMERIC:
+ sprintf(tmpattr, "%d=%d ", att->type, att->value.numeric);
+ wrbuf_puts (w, tmpattr);
+ break;
+ case CCL_RPN_ATTR_STRING:
+ sprintf(tmpattr, "%d ", att->type);
+ wrbuf_puts (w, tmpattr);
+ wrbuf_puts(w, att->value.str);
+ break;
+ }
}
for (cp = p->u.t.term; *cp; cp++)
{