00001
00002
00003
00004
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <string.h>
00013
00014 #include <yaz/tokenizer.h>
00015 #include <yaz/ccl.h>
00016 #include <yaz/log.h>
00017
00018 #define MAX_QUAL 128
00019
00020 int ccl_qual_field2(CCL_bibset bibset, const char *cp, const char *qual_name,
00021 const char **addinfo)
00022 {
00023 yaz_tok_cfg_t yt = yaz_tok_cfg_create();
00024
00025 int type_ar[MAX_QUAL];
00026 int value_ar[MAX_QUAL];
00027 char *svalue_ar[MAX_QUAL];
00028 char *attsets[MAX_QUAL];
00029 int pair_no = 0;
00030 char *type_str = 0;
00031 int t;
00032 yaz_tok_parse_t tp;
00033
00034 yaz_tok_cfg_single_tokens(yt, ",=");
00035
00036 tp = yaz_tok_parse_buf(yt, cp);
00037
00038 yaz_tok_cfg_destroy(yt);
00039 *addinfo = 0;
00040
00041 t = yaz_tok_move(tp);
00042 while (t == YAZ_TOK_STRING)
00043 {
00044
00045 char *lead_str = xstrdup(yaz_tok_parse_string(tp));
00046 const char *value_str = 0;
00047 int type = 0, value = 0;
00048
00049 t = yaz_tok_move(tp);
00050 if (t == ',')
00051 {
00052
00053
00054 attsets[pair_no] = lead_str;
00055 t = yaz_tok_move(tp);
00056 if (t != YAZ_TOK_STRING)
00057 {
00058 *addinfo = "token expected";
00059 goto out;
00060 }
00061 xfree(type_str);
00062 type_str = xstrdup(yaz_tok_parse_string(tp));
00063 if (yaz_tok_move(tp) != '=')
00064 {
00065 *addinfo = "= expected";
00066 goto out;
00067 }
00068 }
00069 else if (t == '=')
00070 {
00071
00072
00073 attsets[pair_no] = 0;
00074 xfree(type_str);
00075 type_str = lead_str;
00076 }
00077 else
00078 {
00079
00080
00081 char *qlist[10];
00082 int i = 0;
00083
00084 qlist[i++] = lead_str;
00085
00086 while ((t=yaz_tok_move(tp)) == YAZ_TOK_STRING)
00087 {
00088 if (i < sizeof(qlist)/sizeof(*qlist)-1)
00089 qlist[i++] = xstrdup(yaz_tok_parse_string(tp));
00090 }
00091 qlist[i] = 0;
00092 yaz_tok_parse_destroy(tp);
00093 ccl_qual_add_combi (bibset, qual_name, (const char **) qlist);
00094 for (i = 0; qlist[i]; i++)
00095 xfree(qlist[i]);
00096 return 0;
00097 }
00098 while (1)
00099 {
00100 t = yaz_tok_move(tp);
00101
00102 if (t != YAZ_TOK_STRING)
00103 {
00104 *addinfo = "value token expected";
00105 goto out;
00106 }
00107 value_str = yaz_tok_parse_string(tp);
00108
00109 if (sscanf(type_str, "%d", &type) == 1)
00110 ;
00111 else if (strlen(type_str) != 1)
00112 {
00113 *addinfo = "bad attribute type";
00114 goto out;
00115 }
00116 else
00117 {
00118 switch (*type_str)
00119 {
00120 case 'u':
00121 case 'U':
00122 type = CCL_BIB1_USE;
00123 break;
00124 case 'r':
00125 case 'R':
00126 type = CCL_BIB1_REL;
00127 if (!ccl_stricmp (value_str, "o"))
00128 value = CCL_BIB1_REL_ORDER;
00129 else if (!ccl_stricmp (value_str, "r"))
00130 value = CCL_BIB1_REL_PORDER;
00131 break;
00132 case 'p':
00133 case 'P':
00134 type = CCL_BIB1_POS;
00135 break;
00136 case 's':
00137 case 'S':
00138 type = CCL_BIB1_STR;
00139 if (!ccl_stricmp (value_str, "pw"))
00140 value = CCL_BIB1_STR_WP;
00141 if (!ccl_stricmp (value_str, "al"))
00142 value = CCL_BIB1_STR_AND_LIST;
00143 if (!ccl_stricmp (value_str, "ol"))
00144 value = CCL_BIB1_STR_OR_LIST;
00145 break;
00146 case 't':
00147 case 'T':
00148 type = CCL_BIB1_TRU;
00149 if (!ccl_stricmp (value_str, "l"))
00150 value = CCL_BIB1_TRU_CAN_LEFT;
00151 else if (!ccl_stricmp (value_str, "r"))
00152 value = CCL_BIB1_TRU_CAN_RIGHT;
00153 else if (!ccl_stricmp (value_str, "b"))
00154 value = CCL_BIB1_TRU_CAN_BOTH;
00155 else if (!ccl_stricmp (value_str, "n"))
00156 value = CCL_BIB1_TRU_CAN_NONE;
00157 break;
00158 case 'c':
00159 case 'C':
00160 type = CCL_BIB1_COM;
00161 break;
00162 }
00163 }
00164 if (type == 0)
00165 {
00166
00167 *addinfo = "bad attribute type";
00168 goto out;
00169 }
00170 type_ar[pair_no] = type;
00171 if (value)
00172 {
00173 value_ar[pair_no] = value;
00174 svalue_ar[pair_no] = 0;
00175 }
00176 else if (*value_str >= '0' && *value_str <= '9')
00177 {
00178 value_ar[pair_no] = atoi (value_str);
00179 svalue_ar[pair_no] = 0;
00180 }
00181 else
00182 {
00183 value_ar[pair_no] = 0;
00184 svalue_ar[pair_no] = xstrdup(value_str);
00185 }
00186 pair_no++;
00187 if (pair_no == MAX_QUAL)
00188 {
00189 *addinfo = "too many attribute values";
00190 goto out;
00191 }
00192 t = yaz_tok_move(tp);
00193 if (t != ',')
00194 break;
00195 attsets[pair_no] = attsets[pair_no-1];
00196 }
00197 }
00198 out:
00199 xfree(type_str);
00200 type_str = 0;
00201
00202 yaz_tok_parse_destroy(tp);
00203
00204 if (*addinfo)
00205 {
00206 int i;
00207 for (i = 0; i<pair_no; i++)
00208 {
00209 xfree(attsets[i]);
00210 xfree(svalue_ar[i]);
00211 }
00212 return -1;
00213 }
00214 ccl_qual_add_set(bibset, qual_name, pair_no, type_ar, value_ar, svalue_ar,
00215 attsets);
00216 return 0;
00217 }
00218
00219 void ccl_qual_field(CCL_bibset bibset, const char *cp, const char *qual_name)
00220 {
00221 const char *addinfo;
00222 ccl_qual_field2(bibset, cp, qual_name, &addinfo);
00223 if (addinfo)
00224 yaz_log(YLOG_WARN, "ccl_qual_field2 fail: %s", addinfo);
00225 }
00226
00227 void ccl_qual_fitem (CCL_bibset bibset, const char *cp, const char *qual_name)
00228 {
00229 if (*qual_name == '@')
00230 ccl_qual_add_special(bibset, qual_name+1, cp);
00231 else
00232 ccl_qual_field(bibset, cp, qual_name);
00233 }
00234
00235 void ccl_qual_buf(CCL_bibset bibset, const char *buf)
00236 {
00237 const char *cp1 = buf;
00238 char line[256];
00239 while (1)
00240 {
00241 const char *cp2 = cp1;
00242 int len;
00243 while (*cp2 && !strchr("\r\n", *cp2))
00244 cp2++;
00245 len = cp2 - cp1;
00246 if (len > 0)
00247 {
00248 if (len >= (sizeof(line)-1))
00249 len = sizeof(line)-1;
00250 memcpy(line, cp1, len);
00251 line[len] = '\0';
00252 ccl_qual_line(bibset, line);
00253 }
00254 if (!*cp2)
00255 break;
00256 cp1 = cp2+1;
00257 }
00258 }
00259
00260 void ccl_qual_line(CCL_bibset bibset, char *line)
00261 {
00262 int no_scan = 0;
00263 char qual_name[128];
00264 char *cp1, *cp = line;
00265
00266 if (*cp == '#')
00267 return;
00268 if (sscanf (cp, "%100s%n", qual_name, &no_scan) < 1)
00269 return;
00270 cp += no_scan;
00271 cp1 = strchr(cp, '#');
00272 if (cp1)
00273 *cp1 = '\0';
00274 ccl_qual_fitem (bibset, cp, qual_name);
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 void ccl_qual_file (CCL_bibset bibset, FILE *inf)
00291 {
00292 char line[256];
00293
00294 while (fgets (line, 255, inf))
00295 ccl_qual_line(bibset, line);
00296 }
00297
00298 int ccl_qual_fname (CCL_bibset bibset, const char *fname)
00299 {
00300 FILE *inf;
00301 inf = fopen (fname, "r");
00302 if (!inf)
00303 return -1;
00304 ccl_qual_file (bibset, inf);
00305 fclose (inf);
00306 return 0;
00307 }
00308
00309
00310
00311
00312
00313
00314
00315