YAZ  5.34.0
cclqfile.c
Go to the documentation of this file.
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
9 #if HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 
17 #include <yaz/tokenizer.h>
18 #include <yaz/ccl.h>
19 #include <yaz/log.h>
20 
21 #define MAX_QUAL 128
22 
23 int ccl_qual_field2(CCL_bibset bibset, const char *cp, const char *qual_name,
24  const char **addinfo)
25 {
27 
28  int type_ar[MAX_QUAL];
29  int value_ar[MAX_QUAL];
30  char *svalue_ar[MAX_QUAL];
31  char *attsets[MAX_QUAL];
32  int pair_no = 0;
33  char *type_str = 0;
34  int t;
35  yaz_tok_parse_t tp;
36 
37  yaz_tok_cfg_single_tokens(yt, ",=");
38 
39  tp = yaz_tok_parse_buf(yt, cp);
40 
42  *addinfo = 0;
43 
44  t = yaz_tok_move(tp);
45  while (t == YAZ_TOK_STRING)
46  {
47  /* we don't know what lead is yet */
48  char *lead_str = xstrdup(yaz_tok_parse_string(tp));
49  const char *value_str = 0;
50  int type = 0, value = 0; /* indicates attribute value UNSET */
51 
52  t = yaz_tok_move(tp);
53  if (t == ',')
54  {
55  /* full attribute spec: set, type = value */
56  /* lead is attribute set */
57  attsets[pair_no] = lead_str;
58  t = yaz_tok_move(tp);
59  if (t != YAZ_TOK_STRING)
60  {
61  *addinfo = "token expected";
62  goto out;
63  }
64  xfree(type_str);
65  type_str = xstrdup(yaz_tok_parse_string(tp));
66  if (yaz_tok_move(tp) != '=')
67  {
68  *addinfo = "= expected";
69  goto out;
70  }
71  }
72  else if (t == '=')
73  {
74  /* lead is attribute type */
75  /* attribute set omitted: type = value */
76  attsets[pair_no] = 0;
77  xfree(type_str);
78  type_str = lead_str;
79  }
80  else
81  {
82  /* lead is first of a list of qualifier aliaeses */
83  /* qualifier alias: q1 q2 ... */
84  char *qlist[10];
85  size_t i = 0;
86 
87  qlist[i++] = lead_str;
88 
89  while (t == YAZ_TOK_STRING)
90  {
91  if (i < sizeof(qlist)/sizeof(*qlist)-1)
92  qlist[i++] = xstrdup(yaz_tok_parse_string(tp));
93  t = yaz_tok_move(tp);
94  }
95  qlist[i] = 0;
97  ccl_qual_add_combi (bibset, qual_name, (const char **) qlist);
98  for (i = 0; qlist[i]; i++)
99  xfree(qlist[i]);
100  return 0;
101  }
102  while (1) /* comma separated attribute value list */
103  {
104  t = yaz_tok_move(tp);
105  /* must have a value now */
106  if (t != YAZ_TOK_STRING)
107  {
108  *addinfo = "value token expected";
109  goto out;
110  }
111  value_str = yaz_tok_parse_string(tp);
112 
113  if (sscanf(type_str, "%d", &type) == 1)
114  ;
115  else if (strlen(type_str) != 1)
116  {
117  *addinfo = "bad attribute type";
118  goto out;
119  }
120  else
121  {
122  switch (*type_str)
123  {
124  case 'u':
125  case 'U':
126  type = CCL_BIB1_USE;
127  break;
128  case 'r':
129  case 'R':
130  type = CCL_BIB1_REL;
131  if (!ccl_stricmp (value_str, "o"))
132  value = CCL_BIB1_REL_ORDER;
133  else if (!ccl_stricmp (value_str, "r"))
134  value = CCL_BIB1_REL_PORDER;
135  else if (!ccl_stricmp (value_str, "omiteq"))
136  value = CCL_BIB1_REL_OMIT_EQUALS;
137  break;
138  case 'p':
139  case 'P':
140  type = CCL_BIB1_POS;
141  break;
142  case 's':
143  case 'S':
144  type = CCL_BIB1_STR;
145  if (!ccl_stricmp (value_str, "pw"))
146  value = CCL_BIB1_STR_WP;
147  if (!ccl_stricmp (value_str, "al"))
148  value = CCL_BIB1_STR_AND_LIST;
149  if (!ccl_stricmp (value_str, "ol"))
150  value = CCL_BIB1_STR_OR_LIST;
151  if (!ccl_stricmp (value_str, "ag"))
152  value = CCL_BIB1_STR_AUTO_GROUP;
153  if (!ccl_stricmp (value_str, "sl"))
154  value = CCL_BIB1_STR_SPLIT_LIST;
155  break;
156  case 't':
157  case 'T':
158  type = CCL_BIB1_TRU;
159  if (!ccl_stricmp (value_str, "l"))
160  value = CCL_BIB1_TRU_CAN_LEFT;
161  else if (!ccl_stricmp (value_str, "r"))
162  value = CCL_BIB1_TRU_CAN_RIGHT;
163  else if (!ccl_stricmp (value_str, "b"))
164  value = CCL_BIB1_TRU_CAN_BOTH;
165  else if (!ccl_stricmp (value_str, "n"))
166  value = CCL_BIB1_TRU_CAN_NONE;
167  else if (!ccl_stricmp (value_str, "x"))
168  value = CCL_BIB1_TRU_CAN_REGEX;
169  else if (!ccl_stricmp (value_str, "z"))
170  value = CCL_BIB1_TRU_CAN_Z3958;
171  break;
172  case 'c':
173  case 'C':
174  type = CCL_BIB1_COM;
175  break;
176  }
177  }
178  if (type == 0)
179  {
180  /* type was not set in switch above */
181  *addinfo = "bad attribute type";
182  goto out;
183  }
184  type_ar[pair_no] = type;
185  if (value)
186  {
187  value_ar[pair_no] = value;
188  svalue_ar[pair_no] = 0;
189  }
190  else if (*value_str >= '0' && *value_str <= '9')
191  {
192  value_ar[pair_no] = atoi (value_str);
193  svalue_ar[pair_no] = 0;
194  }
195  else
196  {
197  value_ar[pair_no] = 0;
198  svalue_ar[pair_no] = xstrdup(value_str);
199  }
200  pair_no++;
201  if (pair_no == MAX_QUAL)
202  {
203  *addinfo = "too many attribute values";
204  goto out;
205  }
206  t = yaz_tok_move(tp);
207  if (t != ',')
208  break;
209  attsets[pair_no] = attsets[pair_no-1];
210  }
211  }
212  out:
213  xfree(type_str);
214  type_str = 0;
215 
217 
218  if (*addinfo)
219  {
220  int i;
221  for (i = 0; i<pair_no; i++)
222  {
223  xfree(attsets[i]);
224  xfree(svalue_ar[i]);
225  }
226  return -1;
227  }
228  ccl_qual_add_set(bibset, qual_name, pair_no, type_ar, value_ar, svalue_ar,
229  attsets);
230  return 0;
231 }
232 
233 void ccl_qual_field(CCL_bibset bibset, const char *cp, const char *qual_name)
234 {
235  const char *addinfo;
236  ccl_qual_field2(bibset, cp, qual_name, &addinfo);
237  if (addinfo)
238  yaz_log(YLOG_WARN, "ccl_qual_field2 fail: %s", addinfo);
239 }
240 
241 int ccl_qual_fitem2(CCL_bibset bibset, const char *cp, const char *qual_name,
242  const char **addinfo)
243 {
244  if (*qual_name == '@')
245  {
246  /* ccl_qual_add_special can not return error (yet) */
247  ccl_qual_add_special(bibset, qual_name+1, cp);
248  *addinfo = 0;
249  return 0;
250  }
251  else
252  return ccl_qual_field2(bibset, cp, qual_name, addinfo);
253 }
254 
255 void ccl_qual_fitem(CCL_bibset bibset, const char *cp, const char *qual_name)
256 {
257  const char *addinfo = 0;
258  ccl_qual_fitem2(bibset, cp, qual_name, &addinfo);
259 }
260 
261 void ccl_qual_buf(CCL_bibset bibset, const char *buf)
262 {
263  const char *cp1 = buf;
264  char line[256];
265  while (1)
266  {
267  const char *cp2 = cp1;
268  size_t len;
269  while (*cp2 && !strchr("\r\n", *cp2))
270  cp2++;
271  len = cp2 - cp1;
272  if (len > 0)
273  {
274  if (len >= (sizeof(line)-1))
275  len = sizeof(line)-1;
276  memcpy(line, cp1, len);
277  line[len] = '\0';
278  ccl_qual_line(bibset, line);
279  }
280  if (!*cp2)
281  break;
282  cp1 = cp2+1;
283  }
284 }
285 
286 void ccl_qual_line(CCL_bibset bibset, char *line)
287 {
288  int no_scan = 0;
289  char qual_name[128];
290  char *cp1, *cp = line;
291 
292  if (*cp == '#')
293  return; /* ignore lines starting with # */
294  if (sscanf (cp, "%100s%n", qual_name, &no_scan) < 1)
295  return; /* also ignore empty lines */
296  cp += no_scan;
297  cp1 = strchr(cp, '#');
298  if (cp1)
299  *cp1 = '\0';
300  ccl_qual_fitem (bibset, cp, qual_name);
301 }
302 
303 /*
304  * ccl_qual_file: Read bibset definition from file.
305  * bibset: Bibset
306  * inf: FILE pointer.
307  *
308  * Each line format is:
309  * <name> <t>=<v> <t>=<v> ....
310  * Where <name> is name of qualifier;
311  * <t>=<v> is a attribute definition pair where <t> is one of:
312  * u(use), r(relation), p(position), t(truncation), c(completeness)
313  * or plain integer.
314  * <v> is an integer or special pseudo-value.
315  */
316 void ccl_qual_file (CCL_bibset bibset, FILE *inf)
317 {
318  char line[256];
319 
320  while (fgets (line, 255, inf))
321  ccl_qual_line(bibset, line);
322 }
323 
324 int ccl_qual_fname (CCL_bibset bibset, const char *fname)
325 {
326  FILE *inf;
327  inf = fopen (fname, "r");
328  if (!inf)
329  return -1;
330  ccl_qual_file (bibset, inf);
331  fclose (inf);
332  return 0;
333 }
334 /*
335  * Local variables:
336  * c-basic-offset: 4
337  * c-file-style: "Stroustrup"
338  * indent-tabs-mode: nil
339  * End:
340  * vim: shiftwidth=4 tabstop=8 expandtab
341  */
342 
Header with public definitions for CCL.
#define CCL_BIB1_COM
Definition: ccl.h:353
#define CCL_BIB1_TRU_CAN_NONE
Definition: ccl.h:367
#define CCL_BIB1_REL_ORDER
Definition: ccl.h:360
#define CCL_BIB1_REL
Definition: ccl.h:349
#define CCL_BIB1_TRU
Definition: ccl.h:352
#define CCL_BIB1_TRU_CAN_LEFT
Definition: ccl.h:364
#define CCL_BIB1_STR
Definition: ccl.h:351
#define CCL_BIB1_TRU_CAN_Z3958
Definition: ccl.h:369
#define CCL_BIB1_REL_PORDER
Definition: ccl.h:361
#define CCL_BIB1_REL_OMIT_EQUALS
Definition: ccl.h:362
#define CCL_BIB1_USE
common attributes
Definition: ccl.h:348
#define CCL_BIB1_STR_AUTO_GROUP
Definition: ccl.h:358
#define CCL_BIB1_TRU_CAN_REGEX
Definition: ccl.h:368
#define CCL_BIB1_TRU_CAN_BOTH
Definition: ccl.h:366
#define CCL_BIB1_TRU_CAN_RIGHT
Definition: ccl.h:365
#define CCL_BIB1_POS
Definition: ccl.h:350
#define CCL_BIB1_STR_OR_LIST
Definition: ccl.h:357
#define CCL_BIB1_STR_AND_LIST
Definition: ccl.h:356
#define CCL_BIB1_STR_SPLIT_LIST
Definition: ccl.h:359
#define CCL_BIB1_STR_WP
Definition: ccl.h:355
int ccl_qual_fname(CCL_bibset bibset, const char *fname)
Definition: cclqfile.c:324
int ccl_qual_fitem2(CCL_bibset bibset, const char *cp, const char *qual_name, const char **addinfo)
Definition: cclqfile.c:241
void ccl_qual_file(CCL_bibset bibset, FILE *inf)
Definition: cclqfile.c:316
int ccl_qual_field2(CCL_bibset bibset, const char *cp, const char *qual_name, const char **addinfo)
Definition: cclqfile.c:23
void ccl_qual_fitem(CCL_bibset bibset, const char *cp, const char *qual_name)
Definition: cclqfile.c:255
#define MAX_QUAL
Definition: cclqfile.c:21
void ccl_qual_field(CCL_bibset bibset, const char *cp, const char *qual_name)
Definition: cclqfile.c:233
void ccl_qual_line(CCL_bibset bibset, char *line)
Definition: cclqfile.c:286
void ccl_qual_buf(CCL_bibset bibset, const char *buf)
Definition: cclqfile.c:261
void ccl_qual_add_set(CCL_bibset b, const char *name, int no, int *type_ar, int *value_ar, char **svalue_ar, char **attsets)
adds specifies attributes for qualifier
Definition: cclqual.c:165
void ccl_qual_add_combi(CCL_bibset b, const char *n, const char **names)
adds specifies qualifier aliases
Definition: cclqual.c:127
void ccl_qual_add_special(CCL_bibset bibset, const char *n, const char *cp)
Definition: cclqual.c:81
int ccl_stricmp(const char *s1, const char *s2)
Definition: cclstr.c:28
enum l_file_type type
Definition: log.c:47
void yaz_log(int level, const char *fmt,...)
Writes log message.
Definition: log.c:487
Logging utility.
#define YLOG_WARN
log level: warning
Definition: log.h:46
yaz_tok_parse_t yaz_tok_parse_buf(yaz_tok_cfg_t t, const char *buf)
Definition: tokenizer.c:83
yaz_tok_cfg_t yaz_tok_cfg_create(void)
Definition: tokenizer.c:45
const char * yaz_tok_parse_string(yaz_tok_parse_t tp)
Definition: tokenizer.c:174
void yaz_tok_parse_destroy(yaz_tok_parse_t tp)
Definition: tokenizer.c:123
void yaz_tok_cfg_single_tokens(yaz_tok_cfg_t t, const char *simple)
Definition: tokenizer.c:39
void yaz_tok_cfg_destroy(yaz_tok_cfg_t t)
Definition: tokenizer.c:57
int yaz_tok_move(yaz_tok_parse_t tp)
Definition: tokenizer.c:130
Header with public definitions about YAZ' tokenizer.
#define YAZ_TOK_STRING
Definition: tokenizer.h:40
#define xstrdup(s)
utility macro which calls xstrdup_f
Definition: xmalloc.h:55
#define xfree(x)
utility macro which calls xfree_f
Definition: xmalloc.h:53