=================================================================== RCS file: /cvs/mandoc/eqn.c,v retrieving revision 1.28 retrieving revision 1.33 diff -u -p -r1.28 -r1.33 --- mandoc/eqn.c 2011/07/22 14:26:32 1.28 +++ mandoc/eqn.c 2011/07/23 12:08:43 1.33 @@ -1,4 +1,4 @@ -/* $Id: eqn.c,v 1.28 2011/07/22 14:26:32 kristaps Exp $ */ +/* $Id: eqn.c,v 1.33 2011/07/23 12:08:43 kristaps Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * @@ -126,19 +126,30 @@ enum eqnpartt { EQN_DEFINE = 0, EQN_SET, EQN_UNDEF, + EQN_GFONT, + EQN_GSIZE, + EQN_BACK, + EQN_FWD, + EQN_UP, + EQN_DOWN, EQN__MAX }; static enum eqn_rest eqn_box(struct eqn_node *, struct eqn_box *); -static struct eqn_box *eqn_box_alloc(struct eqn_box *); +static struct eqn_box *eqn_box_alloc(struct eqn_node *, + struct eqn_box *); static void eqn_box_free(struct eqn_box *); static struct eqn_def *eqn_def_find(struct eqn_node *, const char *, size_t); +static int eqn_do_gfont(struct eqn_node *); +static int eqn_do_gsize(struct eqn_node *); static int eqn_do_define(struct eqn_node *); -static int eqn_do_set(struct eqn_node *); +static int eqn_do_ign1(struct eqn_node *); +static int eqn_do_ign2(struct eqn_node *); static int eqn_do_undef(struct eqn_node *); static enum eqn_rest eqn_eqn(struct eqn_node *, struct eqn_box *); static enum eqn_rest eqn_list(struct eqn_node *, struct eqn_box *); +static enum eqn_rest eqn_matrix(struct eqn_node *, struct eqn_box *); static const char *eqn_nexttok(struct eqn_node *, size_t *); static const char *eqn_nextrawtok(struct eqn_node *, size_t *); static const char *eqn_next(struct eqn_node *, @@ -147,8 +158,14 @@ static void eqn_rewind(struct eqn_node *); static const struct eqnpart eqnparts[EQN__MAX] = { { { "define", 6 }, eqn_do_define }, /* EQN_DEFINE */ - { { "set", 3 }, eqn_do_set }, /* EQN_SET */ + { { "set", 3 }, eqn_do_ign2 }, /* EQN_SET */ { { "undef", 5 }, eqn_do_undef }, /* EQN_UNDEF */ + { { "gfont", 5 }, eqn_do_gfont }, /* EQN_GFONT */ + { { "gsize", 5 }, eqn_do_gsize }, /* EQN_GSIZE */ + { { "back", 4 }, eqn_do_ign1 }, /* EQN_BACK */ + { { "fwd", 3 }, eqn_do_ign1 }, /* EQN_FWD */ + { { "up", 2 }, eqn_do_ign1 }, /* EQN_UP */ + { { "down", 4 }, eqn_do_ign1 }, /* EQN_DOWN */ }; static const struct eqnstr eqnmarks[EQNMARK__MAX] = { @@ -184,6 +201,9 @@ static const struct eqnstr eqnpiles[EQNPILE__MAX] = { { "cpile", 5 }, /* EQNPILE_CPILE */ { "rpile", 5 }, /* EQNPILE_RPILE */ { "lpile", 5 }, /* EQNPILE_LPILE */ + { "ccol", 4 }, /* EQNPILE_CCOL */ + { "rcol", 4 }, /* EQNPILE_RCOL */ + { "lcol", 4 }, /* EQNPILE_LCOL */ }; static const struct eqnsym eqnsyms[EQNSYM__MAX] = { @@ -298,6 +318,7 @@ eqn_alloc(int pos, int line, struct mparse *parse) p->parse = parse; p->eqn.ln = line; p->eqn.pos = pos; + p->gsize = EQN_DEFSIZE; return(p); } @@ -330,7 +351,7 @@ eqn_eqn(struct eqn_node *ep, struct eqn_box *last) struct eqn_box *bp; enum eqn_rest c; - bp = eqn_box_alloc(last); + bp = eqn_box_alloc(ep, last); bp->type = EQN_SUBEXPR; while (EQN_OK == (c = eqn_box(ep, bp))) @@ -340,6 +361,55 @@ eqn_eqn(struct eqn_node *ep, struct eqn_box *last) } static enum eqn_rest +eqn_matrix(struct eqn_node *ep, struct eqn_box *last) +{ + struct eqn_box *bp; + const char *start; + size_t sz; + enum eqn_rest c; + + bp = eqn_box_alloc(ep, last); + bp->type = EQN_MATRIX; + + if (NULL == (start = eqn_nexttok(ep, &sz))) { + EQN_MSG(MANDOCERR_EQNEOF, ep); + return(EQN_ERR); + } + if ( ! STRNEQ(start, sz, "{", 1)) { + EQN_MSG(MANDOCERR_EQNSYNT, ep); + return(EQN_ERR); + } + + while (EQN_OK == (c = eqn_box(ep, bp))) + switch (bp->last->pile) { + case (EQNPILE_LCOL): + /* FALLTHROUGH */ + case (EQNPILE_CCOL): + /* FALLTHROUGH */ + case (EQNPILE_RCOL): + continue; + default: + EQN_MSG(MANDOCERR_EQNSYNT, ep); + return(EQN_ERR); + }; + + if (EQN_DESCOPE != c) { + if (EQN_EOF == c) + EQN_MSG(MANDOCERR_EQNEOF, ep); + return(EQN_ERR); + } + + eqn_rewind(ep); + start = eqn_nexttok(ep, &sz); + assert(start); + if (STRNEQ(start, sz, "}", 1)) + return(EQN_OK); + + EQN_MSG(MANDOCERR_EQNBADSCOPE, ep); + return(EQN_ERR); +} + +static enum eqn_rest eqn_list(struct eqn_node *ep, struct eqn_box *last) { struct eqn_box *bp; @@ -347,7 +417,7 @@ eqn_list(struct eqn_node *ep, struct eqn_box *last) size_t sz; enum eqn_rest c; - bp = eqn_box_alloc(last); + bp = eqn_box_alloc(ep, last); bp->type = EQN_LIST; if (NULL == (start = eqn_nexttok(ep, &sz))) { @@ -365,7 +435,6 @@ eqn_list(struct eqn_node *ep, struct eqn_box *last) assert(start); if ( ! STRNEQ(start, sz, "above", 5)) break; - bp->last->above = 1; } if (EQN_DESCOPE != c) { @@ -404,6 +473,10 @@ eqn_box(struct eqn_node *ep, struct eqn_box *last) return(EQN_DESCOPE); else if (STRNEQ(start, sz, "above", 5)) return(EQN_DESCOPE); + else if (STRNEQ(start, sz, "mark", 4)) + return(EQN_OK); + else if (STRNEQ(start, sz, "lineup", 6)) + return(EQN_OK); for (i = 0; i < (int)EQN__MAX; i++) { if ( ! EQNSTREQ(&eqnparts[i].str, start, sz)) @@ -434,6 +507,9 @@ eqn_box(struct eqn_node *ep, struct eqn_box *last) return(c); } + if (STRNEQ(start, sz, "matrix", 6)) + return(eqn_matrix(ep, last)); + if (STRNEQ(start, sz, "left", 4)) { if (NULL == (start = eqn_nexttok(ep, &sz))) { EQN_MSG(MANDOCERR_EQNEOF, ep); @@ -516,7 +592,7 @@ eqn_box(struct eqn_node *ep, struct eqn_box *last) last->last->size = size; } - bp = eqn_box_alloc(last); + bp = eqn_box_alloc(ep, last); bp->type = EQN_TEXT; for (i = 0; i < (int)EQNSYM__MAX; i++) if (EQNSTREQ(&eqnsyms[i].str, start, sz)) { @@ -548,13 +624,13 @@ eqn_free(struct eqn_node *p) } static struct eqn_box * -eqn_box_alloc(struct eqn_box *parent) +eqn_box_alloc(struct eqn_node *ep, struct eqn_box *parent) { struct eqn_box *bp; bp = mandoc_calloc(1, sizeof(struct eqn_box)); bp->parent = parent; - bp->size = EQN_DEFSIZE; + bp->size = ep->gsize; if (NULL == parent->first) parent->first = bp; @@ -640,7 +716,7 @@ again: if ('{' == *start || '}' == *start) ssz = 1; else - ssz = strcspn(start + 1, " ~\"{}\t") + 1; + ssz = strcspn(start + 1, " ^~\"{}\t") + 1; next = start + (int)ssz; if ('\0' == *next) next = NULL; @@ -654,6 +730,7 @@ again: ep->cur++; while (' ' == ep->data[(int)ep->cur] || '\t' == ep->data[(int)ep->cur] || + '^' == ep->data[(int)ep->cur] || '~' == ep->data[(int)ep->cur]) ep->cur++; } else { @@ -690,14 +767,27 @@ again: } static int -eqn_do_set(struct eqn_node *ep) +eqn_do_ign1(struct eqn_node *ep) { const char *start; if (NULL == (start = eqn_nextrawtok(ep, NULL))) - EQN_MSG(MANDOCERR_EQNARGS, ep); + EQN_MSG(MANDOCERR_EQNEOF, ep); + else + return(1); + + return(0); +} + +static int +eqn_do_ign2(struct eqn_node *ep) +{ + const char *start; + + if (NULL == (start = eqn_nextrawtok(ep, NULL))) + EQN_MSG(MANDOCERR_EQNEOF, ep); else if (NULL == (start = eqn_nextrawtok(ep, NULL))) - EQN_MSG(MANDOCERR_EQNARGS, ep); + EQN_MSG(MANDOCERR_EQNEOF, ep); else return(1); @@ -713,7 +803,7 @@ eqn_do_define(struct eqn_node *ep) int i; if (NULL == (start = eqn_nextrawtok(ep, &sz))) { - EQN_MSG(MANDOCERR_EQNARGS, ep); + EQN_MSG(MANDOCERR_EQNEOF, ep); return(0); } @@ -748,7 +838,7 @@ eqn_do_define(struct eqn_node *ep) start = eqn_next(ep, ep->data[(int)ep->cur], &sz, 0); if (NULL == start) { - EQN_MSG(MANDOCERR_EQNARGS, ep); + EQN_MSG(MANDOCERR_EQNEOF, ep); return(0); } @@ -760,6 +850,33 @@ eqn_do_define(struct eqn_node *ep) } static int +eqn_do_gfont(struct eqn_node *ep) +{ + const char *start; + + if (NULL == (start = eqn_nextrawtok(ep, NULL))) { + EQN_MSG(MANDOCERR_EQNEOF, ep); + return(0); + } + return(1); +} + +static int +eqn_do_gsize(struct eqn_node *ep) +{ + const char *start; + size_t sz; + + if (NULL == (start = eqn_nextrawtok(ep, &sz))) { + EQN_MSG(MANDOCERR_EQNEOF, ep); + return(0); + } + + ep->gsize = mandoc_strntoi(start, sz, 10); + return(1); +} + +static int eqn_do_undef(struct eqn_node *ep) { const char *start; @@ -767,7 +884,7 @@ eqn_do_undef(struct eqn_node *ep) size_t sz; if (NULL == (start = eqn_nextrawtok(ep, &sz))) { - EQN_MSG(MANDOCERR_EQNARGS, ep); + EQN_MSG(MANDOCERR_EQNEOF, ep); return(0); } else if (NULL != (def = eqn_def_find(ep, start, sz))) def->keysz = 0;