IDZEBRA  2.1.2
d1_tagset.c
Go to the documentation of this file.
1 /* This file is part of the Zebra server.
2  Copyright (C) Index Data
3 
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8 
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 
18 */
19 
20 #if HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include <yaz/log.h>
28 #include <idzebra/data1.h>
29 #include <yaz/oid_db.h>
30 
31 /*
32  * We'll probably want to add some sort of hashed index to these lookup-
33  * functions eventually.
34  */
35 
37 {
38  static struct
39  {
40  char *tname;
41  data1_datatype type;
42  } types[] =
43  {
44  {"structured", DATA1K_structured},
45  {"string", DATA1K_string},
46  {"numeric", DATA1K_numeric},
47  {"oid", DATA1K_oid},
48  {"bool", DATA1K_bool},
49  {"generalizedtime", DATA1K_generalizedtime},
50  {"intunit", DATA1K_intunit},
51  {"int", DATA1K_int},
52  {"octetstring", DATA1K_octetstring},
53  {"null", DATA1K_null},
54  {NULL, (data1_datatype) -1}
55  };
56  int i;
57 
58  for (i = 0; types[i].tname; i++)
59  if (!data1_matchstr(types[i].tname, t))
60  return types[i].type;
61  return DATA1K_unknown;
62 }
63 
65  int type, int value)
66 {
67  data1_tag *r;
68 
69  for (; s; s = s->next)
70  {
71  /* scan local set */
72  if (type == s->type)
73  for (r = s->tags; r; r = r->next)
74  if (r->which == DATA1T_numeric && r->value.numeric == value)
75  return r;
76  /* scan included sets */
77  if (s->children &&
78  (r = data1_gettagbynum (dh, s->children, type, value)))
79  return r;
80  }
81  return 0;
82 }
83 
85  const char *name)
86 {
87  data1_tag *r;
88 
89  for (; s; s = s->next)
90  {
91  /* scan local set */
92  for (r = s->tags; r; r = r->next)
93  {
94  data1_name *np;
95 
96  for (np = r->names; np; np = np->next)
97  if (!data1_matchstr(np->name, name))
98  return r;
99  }
100  /* scan included sets */
101  if (s->children && (r = data1_gettagbyname (dh, s->children, name)))
102  return r;
103  }
104  return 0;
105 }
106 
108 {
109  data1_tagset *res =
110  (data1_tagset *) nmem_malloc(data1_nmem_get (dh), sizeof(*res));
111  res->name = 0;
112  res->oid = 0;
113  res->tags = 0;
114  res->type = 0;
115  res->children = 0;
116  res->next = 0;
117  return res;
118 }
119 
120 data1_tagset *data1_read_tagset (data1_handle dh, const char *file, int type)
121 {
122  NMEM mem = data1_nmem_get (dh);
123  data1_tagset *res = 0;
124  data1_tagset **childp;
125  data1_tag **tagp;
126  FILE *f;
127  int lineno = 0;
128  int argc;
129  char *argv[50], line[512];
130 
131  if (!(f = data1_path_fopen(dh, file, "r")))
132  {
133  yaz_log(YLOG_WARN|YLOG_ERRNO, "%s", file);
134  return 0;
135  }
136  res = data1_empty_tagset (dh);
137  res->type = type;
138  childp = &res->children;
139  tagp = &res->tags;
140 
141  while ((argc = readconf_line(f, &lineno, line, 512, argv, 50)))
142  {
143  char *cmd = *argv;
144  if (!strcmp(cmd, "tag"))
145  {
146  int value;
147  char *names, *type, *nm;
148  data1_tag *rr;
149  data1_name **npp;
150 
151  if (argc != 4)
152  {
153  yaz_log(YLOG_WARN, "%s:%d: Bad # args to tag", file, lineno);
154  continue;
155  }
156  value = atoi(argv[1]);
157  names = argv[2];
158  type = argv[3];
159 
160  rr = *tagp = (data1_tag *)nmem_malloc(mem, sizeof(*rr));
161  rr->tagset = res;
162  rr->next = 0;
163  rr->which = DATA1T_numeric;
164  rr->value.numeric = value;
165  /*
166  * how to deal with local numeric tags?
167  */
168 
169  if (!(rr->kind = data1_maptype(dh, type)))
170  {
171  yaz_log(YLOG_WARN, "%s:%d: Unknown datatype %s",
172  file, lineno, type);
173  fclose(f);
174  return 0;
175  }
176 
177  /* read namelist */
178  nm = names;
179  npp = &rr->names;
180  do
181  {
182  char *e;
183 
184  *npp = (data1_name *)nmem_malloc(mem, sizeof(**npp));
185  if ((e = strchr(nm, '/')))
186  *(e++) = '\0';
187  (*npp)->name = nmem_strdup(mem, nm);
188  (*npp)->next = 0;
189  npp = &(*npp)->next;
190  nm = e;
191  }
192  while (nm);
193  tagp = &rr->next;
194  }
195  else if (!strcmp(cmd, "name"))
196  {
197  if (argc != 2)
198  {
199  yaz_log(YLOG_WARN, "%s:%d: Bad # args to name", file, lineno);
200  continue;
201  }
202  res->name = nmem_strdup(mem, argv[1]);
203  }
204  else if (!strcmp(cmd, "reference"))
205  {
206  char *name;
207 
208  if (argc != 2)
209  {
210  yaz_log(YLOG_WARN, "%s:%d: Bad # args to reference",
211  file, lineno);
212  continue;
213  }
214  name = argv[1];
215  res->oid = yaz_string_to_oid_nmem(yaz_oid_std(),
216  CLASS_TAGSET, name, mem);
217  if (!res->oid)
218  {
219  yaz_log(YLOG_WARN, "%s:%d: Unknown tagset ref '%s'",
220  file, lineno, name);
221  continue;
222  }
223  }
224  else if (!strcmp(cmd, "type"))
225  {
226  if (argc != 2)
227  {
228  yaz_log (YLOG_WARN, "%s:%d: Bad # args to type", file, lineno);
229  continue;
230  }
231  if (!res->type)
232  res->type = atoi(argv[1]);
233  }
234  else if (!strcmp(cmd, "include"))
235  {
236  char *name;
237  int type = 0;
238 
239  if (argc < 2)
240  {
241  yaz_log(YLOG_WARN, "%s:%d: Bad # args to include",
242  file, lineno);
243  continue;
244  }
245  name = argv[1];
246  if (argc == 3)
247  type = atoi(argv[2]);
248  *childp = data1_read_tagset (dh, name, type);
249  if (!(*childp))
250  {
251  yaz_log(YLOG_WARN, "%s:%d: Inclusion failed for tagset %s",
252  file, lineno, name);
253  continue;
254  }
255  childp = &(*childp)->next;
256  }
257  else
258  {
259  yaz_log(YLOG_WARN, "%s:%d: Unknown directive '%s'",
260  file, lineno, cmd);
261  }
262  }
263  fclose(f);
264  return res;
265 }
266 /*
267  * Local variables:
268  * c-basic-offset: 4
269  * c-file-style: "Stroustrup"
270  * indent-tabs-mode: nil
271  * End:
272  * vim: shiftwidth=4 tabstop=8 expandtab
273  */
274 
data1_datatype kind
Definition: data1.h:212
Odr_oid * oid
Definition: data1.h:224
data1_name * names
Definition: data1.h:203
data1_tag * tags
Definition: data1.h:225
#define data1_matchstr(s1, s2)
Definition: data1.h:36
char * name
Definition: data1.h:114
data1_datatype data1_maptype(data1_handle dh, char *t)
Definition: d1_tagset.c:36
FILE * data1_path_fopen(data1_handle dh, const char *file, const char *mode)
Definition: d1_handle.c:151
data1_tagset * data1_empty_tagset(data1_handle dh)
Definition: d1_tagset.c:107
int numeric
Definition: data1.h:209
struct data1_tagset * tagset
Definition: data1.h:214
data1_tag * data1_gettagbynum(data1_handle dh, data1_tagset *s, int type, int value)
Definition: d1_tagset.c:64
data1_datatype
Definition: data1.h:122
data1_tagset * next
Definition: data1.h:227
data1_tag * data1_gettagbyname(data1_handle dh, data1_tagset *s, const char *name)
Definition: d1_tagset.c:84
int which
Definition: data1.h:206
union data1_tag::@1 value
int type
Definition: data1.h:222
#define DATA1T_numeric
Definition: data1.h:204
data1_tagset * data1_read_tagset(data1_handle dh, const char *file, int type)
Definition: d1_tagset.c:120
char * name
Definition: data1.h:223
NMEM data1_nmem_get(data1_handle dh)
Definition: d1_handle.c:66
struct data1_name * next
Definition: data1.h:115
struct data1_tag * next
Definition: data1.h:215
data1_tagset * children
Definition: data1.h:226