-/* $Id: tbl_layout.c,v 1.7 2011/01/02 12:04:23 kristaps Exp $ */
+/* $Id: tbl_layout.c,v 1.15 2011/01/10 15:31:00 kristaps Exp $ */
/*
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
enum tbl_cellt key;
};
+/*
+ * FIXME: we can make this parse a lot nicer by, when an error is
+ * encountered in a layout key, bailing to the next key (i.e. to the
+ * next whitespace then continuing).
+ */
+
#define KEYS_MAX 11
static const struct tbl_phrase keys[KEYS_MAX] = {
break;
}
+ /* Throw away parenthesised expression. */
+
+ if ('(' == p[*pos]) {
+ (*pos)++;
+ while (p[*pos] && ')' != p[*pos])
+ (*pos)++;
+ if (')' == p[*pos]) {
+ (*pos)++;
+ goto mod;
+ }
+ TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos);
+ return(0);
+ }
+
/* Parse numerical spacing from modifier string. */
if (isdigit((unsigned char)p[*pos])) {
}
*pos += i;
- cp->spacing = atoi(buf);
+ cp->spacing = (size_t)atoi(buf);
goto mod;
/* NOTREACHED */
/* TODO: GNU has many more extensions. */
- switch (tolower(p[(*pos)++])) {
+ switch (tolower((unsigned char)p[(*pos)++])) {
case ('z'):
cp->flags |= TBL_CELL_WIGN;
goto mod;
case ('d'):
cp->flags |= TBL_CELL_BALIGN;
goto mod;
+ case ('w'): /* XXX for now, ignore minimal column width */
+ goto mod;
case ('f'):
break;
case ('b'):
return(0);
}
- switch (tolower(p[(*pos)++])) {
+ switch (tolower((unsigned char)p[(*pos)++])) {
case ('b'):
cp->flags |= TBL_CELL_BOLD;
goto mod;
/* Parse the column position (`r', `R', `|', ...). */
for (i = 0; i < KEYS_MAX; i++)
- if (tolower(p[*pos]) == keys[i].name)
+ if (tolower((unsigned char)p[*pos]) == keys[i].name)
break;
if (KEYS_MAX == i) {
return(0);
}
- (*pos)++;
c = keys[i].key;
+ /*
+ * If a span cell is found first, raise a warning and abort the
+ * parse. If a span cell is found and the last layout element
+ * isn't a "normal" layout, bail.
+ *
+ * FIXME: recover from this somehow?
+ */
+
+ if (TBL_CELL_SPAN == c) {
+ if (NULL == rp->first) {
+ TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos);
+ return(0);
+ } else if (rp->last)
+ switch (rp->last->pos) {
+ case (TBL_CELL_VERT):
+ case (TBL_CELL_DVERT):
+ case (TBL_CELL_HORIZ):
+ case (TBL_CELL_DHORIZ):
+ TBL_MSG(tbl, MANDOCERR_TBLLAYOUT, ln, *pos);
+ return(0);
+ default:
+ break;
+ }
+ }
+
+ (*pos)++;
+
/* Extra check for the double-vertical. */
if (TBL_CELL_VERT == c && '|' == p[*pos]) {
* ones.
*/
- h = pp ? pp->head->prev : tbl->first_head;
+ h = pp ? pp->head->next : tbl->first_head;
if (h) {
/* Re-use data header. */
(TBL_CELL_VERT == p->pos ||
TBL_CELL_DVERT == p->pos)) {
hp = mandoc_calloc(1, sizeof(struct tbl_head));
+ hp->ident = tbl->opts.cols++;
hp->prev = h->prev;
if (h->prev)
h->prev->next = hp;
}
hp = mandoc_calloc(1, sizeof(struct tbl_head));
+ hp->ident = tbl->opts.cols++;
if (tbl->last_head) {
hp->prev = tbl->last_head;