xref: /titanic_52/usr/src/cmd/mandoc/tbl.c (revision 260e9a87725c090ba5835b1f9f0b62fa2f96036f)
1*260e9a87SYuri Pankov /*	$Id: tbl.c,v 1.39 2015/01/30 17:32:16 schwarze Exp $ */
295c635efSGarrett D'Amore /*
395c635efSGarrett D'Amore  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
4*260e9a87SYuri 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"
19*260e9a87SYuri Pankov 
20*260e9a87SYuri 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"
29*260e9a87SYuri Pankov #include "mandoc_aux.h"
3095c635efSGarrett D'Amore #include "libmandoc.h"
3195c635efSGarrett D'Amore #include "libroff.h"
3295c635efSGarrett D'Amore 
3395c635efSGarrett D'Amore 
34*260e9a87SYuri Pankov enum rofferr
35*260e9a87SYuri Pankov tbl_read(struct tbl_node *tbl, int ln, const char *p, int pos)
36*260e9a87SYuri Pankov {
37*260e9a87SYuri Pankov 	const char	*cp;
38*260e9a87SYuri Pankov 	int		 active;
3995c635efSGarrett D'Amore 
4095c635efSGarrett D'Amore 	/*
41*260e9a87SYuri Pankov 	 * In the options section, proceed to the layout section
42*260e9a87SYuri Pankov 	 * after a semicolon, or right away if there is no semicolon.
43*260e9a87SYuri Pankov 	 * Ignore semicolons in arguments.
4495c635efSGarrett D'Amore 	 */
4595c635efSGarrett D'Amore 
46*260e9a87SYuri Pankov 	if (tbl->part == TBL_PART_OPTS) {
4795c635efSGarrett D'Amore 		tbl->part = TBL_PART_LAYOUT;
48*260e9a87SYuri Pankov 		active = 1;
49*260e9a87SYuri Pankov 		for (cp = p + pos; *cp != '\0'; cp++) {
50*260e9a87SYuri Pankov 			switch (*cp) {
51*260e9a87SYuri Pankov 			case '(':
52*260e9a87SYuri Pankov 				active = 0;
53*260e9a87SYuri Pankov 				continue;
54*260e9a87SYuri Pankov 			case ')':
55*260e9a87SYuri Pankov 				active = 1;
56*260e9a87SYuri Pankov 				continue;
57*260e9a87SYuri Pankov 			case ';':
58*260e9a87SYuri Pankov 				if (active)
59*260e9a87SYuri Pankov 					break;
60*260e9a87SYuri Pankov 				continue;
61*260e9a87SYuri Pankov 			default:
62*260e9a87SYuri Pankov 				continue;
63*260e9a87SYuri Pankov 			}
64*260e9a87SYuri Pankov 			break;
65*260e9a87SYuri Pankov 		}
66*260e9a87SYuri Pankov 		if (*cp == ';') {
67*260e9a87SYuri Pankov 			tbl_option(tbl, ln, p, &pos);
68*260e9a87SYuri Pankov 			if (p[pos] == '\0')
69*260e9a87SYuri Pankov 				return(ROFF_IGN);
70*260e9a87SYuri Pankov 		}
71*260e9a87SYuri Pankov 	}
7295c635efSGarrett D'Amore 
73*260e9a87SYuri Pankov 	/* Process the other section types.  */
7495c635efSGarrett D'Amore 
7595c635efSGarrett D'Amore 	switch (tbl->part) {
76*260e9a87SYuri Pankov 	case TBL_PART_LAYOUT:
77*260e9a87SYuri Pankov 		tbl_layout(tbl, ln, p, pos);
78*260e9a87SYuri Pankov 		return(ROFF_IGN);
79*260e9a87SYuri Pankov 	case TBL_PART_CDATA:
80*260e9a87SYuri 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 
85*260e9a87SYuri Pankov 	tbl_data(tbl, ln, p, pos);
86*260e9a87SYuri 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;
9395c635efSGarrett D'Amore 
94*260e9a87SYuri 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 = '.';
101698f87a4SGarrett D'Amore 	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 
112*260e9a87SYuri Pankov 	while ((rp = tbl->first_row) != NULL) {
113698f87a4SGarrett D'Amore 		tbl->first_row = rp->next;
114*260e9a87SYuri 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 
122*260e9a87SYuri Pankov 	while ((sp = tbl->first_span) != NULL) {
123698f87a4SGarrett D'Amore 		tbl->first_span = sp->next;
124*260e9a87SYuri Pankov 		while (sp->first != NULL) {
12595c635efSGarrett D'Amore 			dp = sp->first;
12695c635efSGarrett D'Amore 			sp->first = dp->next;
12795c635efSGarrett D'Amore 			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 {
139*260e9a87SYuri Pankov 	if (tbl->part == TBL_PART_CDATA)
140*260e9a87SYuri Pankov 		mandoc_msg(MANDOCERR_TBLDATA_BLK, tbl->parse,
141*260e9a87SYuri 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;
15895c635efSGarrett D'Amore 	return(span);
15995c635efSGarrett D'Amore }
16095c635efSGarrett D'Amore 
161*260e9a87SYuri Pankov int
16295c635efSGarrett D'Amore tbl_end(struct tbl_node **tblp)
16395c635efSGarrett D'Amore {
16495c635efSGarrett D'Amore 	struct tbl_node	*tbl;
165*260e9a87SYuri Pankov 	struct tbl_span *sp;
16695c635efSGarrett D'Amore 
16795c635efSGarrett D'Amore 	tbl = *tblp;
16895c635efSGarrett D'Amore 	*tblp = NULL;
16995c635efSGarrett D'Amore 
170*260e9a87SYuri Pankov 	if (tbl->part == TBL_PART_CDATA)
171*260e9a87SYuri Pankov 		mandoc_msg(MANDOCERR_TBLDATA_BLK, tbl->parse,
172*260e9a87SYuri Pankov 		    tbl->line, tbl->pos, "TE");
17395c635efSGarrett D'Amore 
174*260e9a87SYuri Pankov 	sp = tbl->first_span;
175*260e9a87SYuri Pankov 	while (sp != NULL && sp->first == NULL)
176*260e9a87SYuri Pankov 		sp = sp->next;
177*260e9a87SYuri Pankov 	if (sp == NULL) {
178*260e9a87SYuri Pankov 		mandoc_msg(MANDOCERR_TBLDATA_NONE, tbl->parse,
17995c635efSGarrett D'Amore 		    tbl->line, tbl->pos, NULL);
180*260e9a87SYuri Pankov 		return(0);
18195c635efSGarrett D'Amore 	}
182*260e9a87SYuri Pankov 	return(1);
183*260e9a87SYuri Pankov }
184