summaryrefslogtreecommitdiff
path: root/usr.bin/mandoc/tbl_data.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2011-01-04 22:28:18 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2011-01-04 22:28:18 +0000
commit3f808e58f9b1e56a31e679de60386c10cefbe115 (patch)
treebc87b62f89cfcead15638c92e75e667be76752d5 /usr.bin/mandoc/tbl_data.c
parent520623cefde5dd43125b0e3bd121266079514407 (diff)
Merge kristaps@' cleaner tbl integration, removing mine;
there are still a few bugs, but fixing these will be easier in tree.
Diffstat (limited to 'usr.bin/mandoc/tbl_data.c')
-rw-r--r--usr.bin/mandoc/tbl_data.c215
1 files changed, 137 insertions, 78 deletions
diff --git a/usr.bin/mandoc/tbl_data.c b/usr.bin/mandoc/tbl_data.c
index 09bfbebcda5..a10404df38a 100644
--- a/usr.bin/mandoc/tbl_data.c
+++ b/usr.bin/mandoc/tbl_data.c
@@ -1,6 +1,6 @@
-/* $Id: tbl_data.c,v 1.3 2010/10/15 23:19:40 schwarze Exp $ */
+/* $Id: tbl_data.c,v 1.4 2011/01/04 22:28:17 schwarze Exp $ */
/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,119 +14,178 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <sys/queue.h>
-#include <sys/types.h>
-
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
-#include "out.h"
-#include "term.h"
-#include "tbl_extern.h"
-
-/* FIXME: warn about losing data contents if cell is HORIZ. */
-
-static int data(struct tbl *, struct tbl_span *,
- const char *, int, int,
- const char *, int, int);
+#include "mandoc.h"
+#include "libmandoc.h"
+#include "libroff.h"
+static int data(struct tbl_node *, struct tbl_span *,
+ int, const char *, int *);
-int
-data(struct tbl *tbl, struct tbl_span *dp,
- const char *f, int ln, int pos,
- const char *p, int start, int end)
+static int
+data(struct tbl_node *tbl, struct tbl_span *dp,
+ int ln, const char *p, int *pos)
{
- struct tbl_data *dat;
-
- if (NULL == (dat = tbl_data_alloc(dp)))
+ struct tbl_dat *dat;
+ struct tbl_cell *cp;
+ int sv;
+
+ cp = NULL;
+ if (dp->last && dp->last->layout)
+ cp = dp->last->layout->next;
+ else if (NULL == dp->last)
+ cp = dp->layout->first;
+
+ /* Skip over spanners to data formats. */
+
+ while (cp && (TBL_CELL_VERT == cp->pos ||
+ TBL_CELL_DVERT == cp->pos))
+ cp = cp->next;
+
+ dat = mandoc_calloc(1, sizeof(struct tbl_dat));
+ dat->layout = cp;
+ dat->pos = TBL_DATA_NONE;
+
+ if (NULL == dat->layout)
+ TBL_MSG(tbl, MANDOCERR_TBLEXTRADAT, ln, *pos);
+
+ if (dp->last) {
+ dp->last->next = dat;
+ dp->last = dat;
+ } else
+ dp->last = dp->first = dat;
+
+ sv = *pos;
+ while (p[*pos] && p[*pos] != tbl->opts.tab)
+ (*pos)++;
+
+ /*
+ * Check for a continued-data scope opening. This consists of a
+ * trailing `T{' at the end of the line. Subsequent lines,
+ * until a standalone `T}', are included in our cell.
+ */
+
+ if (*pos - sv == 2 && 'T' == p[sv] && '{' == p[sv + 1]) {
+ tbl->part = TBL_PART_CDATA;
return(0);
+ }
- if (NULL == dat->cell)
- if ( ! tbl_warnx(tbl, ERR_SYNTAX, f, ln, pos))
- return(0);
-
- assert(end >= start);
- if (NULL == (dat->string = malloc((size_t)(end - start + 1))))
- return(tbl_err(tbl));
-
- (void)memcpy(dat->string, &p[start], (size_t)(end - start));
- dat->string[end - start] = 0;
+ dat->string = mandoc_malloc(*pos - sv + 1);
+ memcpy(dat->string, &p[sv], *pos - sv);
+ dat->string[*pos - sv] = '\0';
- /* XXX: do the strcmps, then malloc(). */
+ if (p[*pos])
+ (*pos)++;
if ( ! strcmp(dat->string, "_"))
- dat->flags |= TBL_DATA_HORIZ;
+ dat->pos = TBL_DATA_HORIZ;
else if ( ! strcmp(dat->string, "="))
- dat->flags |= TBL_DATA_DHORIZ;
+ dat->pos = TBL_DATA_DHORIZ;
else if ( ! strcmp(dat->string, "\\_"))
- dat->flags |= TBL_DATA_NHORIZ;
+ dat->pos = TBL_DATA_NHORIZ;
else if ( ! strcmp(dat->string, "\\="))
- dat->flags |= TBL_DATA_NDHORIZ;
+ dat->pos = TBL_DATA_NDHORIZ;
else
+ dat->pos = TBL_DATA_DATA;
+
+ if (NULL == dat->layout)
return(1);
- free(dat->string);
- dat->string = NULL;
+ if (TBL_CELL_HORIZ == dat->layout->pos ||
+ TBL_CELL_DHORIZ == dat->layout->pos)
+ if (TBL_DATA_DATA == dat->pos && '\0' != *dat->string)
+ TBL_MSG(tbl, MANDOCERR_TBLIGNDATA, ln, sv);
+
return(1);
}
+int
+tbl_cdata(struct tbl_node *tbl, int ln, const char *p)
+{
+ struct tbl_dat *dat;
+ size_t sz;
+
+ if (0 == strcmp(p, "T}")) {
+ tbl->part = TBL_PART_DATA;
+ return(1);
+ }
+
+ dat = tbl->last_span->last;
+ dat->pos = TBL_DATA_DATA;
+
+ if (dat->string) {
+ sz = strlen(p) + strlen(dat->string) + 2;
+ dat->string = mandoc_realloc(dat->string, sz);
+ strlcat(dat->string, " ", sz);
+ strlcat(dat->string, p, sz);
+ } else
+ dat->string = mandoc_strdup(p);
+
+ return(0);
+}
int
-tbl_data(struct tbl *tbl, const char *f, int ln, const char *p)
+tbl_data(struct tbl_node *tbl, int ln, const char *p)
{
struct tbl_span *dp;
- int i, j;
-
- if ('.' == p[0] && ! isdigit((u_char)p[1])) {
- /* Comment lines end up here with just a dot. */
- if ('\0' == p[1])
- return(1);
- /*
- * XXX: departs from tbl convention in that we disallow
- * macros in the data body.
- */
- if (strncasecmp(p, ".T&", 3))
- return(tbl_errx(tbl, ERR_SYNTAX, f, ln, 0));
- return(tbl_data_close(tbl, f, ln));
- }
+ struct tbl_row *rp;
+ int pos;
- if (NULL == (dp = tbl_span_alloc(tbl)))
+ pos = 0;
+
+ if ('\0' == p[pos]) {
+ TBL_MSG(tbl, MANDOCERR_TBL, ln, pos);
return(0);
+ }
+
+ /*
+ * Choose a layout row: take the one following the last parsed
+ * span's. If that doesn't exist, use the last parsed span's.
+ * If there's no last parsed span, use the first row. This can
+ * be NULL!
+ */
+
+ if (tbl->last_span) {
+ assert(tbl->last_span->layout);
+ rp = tbl->last_span->layout->next;
+ if (NULL == rp)
+ rp = tbl->last_span->layout;
+ } else
+ rp = tbl->first_row;
+
+ dp = mandoc_calloc(1, sizeof(struct tbl_span));
+ dp->tbl = &tbl->opts;
+ dp->layout = rp;
+ dp->head = tbl->first_head;
+
+ if (tbl->last_span) {
+ tbl->last_span->next = dp;
+ tbl->last_span = dp;
+ } else {
+ tbl->last_span = tbl->first_span = dp;
+ dp->flags |= TBL_SPAN_FIRST;
+ }
if ( ! strcmp(p, "_")) {
- dp->flags |= TBL_SPAN_HORIZ;
+ dp->pos = TBL_SPAN_HORIZ;
return(1);
} else if ( ! strcmp(p, "=")) {
- dp->flags |= TBL_SPAN_DHORIZ;
+ dp->pos = TBL_SPAN_DHORIZ;
return(1);
}
- for (j = i = 0; p[i]; i++) {
- if (p[i] != tbl->tab)
- continue;
- if ( ! data(tbl, dp, f, ln, i, p, j, i))
- return(0);
- j = i + 1;
- }
-
- return(data(tbl, dp, f, ln, i, p, j, i));
-}
+ dp->pos = TBL_SPAN_DATA;
+ /* This returns 0 when TBL_PART_CDATA is entered. */
-int
-tbl_data_close(struct tbl *tbl, const char *f, int ln)
-{
- struct tbl_span *span;
-
- /* LINTED */
- span = TAILQ_LAST(&tbl->span, tbl_spanh);
- if (NULL == span)
- return(tbl_errx(tbl, ERR_SYNTAX, f, ln, 0));
- if (TAILQ_NEXT(span->row, entries))
- return(tbl_errx(tbl, ERR_SYNTAX, f, ln, 0));
+ while ('\0' != p[pos])
+ if ( ! data(tbl, dp, ln, p, &pos))
+ return(0);
- tbl->part = TBL_PART_LAYOUT;
return(1);
}