-/* $Id: d1_absyn.c,v 1.10 2004-08-04 08:35:22 adam Exp $
+/* $Id: d1_absyn.c,v 1.9.2.1 2004-08-24 14:06:31 adam Exp $
Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
Index Data Aps
while (p)
{
- if (!yaz_matchstr (name, p->name))
+ if (!strcmp (name, p->name))
return p->absyn;
p = p->next;
}
while (p)
{
- if (!yaz_matchstr (name, p->name))
+ if (!strcmp (name, p->name))
return p->attset;
p = p->next;
}
pop, 2002-12-13
*/
static int parse_termlists (data1_handle dh, data1_termlist ***tpp,
- char *p, const char *file, int lineno,
+ char *cp, const char *file, int lineno,
const char *element_name, data1_absyn *res,
int xpelement)
{
data1_termlist **tp = *tpp;
- do
+ while(1)
{
char attname[512], structure[512];
char *source;
- int r;
-
- if (!(r = sscanf(p, "%511[^:,]:%511[^,]", attname,
- structure)))
+ int r, i;
+ int level = 0;
+ structure[0] = '\0';
+ for (i = 0; cp[i] && i<sizeof(attname)-1; i++)
+ if (strchr(":,", cp[i]))
+ break;
+ else
+ attname[i] = cp[i];
+ if (i == 0)
{
- yaz_log(LOG_WARN,
- "%s:%d: Syntax error in termlistspec '%s'",
- file, lineno, p);
- return -1;
+ if (*cp)
+ yaz_log(LOG_WARN,
+ "%s:%d: Syntax error in termlistspec '%s'",
+ file, lineno, cp);
+ break;
}
+ attname[i] = '\0';
+ r = 1;
+ cp += i;
+ if (*cp == ':')
+ cp++;
+
+ for (i = 0; cp[i] && i<sizeof(structure)-1; i++)
+ if (level == 0 && strchr(",", cp[i]))
+ break;
+ else
+ {
+ structure[i] = cp[i];
+ if (cp[i] == '(')
+ level++;
+ else if (cp[i] == ')')
+ level--;
+ }
+ structure[i] = '\0';
+ if (i)
+ r = 2;
+ cp += i;
+ if (*cp)
+ cp++; /* skip , */
*tp = (data1_termlist *)
- nmem_malloc(data1_nmem_get(dh), sizeof(**tp));
+ nmem_malloc(data1_nmem_get(dh), sizeof(**tp));
(*tp)->next = 0;
if (!xpelement) {
nmem_strdup (data1_nmem_get (dh), structure);
tp = &(*tp)->next;
}
- while ((p = strchr(p, ',')) && *(++p));
+
*tpp = tp;
return 0;
}
-/* $Id: recgrs.c,v 1.86 2004-05-21 11:58:56 adam Exp $
+/* $Id: recgrs.c,v 1.86.2.1 2004-08-24 14:06:32 adam Exp $
Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003
Index Data Aps
xfree (h);
}
+struct source_parser {
+ int len;
+ const char *tok;
+ const char *src;
+ int lookahead;
+};
+
+static int sp_lex(struct source_parser *sp)
+{
+ while (*sp->src == ' ')
+ (sp->src)++;
+ sp->tok = sp->src;
+ sp->len = 0;
+ while (*sp->src && !strchr("<>();,-: ", *sp->src))
+ {
+ sp->src++;
+ sp->len++;
+ }
+ if (sp->len)
+ sp->lookahead = 't';
+ else
+ {
+ sp->lookahead = *sp->src;
+ if (*sp->src)
+ sp->src++;
+ }
+ return sp->lookahead;
+}
+
+
+static int sp_expr(struct source_parser *sp, data1_node *n, RecWord *wrd)
+{
+ if (sp->lookahead != 't')
+ return 0;
+ if (sp->len == 4 && !memcmp(sp->tok, "data", sp->len))
+ {
+ if (n->which == DATA1N_data)
+ {
+ wrd->string = n->u.data.data;
+ wrd->length = n->u.data.len;
+ }
+ sp_lex(sp);
+ }
+ else if (sp->len == 3 && !memcmp(sp->tok, "tag", sp->len))
+ {
+ if (n->which == DATA1N_tag)
+ {
+ wrd->string = n->u.tag.tag;
+ wrd->length = strlen(n->u.tag.tag);
+ }
+ sp_lex(sp);
+ }
+ else if (sp->len == 4 && !memcmp(sp->tok, "attr", sp->len))
+ {
+ sp_lex(sp);
+ if (sp->lookahead != '(')
+ return 0;
+ sp_lex(sp);
+ if (sp->lookahead != 't')
+ return 0;
+
+ if (n->which == DATA1N_tag)
+ {
+ data1_xattr *p = n->u.tag.attributes;
+ while (p && strlen(p->name) != sp->len &&
+ memcmp (p->name, sp->tok, sp->len))
+ p = p->next;
+ if (p)
+ {
+ wrd->string = p->value;
+ wrd->length = strlen(p->value);
+ }
+ }
+ sp_lex(sp);
+ if (sp->lookahead != ')')
+ return 0;
+ sp_lex(sp);
+ }
+ else if (sp->len == 5 && !memcmp(sp->tok, "range", sp->len))
+ {
+ int start, len;
+ sp_lex(sp);
+ if (sp->lookahead != '(')
+ return 0;
+
+ sp_lex(sp);
+ sp_expr(sp, n, wrd);
+ if (sp->lookahead != ',')
+ return 0;
+
+ sp_lex(sp);
+ if (sp->lookahead != 't')
+ return 0;
+ start = atoi_n(sp->tok, sp->len);
+
+ sp_lex(sp);
+ if (sp->lookahead != ',')
+ return 0;
+
+ sp_lex(sp);
+ if (sp->lookahead != 't')
+ return 0;
+ len = atoi_n(sp->tok, sp->len);
+
+ sp_lex(sp);
+ if (sp->lookahead != ')')
+ return 0;
+
+ sp_lex(sp);
+ if (wrd->string && wrd->length)
+ {
+ wrd->string += start;
+ wrd->length -= start;
+ if (wrd->length > len)
+ wrd->length = len;
+ }
+ }
+ return 1;
+}
+
+static int sp_parse(data1_node *n, RecWord *wrd, const char *src)
+{
+ struct source_parser sp;
+ sp.len = 0;
+ sp.tok = 0;
+ sp.src = src;
+ sp.lookahead = 0;
+ sp_lex(&sp);
+
+ return sp_expr(&sp, n, wrd);
+}
+
int d1_check_xpath_predicate(data1_node *n, struct xpath_predicate *p)
{
int res = 1;
size_t flen = 0;
data1_node *nn;
int termlist_only = 1;
+ data1_termlist *tl;
+ int xpdone = 0;
yaz_log(LOG_DEBUG, "index_xpath level=%d use=%d", level, use);
if ((!n->root->u.root.absyn) ||
case DATA1N_data:
wrd->string = n->u.data.data;
wrd->length = n->u.data.len;
- if (p->flagShowRecords)
- {
- printf("%*s XData:\"", (level + 1) * 4, "");
- for (i = 0; i<wrd->length && i < 8; i++)
- fputc (wrd->string[i], stdout);
- printf("\"\n");
- }
- else {
- data1_termlist *tl;
- int xpdone = 0;
- flen = 0;
-
- /* we have to fetch the whole path to the data tag */
- for (nn = n; nn; nn = nn->parent) {
- if (nn->which == DATA1N_tag) {
- size_t tlen = strlen(nn->u.tag.tag);
- if (tlen + flen > (sizeof(tag_path_full)-2)) return;
- memcpy (tag_path_full + flen, nn->u.tag.tag, tlen);
- flen += tlen;
- tag_path_full[flen++] = '/';
- }
- else if (nn->which == DATA1N_root) break;
- }
-
- tag_path_full[flen] = 0;
+ xpdone = 0;
+ flen = 0;
- /* If we have a matching termlist... */
- if (n->root->u.root.absyn && (tl = xpath_termlist_by_tagpath(tag_path_full, n))) {
- for (; tl; tl = tl->next) {
- wrd->reg_type = *tl->structure;
- /* this is the ! case, so structure is for the xpath index */
- if (!tl->att) {
- wrd->attrSet = VAL_IDXPATH;
- wrd->attrUse = use;
- (*p->tokenAdd)(wrd);
- xpdone = 1;
- } else {
- /* this is just the old fashioned attribute based index */
- wrd->attrSet = (int) (tl->att->parent->reference);
- wrd->attrUse = tl->att->locals->local;
- (*p->tokenAdd)(wrd);
- }
- }
- }
- /* xpath indexing is done, if there was no termlist given,
- or no ! in the termlist, and default indexing is enabled... */
- if ((!xpdone) && (!termlist_only)) {
- wrd->attrSet = VAL_IDXPATH;
- wrd->attrUse = use;
- wrd->reg_type = 'w';
- (*p->tokenAdd)(wrd);
- }
+ /* we have to fetch the whole path to the data tag */
+ for (nn = n; nn; nn = nn->parent) {
+ if (nn->which == DATA1N_tag) {
+ size_t tlen = strlen(nn->u.tag.tag);
+ if (tlen + flen > (sizeof(tag_path_full)-2)) return;
+ memcpy (tag_path_full + flen, nn->u.tag.tag, tlen);
+ flen += tlen;
+ tag_path_full[flen++] = '/';
+ }
+ else if (nn->which == DATA1N_root) break;
+ }
+
+ tag_path_full[flen] = 0;
+
+ /* If we have a matching termlist... */
+ if (n->root->u.root.absyn &&
+ (tl = xpath_termlist_by_tagpath(tag_path_full, n)))
+ {
+ for (; tl; tl = tl->next)
+ {
+ /* need to copy recword because it may be changed */
+ RecWord wrd_tl;
+ wrd->reg_type = *tl->structure;
+ /* this is the ! case, so structure is for the xpath index */
+ memcpy (&wrd_tl, wrd, sizeof(*wrd));
+ if (tl->source)
+ sp_parse(n, &wrd_tl, tl->source);
+ if (!tl->att) {
+ wrd_tl.attrSet = VAL_IDXPATH;
+ wrd_tl.attrUse = use;
+ if (p->flagShowRecords)
+ {
+ int i;
+ printf("%*sXPath index", (level + 1) * 4, "");
+ printf (" XData:\"");
+ for (i = 0; i<wrd_tl.length && i < 40; i++)
+ fputc (wrd_tl.string[i], stdout);
+ fputc ('"', stdout);
+ if (wrd_tl.length > 40)
+ printf (" ...");
+ fputc ('\n', stdout);
+ }
+ else
+ (*p->tokenAdd)(&wrd_tl);
+ xpdone = 1;
+ } else {
+ /* this is just the old fashioned attribute based index */
+ wrd_tl.attrSet = (int) (tl->att->parent->reference);
+ wrd_tl.attrUse = tl->att->locals->local;
+ if (p->flagShowRecords)
+ {
+ int i;
+ printf("%*sIdx: [%s]", (level + 1) * 4, "",
+ tl->structure);
+ printf("%s:%s [%d] %s",
+ tl->att->parent->name,
+ tl->att->name, tl->att->value,
+ tl->source);
+ printf (" XData:\"");
+ for (i = 0; i<wrd_tl.length && i < 40; i++)
+ fputc (wrd_tl.string[i], stdout);
+ fputc ('"', stdout);
+ if (wrd_tl.length > 40)
+ printf (" ...");
+ fputc ('\n', stdout);
+ }
+ else
+ (*p->tokenAdd)(&wrd_tl);
+ }
+ }
+ }
+ /* xpath indexing is done, if there was no termlist given,
+ or no ! in the termlist, and default indexing is enabled... */
+ if (!p->flagShowRecords && !xpdone && !termlist_only)
+ {
+ wrd->attrSet = VAL_IDXPATH;
+ wrd->attrUse = use;
+ wrd->reg_type = 'w';
+ (*p->tokenAdd)(wrd);
}
break;
case DATA1N_tag:
for (; tlist; tlist = tlist->next)
{
-
- char xattr[512];
/* consider source */
wrd->string = 0;
+ assert(tlist->source);
+ sp_parse(n, wrd, tlist->source);
- if (!strcmp (tlist->source, "data") && n->which == DATA1N_data)
- {
- wrd->string = n->u.data.data;
- wrd->length = n->u.data.len;
- }
- else if (!strcmp (tlist->source, "tag") && n->which == DATA1N_tag)
- {
- wrd->string = n->u.tag.tag;
- wrd->length = strlen(n->u.tag.tag);
- }
- else if (sscanf (tlist->source, "attr(%511[^)])", xattr) == 1 &&
- n->which == DATA1N_tag)
- {
- data1_xattr *p = n->u.tag.attributes;
- while (p && strcmp (p->name, xattr))
- p = p->next;
- if (p)
- {
- wrd->string = p->value;
- wrd->length = strlen(p->value);
- }
- }
if (wrd->string)
{
if (p->flagShowRecords)