IDZEBRA 2.2.8
marcomp.c
Go to the documentation of this file.
1/* This file is part of the Zebra server.
2 Copyright (C) Index Data
3
4Zebra is free software; you can redistribute it and/or modify it under
5the terms of the GNU General Public License as published by the Free
6Software Foundation; either version 2, or (at your option) any later
7version.
8
9Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10WARRANTY; without even the implied warranty of MERCHANTABILITY or
11FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
18*/
19
20#if HAVE_CONFIG_H
21#include <config.h>
22#endif
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <ctype.h>
27
28#include <yaz/yaz-util.h>
29
30#include "marcomp.h"
31
33static void mc_ungettoken(mc_context *c);
34static int mc_getval(mc_context *c);
35static int mc_getdata(mc_context *c, char *s, int sz);
36static void mc_getinterval(mc_context *c, int *start, int *end);
37
39static mc_field *mc_mk_field(void);
40
41static struct mc_errmsg
42{
44 const char *msg;
45} mc_errmsg[] = {
46{EMCOK, "OK"},
47{EMCNOMEM, "NO mem"},
48{EMCF, "not complete field"},
49{EMCSF, "not complete subfield"},
50{EMCSFGROUP, "not closed GROUP"},
51{EMCSFVAR, "not closed VARIANT"},
52{EMCSFINLINE, "not closed IN-LINE"},
53{EMCEND, "not correct errno"}
54};
56{
57 return c->errcode;
58}
59const char *mc_error(mc_errcode no)
60{
61 if (no >= EMCOK && no<EMCEND)
62 return mc_errmsg[no].msg;
63 else
64 return mc_errmsg[EMCEND].msg;
65}
67{
68 mc_context *p=0;
69
70 if (s && strlen(s))
71 {
72 p = (mc_context*) xmalloc(sizeof(*p));
73
74 if (!p)
75 return 0;
76
77 memset(p, 0, sizeof(*p));
78 p->errcode = EMCOK;
79 p->data = s;
80 p->len = strlen(s);
81 p->crrtok = NOP;
82 }
83
84 return p;
85}
87{
88 if (c) xfree(c);
89}
91{
92 if (c->offset >= c->len)
93 return NOP;
94
95 switch (*(c->data+c->offset))
96 {
97 case '{': c->crrtok = LVARIANT; break;
98 case '}': c->crrtok = RVARIANT; break;
99 case '(': c->crrtok = LGROUP; break;
100 case ')': c->crrtok = RGROUP; break;
101 case '<': c->crrtok = LINLINE; break;
102 case '>': c->crrtok = RINLINE; break;
103 case '$': c->crrtok = SUBFIELD; break;
104 case '[': c->crrtok = LINTERVAL; break;
105 case ']': c->crrtok = RINTERVAL; break;
106 default:
107 if (isspace(*(unsigned char *) (c->data+c->offset))
108 || *(c->data+c->offset) == '\n')
109 {
110 c->crrtok = NOP;
111 }
112 else
113 {
114 c->crrtok = REGULAR;
115 c->crrval = *(c->data+c->offset);
116 }
117 }
118#ifdef DEBUG
119 fprintf(stderr, "gettoken(): offset: %d", c->offset);
120 if (c->crrtok == REGULAR)
121 fprintf(stderr, "<%c>", c->crrval);
122 fprintf(stderr, "\n");
123#endif
124 c->offset++;
125 return c->crrtok;
126}
128{
129 if (c->offset > 0)
130 c->offset--;
131}
133{
134 return c->crrval;
135}
136int mc_getdata(mc_context *c, char *s, int sz)
137{
138 int i;
139
140 for (i=0; i<sz; i++)
141 {
142 if (mc_gettoken(c)!=REGULAR)
143 {
144 mc_ungettoken(c);
145 break;
146 }
147 s[i] = mc_getval(c);
148 }
149 s[i] = '\0';
150
151 return i;
152}
153void mc_getinterval(mc_context *c, int *start, int *end)
154{
155 char buf[6+1];
156 int start_pos, end_pos;
157
158 start_pos = end_pos = -1;
159
160 if (mc_gettoken(c) == LINTERVAL)
161 {
162 int i;
163
164 for (i=0;i<6;i++)
165 {
166 mc_token tok = mc_gettoken(c);
167
168 if (tok == RINTERVAL || tok == NOP)
169 break;
170
171 buf[i] = mc_getval(c);
172 }
173
174 buf[i] = '\0';
175 i = sscanf(buf, "%d-%d", &start_pos, &end_pos);
176
177 if (i == 1)
178 end_pos = start_pos;
179 else if ( i == 0)
180 {
181 start_pos = 0;
182 }
183 }
184 *start = start_pos;
185 *end = end_pos;
186}
188{
189 mc_field *p = (mc_field *)xmalloc(sizeof(*p));
190
191 if (p)
192 {
193 memset(p, 0, sizeof(*p));
194 p->name = (char *)xmalloc(SZ_FNAME+1);
195 *p->name = '\0';
196 p->ind1 = (char *)xmalloc(SZ_IND+1);
197 *p->ind1 = '\0';
198 p->ind2 = (char *)xmalloc(SZ_IND+1);
199 *p->ind2 = '\0';
200 p->interval.start = p->interval.end = -1;
201 }
202 return p;
203}
205{
206 if (!p)
207 return;
208 if (p->name) xfree(p->name);
209 if (p->ind1) xfree(p->ind1);
210 if (p->ind2) xfree(p->ind2);
212 xfree(p);
213}
215{
216 mc_field *pf;
217
218 pf = mc_mk_field();
219
220 if (!pf)
221 {
222 c->errcode = EMCNOMEM;
223 return 0;
224 }
225
226 if (mc_getdata(c, pf->name, SZ_FNAME) == SZ_FNAME)
227 {
228 mc_token nexttok = mc_gettoken(c);
229
230 mc_ungettoken(c);
231
232 if (nexttok == LINTERVAL)
233 {
235#ifdef DEBUG
236 fprintf(stderr, "ineterval (%d)-(%d)\n", pf->interval.start,
237 pf->interval.end);
238#endif
239 }
240
241 if ((mc_getdata(c, pf->ind1, SZ_IND) == SZ_IND) &&
242 (mc_getdata(c, pf->ind2, SZ_IND) == SZ_IND))
243 {
244 pf->list = mc_getsubfields(c, 0);
245 }
246 }
247 else
248 {
249 c->errcode = EMCF;
251 return 0;
252 }
253
254 return pf;
255}
257{
258 mc_subfield *p = (mc_subfield*)xmalloc(sizeof(*p));
259
260 if (p)
261 {
262 memset(p, 0, sizeof(*p));
263 p->which = MC_SF;
264 p->name = (char *)xmalloc(SZ_SFNAME+1);
265 *p->name = '\0';
266 p->prefix = (char *)xmalloc(SZ_PREFIX+1);
267 *p->prefix = '\0';
268 p->suffix = (char *)xmalloc(SZ_SUFFIX+1);
269 *p->suffix = '\0';
270 p->parent = parent;
271 p->interval.start = p->interval.end = -1;
272 }
273 return p;
274}
276{
277 if (!p)
278 return;
279
280 if (p->which == MC_SFGROUP || p->which == MC_SFVARIANT)
281 {
282 if (p->u.child)
284 }
285 else if (p->which == MC_SF)
286 {
287 if (p->u.in_line)
289 }
290 if (p->name) xfree(p->name);
291 if (p->prefix) xfree(p->prefix);
292 if (p->suffix) xfree(p->suffix);
293 if (p->parent) p->parent->next = p->next;
294 xfree(p);
295}
297{
298 if (!p)
299 return;
300
302
303 if (p->which == MC_SFGROUP || p->which == MC_SFVARIANT)
304 {
305 if (p->u.child)
307 }
308 else if (p->which == MC_SF)
309 {
310 if (p->u.in_line)
312 }
313
314 if (p->name) xfree(p->name);
315 if (p->prefix) xfree(p->prefix);
316 if (p->suffix) xfree(p->suffix);
317 if (p->parent) p->parent->next = 0;
318 xfree(p);
319}
321{
322 mc_subfield *psf=0;
323 mc_token tok = mc_gettoken(c);
324
325 if (tok == NOP)
326 return 0;
327
328 if (tok == LGROUP)
329 {
330 if (!(psf = mc_mk_subfield(parent)))
331 {
332 c->errcode = EMCNOMEM;
333 return 0;
334 }
335
336 psf->which = MC_SFGROUP;
337 psf->u.child = mc_getsubfields(c, psf);
338
339 if (mc_gettoken(c) == RGROUP)
340 psf->next = mc_getsubfields(c, psf);
341 else
342 {
343 c->errcode = EMCSFGROUP;
345 return 0;
346 }
347 }
348 else if (tok == LVARIANT)
349 {
350 if (!(psf = mc_mk_subfield(parent)))
351 {
352 c->errcode = EMCNOMEM;
353 return 0;
354 }
355
356 psf->which = MC_SFVARIANT;
357 psf->u.child = mc_getsubfields(c, psf);
358
359 if (mc_gettoken(c) == RVARIANT)
360 psf->next = mc_getsubfields(c, psf);
361 else
362 {
363 c->errcode = EMCSFVAR;
365 return 0;
366 }
367 }
368 else if (tok == RGROUP || tok == RVARIANT || tok == RINLINE)
369 {
370 mc_ungettoken(c);
371 return 0;
372 }
373 else if (tok == REGULAR)
374 {
375 if (!(psf = mc_mk_subfield(parent)))
376 {
377 c->errcode = EMCNOMEM;
378 return 0;
379 }
380
381 mc_ungettoken(c);
382
383 if((mc_getdata(c, psf->prefix, SZ_PREFIX) == SZ_PREFIX) &&
384 (mc_gettoken(c) == SUBFIELD) &&
385 (mc_getdata(c, psf->name, SZ_SFNAME) == SZ_SFNAME))
386 {
387 mc_token tok = mc_gettoken(c);
388
389 mc_ungettoken(c);
390
391 if (tok == LINTERVAL)
392 {
393 mc_getinterval(c, &psf->interval.start, &psf->interval.end);
394 }
395 else if (tok == LINLINE)
396 {
397 mc_gettoken(c);
398 psf->u.in_line = mc_getfield(c);
399 if (mc_gettoken(c) != RINLINE)
400 {
401 c->errcode = EMCSFINLINE;
403 return 0;
404 }
405 }
406
407 if (mc_getdata(c, psf->suffix, SZ_SUFFIX) == SZ_SUFFIX)
408 {
409 psf->which = MC_SF;
410 psf->next = mc_getsubfields(c, psf);
411 }
412 else
413 {
414 c->errcode = EMCSF;
416 return 0;
417 }
418 }
419 }
420 return psf;
421}
422/*
423 * Local variables:
424 * c-basic-offset: 4
425 * c-file-style: "Stroustrup"
426 * indent-tabs-mode: nil
427 * End:
428 * vim: shiftwidth=4 tabstop=8 expandtab
429 */
430
static mc_subfield * mc_mk_subfield(mc_subfield *parent)
Definition marcomp.c:256
void mc_destroy_field(mc_field *p)
Definition marcomp.c:204
static mc_field * mc_mk_field(void)
Definition marcomp.c:187
static void mc_ungettoken(mc_context *c)
Definition marcomp.c:127
mc_field * mc_getfield(mc_context *c)
Definition marcomp.c:214
const char * mc_error(mc_errcode no)
Definition marcomp.c:59
void mc_destroy_subfield(mc_subfield *p)
Definition marcomp.c:275
mc_errcode mc_errno(mc_context *c)
Definition marcomp.c:55
static int mc_getval(mc_context *c)
Definition marcomp.c:132
mc_context * mc_mk_context(const char *s)
Definition marcomp.c:66
static mc_token mc_gettoken(mc_context *c)
Definition marcomp.c:90
void mc_destroy_context(mc_context *c)
Definition marcomp.c:86
static void mc_getinterval(mc_context *c, int *start, int *end)
Definition marcomp.c:153
mc_subfield * mc_getsubfields(mc_context *c, mc_subfield *parent)
Definition marcomp.c:320
static int mc_getdata(mc_context *c, char *s, int sz)
Definition marcomp.c:136
void mc_destroy_subfields_recursive(mc_subfield *p)
Definition marcomp.c:296
#define SZ_FNAME
Definition marcomp.h:47
#define SZ_SUFFIX
Definition marcomp.h:51
#define MC_SFGROUP
Definition marcomp.h:38
#define SZ_PREFIX
Definition marcomp.h:50
#define MC_SF
Definition marcomp.h:37
#define MC_SFVARIANT
Definition marcomp.h:39
#define SZ_SFNAME
Definition marcomp.h:49
mc_token
Definition marcomp.h:66
@ RINLINE
Definition marcomp.h:74
@ RGROUP
Definition marcomp.h:72
@ LINLINE
Definition marcomp.h:73
@ LINTERVAL
Definition marcomp.h:76
@ RVARIANT
Definition marcomp.h:70
@ RINTERVAL
Definition marcomp.h:77
@ LVARIANT
Definition marcomp.h:69
@ LGROUP
Definition marcomp.h:71
@ SUBFIELD
Definition marcomp.h:75
@ NOP
Definition marcomp.h:67
@ REGULAR
Definition marcomp.h:68
mc_errcode
Definition marcomp.h:81
@ EMCSFVAR
Definition marcomp.h:87
@ EMCSF
Definition marcomp.h:85
@ EMCSFGROUP
Definition marcomp.h:86
@ EMCSFINLINE
Definition marcomp.h:88
@ EMCEND
Definition marcomp.h:89
@ EMCNOMEM
Definition marcomp.h:83
@ EMCOK
Definition marcomp.h:82
@ EMCF
Definition marcomp.h:84
#define SZ_IND
Definition marcomp.h:48
static void end(struct zebra_register *reg, void *set_handle)
Definition rank1.c:156
const char * data
Definition marcomp.h:102
int offset
Definition marcomp.h:94
mc_errcode errcode
Definition marcomp.h:99
int crrval
Definition marcomp.h:96
mc_token crrtok
Definition marcomp.h:97
mc_errcode code
Definition marcomp.c:43
const char * msg
Definition marcomp.c:44
char * ind1
Definition marcomp.h:56
struct mc_subfield * list
Definition marcomp.h:62
int start
Definition marcomp.h:59
char * ind2
Definition marcomp.h:57
int end
Definition marcomp.h:60
char * name
Definition marcomp.h:55
struct mc_field::@17 interval
struct mc_field * in_line
Definition marcomp.h:40
struct mc_subfield::@15 interval
char * prefix
Definition marcomp.h:29
union mc_subfield::@16 u
struct mc_subfield * child
Definition marcomp.h:41
int which
Definition marcomp.h:35
char * name
Definition marcomp.h:28
struct mc_subfield * parent
Definition marcomp.h:44
char * suffix
Definition marcomp.h:30
int start
Definition marcomp.h:32
struct mc_subfield * next
Definition marcomp.h:43