2 $Id: marcomp.c,v 1.5 2005-01-03 19:27:53 adam Exp $
4 marcomp.c - compiler of MARC statements.
12 #include <yaz/yaz-util.h>
16 static mc_token mc_gettoken(mc_context *c);
17 static void mc_ungettoken(mc_context *c);
18 static int mc_getval(mc_context *c);
19 static int mc_getdata(mc_context *c, char *s, int sz);
20 static void mc_getinterval(mc_context *c, int *start, int *end);
22 static mc_subfield *mc_mk_subfield(mc_subfield *parent);
23 static mc_field *mc_mk_field(void);
25 static struct mc_errmsg
32 {EMCF, "not complete field"},
33 {EMCSF, "not complete subfield"},
34 {EMCSFGROUP, "not closed GROUP"},
35 {EMCSFVAR, "not closed VARIANT"},
36 {EMCSFINLINE, "not closed IN-LINE"},
37 {EMCEND, "not correct errno"}
39 mc_errcode mc_errno(mc_context *c)
43 const char *mc_error(mc_errcode no)
45 if (no >= EMCOK && no<EMCEND)
46 return mc_errmsg[no].msg;
48 return mc_errmsg[EMCEND].msg;
50 mc_context *mc_mk_context(const char *s)
56 p = (mc_context*) xmalloc(sizeof(*p));
61 memset(p, 0, sizeof(*p));
70 void mc_destroy_context(mc_context *c)
74 mc_token mc_gettoken(mc_context *c)
76 if (c->offset >= c->len)
79 switch (*(c->data+c->offset))
81 case '{': c->crrtok = LVARIANT; break;
82 case '}': c->crrtok = RVARIANT; break;
83 case '(': c->crrtok = LGROUP; break;
84 case ')': c->crrtok = RGROUP; break;
85 case '<': c->crrtok = LINLINE; break;
86 case '>': c->crrtok = RINLINE; break;
87 case '$': c->crrtok = SUBFIELD; break;
88 case '[': c->crrtok = LINTERVAL; break;
89 case ']': c->crrtok = RINTERVAL; break;
91 if (isspace(*(unsigned char *) (c->data+c->offset))
92 || *(c->data+c->offset) == '\n')
99 c->crrval = *(c->data+c->offset);
103 fprintf(stderr, "gettoken(): offset: %d", c->offset);
104 if (c->crrtok == REGULAR)
105 fprintf(stderr, "<%c>", c->crrval);
106 fprintf(stderr, "\n");
111 void mc_ungettoken(mc_context *c)
116 int mc_getval(mc_context *c)
120 int mc_getdata(mc_context *c, char *s, int sz)
126 if (mc_gettoken(c)!=REGULAR)
137 void mc_getinterval(mc_context *c, int *start, int *end)
140 int start_pos, end_pos;
142 start_pos = end_pos = -1;
144 if (mc_gettoken(c) == LINTERVAL)
150 mc_token tok = mc_gettoken(c);
152 if (tok == RINTERVAL || tok == NOP)
155 buf[i] = mc_getval(c);
159 i = sscanf(buf, "%d-%d", &start_pos, &end_pos);
171 mc_field *mc_mk_field(void)
173 mc_field *p = (mc_field *)xmalloc(sizeof(*p));
177 memset(p, 0, sizeof(*p));
178 p->name = (char *)xmalloc(SZ_FNAME+1);
180 p->ind1 = (char *)xmalloc(SZ_IND+1);
182 p->ind2 = (char *)xmalloc(SZ_IND+1);
184 p->interval.start = p->interval.end = -1;
188 void mc_destroy_field(mc_field *p)
192 if (p->name) xfree(p->name);
193 if (p->ind1) xfree(p->ind1);
194 if (p->ind2) xfree(p->ind2);
195 if (p->list) mc_destroy_subfields_recursive(p->list);
198 mc_field *mc_getfield(mc_context *c)
206 c->errcode = EMCNOMEM;
210 if (mc_getdata(c, pf->name, SZ_FNAME) == SZ_FNAME)
212 mc_token nexttok = mc_gettoken(c);
216 if (nexttok == LINTERVAL)
218 mc_getinterval(c, &pf->interval.start, &pf->interval.end);
220 fprintf(stderr, "ineterval (%d)-(%d)\n", pf->interval.start,
225 if ((mc_getdata(c, pf->ind1, SZ_IND) == SZ_IND) &&
226 (mc_getdata(c, pf->ind2, SZ_IND) == SZ_IND))
228 pf->list = mc_getsubfields(c, 0);
234 mc_destroy_field(pf);
240 mc_subfield *mc_mk_subfield(mc_subfield *parent)
242 mc_subfield *p = (mc_subfield*)xmalloc(sizeof(*p));
246 memset(p, 0, sizeof(*p));
248 p->name = (char *)xmalloc(SZ_SFNAME+1);
250 p->prefix = (char *)xmalloc(SZ_PREFIX+1);
252 p->suffix = (char *)xmalloc(SZ_SUFFIX+1);
255 p->interval.start = p->interval.end = -1;
259 void mc_destroy_subfield(mc_subfield *p)
264 if (p->which == MC_SFGROUP || p->which == MC_SFVARIANT)
267 mc_destroy_subfields_recursive(p->u.child);
269 else if (p->which == MC_SF)
272 mc_destroy_field(p->u.in_line);
274 if (p->name) xfree(p->name);
275 if (p->prefix) xfree(p->prefix);
276 if (p->suffix) xfree(p->suffix);
277 if (p->parent) p->parent->next = p->next;
280 void mc_destroy_subfields_recursive(mc_subfield *p)
285 mc_destroy_subfields_recursive(p->next);
287 if (p->which == MC_SFGROUP || p->which == MC_SFVARIANT)
290 mc_destroy_subfields_recursive(p->u.child);
292 else if (p->which == MC_SF)
295 mc_destroy_field(p->u.in_line);
298 if (p->name) xfree(p->name);
299 if (p->prefix) xfree(p->prefix);
300 if (p->suffix) xfree(p->suffix);
301 if (p->parent) p->parent->next = 0;
304 mc_subfield *mc_getsubfields(mc_context *c, mc_subfield *parent)
307 mc_token tok = mc_gettoken(c);
314 if (!(psf = mc_mk_subfield(parent)))
316 c->errcode = EMCNOMEM;
320 psf->which = MC_SFGROUP;
321 psf->u.child = mc_getsubfields(c, psf);
323 if (mc_gettoken(c) == RGROUP)
324 psf->next = mc_getsubfields(c, psf);
327 c->errcode = EMCSFGROUP;
328 mc_destroy_subfield(psf);
332 else if (tok == LVARIANT)
334 if (!(psf = mc_mk_subfield(parent)))
336 c->errcode = EMCNOMEM;
340 psf->which = MC_SFVARIANT;
341 psf->u.child = mc_getsubfields(c, psf);
343 if (mc_gettoken(c) == RVARIANT)
344 psf->next = mc_getsubfields(c, psf);
347 c->errcode = EMCSFVAR;
348 mc_destroy_subfield(psf);
352 else if (tok == RGROUP || tok == RVARIANT || tok == RINLINE)
357 else if (tok == REGULAR)
359 if (!(psf = mc_mk_subfield(parent)))
361 c->errcode = EMCNOMEM;
367 if((mc_getdata(c, psf->prefix, SZ_PREFIX) == SZ_PREFIX) &&
368 (mc_gettoken(c) == SUBFIELD) &&
369 (mc_getdata(c, psf->name, SZ_SFNAME) == SZ_SFNAME))
371 mc_token tok = mc_gettoken(c);
375 if (tok == LINTERVAL)
377 mc_getinterval(c, &psf->interval.start, &psf->interval.end);
379 else if (tok == LINLINE)
382 psf->u.in_line = mc_getfield(c);
383 if (mc_gettoken(c) != RINLINE)
385 c->errcode = EMCSFINLINE;
386 mc_destroy_subfield(psf);
391 if (mc_getdata(c, psf->suffix, SZ_SUFFIX) == SZ_SUFFIX)
394 psf->next = mc_getsubfields(c, psf);
399 mc_destroy_subfield(psf);