2 * Copyright (c) 1995-1997, Index Data.
3 * See the file LICENSE for details.
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.15 1997-12-09 16:18:16 adam
8 * Work on EXPLAIN schema. First implementation of sub-schema facility
11 * Revision 1.14 1997/10/31 12:20:09 adam
12 * Improved memory debugging for xmalloc/nmem.c. References to NMEM
13 * instead of ODR in n ESPEC-1 handling in source d1_espec.c.
14 * Bug fix: missing fclose in data1_read_espec1.
16 * Revision 1.13 1997/10/27 13:54:18 adam
17 * Changed structure field in data1 node to be simple string which
18 * is "unknown" to the retrieval system itself.
20 * Revision 1.12 1997/09/17 12:10:34 adam
23 * Revision 1.11 1997/09/05 09:50:55 adam
24 * Removed global data1_tabpath - uses data1_get_tabpath() instead.
26 * Revision 1.10 1997/05/14 06:54:01 adam
29 * Revision 1.9 1997/02/19 14:46:15 adam
30 * The "all" specifier only affects elements that are indexed (and not
33 * Revision 1.8 1997/01/02 10:47:59 quinn
34 * Added optional, physical ANY
36 * Revision 1.7 1996/06/10 08:56:01 quinn
39 * Revision 1.6 1996/05/31 13:52:21 quinn
40 * Fixed uninitialized variable for local tags in abstract syntax.
42 * Revision 1.5 1996/05/09 07:27:43 quinn
43 * Multiple local attributes values supported.
45 * Revision 1.4 1996/05/01 12:45:28 quinn
46 * Support use of local tag names in abs file.
48 * Revision 1.3 1995/11/01 16:34:55 quinn
49 * Making data1 look for tables in data1_tabpath
51 * Revision 1.2 1995/11/01 13:54:44 quinn
54 * Revision 1.1 1995/11/01 11:56:06 quinn
55 * Added Retrieval (data management) functions en masse.
72 #define D1_MAX_NESTING 128
74 struct data1_absyn_cache_info
78 data1_absyn_cache next;
81 data1_absyn *data1_absyn_search (data1_handle dh, const char *name)
83 data1_absyn_cache p = *data1_absyn_cache_get (dh);
87 if (!strcmp (name, p->name))
94 data1_absyn *data1_absyn_add (data1_handle dh, const char *name)
97 NMEM mem = data1_nmem_get (dh);
99 data1_absyn_cache p = nmem_malloc (mem, sizeof(*p));
100 data1_absyn_cache *pp = data1_absyn_cache_get (dh);
102 sprintf(fname, "%s.abs", name);
103 p->absyn = data1_read_absyn (dh, fname);
104 p->name = nmem_strdup (mem, name);
110 data1_absyn *data1_get_absyn (data1_handle dh, char *name)
114 if (!(absyn = data1_absyn_search (dh, name)))
115 absyn = data1_absyn_add (dh, name);
119 data1_esetname *data1_getesetbyname(data1_handle dh, data1_absyn *a,
124 for (r = a->esetnames; r; r = r->next)
125 if (!data1_matchstr(r->name, name))
130 data1_element *data1_getelementbytagname (data1_handle dh, data1_absyn *abs,
131 data1_element *parent,
137 r = abs->main_elements;
139 r = parent->children;
140 assert (abs->main_elements);
141 for (; r; r = r->next)
145 for (n = r->tag->names; n; n = n->next)
146 if (!data1_matchstr(tagname, n->name))
152 data1_element *data1_getelementbyname (data1_handle dh, data1_absyn *absyn,
156 assert (absyn->main_elements);
157 for (r = absyn->main_elements; r; r = r->next)
158 if (!data1_matchstr(r->name, name))
163 data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
165 char line[512], *r, cmd[512], args[512];
166 data1_sub_elements *cur_elements = NULL;
167 data1_absyn *res = 0;
169 data1_element **ppl[D1_MAX_NESTING];
170 data1_esetname **esetpp;
171 data1_maptab **maptabp;
172 data1_marctab **marcp;
173 data1_termlist *all = 0;
176 logf (LOG_DEBUG, "begin data1_read_absyn file=%s", file);
177 if (!(f = yaz_path_fopen(data1_get_tabpath (dh), file, "r")))
179 logf(LOG_WARN|LOG_ERRNO, "Couldn't open %s", file);
183 res = nmem_malloc(data1_nmem_get(dh), sizeof(*res));
185 res->reference = VAL_NONE;
190 esetpp = &res->esetnames;
192 maptabp = &res->maptabs;
196 res->sub_elements = NULL;
197 res->main_elements = NULL;
201 while ((r = fgets(line, 512, f)))
203 while (*r && isspace(*r))
210 if (sscanf(r, "%s %[^\n]", cmd, args) < 2)
212 if (!strcmp(cmd, "elm"))
214 data1_element *new_element;
216 char path[512], name[512], termlists[512], *p;
222 cur_elements = nmem_malloc(data1_nmem_get(dh),
223 sizeof(*cur_elements));
224 cur_elements->next = res->sub_elements;
225 cur_elements->elements = NULL;
226 cur_elements->name = "main";
227 res->sub_elements = cur_elements;
230 ppl[level] = &cur_elements->elements;
232 if (sscanf(args, "%511s %511s %511s", path, name, termlists) < 3)
234 logf(LOG_WARN, "Bad # of args to elm in %s: '%s'",
244 if ((e = strchr(p, '/')))
251 logf(LOG_WARN, "Bad level inc in %s in '%s'", file, args);
256 if (*p == '$' && level > 0)
258 data1_sub_elements *sub_e = res->sub_elements;
261 while (sub_e && strcmp (p, sub_e->name))
264 *ppl[level] = sub_e->elements;
269 new_element = *ppl[level] =
270 nmem_malloc(data1_nmem_get(dh), sizeof(*new_element));
271 new_element->next = new_element->children = 0;
272 new_element->tag = 0;
273 new_element->termlists = 0;
275 tp = &new_element->termlists;
276 ppl[level] = &new_element->next;
277 ppl[level+1] = &new_element->children;
279 /* well-defined tag */
280 if (sscanf(p, "(%d,%d)", &type, &value) == 2)
284 logf(LOG_WARN, "No tagset loaded in %s", file);
288 if (!(new_element->tag = data1_gettagbynum (dh, res->tagset,
291 logf(LOG_WARN, "Couldn't find tag %s in tagset in %s",
301 new_element->tag = nmem_malloc(data1_nmem_get (dh),
302 sizeof(*new_element->tag));
303 nt->which = DATA1T_string;
304 nt->value.string = nmem_strdup(data1_nmem_get (dh), p);
305 nt->names = nmem_malloc(data1_nmem_get(dh),
306 sizeof(*new_element->tag->names));
307 nt->names->name = nt->value.string;
309 nt->kind = DATA1K_string;
315 logf(LOG_WARN, "Bad element is %s", file);
320 /* parse termList definitions */
323 new_element->termlists = 0;
328 logf(LOG_WARN, "No attset loaded in %s", file);
334 char attname[512], structure[512];
337 if (!(r = sscanf(p, "%511[^:,]:%511[^,]", attname,
340 logf(LOG_WARN, "Syntax error in termlistspec in %s",
346 strcpy(attname, name);
347 *tp = nmem_malloc(data1_nmem_get(dh), sizeof(**tp));
349 if (!((*tp)->att = data1_getattbyname(dh, res->attset,
352 logf(LOG_WARN, "Couldn't find att '%s' in attset",
357 if (r < 2) /* is the structure qualified? */
358 (*tp)->structure = "w";
361 (*tp)->structure = nmem_malloc (data1_nmem_get (dh),
362 strlen(structure)+1);
363 strcpy ((*tp)->structure, structure);
367 while ((p = strchr(p, ',')) && *(++p));
368 *tp = all; /* append any ALL entries to the list */
371 new_element->name = nmem_strdup(data1_nmem_get (dh), name);
373 else if (!strcmp(cmd, "section"))
376 if (sscanf(args, "%511s", name) < 1)
378 logf(LOG_WARN, "Bad # of args to sub in %s: '%s'",
382 cur_elements = nmem_malloc(data1_nmem_get(dh),
383 sizeof(*cur_elements));
384 cur_elements->next = res->sub_elements;
385 cur_elements->elements = NULL;
386 cur_elements->name = nmem_strdup (data1_nmem_get(dh), name);
387 res->sub_elements = cur_elements;
390 ppl[level] = &cur_elements->elements;
392 else if (!strcmp(cmd, "all"))
395 data1_termlist **tp = &all;
399 logf(LOG_WARN, "Too many ALL declarations in %s - ignored",
407 logf(LOG_WARN, "No attset loaded in %s", file);
413 char attname[512], structure[512];
416 if (!(r = sscanf(p, "%511[^:,]:%511[^,]", attname,
419 logf(LOG_WARN, "Syntax error in termlistspec in %s",
424 *tp = nmem_malloc(data1_nmem_get(dh), sizeof(**tp));
425 if (!((*tp)->att = data1_getattbyname (dh, res->attset,
428 logf(LOG_WARN, "Couldn't find att '%s' in attset",
433 if (r < 2) /* is the structure qualified? */
434 (*tp)->structure = "w";
437 (*tp)->structure = nmem_malloc (data1_nmem_get (dh),
438 strlen(structure)+1);
439 strcpy ((*tp)->structure, structure);
444 while ((p = strchr(p, ',')) && *(++p));
446 else if (!strcmp(cmd, "name"))
450 if (!sscanf(args, "%511s", name))
452 logf(LOG_WARN, "Malformed name directive in %s", file);
456 res->name = nmem_strdup(data1_nmem_get(dh), name);
458 else if (!strcmp(cmd, "reference"))
462 if (!sscanf(args, "%s", name))
464 logf(LOG_WARN, "Malformed reference in %s", file);
468 if ((res->reference = oid_getvalbyname(name)) == VAL_NONE)
470 logf(LOG_WARN, "Unknown tagset ref '%s' in %s", name, file);
475 else if (!strcmp(cmd, "attset"))
479 if (!sscanf(args, "%s", name))
481 logf(LOG_WARN, "Malformed attset directive in %s", file);
485 if (!(res->attset = data1_read_attset (dh, name)))
487 logf(LOG_WARN, "Attset failed in %s", file);
492 else if (!strcmp(cmd, "tagset"))
496 if (!sscanf(args, "%s", name))
498 logf(LOG_WARN, "Malformed tagset directive in %s", file);
502 if (!(res->tagset = data1_read_tagset (dh, name)))
504 logf(LOG_WARN, "Tagset failed in %s", file);
509 else if (!strcmp(cmd, "varset"))
513 if (!sscanf(args, "%s", name))
515 logf(LOG_WARN, "Malformed varset directive in %s", file);
519 if (!(res->varset = data1_read_varset (dh, name)))
521 logf(LOG_WARN, "Varset failed in %s", file);
526 else if (!strcmp(cmd, "esetname"))
528 char name[512], fname[512];
530 if (sscanf(args, "%s %s", name, fname) != 2)
532 logf(LOG_WARN, "Two arg's required for esetname in %s",
537 *esetpp = nmem_malloc(data1_nmem_get(dh), sizeof(**esetpp));
538 (*esetpp)->name = nmem_strdup(data1_nmem_get(dh), name);
542 else if (!((*esetpp)->spec = data1_read_espec1 (dh, fname)))
544 logf(LOG_WARN, "%s: Espec-1 read failed", file);
548 esetpp = &(*esetpp)->next;
550 else if (!strcmp(cmd, "maptab"))
554 if (sscanf(args, "%s", name) != 1)
556 logf(LOG_WARN, "One argument for maptab directive in %s",
560 if (!(*maptabp = data1_read_maptab (dh, name)))
562 logf(LOG_WARN, "Failed to read maptab %s in %s",
566 maptabp = &(*maptabp)->next;
568 else if (!strcmp(cmd, "marc"))
572 if (sscanf(args, "%s", name) != 1)
574 logf(LOG_WARN, "One argument for marc directive in %s",
578 if (!(*marcp = data1_read_marctab (dh, name)))
580 logf(LOG_WARN, "%Failed to read marctab %s in %s",
584 marcp = &(*marcp)->next;
588 logf(LOG_WARN, "Unknown directive '%s' in %s", cmd, file);
595 cur_elements = res->sub_elements;
596 while (cur_elements && strcmp (cur_elements->name, "main"))
597 cur_elements = cur_elements->next;
599 res->main_elements = cur_elements->elements;
601 logf (LOG_DEBUG, "end data1_read_absyn file=%s", file);