xref: /illumos-gate/usr/src/cmd/mandoc/tbl.c (revision 371584c2)
1*371584c2SYuri Pankov /*	$Id: tbl.c,v 1.40 2015/10/06 18:32:20 schwarze Exp $ */
295c635efSGarrett D'Amore /*
395c635efSGarrett D'Amore  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
4260e9a87SYuri Pankov  * Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org>
595c635efSGarrett D'Amore  *
695c635efSGarrett D'Amore  * Permission to use, copy, modify, and distribute this software for any
795c635efSGarrett D'Amore  * purpose with or without fee is hereby granted, provided that the above
895c635efSGarrett D'Amore  * copyright notice and this permission notice appear in all copies.
995c635efSGarrett D'Amore  *
1095c635efSGarrett D'Amore  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1195c635efSGarrett D'Amore  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1295c635efSGarrett D'Amore  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1395c635efSGarrett D'Amore  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1495c635efSGarrett D'Amore  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1595c635efSGarrett D'Amore  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1695c635efSGarrett D'Amore  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1795c635efSGarrett D'Amore  */
1895c635efSGarrett D'Amore #include "config.h"
19260e9a87SYuri Pankov 
20260e9a87SYuri Pankov #include <sys/types.h>
2195c635efSGarrett D'Amore 
2295c635efSGarrett D'Amore #include <assert.h>
2395c635efSGarrett D'Amore #include <stdio.h>
2495c635efSGarrett D'Amore #include <stdlib.h>
2595c635efSGarrett D'Amore #include <string.h>
2695c635efSGarrett D'Amore #include <time.h>
2795c635efSGarrett D'Amore 
2895c635efSGarrett D'Amore #include "mandoc.h"
29260e9a87SYuri Pankov #include "mandoc_aux.h"
3095c635efSGarrett D'Amore #include "libmandoc.h"
3195c635efSGarrett D'Amore #include "libroff.h"
3295c635efSGarrett D'Amore 
33260e9a87SYuri Pankov 
3495c635efSGarrett D'Amore enum rofferr
35260e9a87SYuri Pankov tbl_read(struct tbl_node *tbl, int ln, const char *p, int pos)
3695c635efSGarrett D'Amore {
3795c635efSGarrett D'Amore 	const char	*cp;
38260e9a87SYuri Pankov 	int		 active;
3995c635efSGarrett D'Amore 
4095c635efSGarrett D'Amore 	/*
41260e9a87SYuri Pankov 	 * In the options section, proceed to the layout section
42260e9a87SYuri Pankov 	 * after a semicolon, or right away if there is no semicolon.
43260e9a87SYuri Pankov 	 * Ignore semicolons in arguments.
4495c635efSGarrett D'Amore 	 */
4595c635efSGarrett D'Amore 
46260e9a87SYuri Pankov 	if (tbl->part == TBL_PART_OPTS) {
47260e9a87SYuri Pankov 		tbl->part = TBL_PART_LAYOUT;
48260e9a87SYuri Pankov 		active = 1;
49260e9a87SYuri Pankov 		for (cp = p + pos; *cp != '\0'; cp++) {
50260e9a87SYuri Pankov 			switch (*cp) {
51260e9a87SYuri Pankov 			case '(':
52260e9a87SYuri Pankov 				active = 0;
53260e9a87SYuri Pankov 				continue;
54260e9a87SYuri Pankov 			case ')':
55260e9a87SYuri Pankov 				active = 1;
56260e9a87SYuri Pankov 				continue;
57260e9a87SYuri Pankov 			case ';':
58260e9a87SYuri Pankov 				if (active)
59260e9a87SYuri Pankov 					break;
60260e9a87SYuri Pankov 				continue;
61260e9a87SYuri Pankov 			default:
62260e9a87SYuri Pankov 				continue;
63260e9a87SYuri Pankov 			}
64260e9a87SYuri Pankov 			break;
65260e9a87SYuri Pankov 		}
66260e9a87SYuri Pankov 		if (*cp == ';') {
67260e9a87SYuri Pankov 			tbl_option(tbl, ln, p, &pos);
68260e9a87SYuri Pankov 			if (p[pos] == '\0')
69*371584c2SYuri Pankov 				return ROFF_IGN;
70260e9a87SYuri Pankov 		}
71260e9a87SYuri Pankov 	}
7295c635efSGarrett D'Amore 
73260e9a87SYuri Pankov 	/* Process the other section types.  */
7495c635efSGarrett D'Amore 
7595c635efSGarrett D'Amore 	switch (tbl->part) {
76260e9a87SYuri Pankov 	case TBL_PART_LAYOUT:
77260e9a87SYuri Pankov 		tbl_layout(tbl, ln, p, pos);
78*371584c2SYuri Pankov 		return ROFF_IGN;
79260e9a87SYuri Pankov 	case TBL_PART_CDATA:
80*371584c2SYuri Pankov 		return tbl_cdata(tbl, ln, p, pos) ? ROFF_TBL : ROFF_IGN;
8195c635efSGarrett D'Amore 	default:
8295c635efSGarrett D'Amore 		break;
8395c635efSGarrett D'Amore 	}
8495c635efSGarrett D'Amore 
85260e9a87SYuri Pankov 	tbl_data(tbl, ln, p, pos);
86*371584c2SYuri Pankov 	return ROFF_TBL;
8795c635efSGarrett D'Amore }
8895c635efSGarrett D'Amore 
8995c635efSGarrett D'Amore struct tbl_node *
9095c635efSGarrett D'Amore tbl_alloc(int pos, int line, struct mparse *parse)
9195c635efSGarrett D'Amore {
92698f87a4SGarrett D'Amore 	struct tbl_node	*tbl;
93698f87a4SGarrett D'Amore 
94260e9a87SYuri Pankov 	tbl = mandoc_calloc(1, sizeof(*tbl));
95698f87a4SGarrett D'Amore 	tbl->line = line;
96698f87a4SGarrett D'Amore 	tbl->pos = pos;
97698f87a4SGarrett D'Amore 	tbl->parse = parse;
98698f87a4SGarrett D'Amore 	tbl->part = TBL_PART_OPTS;
99698f87a4SGarrett D'Amore 	tbl->opts.tab = '\t';
100698f87a4SGarrett D'Amore 	tbl->opts.decimal = '.';
101*371584c2SYuri Pankov 	return tbl;
10295c635efSGarrett D'Amore }
10395c635efSGarrett D'Amore 
10495c635efSGarrett D'Amore void
105698f87a4SGarrett D'Amore tbl_free(struct tbl_node *tbl)
10695c635efSGarrett D'Amore {
10795c635efSGarrett D'Amore 	struct tbl_row	*rp;
10895c635efSGarrett D'Amore 	struct tbl_cell	*cp;
10995c635efSGarrett D'Amore 	struct tbl_span	*sp;
11095c635efSGarrett D'Amore 	struct tbl_dat	*dp;
11195c635efSGarrett D'Amore 
112260e9a87SYuri Pankov 	while ((rp = tbl->first_row) != NULL) {
113698f87a4SGarrett D'Amore 		tbl->first_row = rp->next;
114260e9a87SYuri Pankov 		while (rp->first != NULL) {
11595c635efSGarrett D'Amore 			cp = rp->first;
11695c635efSGarrett D'Amore 			rp->first = cp->next;
11795c635efSGarrett D'Amore 			free(cp);
11895c635efSGarrett D'Amore 		}
11995c635efSGarrett D'Amore 		free(rp);
12095c635efSGarrett D'Amore 	}
12195c635efSGarrett D'Amore 
122260e9a87SYuri Pankov 	while ((sp = tbl->first_span) != NULL) {
123698f87a4SGarrett D'Amore 		tbl->first_span = sp->next;
124260e9a87SYuri Pankov 		while (sp->first != NULL) {
12595c635efSGarrett D'Amore 			dp = sp->first;
12695c635efSGarrett D'Amore 			sp->first = dp->next;
127260e9a87SYuri Pankov 			free(dp->string);
12895c635efSGarrett D'Amore 			free(dp);
12995c635efSGarrett D'Amore 		}
13095c635efSGarrett D'Amore 		free(sp);
13195c635efSGarrett D'Amore 	}
13295c635efSGarrett D'Amore 
133698f87a4SGarrett D'Amore 	free(tbl);
13495c635efSGarrett D'Amore }
13595c635efSGarrett D'Amore 
13695c635efSGarrett D'Amore void
13795c635efSGarrett D'Amore tbl_restart(int line, int pos, struct tbl_node *tbl)
13895c635efSGarrett D'Amore {
139260e9a87SYuri Pankov 	if (tbl->part == TBL_PART_CDATA)
140260e9a87SYuri Pankov 		mandoc_msg(MANDOCERR_TBLDATA_BLK, tbl->parse,
141260e9a87SYuri Pankov 		    line, pos, "T&");
14295c635efSGarrett D'Amore 
14395c635efSGarrett D'Amore 	tbl->part = TBL_PART_LAYOUT;
14495c635efSGarrett D'Amore 	tbl->line = line;
14595c635efSGarrett D'Amore 	tbl->pos = pos;
14695c635efSGarrett D'Amore }
14795c635efSGarrett D'Amore 
14895c635efSGarrett D'Amore const struct tbl_span *
14995c635efSGarrett D'Amore tbl_span(struct tbl_node *tbl)
15095c635efSGarrett D'Amore {
15195c635efSGarrett D'Amore 	struct tbl_span	 *span;
15295c635efSGarrett D'Amore 
15395c635efSGarrett D'Amore 	assert(tbl);
15495c635efSGarrett D'Amore 	span = tbl->current_span ? tbl->current_span->next
15595c635efSGarrett D'Amore 				 : tbl->first_span;
15695c635efSGarrett D'Amore 	if (span)
15795c635efSGarrett D'Amore 		tbl->current_span = span;
158*371584c2SYuri Pankov 	return span;
15995c635efSGarrett D'Amore }
16095c635efSGarrett D'Amore 
161260e9a87SYuri Pankov int
16295c635efSGarrett D'Amore tbl_end(struct tbl_node **tblp)
16395c635efSGarrett D'Amore {
16495c635efSGarrett D'Amore 	struct tbl_node	*tbl;
165260e9a87SYuri Pankov 	struct tbl_span *sp;
16695c635efSGarrett D'Amore 
16795c635efSGarrett D'Amore 	tbl = *tblp;
16895c635efSGarrett D'Amore 	*tblp = NULL;
16995c635efSGarrett D'Amore 
170260e9a87SYuri Pankov 	if (tbl->part == TBL_PART_CDATA)
171260e9a87SYuri Pankov 		mandoc_msg(MANDOCERR_TBLDATA_BLK, tbl->parse,
172260e9a87SYuri Pankov 		    tbl->line, tbl->pos, "TE");
173260e9a87SYuri Pankov 
174260e9a87SYuri Pankov 	sp = tbl->first_span;
175260e9a87SYuri Pankov 	while (sp != NULL && sp->first == NULL)
176260e9a87SYuri Pankov 		sp = sp->next;
177260e9a87SYuri Pankov 	if (sp == NULL) {
178260e9a87SYuri Pankov 		mandoc_msg(MANDOCERR_TBLDATA_NONE, tbl->parse,
179260e9a87SYuri Pankov 		    tbl->line, tbl->pos, NULL);
180*371584c2SYuri Pankov 		return 0;
181260e9a87SYuri Pankov 	}
182*371584c2SYuri Pankov 	return 1;
18395c635efSGarrett D'Amore }
184