+ return(i + 1);
+ }
+
+ assert(lim > 0);
+ *sz = (size_t)lim;
+
+ for (j = 0; wp[i] && j < lim; j++)
+ i++;
+ if (j < lim)
+ *d = DECO_NONE;
+
+ return(i);
+}
+
+/*
+ * Calculate the abstract widths and decimal positions of columns in a
+ * table. This routine allocates the columns structures then runs over
+ * all rows and cells in the table. The function pointers in "tbl" are
+ * used for the actual width calculations.
+ */
+void
+tblcalc(struct rofftbl *tbl, const struct tbl_span *sp)
+{
+ const struct tbl_dat *dp;
+ const struct tbl_head *hp;
+ struct roffcol *col;
+
+ /*
+ * Allocate the master column specifiers. These will hold the
+ * widths and decimal positions for all cells in the column. It
+ * must be freed and nullified by the caller.
+ */
+
+ assert(NULL == tbl->cols);
+ tbl->cols = mandoc_calloc
+ ((size_t)sp->tbl->cols, sizeof(struct roffcol));
+
+ hp = sp->head;
+
+ for ( ; sp; sp = sp->next) {
+ if (TBL_SPAN_DATA != sp->pos)
+ continue;
+ /*
+ * Account for the data cells in the layout, matching it
+ * to data cells in the data section.
+ */
+ for (dp = sp->first; dp; dp = dp->next) {
+ assert(dp->layout);
+ col = &tbl->cols[dp->layout->head->ident];
+ tblcalc_data(tbl, col, sp->tbl, dp);
+ }
+ }
+
+ /*
+ * Calculate width of the spanners. These get one space for a
+ * vertical line, two for a double-vertical line.
+ */
+
+ for ( ; hp; hp = hp->next) {
+ col = &tbl->cols[hp->ident];
+ switch (hp->pos) {
+ case (TBL_HEAD_VERT):
+ col->width = (*tbl->len)(1, tbl->arg);