29 #include <yaz/oid_db.h>
30 #include <yaz/snprintf.h>
36 #define D1_MAX_NESTING 128
56 if (*
str >=
'a' && *
str <=
'z')
57 v = v*65509 + *
str -
'a'+10;
58 else if (*
str >=
'A' && *
str <=
'Z')
59 v = v*65509 + *
str -
'A'+10;
60 else if (*
str >=
'0' && *
str <=
'9')
61 v = v*65509 + *
str -
'0';
76 for (i = 0; i<ht->
size; i++)
82 void *clientData,
int copy)
84 char *dstr = copy ? nmem_strdup(ht->
nmem, str) : (
char*) str;
85 if (strchr(str,
'?') || strchr(str,
'.'))
88 for (i = 0; i<ht->
size; i++)
91 for (; *he && strcmp(
str, (*he)->str); he = &(*he)->
next)
95 *he = nmem_malloc(ht->
nmem,
sizeof(**he));
105 for (; *he && strcmp(
str, (*he)->str); he = &(*he)->
next)
109 *he = nmem_malloc(ht->
nmem,
sizeof(**he));
121 for (; *he && yaz_matchstr(
str, (*he)->str); he = &(*he)->
next)
166 if (!yaz_matchstr(name, p->
name))
188 yaz_log (YLOG_DEBUG,
"Destroy xp element %s",xpe->
xpath_expr);
206 (*fh)(dh, handle, p->
absyn);
223 yaz_snprintf(fname,
sizeof(fname),
"%s.abs", name);
225 p->
name = nmem_strdup(mem, name);
247 if (!yaz_matchstr(name, p->
name))
274 yaz_log(YLOG_WARN|YLOG_ERRNO,
"Couldn't load attribute set %s", name);
278 nmem_malloc (mem,
sizeof(*p));
281 attset->
name = p->
name = nmem_strdup(mem, name);
310 #define DATA1_GETELEMENTBYTAGNAME_VERSION 1
328 #if DATA1_GETELEMENTBYTAGNAME_VERSION==1
338 for (; r; r = r->
next)
349 for (; r; r = r->
next)
382 for (; e; e = e->
next)
397 yaz_log(YLOG_WARN,
"Unresolved reference to sub-elements %s",
425 const char *p = expr;
429 char *res_p, *res = 0;
442 int is_predicate = 0;
445 for (i = 0; *p && !strchr(
"/",*p); i++, p++)
449 for (j = 0; j < i; j++)
451 const char *pp = p-i+j;
472 if (stack[e-1][0] ==
'@')
475 strcpy(res_p,
"[^@]*/");
476 res_p = res_p + strlen(res_p);
478 strcpy(res_p, stack[e]);
480 res_p += strlen(stack[e]) + 1;
489 yaz_log(YLOG_DEBUG,
"Got regexp: %s", res);
494 char *cp,
const char *file,
int lineno,
502 char attname[512], structure[512];
507 for (i = 0; cp[i] && i<
sizeof(attname)-1; i++)
508 if (strchr(
":,", cp[i]))
516 "%s:%d: Syntax error in termlistspec '%s'",
526 for (i = 0; cp[i] && i<
sizeof(structure)-1; i++)
527 if (level == 0 && strchr(
",", cp[i]))
531 structure[i] = cp[i];
534 else if (cp[i] ==
')')
550 if (!xpelement && element_name)
551 strcpy(attname, element_name);
559 yaz_log(YLOG_WARN,
"Index '%s' not found in attset(s)",
565 assert (*(*tp)->index_name !=
'!');
566 if (r == 2 && (source = strchr(structure,
':')))
573 (*tp)->structure =
"w";
592 if ((dollar = strchr(melm,
'$'))) {
597 if (field[0] ==
'0' && field[1] ==
'0')
598 fieldtype =
"controlfield";
600 fieldtype =
"datafield";
601 yaz_snprintf(buf, 60,
"/*/%s[@tag=\"%s\"]", fieldtype, field);
603 yaz_snprintf(buf + strlen(buf), 60,
"/subfield[@code=\"%s\"]", subfield);
604 else if (field[0] !=
'0' || field[1] !=
'0')
605 strcat(buf,
"/subfield");
606 yaz_log(YLOG_DEBUG,
"Created xpath: '%s'", buf);
611 const char *default_value)
614 for (; p; p = p->
next)
615 if (!strcmp(p->
name, tag))
617 return default_value;
620 #define l_isspace(c) ((c) == '\t' || (c) == ' ' || (c) == '\n' || (c) == '\r')
623 char *argv[],
int num)
629 while ((p = fgets(line, len, f)))
640 for (argc = 0; *p ; argc++)
645 while (*p && !(
l_isspace(*p) && !quoted)) {
646 if (*p ==
'"') quoted = 1 - quoted;
647 if (*p ==
'[') quoted = 1;
648 if (*p ==
']') quoted = 0;
663 if (root->
u.
root.absyn)
664 return root->
u.
root.absyn->marc;
671 if (root->
u.
root.absyn)
672 return root->
u.
root.absyn->main_elements;
696 char *argv[50], line[512];
709 tagset_childp = &res->
tagset;
726 if (!strcmp(cmd,
"elm") || !strcmp(cmd,
"element"))
730 char *p, *sub_p, *path, *
name, *termlists;
736 yaz_log(YLOG_WARN,
"%s:%d: Bad # of args to elm", file, lineno);
749 cur_elements->
name =
"main";
753 ppl[level] = &cur_elements->
elements;
760 if ((e = strchr(p,
'/')))
767 yaz_log(YLOG_WARN,
"%s:%d: Bad level increase", file, lineno);
775 ppl[level-1] = &new_element->
next;
776 ppl[level] = &new_element->
children;
779 if ((sub_p = strchr (p,
':')) && sub_p[1])
786 if (sscanf(p,
"(%d,%d)", &type, &
value) == 2)
790 yaz_log(YLOG_WARN,
"%s:%d: No tagset loaded", file, lineno);
797 yaz_log(YLOG_WARN,
"%s:%d: Couldn't find tag %s in tagset",
809 sizeof(*new_element->
tag));
823 yaz_log(YLOG_WARN,
"%s:%d: Bad element", file, lineno);
855 else if (!strcmp(cmd,
"xelm") || !strcmp(cmd,
"melm")) {
858 char *p, *xpath_expr, *termlists;
862 char melm_xpath[128];
868 yaz_log(YLOG_WARN,
"%s:%d: Bad # of args to %s",
873 if (!strcmp(cmd,
"melm")) {
876 xpath_expr = melm_xpath;
878 xpath_expr = argv[1];
886 if (!strcmp(xp_ele->
regexp, regexp))
892 const char *regexp_ptr = regexp;
896 if (i || *regexp_ptr) {
897 yaz_log(YLOG_WARN,
"%s:%d: Bad xpath to xelm", file, lineno);
904 (*cur_xpelement)->
next = 0;
909 (*cur_xpelement)->
regexp = regexp;
916 (*cur_xpelement)->dfa = dfa;
919 (*cur_xpelement)->xpath_len =
925 (*cur_xpelement)->termlists = 0;
926 tp = &(*cur_xpelement)->termlists;
933 xpath_expr, res, 1, attset_list))
940 cur_xpelement = &(*cur_xpelement)->
next;
942 else if (!strcmp(cmd,
"section"))
948 yaz_log(YLOG_WARN,
"%s:%d: Bad # of args to section",
962 ppl[level] = &cur_elements->
elements;
964 else if (!strcmp(cmd,
"xpath"))
968 yaz_log(YLOG_WARN,
"%s:%d: Bad # of args to 'xpath' directive",
972 if (!strcmp(argv[1],
"enable"))
974 else if (!strcmp (argv[1],
"disable"))
978 yaz_log(YLOG_WARN,
"%s:%d: Expecting disable/enable "
979 "after 'xpath' directive", file, lineno);
982 else if (!strcmp(cmd,
"all"))
987 yaz_log(YLOG_WARN,
"%s:%d: Too many 'all' directives - ignored",
993 yaz_log(YLOG_WARN,
"%s:%d: Bad # of args to 'all' directive",
1004 else if (!strcmp(cmd,
"name"))
1008 yaz_log(YLOG_WARN,
"%s:%d: Bad # of args to name directive",
1014 else if (!strcmp(cmd,
"reference"))
1020 yaz_log(YLOG_WARN,
"%s:%d: Bad # of args to reference",
1025 res->
oid = yaz_string_to_oid_nmem(yaz_oid_std(),
1030 yaz_log(YLOG_WARN,
"%s:%d: Unknown tagset ref '%s'",
1031 file, lineno, name);
1035 else if (!strcmp(cmd,
"attset"))
1042 yaz_log(YLOG_WARN,
"%s:%d: Bad # of args to attset",
1049 yaz_log(YLOG_WARN,
"%s:%d: Couldn't find attset %s",
1050 file, lineno, name);
1055 (*attset_childp)->
child = attset;
1056 (*attset_childp)->
next = 0;
1057 attset_childp = &(*attset_childp)->
next;
1059 else if (!strcmp(cmd,
"tagset"))
1065 yaz_log(YLOG_WARN,
"%s:%d: Bad # of args to tagset",
1071 type = atoi(argv[2]);
1073 if (!(*tagset_childp))
1075 yaz_log(YLOG_WARN,
"%s:%d: Couldn't load tagset %s",
1076 file, lineno, name);
1079 tagset_childp = &(*tagset_childp)->
next;
1081 else if (!strcmp(cmd,
"varset"))
1087 yaz_log(YLOG_WARN,
"%s:%d: Bad # of args in varset",
1094 yaz_log(YLOG_WARN,
"%s:%d: Couldn't load Varset %s",
1095 file, lineno, name);
1099 else if (!strcmp(cmd,
"esetname"))
1105 yaz_log(YLOG_WARN,
"%s:%d: Bad # of args in esetname",
1115 (*esetpp)->next = 0;
1117 (*esetpp)->spec = 0;
1120 yaz_log(YLOG_WARN,
"%s:%d: Espec-1 read failed for %s",
1121 file, lineno, fname);
1124 esetpp = &(*esetpp)->
next;
1126 else if (!strcmp(cmd,
"maptab"))
1132 yaz_log(YLOG_WARN,
"%s:%d: Bad # of args for maptab",
1139 yaz_log(YLOG_WARN,
"%s:%d: Couldn't load maptab %s",
1140 file, lineno, name);
1143 maptabp = &(*maptabp)->
next;
1145 else if (!strcmp(cmd,
"marc"))
1151 yaz_log(YLOG_WARN,
"%s:%d: Bad # or args for marc",
1158 yaz_log(YLOG_WARN,
"%s:%d: Couldn't read marctab %s",
1159 file, lineno, name);
1162 marcp = &(*marcp)->
next;
1164 else if (!strcmp(cmd,
"encoding"))
1168 yaz_log(YLOG_WARN,
"%s:%d: Bad # or args for encoding",
1174 else if (!strcmp(cmd,
"systag"))
1178 yaz_log(YLOG_WARN,
"%s:%d: Bad # or args for systag",
1186 systagsp = &(*systagsp)->
next;
1190 yaz_log(YLOG_WARN,
"%s:%d: Unknown directive '%s'", file,
1199 cur_elements = cur_elements->
next)
1201 if (!strcmp(cur_elements->
name,
"main"))
static const char * mk_xpath_regexp(data1_handle dh, const char *expr)
data1_element * data1_getelementbytagname(data1_handle dh, data1_absyn *abs, data1_element *parent, const char *tagname)
void data1_absyn_destroy(data1_handle dh)
data1_attset * data1_attset_add(data1_handle dh, const char *name)
data1_absyn * data1_get_absyn(data1_handle dh, const char *name, enum DATA1_XPATH_INDEXING en)
static data1_absyn * data1_read_absyn(data1_handle dh, const char *file, enum DATA1_XPATH_INDEXING en)
struct data1_hash_table * data1_hash_open(int size, NMEM nmem)
data1_attset * data1_attset_search_id(data1_handle dh, const Odr_oid *oid)
void data1_absyn_trav(data1_handle dh, void *handle, void(*fh)(data1_handle dh, void *h, data1_absyn *a))
data1_attset * data1_attset_search_name(data1_handle dh, const char *name)
data1_attset * data1_get_attset(data1_handle dh, const char *name)
void data1_hash_insert(struct data1_hash_table *ht, const char *str, void *clientData, int copy)
data1_element * data1_absyn_getelements(data1_handle dh, data1_node *root)
data1_element * data1_getelementbyname(data1_handle dh, data1_absyn *absyn, const char *name)
static int melm2xpath(char *melm, char *buf)
void fix_element_ref(data1_handle dh, data1_absyn *absyn, data1_element *e)
int read_absyn_line(FILE *f, int *lineno, char *line, int len, char *argv[], int num)
static int parse_termlists(data1_handle dh, data1_termlist ***tpp, char *cp, const char *file, int lineno, const char *element_name, data1_absyn *res, int xpelement, data1_attset *attset)
data1_esetname * data1_getesetbyname(data1_handle dh, data1_absyn *a, const char *name)
unsigned data1_hash_calc(struct data1_hash_table *ht, const char *str)
data1_element * data1_mk_element(data1_handle dh)
static data1_absyn * data1_absyn_add(data1_handle dh, const char *name, enum DATA1_XPATH_INDEXING en)
data1_marctab * data1_absyn_getmarctab(data1_handle dh, data1_node *root)
void * data1_hash_lookup(struct data1_hash_table *ht, const char *str)
const char * data1_systag_lookup(data1_absyn *absyn, const char *tag, const char *default_value)
data1_absyn * data1_absyn_search(data1_handle dh, const char *name)
struct data1_absyn_cache_info * data1_absyn_cache
data1_marctab * data1_read_marctab(data1_handle dh, const char *file)
data1_attset * data1_empty_attset(data1_handle dh)
data1_attset_cache * data1_attset_cache_get(data1_handle dh)
FILE * data1_path_fopen(data1_handle dh, const char *file, const char *mode)
data1_attset * data1_read_attset(data1_handle dh, const char *file)
Z_Espec1 * data1_read_espec1(data1_handle dh, const char *file)
data1_tag * data1_gettagbynum(data1_handle dh, data1_tagset *s, int type, int value)
data1_maptab * data1_read_maptab(data1_handle dh, const char *file)
NMEM data1_nmem_get(data1_handle dh)
#define data1_matchstr(s1, s2)
struct data1_attset_cache_info * data1_attset_cache
data1_varset * data1_read_varset(data1_handle dh, const char *file)
data1_att * data1_getattbyname(data1_handle dh, data1_attset *s, const char *name)
data1_tagset * data1_read_tagset(data1_handle dh, const char *file, int type)
@ DATA1_XPATH_INDEXING_ENABLE
@ DATA1_XPATH_INDEXING_DISABLE
data1_absyn_cache * data1_absyn_cache_get(data1_handle dh)
int dfa_parse(struct DFA *, const char **)
void dfa_mkstate(struct DFA *)
void dfa_delete(struct DFA **)
struct DFA * dfa_init(void)
#define ZEBRA_XPATH_CDATA
data1_esetname * esetnames
data1_sub_elements * sub_elements
enum DATA1_XPATH_INDEXING xpath_indexing
struct data1_xpelement * xp_elements
data1_element * main_elements
struct data1_systag * systags
data1_attset_child * next
data1_attset_child * children
data1_termlist * termlists
struct data1_element * next
struct data1_element * children
struct data1_hash_table * hash
struct data1_esetname * next
struct data1_hash_entry * next
struct data1_hash_entry ** ar
struct data1_maptab * next
struct data1_marctab * next
struct data1_node::@2::@3 root
struct data1_sub_elements * next
struct data1_systag * next
struct data1_tagset * tagset
union data1_tag::@1 value
struct data1_termlist * next
struct data1_xpelement * match_next
struct data1_xpelement * next
int zebra_parse_xpath_str(const char *xpath_string, struct xpath_location_step *xpath, int max, NMEM mem)