xref: /illumos-gate/usr/src/cmd/mandoc/tbl.c (revision cec8643b)
1*cec8643bSMichal Nowak /*	$Id: tbl.c,v 1.46 2018/12/14 06:33:14 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 
28260e9a87SYuri Pankov #include "mandoc_aux.h"
29*cec8643bSMichal Nowak #include "mandoc.h"
30*cec8643bSMichal Nowak #include "tbl.h"
3195c635efSGarrett D'Amore #include "libmandoc.h"
32*cec8643bSMichal Nowak #include "tbl_parse.h"
33*cec8643bSMichal Nowak #include "tbl_int.h"
3495c635efSGarrett D'Amore 
35260e9a87SYuri Pankov 
36c66b8046SYuri Pankov void
tbl_read(struct tbl_node * tbl,int ln,const char * p,int pos)37260e9a87SYuri Pankov tbl_read(struct tbl_node *tbl, int ln, const char *p, int pos)
3895c635efSGarrett D'Amore {
3995c635efSGarrett D'Amore 	const char	*cp;
40260e9a87SYuri Pankov 	int		 active;
4195c635efSGarrett D'Amore 
4295c635efSGarrett D'Amore 	/*
43260e9a87SYuri Pankov 	 * In the options section, proceed to the layout section
44260e9a87SYuri Pankov 	 * after a semicolon, or right away if there is no semicolon.
45260e9a87SYuri Pankov 	 * Ignore semicolons in arguments.
4695c635efSGarrett D'Amore 	 */
4795c635efSGarrett D'Amore 
48260e9a87SYuri Pankov 	if (tbl->part == TBL_PART_OPTS) {
49260e9a87SYuri Pankov 		tbl->part = TBL_PART_LAYOUT;
50260e9a87SYuri Pankov 		active = 1;
51260e9a87SYuri Pankov 		for (cp = p + pos; *cp != '\0'; cp++) {
52260e9a87SYuri Pankov 			switch (*cp) {
53260e9a87SYuri Pankov 			case '(':
54260e9a87SYuri Pankov 				active = 0;
55260e9a87SYuri Pankov 				continue;
56260e9a87SYuri Pankov 			case ')':
57260e9a87SYuri Pankov 				active = 1;
58260e9a87SYuri Pankov 				continue;
59260e9a87SYuri Pankov 			case ';':
60260e9a87SYuri Pankov 				if (active)
61260e9a87SYuri Pankov 					break;
62260e9a87SYuri Pankov 				continue;
63260e9a87SYuri Pankov 			default:
64260e9a87SYuri Pankov 				continue;
65260e9a87SYuri Pankov 			}
66260e9a87SYuri Pankov 			break;
67260e9a87SYuri Pankov 		}
68260e9a87SYuri Pankov 		if (*cp == ';') {
69260e9a87SYuri Pankov 			tbl_option(tbl, ln, p, &pos);
70260e9a87SYuri Pankov 			if (p[pos] == '\0')
71c66b8046SYuri Pankov 				return;
72260e9a87SYuri Pankov 		}
73260e9a87SYuri Pankov 	}
7495c635efSGarrett D'Amore 
75260e9a87SYuri Pankov 	/* Process the other section types.  */
7695c635efSGarrett D'Amore 
7795c635efSGarrett D'Amore 	switch (tbl->part) {
78260e9a87SYuri Pankov 	case TBL_PART_LAYOUT:
79260e9a87SYuri Pankov 		tbl_layout(tbl, ln, p, pos);
80c66b8046SYuri Pankov 		break;
81260e9a87SYuri Pankov 	case TBL_PART_CDATA:
82c66b8046SYuri Pankov 		tbl_cdata(tbl, ln, p, pos);
83c66b8046SYuri Pankov 		break;
8495c635efSGarrett D'Amore 	default:
85c66b8046SYuri Pankov 		tbl_data(tbl, ln, p, pos);
8695c635efSGarrett D'Amore 		break;
8795c635efSGarrett D'Amore 	}
8895c635efSGarrett D'Amore }
8995c635efSGarrett D'Amore 
9095c635efSGarrett D'Amore struct tbl_node *
tbl_alloc(int pos,int line,struct tbl_node * last_tbl)91*cec8643bSMichal Nowak tbl_alloc(int pos, int line, struct tbl_node *last_tbl)
9295c635efSGarrett D'Amore {
93698f87a4SGarrett D'Amore 	struct tbl_node	*tbl;
94698f87a4SGarrett D'Amore 
95260e9a87SYuri Pankov 	tbl = mandoc_calloc(1, sizeof(*tbl));
96*cec8643bSMichal Nowak 	if (last_tbl != NULL)
97*cec8643bSMichal Nowak 		last_tbl->next = tbl;
98698f87a4SGarrett D'Amore 	tbl->line = line;
99698f87a4SGarrett D'Amore 	tbl->pos = pos;
100698f87a4SGarrett D'Amore 	tbl->part = TBL_PART_OPTS;
101698f87a4SGarrett D'Amore 	tbl->opts.tab = '\t';
102698f87a4SGarrett D'Amore 	tbl->opts.decimal = '.';
103371584c2SYuri Pankov 	return tbl;
10495c635efSGarrett D'Amore }
10595c635efSGarrett D'Amore 
10695c635efSGarrett D'Amore void
tbl_free(struct tbl_node * tbl)107698f87a4SGarrett D'Amore tbl_free(struct tbl_node *tbl)
10895c635efSGarrett D'Amore {
109*cec8643bSMichal Nowak 	struct tbl_node	*old_tbl;
11095c635efSGarrett D'Amore 	struct tbl_row	*rp;
11195c635efSGarrett D'Amore 	struct tbl_cell	*cp;
11295c635efSGarrett D'Amore 	struct tbl_span	*sp;
11395c635efSGarrett D'Amore 	struct tbl_dat	*dp;
11495c635efSGarrett D'Amore 
115*cec8643bSMichal Nowak 	while (tbl != NULL) {
116*cec8643bSMichal Nowak 		while ((rp = tbl->first_row) != NULL) {
117*cec8643bSMichal Nowak 			tbl->first_row = rp->next;
118*cec8643bSMichal Nowak 			while (rp->first != NULL) {
119*cec8643bSMichal Nowak 				cp = rp->first;
120*cec8643bSMichal Nowak 				rp->first = cp->next;
121*cec8643bSMichal Nowak 				free(cp->wstr);
122*cec8643bSMichal Nowak 				free(cp);
123*cec8643bSMichal Nowak 			}
124*cec8643bSMichal Nowak 			free(rp);
12595c635efSGarrett D'Amore 		}
126*cec8643bSMichal Nowak 		while ((sp = tbl->first_span) != NULL) {
127*cec8643bSMichal Nowak 			tbl->first_span = sp->next;
128*cec8643bSMichal Nowak 			while (sp->first != NULL) {
129*cec8643bSMichal Nowak 				dp = sp->first;
130*cec8643bSMichal Nowak 				sp->first = dp->next;
131*cec8643bSMichal Nowak 				free(dp->string);
132*cec8643bSMichal Nowak 				free(dp);
133*cec8643bSMichal Nowak 			}
134*cec8643bSMichal Nowak 			free(sp);
13595c635efSGarrett D'Amore 		}
136*cec8643bSMichal Nowak 		old_tbl = tbl;
137*cec8643bSMichal Nowak 		tbl = tbl->next;
138*cec8643bSMichal Nowak 		free(old_tbl);
13995c635efSGarrett D'Amore 	}
14095c635efSGarrett D'Amore }
14195c635efSGarrett D'Amore 
14295c635efSGarrett D'Amore void
tbl_restart(int line,int pos,struct tbl_node * tbl)14395c635efSGarrett D'Amore tbl_restart(int line, int pos, struct tbl_node *tbl)
14495c635efSGarrett D'Amore {
145260e9a87SYuri Pankov 	if (tbl->part == TBL_PART_CDATA)
146*cec8643bSMichal Nowak 		mandoc_msg(MANDOCERR_TBLDATA_BLK, line, pos, "T&");
14795c635efSGarrett D'Amore 
14895c635efSGarrett D'Amore 	tbl->part = TBL_PART_LAYOUT;
14995c635efSGarrett D'Amore 	tbl->line = line;
15095c635efSGarrett D'Amore 	tbl->pos = pos;
15195c635efSGarrett D'Amore }
15295c635efSGarrett D'Amore 
153*cec8643bSMichal Nowak struct tbl_span *
tbl_span(struct tbl_node * tbl)15495c635efSGarrett D'Amore tbl_span(struct tbl_node *tbl)
15595c635efSGarrett D'Amore {
15695c635efSGarrett D'Amore 	struct tbl_span	 *span;
15795c635efSGarrett D'Amore 
15895c635efSGarrett D'Amore 	span = tbl->current_span ? tbl->current_span->next
15995c635efSGarrett D'Amore 				 : tbl->first_span;
160*cec8643bSMichal Nowak 	if (span != NULL)
16195c635efSGarrett D'Amore 		tbl->current_span = span;
162371584c2SYuri Pankov 	return span;
16395c635efSGarrett D'Amore }
16495c635efSGarrett D'Amore 
165260e9a87SYuri Pankov int
tbl_end(struct tbl_node * tbl,int still_open)166*cec8643bSMichal Nowak tbl_end(struct tbl_node *tbl, int still_open)
16795c635efSGarrett D'Amore {
168260e9a87SYuri Pankov 	struct tbl_span *sp;
16995c635efSGarrett D'Amore 
170*cec8643bSMichal Nowak 	if (still_open)
171*cec8643bSMichal Nowak 		mandoc_msg(MANDOCERR_BLK_NOEND, tbl->line, tbl->pos, "TS");
172*cec8643bSMichal Nowak 	else if (tbl->part == TBL_PART_CDATA)
173*cec8643bSMichal Nowak 		mandoc_msg(MANDOCERR_TBLDATA_BLK, tbl->line, tbl->pos, "TE");
174260e9a87SYuri Pankov 
175260e9a87SYuri Pankov 	sp = tbl->first_span;
176260e9a87SYuri Pankov 	while (sp != NULL && sp->first == NULL)
177260e9a87SYuri Pankov 		sp = sp->next;
178260e9a87SYuri Pankov 	if (sp == NULL) {
179*cec8643bSMichal Nowak 		mandoc_msg(MANDOCERR_TBLDATA_NONE, tbl->line, tbl->pos, NULL);
180371584c2SYuri Pankov 		return 0;
181260e9a87SYuri Pankov 	}
182371584c2SYuri Pankov 	return 1;
18395c635efSGarrett D'Amore }
184