2 $Id: marcomp.c,v 1.3 2004-12-10 11:56:22 heikki Exp $
4 marcomp.c - compiler of MARC statements.
13 /* Old yaz-util includes (FIXME - clean up what is not needed)*/
14 #include <yaz/yconfig.h>
15 #include <yaz/yaz-version.h>
16 #include <yaz/xmalloc.h>
18 #include <yaz/tpath.h>
19 #include <yaz/options.h>
20 #include <yaz/wrbuf.h>
22 #include <yaz/readconf.h>
23 #include <yaz/marcdisp.h>
24 #include <yaz/yaz-iconv.h>
28 static mc_token mc_gettoken(mc_context *c);
29 static void mc_ungettoken(mc_context *c);
30 static int mc_getval(mc_context *c);
31 static int mc_getdata(mc_context *c, char *s, int sz);
32 static void mc_getinterval(mc_context *c, int *start, int *end);
34 static mc_subfield *mc_mk_subfield(mc_subfield *parent);
35 static mc_field *mc_mk_field(void);
37 static struct mc_errmsg
44 {EMCF, "not complete field"},
45 {EMCSF, "not complete subfield"},
46 {EMCSFGROUP, "not closed GROUP"},
47 {EMCSFVAR, "not closed VARIANT"},
48 {EMCSFINLINE, "not closed IN-LINE"},
49 {EMCEND, "not correct errno"}
51 mc_errcode mc_errno(mc_context *c)
55 const char *mc_error(mc_errcode no)
57 if (no >= EMCOK && no<EMCEND)
58 return mc_errmsg[no].msg;
60 return mc_errmsg[EMCEND].msg;
62 mc_context *mc_mk_context(const char *s)
68 p = (mc_context*) xmalloc(sizeof(*p));
73 memset(p, 0, sizeof(*p));
82 void mc_destroy_context(mc_context *c)
86 mc_token mc_gettoken(mc_context *c)
88 if (c->offset >= c->len)
91 switch (*(c->data+c->offset))
93 case '{': c->crrtok = LVARIANT; break;
94 case '}': c->crrtok = RVARIANT; break;
95 case '(': c->crrtok = LGROUP; break;
96 case ')': c->crrtok = RGROUP; break;
97 case '<': c->crrtok = LINLINE; break;
98 case '>': c->crrtok = RINLINE; break;
99 case '$': c->crrtok = SUBFIELD; break;
100 case '[': c->crrtok = LINTERVAL; break;
101 case ']': c->crrtok = RINTERVAL; break;
103 if (isspace(*(c->data+c->offset)) || *(c->data+c->offset) == '\n')
110 c->crrval = *(c->data+c->offset);
114 fprintf(stderr, "gettoken(): offset: %d", c->offset);
115 if (c->crrtok == REGULAR)
116 fprintf(stderr, "<%c>", c->crrval);
117 fprintf(stderr, "\n");
122 void mc_ungettoken(mc_context *c)
127 int mc_getval(mc_context *c)
131 int mc_getdata(mc_context *c, char *s, int sz)
137 if (mc_gettoken(c)!=REGULAR)
148 void mc_getinterval(mc_context *c, int *start, int *end)
151 int start_pos, end_pos;
153 start_pos = end_pos = -1;
155 if (mc_gettoken(c) == LINTERVAL)
161 mc_token tok = mc_gettoken(c);
163 if (tok == RINTERVAL || tok == NOP)
166 buf[i] = mc_getval(c);
170 i = sscanf(buf, "%d-%d", &start_pos, &end_pos);
182 mc_field *mc_mk_field(void)
184 mc_field *p = (mc_field *)xmalloc(sizeof(*p));
188 memset(p, 0, sizeof(*p));
189 p->name = (char *)xmalloc(SZ_FNAME+1);
191 p->ind1 = (char *)xmalloc(SZ_IND+1);
193 p->ind2 = (char *)xmalloc(SZ_IND+1);
195 p->interval.start = p->interval.end = -1;
199 void mc_destroy_field(mc_field *p)
203 if (p->name) xfree(p->name);
204 if (p->ind1) xfree(p->ind1);
205 if (p->ind2) xfree(p->ind2);
206 if (p->list) mc_destroy_subfields_recursive(p->list);
209 mc_field *mc_getfield(mc_context *c)
217 c->errcode = EMCNOMEM;
221 if (mc_getdata(c, pf->name, SZ_FNAME) == SZ_FNAME)
223 mc_token nexttok = mc_gettoken(c);
227 if (nexttok == LINTERVAL)
229 mc_getinterval(c, &pf->interval.start, &pf->interval.end);
231 fprintf(stderr, "ineterval (%d)-(%d)\n", pf->interval.start,
236 if ((mc_getdata(c, pf->ind1, SZ_IND) == SZ_IND) &&
237 (mc_getdata(c, pf->ind2, SZ_IND) == SZ_IND))
239 pf->list = mc_getsubfields(c, 0);
245 mc_destroy_field(pf);
251 mc_subfield *mc_mk_subfield(mc_subfield *parent)
253 mc_subfield *p = (mc_subfield*)xmalloc(sizeof(*p));
257 memset(p, 0, sizeof(*p));
259 p->name = (char *)xmalloc(SZ_SFNAME+1);
261 p->prefix = (char *)xmalloc(SZ_PREFIX+1);
263 p->suffix = (char *)xmalloc(SZ_SUFFIX+1);
266 p->interval.start = p->interval.end = -1;
270 void mc_destroy_subfield(mc_subfield *p)
275 if (p->which == MC_SFGROUP || p->which == MC_SFVARIANT)
278 mc_destroy_subfields_recursive(p->u.child);
280 else if (p->which == MC_SF)
283 mc_destroy_field(p->u.in_line);
285 if (p->name) xfree(p->name);
286 if (p->prefix) xfree(p->prefix);
287 if (p->suffix) xfree(p->suffix);
288 if (p->parent) p->parent->next = p->next;
291 void mc_destroy_subfields_recursive(mc_subfield *p)
296 mc_destroy_subfields_recursive(p->next);
298 if (p->which == MC_SFGROUP || p->which == MC_SFVARIANT)
301 mc_destroy_subfields_recursive(p->u.child);
303 else if (p->which == MC_SF)
306 mc_destroy_field(p->u.in_line);
309 if (p->name) xfree(p->name);
310 if (p->prefix) xfree(p->prefix);
311 if (p->suffix) xfree(p->suffix);
312 if (p->parent) p->parent->next = 0;
315 mc_subfield *mc_getsubfields(mc_context *c, mc_subfield *parent)
318 mc_token tok = mc_gettoken(c);
325 if (!(psf = mc_mk_subfield(parent)))
327 c->errcode = EMCNOMEM;
331 psf->which = MC_SFGROUP;
332 psf->u.child = mc_getsubfields(c, psf);
334 if (mc_gettoken(c) == RGROUP)
335 psf->next = mc_getsubfields(c, psf);
338 c->errcode = EMCSFGROUP;
339 mc_destroy_subfield(psf);
343 else if (tok == LVARIANT)
345 if (!(psf = mc_mk_subfield(parent)))
347 c->errcode = EMCNOMEM;
351 psf->which = MC_SFVARIANT;
352 psf->u.child = mc_getsubfields(c, psf);
354 if (mc_gettoken(c) == RVARIANT)
355 psf->next = mc_getsubfields(c, psf);
358 c->errcode = EMCSFVAR;
359 mc_destroy_subfield(psf);
363 else if (tok == RGROUP || tok == RVARIANT || tok == RINLINE)
368 else if (tok == REGULAR)
370 if (!(psf = mc_mk_subfield(parent)))
372 c->errcode = EMCNOMEM;
378 if((mc_getdata(c, psf->prefix, SZ_PREFIX) == SZ_PREFIX) &&
379 (mc_gettoken(c) == SUBFIELD) &&
380 (mc_getdata(c, psf->name, SZ_SFNAME) == SZ_SFNAME))
382 mc_token tok = mc_gettoken(c);
386 if (tok == LINTERVAL)
388 mc_getinterval(c, &psf->interval.start, &psf->interval.end);
390 else if (tok == LINLINE)
393 psf->u.in_line = mc_getfield(c);
394 if (mc_gettoken(c) != RINLINE)
396 c->errcode = EMCSFINLINE;
397 mc_destroy_subfield(psf);
402 if (mc_getdata(c, psf->suffix, SZ_SUFFIX) == SZ_SUFFIX)
405 psf->next = mc_getsubfields(c, psf);
410 mc_destroy_subfield(psf);