Added Retrieval (data management) functions en masse.
[yaz-moved-to-github.git] / retrieval / d1_espec.c
1 /*
2  * Copyright (c) 1995, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: d1_espec.c,v $
7  * Revision 1.1  1995-11-01 11:56:07  quinn
8  * Added Retrieval (data management) functions en masse.
9  *
10  *
11  */
12
13
14 #include <stdlib.h>
15 #include <assert.h>
16 #include <string.h>
17 #include <ctype.h>
18 #include <xmalloc.h>
19 #include <odr.h>
20 #include <proto.h>
21 #include <log.h>
22 #include <readconf.h>
23
24 /*
25  * Read an element-set specification from a file. If !o, use xmalloc for
26  * memory allocation.
27  */
28 Z_Espec1 *data1_read_espec1(char *file, ODR o)
29 {
30     FILE *f;
31     int argc, size_esn = 0;
32     char *argv[50], line[512];
33     Z_Espec1 *res = odr_malloc(o, sizeof(*res));
34
35     if (!(f = fopen(file, "r")))
36     {
37         logf(LOG_WARN|LOG_ERRNO, "%s", file);
38         return 0;
39     }
40
41     res->num_elementSetNames = 0;
42     res->elementSetNames = 0;
43     res->defaultVariantSetId = 0;
44     res->defaultVariantRequest = 0;
45     res->defaultTagType = 0;
46     res->num_elements = 0;
47     res->elements = 0;
48
49     while ((argc = readconf_line(f, line, 512, argv, 50)))
50         if (!strcmp(argv[0], "elementsetnames"))
51         {
52             int nnames = argc-1, i;
53
54             if (!nnames)
55             {
56                 logf(LOG_WARN, "%s: Empty elementsetnames directive",
57                     file);
58                 continue;
59             }
60
61             res->elementSetNames = odr_malloc(o, sizeof(char*)*nnames);
62             for (i = 0; i < nnames; i++)
63             {
64                 res->elementSetNames[i] = odr_malloc(o, strlen(argv[i+1])+1);
65                 strcpy(res->elementSetNames[i], argv[i+1]);
66             }
67             res->num_elementSetNames = nnames;
68         }
69         else if (!strcmp(argv[0], "defaultvariantsetid"))
70         {
71             if (argc != 2 || !(res->defaultVariantSetId =
72                 odr_getoidbystr(o, argv[1])))
73             {
74                 logf(LOG_WARN, "%s: Bad defaultvariantsetid directive", file);
75                 continue;
76             }
77         }
78         else if (!strcmp(argv[0], "defaulttagtype"))
79         {
80             if (argc != 2)
81             {
82                 logf(LOG_WARN, "%s: Bad defaulttagtype directive", file);
83                 continue;
84             }
85             res->defaultTagType = odr_malloc(o, sizeof(int));
86             *res->defaultTagType = atoi(argv[1]);
87         }
88         else if (!strcmp(argv[0], "defaultvariantrequest"))
89         {
90             abort();
91         }
92         else if (!strcmp(argv[0], "simpleelement"))
93         {
94             Z_ElementRequest *er;
95             Z_SimpleElement *se;
96             Z_ETagPath *tp;
97             char *path = argv[1];
98             char *ep;
99             int num, i = 0;
100
101             if (!res->elements)
102                 res->elements = odr_malloc(o, size_esn = 24*sizeof(*er));
103             else if (res->num_elements >= size_esn)
104             {
105                 size_esn *= 2;
106                 res->elements = o ? odr_malloc(o, size_esn) :
107                     xrealloc(res->elements, size_esn);
108             }
109             if (argc < 2)
110             {
111                 logf(LOG_WARN, "%s: Empty simpleelement directive", file);
112                 continue;
113             }
114             res->elements[res->num_elements++] = er =
115                 odr_malloc(o, sizeof(*er));
116             er->which = Z_ERequest_simpleElement;
117             er->u.simpleElement = se = odr_malloc(o, sizeof(*se));
118             se->variantRequest = 0;
119             se->path = tp = odr_malloc(o, sizeof(*tp));
120             tp->num_tags = 0;
121             for (num = 1, ep = path; (ep = strchr(ep, '/')); num++, ep++);
122             tp->tags = odr_malloc(o, sizeof(Z_ETagUnit*)*num);
123
124             for ((ep = strchr(path, '/')) ; path ; (void)((path = ep) &&
125                 (ep = strchr(path, '/'))))
126             {
127                 int type;
128                 char value[512];
129                 Z_ETagUnit *u;
130
131                 if (ep)
132                     ep++;
133
134                 assert(i<num);
135                 tp->tags[tp->num_tags++] = u = odr_malloc(o, sizeof(*u));
136                 if (sscanf(path, "(%d,%[^)])", &type, value) == 2)
137                 {
138                     int numval;
139                     Z_SpecificTag *t;
140                     char *valp = value;
141                     int force_string = 0;
142
143                     if (*valp == '\'')
144                     {
145                         valp++;
146                         force_string = 1;
147                     }
148                     u->which = Z_ETagUnit_specificTag;
149                     u->u.specificTag = t = odr_malloc(o, sizeof(*t));
150                     t->tagType = odr_malloc(o, sizeof(*t->tagType));
151                     *t->tagType = type;
152                     t->tagValue = odr_malloc(o, sizeof(*t->tagValue));
153                     if (!force_string && (numval = atoi(valp)))
154                     {
155                         t->tagValue->which = Z_StringOrNumeric_numeric;
156                         t->tagValue->u.numeric = odr_malloc(o, sizeof(int));
157                         *t->tagValue->u.numeric = numval;
158                     }
159                     else
160                     {
161                         t->tagValue->which = Z_StringOrNumeric_string;
162                         t->tagValue->u.string = odr_malloc(o, strlen(valp)+1);
163                         strcpy(t->tagValue->u.string, valp);
164                     }
165                     t->occurrences = 0; /* for later */
166                 }
167             }
168         }
169         else
170         {
171             logf(LOG_WARN, "%s: Unknown directive %s", file, argv[0]);
172             fclose(f);
173             return 0;
174         }
175
176     return res;
177 }