1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
7 * \brief Implements CCL qualifier utilities
16 #include <yaz/snprintf.h>
17 #include <yaz/tokenizer.h>
21 struct ccl_qualifier {
24 struct ccl_qualifier **sub;
25 struct ccl_rpn_attr *attr_list;
26 struct ccl_qualifier *next;
30 /** Definition of CCL_bibset pointer */
31 struct ccl_qualifiers {
32 struct ccl_qualifier *list;
33 struct ccl_qualifier_special *special;
37 /** CCL Qualifier special */
38 struct ccl_qualifier_special {
41 struct ccl_qualifier_special *next;
45 static struct ccl_qualifier *ccl_qual_lookup(CCL_bibset b,
46 const char *n, size_t len)
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))
55 void ccl_qual_add_special_ar(CCL_bibset bibset, const char *n,
58 struct ccl_qualifier_special *p;
59 for (p = bibset->special; p && strcmp(p->name, n); p = p->next)
66 for (i = 0; p->values[i]; i++)
67 xfree((char *) p->values[i]);
68 xfree((char **)p->values);
73 p = (struct ccl_qualifier_special *) xmalloc(sizeof(*p));
75 p->next = bibset->special;
81 void ccl_qual_add_special(CCL_bibset bibset, const char *n, const char *cp)
84 char **vlist = (char **) xmalloc(no * sizeof(*vlist));
85 yaz_tok_cfg_t yt = yaz_tok_cfg_create();
89 yaz_tok_parse_t tp = yaz_tok_parse_buf(yt, cp);
91 yaz_tok_cfg_destroy(yt);
94 while (t == YAZ_TOK_STRING)
97 vlist = (char **) xrealloc(vlist, (no = no * 2) * sizeof(*vlist));
98 vlist[i++] = xstrdup(yaz_tok_parse_string(tp));
102 ccl_qual_add_special_ar(bibset, n, (const char **) vlist);
104 yaz_tok_parse_destroy(tp);
107 static struct ccl_qualifier *ccl_qual_new(CCL_bibset b, const char *name)
109 struct ccl_qualifier *q;
110 q = (struct ccl_qualifier *)xmalloc(sizeof(*q));
114 q->name = xstrdup(name);
121 /** \brief adds specifies qualifier aliases
124 \param n qualifier name
125 \param names list of qualifier aliases
127 void ccl_qual_add_combi(CCL_bibset b, const char *n, const char **names)
130 struct ccl_qualifier *q;
131 for (q = b->list; q && strcmp(q->name, n); q = q->next)
135 q = (struct ccl_qualifier *) xmalloc(sizeof(*q));
136 q->name = xstrdup(n);
141 for (i = 0; names[i]; i++)
144 q->sub = (struct ccl_qualifier **)
145 xmalloc(sizeof(*q->sub) * (1+q->no_sub));
146 for (i = 0; names[i]; i++)
148 q->sub[i] = ccl_qual_lookup(b, names[i], strlen(names[i]));
150 q->sub[i] = ccl_qual_new(b, names[i]);
154 /** \brief adds specifies attributes for qualifier
157 \param name qualifier name
158 \param no number of attribute type+value pairs
159 \param type_ar attributes type of size no
160 \param value_ar attribute value of size no
161 \param svalue_ar attribute string values ([i] only used if != NULL)
162 \param attsets attribute sets of size no
165 void ccl_qual_add_set(CCL_bibset b, const char *name, int no,
166 int *type_ar, int *value_ar, char **svalue_ar,
169 struct ccl_qualifier *q;
170 struct ccl_rpn_attr **attrp;
173 for (q = b->list; q; q = q->next)
174 if (!strcmp(name, q->name))
177 q = ccl_qual_new(b, name);
178 attrp = &q->attr_list;
180 attrp = &(*attrp)->next;
183 struct ccl_rpn_attr *attr;
185 attr = (struct ccl_rpn_attr *)xmalloc(sizeof(*attr));
187 attr->set = *attsets++;
188 attr->type = *type_ar++;
191 attr->kind = CCL_RPN_ATTR_STRING;
192 attr->value.str = *svalue_ar;
196 attr->kind = CCL_RPN_ATTR_NUMERIC;
197 attr->value.numeric = *value_ar;
207 /** \brief creates Bibset
210 CCL_bibset ccl_qual_mk(void)
212 CCL_bibset b = (CCL_bibset)xmalloc(sizeof(*b));
219 /** \brief destroys Bibset
220 \param b pointer to Bibset
222 *b will be set to NULL.
224 void ccl_qual_rm(CCL_bibset *b)
226 struct ccl_qualifier *q, *q1;
227 struct ccl_qualifier_special *sp, *sp1;
231 for (q = (*b)->list; q; q = q1)
233 struct ccl_rpn_attr *attr, *attr1;
235 for (attr = q->attr_list; attr; attr = attr1)
240 if (attr->kind == CCL_RPN_ATTR_STRING)
241 xfree(attr->value.str);
250 for (sp = (*b)->special; sp; sp = sp1)
257 for (i = 0; sp->values[i]; i++)
258 xfree((char*) sp->values[i]);
259 xfree((char **)sp->values);
267 CCL_bibset ccl_qual_dup(CCL_bibset b)
269 CCL_bibset n = ccl_qual_mk();
270 struct ccl_qualifier *q, **qp;
271 struct ccl_qualifier_special *s, **sp;
274 for (q = b->list; q; q = q->next)
276 struct ccl_rpn_attr *attr, **attrp;
277 *qp = xmalloc(sizeof(**qp));
279 (*qp)->attr_list = 0;
280 (*qp)->name = xstrdup(q->name);
282 attrp = &(*qp)->attr_list;
283 for (attr = q->attr_list; attr; attr = attr->next)
285 *attrp = xmalloc(sizeof(**attrp));
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);
295 attrp = &(*attrp)->next;
297 (*qp)->no_sub = q->no_sub;
302 /* fix up the sub qualifiers.. */
304 (*qp)->sub = xmalloc(sizeof(*q->sub) * (q->no_sub + 1));
305 for (i = 0; i < q->no_sub; i++)
307 struct ccl_qualifier *q1, *q2;
309 /* sweep though original and match up the corresponding ent */
311 for (q1 = b->list; q1 && q2; q1 = q1->next, q2 = q2->next)
320 for (s = b->special; s; s = s->next)
324 for (i = 0; s->values[i]; i++)
326 *sp = xmalloc(sizeof(**sp));
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;
338 ccl_qualifier_t ccl_qual_search(CCL_parser cclp, const char *name,
339 size_t name_len, int seq)
341 struct ccl_qualifier *q = 0;
342 const char **aliases;
343 int case_sensitive = cclp->ccl_case_sensitive;
349 aliases = ccl_qual_search_special(cclp->bibset, "case");
351 case_sensitive = atoi(aliases[0]);
353 for (q = cclp->bibset->list; q; q = q->next)
354 if (strlen(q->name) == name_len)
358 if (!memcmp(name, q->name, name_len))
363 if (!ccl_memicmp(name, q->name, name_len))
382 struct ccl_rpn_attr *ccl_qual_get_attr(ccl_qualifier_t q)
387 struct ccl_rpn_attr *ccl_parser_qual_search(CCL_parser cclp, const char *name,
390 ccl_qualifier_t q = ccl_qual_search(cclp, name, name_len, 0);
396 const char *ccl_qual_get_name(ccl_qualifier_t q)
401 const char **ccl_qual_search_special(CCL_bibset b, const char *name)
403 struct ccl_qualifier_special *q;
406 for (q = b->special; q && strcmp(q->name, name); q = q->next)
413 int ccl_search_stop(CCL_bibset bibset, const char *qname,
414 const char *src_str, size_t src_len)
416 const char **slist = 0;
420 yaz_snprintf(qname_buf, sizeof(qname_buf)-1, "stop.%s",
422 slist = ccl_qual_search_special(bibset, qname_buf);
425 slist = ccl_qual_search_special(bibset, "stop.*");
429 for (i = 0; slist[i]; i++)
430 if (src_len == strlen(slist[i])
431 && ccl_memicmp(slist[i], src_str, src_len) == 0)
440 * c-file-style: "Stroustrup"
441 * indent-tabs-mode: nil
443 * vim: shiftwidth=4 tabstop=8 expandtab