YAZ  5.34.0
cclqual.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 #include <yaz/snprintf.h>
17 #include <yaz/tokenizer.h>
18 #include "cclp.h"
19 
21 struct ccl_qualifier {
22  char *name;
23  int no_sub;
24  struct ccl_qualifier **sub;
27 };
28 
29 
34 };
35 
36 
39  char *name;
40  const char **values;
42 };
43 
44 
46  const char *n, size_t len)
47 {
48  struct ccl_qualifier *q;
49  for (q = b->list; q; q = q->next)
50  if (len == strlen(q->name) && !memcmp(q->name, n, len))
51  break;
52  return q;
53 }
54 
55 void ccl_qual_add_special_ar(CCL_bibset bibset, const char *n,
56  const char **values)
57 {
58  struct ccl_qualifier_special *p;
59  for (p = bibset->special; p && strcmp(p->name, n); p = p->next)
60  ;
61  if (p)
62  {
63  if (p->values)
64  {
65  int i;
66  for (i = 0; p->values[i]; i++)
67  xfree((char *) p->values[i]);
68  xfree((char **)p->values);
69  }
70  }
71  else
72  {
73  p = (struct ccl_qualifier_special *) xmalloc(sizeof(*p));
74  p->name = xstrdup(n);
75  p->next = bibset->special;
76  bibset->special = p;
77  }
78  p->values = values;
79 }
80 
81 void ccl_qual_add_special(CCL_bibset bibset, const char *n, const char *cp)
82 {
83  size_t no = 2;
84  char **vlist = (char **) xmalloc(no * sizeof(*vlist));
86  int t;
87  size_t i = 0;
88 
90 
92 
93  t = yaz_tok_move(tp);
94  while (t == YAZ_TOK_STRING)
95  {
96  if (i >= no-1)
97  vlist = (char **) xrealloc(vlist, (no = no * 2) * sizeof(*vlist));
98  vlist[i++] = xstrdup(yaz_tok_parse_string(tp));
99  t = yaz_tok_move(tp);
100  }
101  vlist[i] = 0;
102  ccl_qual_add_special_ar(bibset, n, (const char **) vlist);
103 
105 }
106 
107 static struct ccl_qualifier *ccl_qual_new(CCL_bibset b, const char *name)
108 {
109  struct ccl_qualifier *q;
110  q = (struct ccl_qualifier *)xmalloc(sizeof(*q));
111  ccl_assert(q);
112  q->next = b->list;
113  b->list = q;
114  q->name = xstrdup(name);
115  q->attr_list = 0;
116  q->no_sub = 0;
117  q->sub = 0;
118  return q;
119 }
120 
127 void ccl_qual_add_combi(CCL_bibset b, const char *n, const char **names)
128 {
129  int i;
130  struct ccl_qualifier *q;
131  for (q = b->list; q && strcmp(q->name, n); q = q->next)
132  ;
133  if (q)
134  return ;
135  q = (struct ccl_qualifier *) xmalloc(sizeof(*q));
136  q->name = xstrdup(n);
137  q->attr_list = 0;
138  q->next = b->list;
139  b->list = q;
140 
141  for (i = 0; names[i]; i++)
142  ;
143  q->no_sub = i;
144  q->sub = (struct ccl_qualifier **)
145  xmalloc(sizeof(*q->sub) * (1+q->no_sub));
146  for (i = 0; names[i]; i++)
147  {
148  q->sub[i] = ccl_qual_lookup(b, names[i], strlen(names[i]));
149  if (!q->sub[i])
150  q->sub[i] = ccl_qual_new(b, names[i]);
151  }
152 }
153 
165 void ccl_qual_add_set(CCL_bibset b, const char *name, int no,
166  int *type_ar, int *value_ar, char **svalue_ar,
167  char **attsets)
168 {
169  struct ccl_qualifier *q;
170  struct ccl_rpn_attr **attrp;
171 
172  ccl_assert(b);
173  for (q = b->list; q; q = q->next)
174  if (!strcmp(name, q->name))
175  break;
176  if (!q)
177  q = ccl_qual_new(b, name);
178  attrp = &q->attr_list;
179  while (*attrp)
180  attrp = &(*attrp)->next;
181  while (--no >= 0)
182  {
183  struct ccl_rpn_attr *attr;
184 
185  attr = (struct ccl_rpn_attr *)xmalloc(sizeof(*attr));
186  ccl_assert(attr);
187  attr->set = *attsets++;
188  attr->type = *type_ar++;
189  if (*svalue_ar)
190  {
191  attr->kind = CCL_RPN_ATTR_STRING;
192  attr->value.str = *svalue_ar;
193  }
194  else
195  {
196  attr->kind = CCL_RPN_ATTR_NUMERIC;
197  attr->value.numeric = *value_ar;
198  }
199  svalue_ar++;
200  value_ar++;
201  *attrp = attr;
202  attrp = &attr->next;
203  }
204  *attrp = NULL;
205 }
206 
211 {
212  CCL_bibset b = (CCL_bibset)xmalloc(sizeof(*b));
213  ccl_assert(b);
214  b->list = NULL;
215  b->special = NULL;
216  return b;
217 }
218 
225 {
226  struct ccl_qualifier *q, *q1;
227  struct ccl_qualifier_special *sp, *sp1;
228 
229  if (!*b)
230  return;
231  for (q = (*b)->list; q; q = q1)
232  {
233  struct ccl_rpn_attr *attr, *attr1;
234 
235  for (attr = q->attr_list; attr; attr = attr1)
236  {
237  attr1 = attr->next;
238  if (attr->set)
239  xfree(attr->set);
240  if (attr->kind == CCL_RPN_ATTR_STRING)
241  xfree(attr->value.str);
242  xfree(attr);
243  }
244  q1 = q->next;
245  xfree(q->name);
246  if (q->sub)
247  xfree(q->sub);
248  xfree(q);
249  }
250  for (sp = (*b)->special; sp; sp = sp1)
251  {
252  sp1 = sp->next;
253  xfree(sp->name);
254  if (sp->values)
255  {
256  int i;
257  for (i = 0; sp->values[i]; i++)
258  xfree((char*) sp->values[i]);
259  xfree((char **)sp->values);
260  }
261  xfree(sp);
262  }
263  xfree(*b);
264  *b = NULL;
265 }
266 
268 {
269  CCL_bibset n = ccl_qual_mk();
270  struct ccl_qualifier *q, **qp;
271  struct ccl_qualifier_special *s, **sp;
272 
273  qp = &n->list;
274  for (q = b->list; q; q = q->next)
275  {
276  struct ccl_rpn_attr *attr, **attrp;
277  *qp = xmalloc(sizeof(**qp));
278  (*qp)->next = 0;
279  (*qp)->attr_list = 0;
280  (*qp)->name = xstrdup(q->name);
281 
282  attrp = &(*qp)->attr_list;
283  for (attr = q->attr_list; attr; attr = attr->next)
284  {
285  *attrp = xmalloc(sizeof(**attrp));
286  (*attrp)->next = 0;
287  (*attrp)->set = attr->set ? xstrdup(attr->set) : 0;
288  (*attrp)->type = attr->type;
289  (*attrp)->kind = attr->kind;
290  if (attr->kind == CCL_RPN_ATTR_NUMERIC)
291  (*attrp)->value.numeric = attr->value.numeric;
292  else if (attr->kind == CCL_RPN_ATTR_STRING)
293  (*attrp)->value.str = xstrdup(attr->value.str);
294 
295  attrp = &(*attrp)->next;
296  }
297  (*qp)->no_sub = q->no_sub;
298  if (!q->sub)
299  (*qp)->sub = 0;
300  else
301  {
302  /* fix up the sub qualifiers.. */
303  int i;
304  (*qp)->sub = xmalloc(sizeof(*q->sub) * (q->no_sub + 1));
305  for (i = 0; i < q->no_sub; i++)
306  {
307  struct ccl_qualifier *q1, *q2;
308 
309  /* sweep though original and match up the corresponding ent */
310  q2 = n->list;
311  for (q1 = b->list; q1 && q2; q1 = q1->next, q2 = q2->next)
312  if (q1 == q->sub[i])
313  break;
314  (*qp)->sub[i] = q2;
315  }
316  }
317  qp = &(*qp)->next;
318  }
319  sp = &n->special;
320  for (s = b->special; s; s = s->next)
321  {
322  int i;
323 
324  for (i = 0; s->values[i]; i++)
325  ;
326  *sp = xmalloc(sizeof(**sp));
327  (*sp)->next = 0;
328  (*sp)->name = xstrdup(s->name);
329  (*sp)->values = xmalloc(sizeof(*(*sp)->values) * (i+1));
330  for (i = 0; s->values[i]; i++)
331  (*sp)->values[i] = xstrdup(s->values[i]);
332  (*sp)->values[i] = 0;
333  sp = &(*sp)->next;
334  }
335  return n;
336 }
337 
339  size_t name_len, int seq)
340 {
341  struct ccl_qualifier *q = 0;
342  const char **aliases;
343  int case_sensitive = cclp->ccl_case_sensitive;
344 
345  ccl_assert(cclp);
346  if (!cclp->bibset)
347  return 0;
348 
349  aliases = ccl_qual_search_special(cclp->bibset, "case");
350  if (aliases)
351  case_sensitive = atoi(aliases[0]);
352 
353  for (q = cclp->bibset->list; q; q = q->next)
354  if (strlen(q->name) == name_len)
355  {
356  if (case_sensitive)
357  {
358  if (!memcmp(name, q->name, name_len))
359  break;
360  }
361  else
362  {
363  if (!ccl_memicmp(name, q->name, name_len))
364  break;
365  }
366  }
367  if (q)
368  {
369  if (q->no_sub)
370  {
371  if (seq < q->no_sub)
372  q = q->sub[seq];
373  else
374  q = 0;
375  }
376  else if (seq)
377  q = 0;
378  }
379  return q;
380 }
381 
383 {
384  return q->attr_list;
385 }
386 
388  size_t name_len)
389 {
390  ccl_qualifier_t q = ccl_qual_search(cclp, name, name_len, 0);
391  if (q)
392  return q->attr_list;
393  return 0;
394 }
395 
397 {
398  return q->name;
399 }
400 
401 const char **ccl_qual_search_special(CCL_bibset b, const char *name)
402 {
403  struct ccl_qualifier_special *q;
404  if (!b)
405  return 0;
406  for (q = b->special; q && strcmp(q->name, name); q = q->next)
407  ;
408  if (q)
409  return q->values;
410  return 0;
411 }
412 
413 int ccl_search_stop(CCL_bibset bibset, const char *qname,
414  const char *src_str, size_t src_len)
415 {
416  const char **slist = 0;
417  if (qname)
418  {
419  char qname_buf[80];
420  yaz_snprintf(qname_buf, sizeof(qname_buf)-1, "stop.%s",
421  qname);
422  slist = ccl_qual_search_special(bibset, qname_buf);
423  }
424  if (!slist)
425  slist = ccl_qual_search_special(bibset, "stop.*");
426  if (slist)
427  {
428  int i;
429  for (i = 0; slist[i]; i++)
430  if (src_len == strlen(slist[i])
431  && ccl_memicmp(slist[i], src_str, src_len) == 0)
432  return 1;
433  }
434  return 0;
435 }
436 
437 /*
438  * Local variables:
439  * c-basic-offset: 4
440  * c-file-style: "Stroustrup"
441  * indent-tabs-mode: nil
442  * End:
443  * vim: shiftwidth=4 tabstop=8 expandtab
444  */
445 
#define CCL_RPN_ATTR_STRING
Definition: ccl.h:108
#define CCL_RPN_ATTR_NUMERIC
Definition: ccl.h:107
struct ccl_qualifiers * CCL_bibset
CCL bibset, AKA profile.
Definition: ccl.h:146
#define ccl_assert(x)
Definition: ccl.h:314
CCL header with private definitions.
struct ccl_rpn_attr * ccl_parser_qual_search(CCL_parser cclp, const char *name, size_t name_len)
Definition: cclqual.c:387
CCL_bibset ccl_qual_mk(void)
creates Bibset
Definition: cclqual.c:210
ccl_qualifier_t ccl_qual_search(CCL_parser cclp, const char *name, size_t name_len, int seq)
Definition: cclqual.c:338
const char * ccl_qual_get_name(ccl_qualifier_t q)
Definition: cclqual.c:396
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
struct ccl_rpn_attr * ccl_qual_get_attr(ccl_qualifier_t q)
Definition: cclqual.c:382
void ccl_qual_rm(CCL_bibset *b)
destroys Bibset
Definition: cclqual.c:224
int ccl_search_stop(CCL_bibset bibset, const char *qname, const char *src_str, size_t src_len)
Definition: cclqual.c:413
const char ** ccl_qual_search_special(CCL_bibset b, const char *name)
Definition: cclqual.c:401
static struct ccl_qualifier * ccl_qual_new(CCL_bibset b, const char *name)
Definition: cclqual.c:107
CCL_bibset ccl_qual_dup(CCL_bibset b)
Definition: cclqual.c:267
void ccl_qual_add_special_ar(CCL_bibset bibset, const char *n, const char **values)
Definition: cclqual.c:55
void ccl_qual_add_special(CCL_bibset bibset, const char *n, const char *cp)
Definition: cclqual.c:81
static struct ccl_qualifier * ccl_qual_lookup(CCL_bibset b, const char *n, size_t len)
Definition: cclqual.c:45
int ccl_memicmp(const char *s1, const char *s2, size_t n)
Definition: cclstr.c:45
char * name
Definition: initopt.c:18
void yaz_snprintf(char *buf, size_t size, const char *fmt,...)
Definition: snprintf.c:31
Header for config file reading utilities.
CCL_bibset bibset
Definition: cclp.h:73
int ccl_case_sensitive
Definition: cclp.h:84
struct ccl_qualifier_special * next
Definition: cclqual.c:41
const char ** values
Definition: cclqual.c:40
int no_sub
Definition: cclqual.c:23
struct ccl_qualifier * next
Definition: cclqual.c:26
char * name
Definition: cclqual.c:22
struct ccl_rpn_attr * attr_list
Definition: cclqual.c:25
struct ccl_qualifier ** sub
Definition: cclqual.c:24
struct ccl_qualifier_special * special
Definition: cclqual.c:33
struct ccl_qualifier * list
Definition: cclqual.c:32
attribute node (type, value) pair as used in RPN
Definition: ccl.h:98
char * str
string attribute value
Definition: ccl.h:113
int kind
attribute value type (numeric or string)
Definition: ccl.h:106
int numeric
numeric attribute value
Definition: ccl.h:111
int type
attribute type, Bib-1: 1=use, 2=relation, 3=position, etc
Definition: ccl.h:104
union ccl_rpn_attr::@7 value
char * set
attribute set
Definition: ccl.h:102
struct ccl_rpn_attr * next
next attribute
Definition: ccl.h:100
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_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
#define xrealloc(o, x)
utility macro which calls xrealloc_f
Definition: xmalloc.h:47
#define xmalloc(x)
utility macro which calls malloc_f
Definition: xmalloc.h:49