1 | /*
|
---|
2 | * Copyright (c) 1995-1999, Index Data.
|
---|
3 | * See the file LICENSE for details.
|
---|
4 | * Sebastian Hammer, Adam Dickmeiss
|
---|
5 | *
|
---|
6 | * $Log$
|
---|
7 | * Revision 1.1 2000/08/03 03:11:29 johnmcp
|
---|
8 | * Added the YAZ toolkit source to the packages directory (for z39.50 stuff)
|
---|
9 | *
|
---|
10 | * Revision 1.18 1999/11/30 13:47:12 adam
|
---|
11 | * Improved installation. Moved header files to include/yaz.
|
---|
12 | *
|
---|
13 | * Revision 1.17 1999/10/21 12:06:29 adam
|
---|
14 | * Retrieval module no longer uses ctype.h - functions.
|
---|
15 | *
|
---|
16 | * Revision 1.16 1999/08/27 09:40:32 adam
|
---|
17 | * Renamed logf function to yaz_log. Removed VC++ project files.
|
---|
18 | *
|
---|
19 | * Revision 1.15 1998/10/13 16:09:49 adam
|
---|
20 | * Added support for arbitrary OID's for tagsets, schemas and attribute sets.
|
---|
21 | * Added support for multiple attribute set references and tagset references
|
---|
22 | * from an abstract syntax file.
|
---|
23 | * Fixed many bad logs-calls in routines that read the various
|
---|
24 | * specifications regarding data1 (*.abs,*.att,...) and made the messages
|
---|
25 | * consistent whenever possible.
|
---|
26 | * Added extra 'lineno' argument to function readconf_line.
|
---|
27 | *
|
---|
28 | * Revision 1.14 1998/02/11 11:53:35 adam
|
---|
29 | * Changed code so that it compiles as C++.
|
---|
30 | *
|
---|
31 | * Revision 1.13 1997/11/24 11:33:56 adam
|
---|
32 | * Using function odr_nullval() instead of global ODR_NULLVAL when
|
---|
33 | * appropriate.
|
---|
34 | *
|
---|
35 | * Revision 1.12 1997/10/31 12:20:09 adam
|
---|
36 | * Improved memory debugging for xmalloc/nmem.c. References to NMEM
|
---|
37 | * instead of ODR in n ESPEC-1 handling in source d1_espec.c.
|
---|
38 | * Bug fix: missing fclose in data1_read_espec1.
|
---|
39 | *
|
---|
40 | * Revision 1.11 1997/09/29 13:18:59 adam
|
---|
41 | * Added function, oid_ent_to_oid, to replace the function
|
---|
42 | * oid_getoidbyent, which is not thread safe.
|
---|
43 | *
|
---|
44 | * Revision 1.10 1997/09/29 07:21:10 adam
|
---|
45 | * Added typecast to avoid warnings on MSVC.
|
---|
46 | *
|
---|
47 | * Revision 1.9 1997/09/17 12:10:35 adam
|
---|
48 | * YAZ version 1.4.
|
---|
49 | *
|
---|
50 | * Revision 1.8 1997/09/05 09:50:56 adam
|
---|
51 | * Removed global data1_tabpath - uses data1_get_tabpath() instead.
|
---|
52 | *
|
---|
53 | * Revision 1.7 1997/05/14 06:54:02 adam
|
---|
54 | * C++ support.
|
---|
55 | *
|
---|
56 | * Revision 1.6 1996/07/06 19:58:34 quinn
|
---|
57 | * System headerfiles gathered in yconfig
|
---|
58 | *
|
---|
59 | * Revision 1.5 1996/01/02 08:57:44 quinn
|
---|
60 | * Changed enums in the ASN.1 .h files to #defines. Changed oident.class to oclass
|
---|
61 | *
|
---|
62 | * Revision 1.4 1995/12/05 11:16:10 quinn
|
---|
63 | * Fixed malloc of 0.
|
---|
64 | *
|
---|
65 | * Revision 1.3 1995/11/13 09:27:34 quinn
|
---|
66 | * Fiddling with the variant stuff.
|
---|
67 | *
|
---|
68 | * Revision 1.2 1995/11/01 16:34:56 quinn
|
---|
69 | * Making data1 look for tables in data1_tabpath
|
---|
70 | *
|
---|
71 | * Revision 1.1 1995/11/01 11:56:07 quinn
|
---|
72 | * Added Retrieval (data management) functions en masse.
|
---|
73 | *
|
---|
74 | *
|
---|
75 | */
|
---|
76 |
|
---|
77 |
|
---|
78 | #include <stdlib.h>
|
---|
79 | #include <assert.h>
|
---|
80 | #include <string.h>
|
---|
81 |
|
---|
82 | #include <yaz/odr.h>
|
---|
83 | #include <yaz/proto.h>
|
---|
84 | #include <yaz/log.h>
|
---|
85 | #include <yaz/data1.h>
|
---|
86 |
|
---|
87 | static Z_Variant *read_variant(int argc, char **argv, NMEM nmem,
|
---|
88 | const char *file, int lineno)
|
---|
89 | {
|
---|
90 | Z_Variant *r = (Z_Variant *)nmem_malloc(nmem, sizeof(*r));
|
---|
91 | oident var1;
|
---|
92 | int i;
|
---|
93 | int oid[OID_SIZE];
|
---|
94 |
|
---|
95 | var1.proto = PROTO_Z3950;
|
---|
96 | var1.oclass = CLASS_VARSET;
|
---|
97 | var1.value = VAL_VAR1;
|
---|
98 | r->globalVariantSetId = odr_oiddup_nmem(nmem, oid_ent_to_oid(&var1, oid));
|
---|
99 |
|
---|
100 | if (argc)
|
---|
101 | r->triples = (Z_Triple **)nmem_malloc(nmem, sizeof(Z_Triple*) * argc);
|
---|
102 | else
|
---|
103 | r->triples = 0;
|
---|
104 | r->num_triples = argc;
|
---|
105 | for (i = 0; i < argc; i++)
|
---|
106 | {
|
---|
107 | int zclass, type;
|
---|
108 | char value[512];
|
---|
109 | Z_Triple *t;
|
---|
110 |
|
---|
111 | if (sscanf(argv[i], "(%d,%d,%[^)])", &zclass, &type, value) < 3)
|
---|
112 | {
|
---|
113 | yaz_log(LOG_WARN, "%s:%d: Syntax error in variant component '%s'",
|
---|
114 | file, lineno, argv[i]);
|
---|
115 | return 0;
|
---|
116 | }
|
---|
117 | t = r->triples[i] = (Z_Triple *)nmem_malloc(nmem, sizeof(Z_Triple));
|
---|
118 | t->variantSetId = 0;
|
---|
119 | t->zclass = (int *)nmem_malloc(nmem, sizeof(int));
|
---|
120 | *t->zclass = zclass;
|
---|
121 | t->type = (int *)nmem_malloc(nmem, sizeof(int));
|
---|
122 | *t->type = type;
|
---|
123 | /*
|
---|
124 | * This is wrong.. we gotta look up the correct type for the
|
---|
125 | * variant, I guess... damn this stuff.
|
---|
126 | */
|
---|
127 | if (*value == '@')
|
---|
128 | {
|
---|
129 | t->which = Z_Triple_null;
|
---|
130 | t->value.null = odr_nullval();
|
---|
131 | }
|
---|
132 | else if (d1_isdigit(*value))
|
---|
133 | {
|
---|
134 | t->which = Z_Triple_integer;
|
---|
135 | t->value.integer = (int *)
|
---|
136 | nmem_malloc(nmem, sizeof(*t->value.integer));
|
---|
137 | *t->value.integer = atoi(value);
|
---|
138 | }
|
---|
139 | else
|
---|
140 | {
|
---|
141 | t->which = Z_Triple_internationalString;
|
---|
142 | t->value.internationalString = (char *)
|
---|
143 | nmem_malloc(nmem, strlen(value)+1);
|
---|
144 | strcpy(t->value.internationalString, value);
|
---|
145 | }
|
---|
146 | }
|
---|
147 | return r;
|
---|
148 | }
|
---|
149 |
|
---|
150 | static Z_Occurrences *read_occurrences(char *occ, NMEM nmem,
|
---|
151 | const char *file, int lineno)
|
---|
152 | {
|
---|
153 | Z_Occurrences *op = (Z_Occurrences *)nmem_malloc(nmem, sizeof(*op));
|
---|
154 | char *p;
|
---|
155 |
|
---|
156 | if (!occ)
|
---|
157 | {
|
---|
158 | op->which = Z_Occurrences_values;
|
---|
159 | op->u.values = (Z_OccurValues *)
|
---|
160 | nmem_malloc(nmem, sizeof(Z_OccurValues));
|
---|
161 | op->u.values->start = (int *)nmem_malloc(nmem, sizeof(int));
|
---|
162 | *op->u.values->start = 1;
|
---|
163 | op->u.values->howMany = 0;
|
---|
164 | }
|
---|
165 | else if (!strcmp(occ, "all"))
|
---|
166 | {
|
---|
167 | op->which = Z_Occurrences_all;
|
---|
168 | op->u.all = odr_nullval();
|
---|
169 | }
|
---|
170 | else if (!strcmp(occ, "last"))
|
---|
171 | {
|
---|
172 | op->which = Z_Occurrences_last;
|
---|
173 | op->u.all = odr_nullval();
|
---|
174 | }
|
---|
175 | else
|
---|
176 | {
|
---|
177 | Z_OccurValues *ov = (Z_OccurValues *)nmem_malloc(nmem, sizeof(*ov));
|
---|
178 |
|
---|
179 | if (!d1_isdigit(*occ))
|
---|
180 | {
|
---|
181 | yaz_log(LOG_WARN, "%s:%d: Bad occurrences-spec %s",
|
---|
182 | file, lineno, occ);
|
---|
183 | return 0;
|
---|
184 | }
|
---|
185 | op->which = Z_Occurrences_values;
|
---|
186 | op->u.values = ov;
|
---|
187 | ov->start = (int *)nmem_malloc(nmem, sizeof(*ov->start));
|
---|
188 | *ov->start = atoi(occ);
|
---|
189 | if ((p = strchr(occ, '+')))
|
---|
190 | {
|
---|
191 | ov->howMany = (int *)nmem_malloc(nmem, sizeof(*ov->howMany));
|
---|
192 | *ov->howMany = atoi(p + 1);
|
---|
193 | }
|
---|
194 | else
|
---|
195 | ov->howMany = 0;
|
---|
196 | }
|
---|
197 | return op;
|
---|
198 | }
|
---|
199 |
|
---|
200 |
|
---|
201 | static Z_ETagUnit *read_tagunit(char *buf, NMEM nmem,
|
---|
202 | const char *file, int lineno)
|
---|
203 | {
|
---|
204 | Z_ETagUnit *u = (Z_ETagUnit *)nmem_malloc(nmem, sizeof(*u));
|
---|
205 | int terms;
|
---|
206 | int type;
|
---|
207 | char value[512], occ[512];
|
---|
208 |
|
---|
209 | if (*buf == '*')
|
---|
210 | {
|
---|
211 | u->which = Z_ETagUnit_wildPath;
|
---|
212 | u->u.wildPath = odr_nullval();
|
---|
213 | }
|
---|
214 | else if (*buf == '?')
|
---|
215 | {
|
---|
216 | u->which = Z_ETagUnit_wildThing;
|
---|
217 | if (buf[1] == ':')
|
---|
218 | u->u.wildThing = read_occurrences(buf+2, nmem, file, lineno);
|
---|
219 | else
|
---|
220 | u->u.wildThing = read_occurrences(0, nmem, file, lineno);
|
---|
221 | }
|
---|
222 | else if ((terms = sscanf(buf, "(%d,%[^)]):%[a-z0-9+]", &type, value,
|
---|
223 | occ)) >= 2)
|
---|
224 | {
|
---|
225 | int numval;
|
---|
226 | Z_SpecificTag *t;
|
---|
227 | char *valp = value;
|
---|
228 | int force_string = 0;
|
---|
229 |
|
---|
230 | if (*valp == '\'')
|
---|
231 | {
|
---|
232 | valp++;
|
---|
233 | force_string = 1;
|
---|
234 | }
|
---|
235 | u->which = Z_ETagUnit_specificTag;
|
---|
236 | u->u.specificTag = t = (Z_SpecificTag *)nmem_malloc(nmem, sizeof(*t));
|
---|
237 | t->tagType = (int *)nmem_malloc(nmem, sizeof(*t->tagType));
|
---|
238 | *t->tagType = type;
|
---|
239 | t->tagValue = (Z_StringOrNumeric *)
|
---|
240 | nmem_malloc(nmem, sizeof(*t->tagValue));
|
---|
241 | if (!force_string && (numval = atoi(valp)))
|
---|
242 | {
|
---|
243 | t->tagValue->which = Z_StringOrNumeric_numeric;
|
---|
244 | t->tagValue->u.numeric = (int *)nmem_malloc(nmem, sizeof(int));
|
---|
245 | *t->tagValue->u.numeric = numval;
|
---|
246 | }
|
---|
247 | else
|
---|
248 | {
|
---|
249 | t->tagValue->which = Z_StringOrNumeric_string;
|
---|
250 | t->tagValue->u.string = (char *)nmem_malloc(nmem, strlen(valp)+1);
|
---|
251 | strcpy(t->tagValue->u.string, valp);
|
---|
252 | }
|
---|
253 | if (terms > 2) /* an occurrences-spec exists */
|
---|
254 | t->occurrences = read_occurrences(occ, nmem, file, lineno);
|
---|
255 | else
|
---|
256 | t->occurrences = 0;
|
---|
257 | }
|
---|
258 | return u;
|
---|
259 | }
|
---|
260 |
|
---|
261 | /*
|
---|
262 | * Read an element-set specification from a file.
|
---|
263 | * NOTE: If !o, memory is allocated directly from the heap by nmem_malloc().
|
---|
264 | */
|
---|
265 | Z_Espec1 *data1_read_espec1 (data1_handle dh, const char *file)
|
---|
266 | {
|
---|
267 | FILE *f;
|
---|
268 | NMEM nmem = data1_nmem_get (dh);
|
---|
269 | int lineno = 0;
|
---|
270 | int argc, size_esn = 0;
|
---|
271 | char *argv[50], line[512];
|
---|
272 | Z_Espec1 *res = (Z_Espec1 *)nmem_malloc(nmem, sizeof(*res));
|
---|
273 |
|
---|
274 | if (!(f = yaz_path_fopen(data1_get_tabpath(dh), file, "r")))
|
---|
275 | {
|
---|
276 | yaz_log(LOG_WARN|LOG_ERRNO, "%s", file);
|
---|
277 | return 0;
|
---|
278 | }
|
---|
279 |
|
---|
280 | res->num_elementSetNames = 0;
|
---|
281 | res->elementSetNames = 0;
|
---|
282 | res->defaultVariantSetId = 0;
|
---|
283 | res->defaultVariantRequest = 0;
|
---|
284 | res->defaultTagType = 0;
|
---|
285 | res->num_elements = 0;
|
---|
286 | res->elements = 0;
|
---|
287 |
|
---|
288 | while ((argc = readconf_line(f, &lineno, line, 512, argv, 50)))
|
---|
289 | if (!strcmp(argv[0], "elementsetnames"))
|
---|
290 | {
|
---|
291 | int nnames = argc-1, i;
|
---|
292 |
|
---|
293 | if (!nnames)
|
---|
294 | {
|
---|
295 | yaz_log(LOG_WARN, "%s:%d: Empty elementsetnames directive",
|
---|
296 | file, lineno);
|
---|
297 | continue;
|
---|
298 | }
|
---|
299 |
|
---|
300 | res->elementSetNames =
|
---|
301 | (char **)nmem_malloc(nmem, sizeof(char**)*nnames);
|
---|
302 | for (i = 0; i < nnames; i++)
|
---|
303 | {
|
---|
304 | res->elementSetNames[i] = (char *)
|
---|
305 | nmem_malloc(nmem, strlen(argv[i+1])+1);
|
---|
306 | strcpy(res->elementSetNames[i], argv[i+1]);
|
---|
307 | }
|
---|
308 | res->num_elementSetNames = nnames;
|
---|
309 | }
|
---|
310 | else if (!strcmp(argv[0], "defaultvariantsetid"))
|
---|
311 | {
|
---|
312 | if (argc != 2)
|
---|
313 | {
|
---|
314 | yaz_log(LOG_WARN, "%s:%d: Bad # of args for %s",
|
---|
315 | file, lineno, argv[0]);
|
---|
316 | continue;
|
---|
317 | }
|
---|
318 | if (!(res->defaultVariantSetId =
|
---|
319 | odr_getoidbystr_nmem(nmem, argv[1])))
|
---|
320 | {
|
---|
321 | yaz_log(LOG_WARN, "%s:%d: Bad defaultvariantsetid",
|
---|
322 | file, lineno);
|
---|
323 | continue;
|
---|
324 | }
|
---|
325 | }
|
---|
326 | else if (!strcmp(argv[0], "defaulttagtype"))
|
---|
327 | {
|
---|
328 | if (argc != 2)
|
---|
329 | {
|
---|
330 | yaz_log(LOG_WARN, "%s:%d: Bad # of args for %s",
|
---|
331 | file, lineno, argv[0]);
|
---|
332 | continue;
|
---|
333 | }
|
---|
334 | res->defaultTagType = (int *)nmem_malloc(nmem, sizeof(int));
|
---|
335 | *res->defaultTagType = atoi(argv[1]);
|
---|
336 | }
|
---|
337 | else if (!strcmp(argv[0], "defaultvariantrequest"))
|
---|
338 | {
|
---|
339 | if (!(res->defaultVariantRequest =
|
---|
340 | read_variant(argc-1, argv+1, nmem, file, lineno)))
|
---|
341 | {
|
---|
342 | yaz_log(LOG_WARN, "%s:%d: Bad defaultvariantrequest",
|
---|
343 | file, lineno);
|
---|
344 | continue;
|
---|
345 | }
|
---|
346 | }
|
---|
347 | else if (!strcmp(argv[0], "simpleelement"))
|
---|
348 | {
|
---|
349 | Z_ElementRequest *er;
|
---|
350 | Z_SimpleElement *se;
|
---|
351 | Z_ETagPath *tp;
|
---|
352 | char *path = argv[1];
|
---|
353 | char *ep;
|
---|
354 | int num, i = 0;
|
---|
355 |
|
---|
356 | if (!res->elements)
|
---|
357 | res->elements = (Z_ElementRequest **)
|
---|
358 | nmem_malloc(nmem, size_esn = 24*sizeof(er));
|
---|
359 | else if (res->num_elements >= (int) (size_esn/sizeof(er)))
|
---|
360 | {
|
---|
361 | Z_ElementRequest **oe = res->elements;
|
---|
362 | size_esn *= 2;
|
---|
363 | res->elements = (Z_ElementRequest **)
|
---|
364 | nmem_malloc (nmem, size_esn*sizeof(er));
|
---|
365 | memcpy (res->elements, oe, size_esn/2);
|
---|
366 | }
|
---|
367 | if (argc < 2)
|
---|
368 | {
|
---|
369 | yaz_log(LOG_WARN, "%s:%d: Bad # of args for %s",
|
---|
370 | file, lineno, argv[0]);
|
---|
371 | continue;
|
---|
372 | }
|
---|
373 |
|
---|
374 | res->elements[res->num_elements++] = er =
|
---|
375 | (Z_ElementRequest *)nmem_malloc(nmem, sizeof(*er));
|
---|
376 | er->which = Z_ERequest_simpleElement;
|
---|
377 | er->u.simpleElement = se = (Z_SimpleElement *)
|
---|
378 | nmem_malloc(nmem, sizeof(*se));
|
---|
379 | se->variantRequest = 0;
|
---|
380 | se->path = tp = (Z_ETagPath *)nmem_malloc(nmem, sizeof(*tp));
|
---|
381 | tp->num_tags = 0;
|
---|
382 | /*
|
---|
383 | * Parse the element selector.
|
---|
384 | */
|
---|
385 | for (num = 1, ep = path; (ep = strchr(ep, '/')); num++, ep++)
|
---|
386 | ;
|
---|
387 | tp->tags = (Z_ETagUnit **)
|
---|
388 | nmem_malloc(nmem, sizeof(Z_ETagUnit*)*num);
|
---|
389 |
|
---|
390 | for ((ep = strchr(path, '/')) ; path ;
|
---|
391 | (void)((path = ep) && (ep = strchr(path, '/'))))
|
---|
392 | {
|
---|
393 | if (ep)
|
---|
394 | ep++;
|
---|
395 |
|
---|
396 | assert(i<num);
|
---|
397 | tp->tags[tp->num_tags++] =
|
---|
398 | read_tagunit(path, nmem, file, lineno);
|
---|
399 | }
|
---|
400 |
|
---|
401 | if (argc > 2 && !strcmp(argv[2], "variant"))
|
---|
402 | se->variantRequest=
|
---|
403 | read_variant(argc-3, argv+3, nmem, file, lineno);
|
---|
404 | }
|
---|
405 | else
|
---|
406 | yaz_log(LOG_WARN, "%s:%d: Unknown directive '%s'",
|
---|
407 | file, lineno, argv[0]);
|
---|
408 | fclose (f);
|
---|
409 | return res;
|
---|
410 | }
|
---|