Let all .asn depend on yaz-asncomp
[yaz-moved-to-github.git] / src / cclqfile.c
1 /*
2  * Copyright (c) 1995, the EUROPAGATE consortium (see below).
3  *
4  * The EUROPAGATE consortium members are:
5  *
6  *    University College Dublin
7  *    Danmarks Teknologiske Videnscenter
8  *    An Chomhairle Leabharlanna
9  *    Consejo Superior de Investigaciones Cientificas
10  *
11  * Permission to use, copy, modify, distribute, and sell this software and
12  * its documentation, in whole or in part, for any purpose, is hereby granted,
13  * provided that:
14  *
15  * 1. This copyright and permission notice appear in all copies of the
16  * software and its documentation. Notices of copyright or attribution
17  * which appear at the beginning of any file must remain unchanged.
18  *
19  * 2. The names of EUROPAGATE or the project partners may not be used to
20  * endorse or promote products derived from this software without specific
21  * prior written permission.
22  *
23  * 3. Users of this software (implementors and gateway operators) agree to
24  * inform the EUROPAGATE consortium of their use of the software. This
25  * information will be used to evaluate the EUROPAGATE project and the
26  * software, and to plan further developments. The consortium may use
27  * the information in later publications.
28  * 
29  * 4. Users of this software agree to make their best efforts, when
30  * documenting their use of the software, to acknowledge the EUROPAGATE
31  * consortium, and the role played by the software in their work.
32  *
33  * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
34  * EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
35  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
36  * IN NO EVENT SHALL THE EUROPAGATE CONSORTIUM OR ITS MEMBERS BE LIABLE
37  * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF
38  * ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
39  * OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND
40  * ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
41  * USE OR PERFORMANCE OF THIS SOFTWARE.
42  *
43  */
44 /** 
45  * \file cclqfile.c
46  * \brief Implements parsing of CCL qualifier specs in files
47  */
48 /* CCL qualifiers
49  * Europagate, 1995
50  *
51  * $Id: cclqfile.c,v 1.7 2005-06-25 15:46:03 adam Exp $
52  *
53  * Old Europagate Log:
54  *
55  * Revision 1.3  1995/05/16  09:39:26  adam
56  * LICENSE.
57  *
58  * Revision 1.2  1995/05/11  14:03:56  adam
59  * Changes in the reading of qualifier(s). New function: ccl_qual_fitem.
60  * New variable ccl_case_sensitive, which controls whether reserved
61  * words and field names are case sensitive or not.
62  *
63  * Revision 1.1  1995/04/17  09:31:45  adam
64  * Improved handling of qualifiers. Aliases or reserved words.
65  *
66  */
67
68 #include <stdio.h>
69 #include <stdlib.h>
70 #include <string.h>
71
72 #include <yaz/ccl.h>
73
74 void ccl_qual_field (CCL_bibset bibset, const char *cp, const char *qual_name)
75 {
76     char qual_spec[128];
77     int type_ar[128];
78     int value_ar[128];
79     char *svalue_ar[128];
80     char *attsets[128];
81     int pair_no = 0;
82
83     while (pair_no < 128)
84     {
85         char *qual_value, *qual_type;
86         char *split, *setp;
87         int no_scan = 0;
88         
89         if (sscanf (cp, "%100s%n", qual_spec, &no_scan) < 1)
90             break;
91
92         if (!(split = strchr (qual_spec, '=')))
93         {
94             /* alias specification .. */
95             if (pair_no == 0)
96             {
97                 ccl_qual_add_combi (bibset, qual_name, cp);
98                 return;
99             }
100             break;
101         }
102         /* [set,]type=value ... */
103         cp += no_scan;
104         
105         *split++ = '\0';
106
107         setp = strchr (qual_spec, ',');
108         if (setp)
109         {
110             /* set,type=value ... */
111             *setp++ = '\0';
112             qual_type = setp;
113         }
114         else
115         {
116             /* type=value ... */
117             qual_type = qual_spec;
118         }
119         while (pair_no < 128)
120         {
121             int type, value;
122
123             qual_value = split;
124             if ((split = strchr (qual_value, ',')))
125                 *split++ = '\0';
126
127             value = 0;
128             switch (qual_type[0])
129             {
130             case 'u':
131             case 'U':
132                 type = CCL_BIB1_USE;
133                 break;
134             case 'r':
135             case 'R':
136                 type = CCL_BIB1_REL;
137                 if (!ccl_stricmp (qual_value, "o"))
138                     value = CCL_BIB1_REL_ORDER;
139                 else if (!ccl_stricmp (qual_value, "r"))
140                     value = CCL_BIB1_REL_PORDER;
141                 break;                
142             case 'p':
143             case 'P':
144                 type = CCL_BIB1_POS;
145                 break;
146             case 's':
147             case 'S':
148                 type = CCL_BIB1_STR;
149                 if (!ccl_stricmp (qual_value, "pw"))
150                     value = CCL_BIB1_STR_WP;
151                 if (!ccl_stricmp (qual_value, "al"))
152                     value = CCL_BIB1_STR_AND_LIST;
153                 if (!ccl_stricmp (qual_value, "ol"))
154                     value = CCL_BIB1_STR_OR_LIST;
155                 break;                
156             case 't':
157             case 'T':
158                 type = CCL_BIB1_TRU;
159                 if (!ccl_stricmp (qual_value, "l"))
160                     value = CCL_BIB1_TRU_CAN_LEFT;
161                 else if (!ccl_stricmp (qual_value, "r"))
162                     value = CCL_BIB1_TRU_CAN_RIGHT;
163                 else if (!ccl_stricmp (qual_value, "b"))
164                     value = CCL_BIB1_TRU_CAN_BOTH;
165                 else if (!ccl_stricmp (qual_value, "n"))
166                     value = CCL_BIB1_TRU_CAN_NONE;
167                 break;                
168             case 'c':
169             case 'C':
170                 type = CCL_BIB1_COM;
171                 break;
172             default:
173                 type = atoi (qual_type);
174             }
175
176             type_ar[pair_no] = type;
177
178             if (value)
179             {
180                 value_ar[pair_no] = value;
181                 svalue_ar[pair_no] = 0;
182             }
183             else if (*qual_value >= '0' && *qual_value <= '9')
184             {
185                 value_ar[pair_no] = atoi (qual_value);
186                 svalue_ar[pair_no] = 0;
187             }
188             else
189             {
190                 size_t len;
191                 if (split)
192                     len = split - qual_value;
193                 else
194                     len = strlen(qual_value);
195                 svalue_ar[pair_no] = (char *) xmalloc(len+1);
196                 memcpy(svalue_ar[pair_no], qual_value, len);
197                 svalue_ar[pair_no][len] = '\0';
198             }
199             if (setp)
200             {
201                 attsets[pair_no] = (char*) xmalloc (strlen(qual_spec)+1);
202                 strcpy (attsets[pair_no], qual_spec);
203             }
204             else
205                 attsets[pair_no] = 0;
206             pair_no++;
207             if (!split)
208                 break;
209         }
210     }
211     ccl_qual_add_set (bibset, qual_name, pair_no, type_ar, value_ar, svalue_ar,
212                       attsets);
213 }
214
215 void ccl_qual_fitem (CCL_bibset bibset, const char *cp, const char *qual_name)
216 {
217     if (*qual_name == '@')
218         ccl_qual_add_special(bibset, qual_name+1, cp);
219     else
220         ccl_qual_field(bibset, cp, qual_name);
221 }
222
223 void ccl_qual_buf(CCL_bibset bibset, const char *buf)
224 {
225     const char *cp1 = buf;
226     char line[256];
227     while (1)
228     {
229         const char *cp2 = cp1;
230         int len;
231         while (*cp2 && !strchr("\r\n", *cp2))
232             cp2++;
233         len = cp2 - cp1;
234         if (len > 0)
235         {
236             if (len >= (sizeof(line)-1))
237                 len = sizeof(line)-1;
238             memcpy(line, cp1, len);
239             line[len] = '\0';
240             ccl_qual_line(bibset, line);
241         }
242         if (!*cp2)
243             break;
244         cp1 = cp2+1;
245     }
246 }
247
248 void ccl_qual_line(CCL_bibset bibset, char *line)
249 {
250     int  no_scan = 0;
251     char qual_name[128];
252     char *cp1, *cp = line;
253     
254     if (*cp == '#')
255         return;        /* ignore lines starting with # */
256     if (sscanf (cp, "%100s%n", qual_name, &no_scan) < 1)
257         return;        /* also ignore empty lines */
258     cp += no_scan;
259     cp1 = strchr(cp, '#');
260     if (cp1)
261         *cp1 = '\0';
262     ccl_qual_fitem (bibset, cp, qual_name);
263 }
264
265 /*
266  * ccl_qual_file: Read bibset definition from file.
267  * bibset:  Bibset
268  * inf:     FILE pointer.
269  *
270  * Each line format is:
271  *  <name> <t>=<v> <t>=<v> ....
272  *  Where <name> is name of qualifier;
273  *  <t>=<v> is a attribute definition pair where <t> is one of: 
274  *     u(use), r(relation), p(position), t(truncation), c(completeness) 
275  *     or plain integer.
276  *  <v> is an integer or special pseudo-value.
277  */
278 void ccl_qual_file (CCL_bibset bibset, FILE *inf)
279 {
280     char line[256];
281
282     while (fgets (line, 255, inf))
283         ccl_qual_line(bibset, line);
284 }
285
286 int ccl_qual_fname (CCL_bibset bibset, const char *fname)
287 {
288     FILE *inf;
289     inf = fopen (fname, "r");
290     if (!inf)
291         return -1;
292     ccl_qual_file (bibset, inf);
293     fclose (inf);
294     return 0;
295 }
296 /*
297  * Local variables:
298  * c-basic-offset: 4
299  * indent-tabs-mode: nil
300  * End:
301  * vim: shiftwidth=4 tabstop=8 expandtab
302  */
303