1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2012 Index Data
3 * See the file LICENSE for details.
7 * \brief Implements parsing of CCL qualifier specs in files
17 #include <yaz/tokenizer.h>
23 int ccl_qual_field2(CCL_bibset bibset, const char *cp, const char *qual_name,
26 yaz_tok_cfg_t yt = yaz_tok_cfg_create();
28 int type_ar[MAX_QUAL];
29 int value_ar[MAX_QUAL];
30 char *svalue_ar[MAX_QUAL];
31 char *attsets[MAX_QUAL];
37 yaz_tok_cfg_single_tokens(yt, ",=");
39 tp = yaz_tok_parse_buf(yt, cp);
41 yaz_tok_cfg_destroy(yt);
45 while (t == YAZ_TOK_STRING)
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 */
55 /* full attribute spec: set, type = value */
56 /* lead is attribute set */
57 attsets[pair_no] = lead_str;
59 if (t != YAZ_TOK_STRING)
61 *addinfo = "token expected";
65 type_str = xstrdup(yaz_tok_parse_string(tp));
66 if (yaz_tok_move(tp) != '=')
68 *addinfo = "= expected";
74 /* lead is attribute type */
75 /* attribute set omitted: type = value */
82 /* lead is first of a list of qualifier aliaeses */
83 /* qualifier alias: q1 q2 ... */
87 qlist[i++] = lead_str;
89 while (t == YAZ_TOK_STRING)
91 if (i < sizeof(qlist)/sizeof(*qlist)-1)
92 qlist[i++] = xstrdup(yaz_tok_parse_string(tp));
96 yaz_tok_parse_destroy(tp);
97 ccl_qual_add_combi (bibset, qual_name, (const char **) qlist);
98 for (i = 0; qlist[i]; i++)
102 while (1) /* comma separated attribute value list */
104 t = yaz_tok_move(tp);
105 /* must have a value now */
106 if (t != YAZ_TOK_STRING)
108 *addinfo = "value token expected";
111 value_str = yaz_tok_parse_string(tp);
113 if (sscanf(type_str, "%d", &type) == 1)
115 else if (strlen(type_str) != 1)
117 *addinfo = "bad attribute type";
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;
143 if (!ccl_stricmp (value_str, "pw"))
144 value = CCL_BIB1_STR_WP;
145 if (!ccl_stricmp (value_str, "al"))
146 value = CCL_BIB1_STR_AND_LIST;
147 if (!ccl_stricmp (value_str, "ol"))
148 value = CCL_BIB1_STR_OR_LIST;
153 if (!ccl_stricmp (value_str, "l"))
154 value = CCL_BIB1_TRU_CAN_LEFT;
155 else if (!ccl_stricmp (value_str, "r"))
156 value = CCL_BIB1_TRU_CAN_RIGHT;
157 else if (!ccl_stricmp (value_str, "b"))
158 value = CCL_BIB1_TRU_CAN_BOTH;
159 else if (!ccl_stricmp (value_str, "n"))
160 value = CCL_BIB1_TRU_CAN_NONE;
161 else if (!ccl_stricmp (value_str, "x"))
162 value = CCL_BIB1_TRU_CAN_REGEX;
163 else if (!ccl_stricmp (value_str, "z"))
164 value = CCL_BIB1_TRU_CAN_Z3958;
174 /* type was not set in switch above */
175 *addinfo = "bad attribute type";
178 type_ar[pair_no] = type;
181 value_ar[pair_no] = value;
182 svalue_ar[pair_no] = 0;
184 else if (*value_str >= '0' && *value_str <= '9')
186 value_ar[pair_no] = atoi (value_str);
187 svalue_ar[pair_no] = 0;
191 value_ar[pair_no] = 0;
192 svalue_ar[pair_no] = xstrdup(value_str);
195 if (pair_no == MAX_QUAL)
197 *addinfo = "too many attribute values";
200 t = yaz_tok_move(tp);
203 attsets[pair_no] = attsets[pair_no-1];
210 yaz_tok_parse_destroy(tp);
215 for (i = 0; i<pair_no; i++)
222 ccl_qual_add_set(bibset, qual_name, pair_no, type_ar, value_ar, svalue_ar,
227 void ccl_qual_field(CCL_bibset bibset, const char *cp, const char *qual_name)
230 ccl_qual_field2(bibset, cp, qual_name, &addinfo);
232 yaz_log(YLOG_WARN, "ccl_qual_field2 fail: %s", addinfo);
235 void ccl_qual_fitem (CCL_bibset bibset, const char *cp, const char *qual_name)
237 if (*qual_name == '@')
238 ccl_qual_add_special(bibset, qual_name+1, cp);
240 ccl_qual_field(bibset, cp, qual_name);
243 void ccl_qual_buf(CCL_bibset bibset, const char *buf)
245 const char *cp1 = buf;
249 const char *cp2 = cp1;
251 while (*cp2 && !strchr("\r\n", *cp2))
256 if (len >= (sizeof(line)-1))
257 len = sizeof(line)-1;
258 memcpy(line, cp1, len);
260 ccl_qual_line(bibset, line);
268 void ccl_qual_line(CCL_bibset bibset, char *line)
272 char *cp1, *cp = line;
275 return; /* ignore lines starting with # */
276 if (sscanf (cp, "%100s%n", qual_name, &no_scan) < 1)
277 return; /* also ignore empty lines */
279 cp1 = strchr(cp, '#');
282 ccl_qual_fitem (bibset, cp, qual_name);
286 * ccl_qual_file: Read bibset definition from file.
290 * Each line format is:
291 * <name> <t>=<v> <t>=<v> ....
292 * Where <name> is name of qualifier;
293 * <t>=<v> is a attribute definition pair where <t> is one of:
294 * u(use), r(relation), p(position), t(truncation), c(completeness)
296 * <v> is an integer or special pseudo-value.
298 void ccl_qual_file (CCL_bibset bibset, FILE *inf)
302 while (fgets (line, 255, inf))
303 ccl_qual_line(bibset, line);
306 int ccl_qual_fname (CCL_bibset bibset, const char *fname)
309 inf = fopen (fname, "r");
312 ccl_qual_file (bibset, inf);
319 * c-file-style: "Stroustrup"
320 * indent-tabs-mode: nil
322 * vim: shiftwidth=4 tabstop=8 expandtab