xref: /titanic_50/usr/src/cmd/mandoc/tbl.c (revision 95c635efb7c3b86efc493e0447eaec7aecca3f0f)
1*95c635efSGarrett D'Amore /*	$Id: tbl.c,v 1.26 2011/07/25 15:37:00 kristaps Exp $ */
2*95c635efSGarrett D'Amore /*
3*95c635efSGarrett D'Amore  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
4*95c635efSGarrett D'Amore  * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
5*95c635efSGarrett D'Amore  *
6*95c635efSGarrett D'Amore  * Permission to use, copy, modify, and distribute this software for any
7*95c635efSGarrett D'Amore  * purpose with or without fee is hereby granted, provided that the above
8*95c635efSGarrett D'Amore  * copyright notice and this permission notice appear in all copies.
9*95c635efSGarrett D'Amore  *
10*95c635efSGarrett D'Amore  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11*95c635efSGarrett D'Amore  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12*95c635efSGarrett D'Amore  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13*95c635efSGarrett D'Amore  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14*95c635efSGarrett D'Amore  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15*95c635efSGarrett D'Amore  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16*95c635efSGarrett D'Amore  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*95c635efSGarrett D'Amore  */
18*95c635efSGarrett D'Amore #ifdef HAVE_CONFIG_H
19*95c635efSGarrett D'Amore #include "config.h"
20*95c635efSGarrett D'Amore #endif
21*95c635efSGarrett D'Amore 
22*95c635efSGarrett D'Amore #include <assert.h>
23*95c635efSGarrett D'Amore #include <stdio.h>
24*95c635efSGarrett D'Amore #include <stdlib.h>
25*95c635efSGarrett D'Amore #include <string.h>
26*95c635efSGarrett D'Amore #include <time.h>
27*95c635efSGarrett D'Amore 
28*95c635efSGarrett D'Amore #include "mandoc.h"
29*95c635efSGarrett D'Amore #include "libmandoc.h"
30*95c635efSGarrett D'Amore #include "libroff.h"
31*95c635efSGarrett D'Amore 
32*95c635efSGarrett D'Amore enum rofferr
33*95c635efSGarrett D'Amore tbl_read(struct tbl_node *tbl, int ln, const char *p, int offs)
34*95c635efSGarrett D'Amore {
35*95c635efSGarrett D'Amore 	int		 len;
36*95c635efSGarrett D'Amore 	const char	*cp;
37*95c635efSGarrett D'Amore 
38*95c635efSGarrett D'Amore 	cp = &p[offs];
39*95c635efSGarrett D'Amore 	len = (int)strlen(cp);
40*95c635efSGarrett D'Amore 
41*95c635efSGarrett D'Amore 	/*
42*95c635efSGarrett D'Amore 	 * If we're in the options section and we don't have a
43*95c635efSGarrett D'Amore 	 * terminating semicolon, assume we've moved directly into the
44*95c635efSGarrett D'Amore 	 * layout section.  No need to report a warning: this is,
45*95c635efSGarrett D'Amore 	 * apparently, standard behaviour.
46*95c635efSGarrett D'Amore 	 */
47*95c635efSGarrett D'Amore 
48*95c635efSGarrett D'Amore 	if (TBL_PART_OPTS == tbl->part && len)
49*95c635efSGarrett D'Amore 		if (';' != cp[len - 1])
50*95c635efSGarrett D'Amore 			tbl->part = TBL_PART_LAYOUT;
51*95c635efSGarrett D'Amore 
52*95c635efSGarrett D'Amore 	/* Now process each logical section of the table.  */
53*95c635efSGarrett D'Amore 
54*95c635efSGarrett D'Amore 	switch (tbl->part) {
55*95c635efSGarrett D'Amore 	case (TBL_PART_OPTS):
56*95c635efSGarrett D'Amore 		return(tbl_option(tbl, ln, p) ? ROFF_IGN : ROFF_ERR);
57*95c635efSGarrett D'Amore 	case (TBL_PART_LAYOUT):
58*95c635efSGarrett D'Amore 		return(tbl_layout(tbl, ln, p) ? ROFF_IGN : ROFF_ERR);
59*95c635efSGarrett D'Amore 	case (TBL_PART_CDATA):
60*95c635efSGarrett D'Amore 		return(tbl_cdata(tbl, ln, p) ? ROFF_TBL : ROFF_IGN);
61*95c635efSGarrett D'Amore 	default:
62*95c635efSGarrett D'Amore 		break;
63*95c635efSGarrett D'Amore 	}
64*95c635efSGarrett D'Amore 
65*95c635efSGarrett D'Amore 	/*
66*95c635efSGarrett D'Amore 	 * This only returns zero if the line is empty, so we ignore it
67*95c635efSGarrett D'Amore 	 * and continue on.
68*95c635efSGarrett D'Amore 	 */
69*95c635efSGarrett D'Amore 	return(tbl_data(tbl, ln, p) ? ROFF_TBL : ROFF_IGN);
70*95c635efSGarrett D'Amore }
71*95c635efSGarrett D'Amore 
72*95c635efSGarrett D'Amore struct tbl_node *
73*95c635efSGarrett D'Amore tbl_alloc(int pos, int line, struct mparse *parse)
74*95c635efSGarrett D'Amore {
75*95c635efSGarrett D'Amore 	struct tbl_node	*p;
76*95c635efSGarrett D'Amore 
77*95c635efSGarrett D'Amore 	p = mandoc_calloc(1, sizeof(struct tbl_node));
78*95c635efSGarrett D'Amore 	p->line = line;
79*95c635efSGarrett D'Amore 	p->pos = pos;
80*95c635efSGarrett D'Amore 	p->parse = parse;
81*95c635efSGarrett D'Amore 	p->part = TBL_PART_OPTS;
82*95c635efSGarrett D'Amore 	p->opts.tab = '\t';
83*95c635efSGarrett D'Amore 	p->opts.linesize = 12;
84*95c635efSGarrett D'Amore 	p->opts.decimal = '.';
85*95c635efSGarrett D'Amore 	return(p);
86*95c635efSGarrett D'Amore }
87*95c635efSGarrett D'Amore 
88*95c635efSGarrett D'Amore void
89*95c635efSGarrett D'Amore tbl_free(struct tbl_node *p)
90*95c635efSGarrett D'Amore {
91*95c635efSGarrett D'Amore 	struct tbl_row	*rp;
92*95c635efSGarrett D'Amore 	struct tbl_cell	*cp;
93*95c635efSGarrett D'Amore 	struct tbl_span	*sp;
94*95c635efSGarrett D'Amore 	struct tbl_dat	*dp;
95*95c635efSGarrett D'Amore 	struct tbl_head	*hp;
96*95c635efSGarrett D'Amore 
97*95c635efSGarrett D'Amore 	while (NULL != (rp = p->first_row)) {
98*95c635efSGarrett D'Amore 		p->first_row = rp->next;
99*95c635efSGarrett D'Amore 		while (rp->first) {
100*95c635efSGarrett D'Amore 			cp = rp->first;
101*95c635efSGarrett D'Amore 			rp->first = cp->next;
102*95c635efSGarrett D'Amore 			free(cp);
103*95c635efSGarrett D'Amore 		}
104*95c635efSGarrett D'Amore 		free(rp);
105*95c635efSGarrett D'Amore 	}
106*95c635efSGarrett D'Amore 
107*95c635efSGarrett D'Amore 	while (NULL != (sp = p->first_span)) {
108*95c635efSGarrett D'Amore 		p->first_span = sp->next;
109*95c635efSGarrett D'Amore 		while (sp->first) {
110*95c635efSGarrett D'Amore 			dp = sp->first;
111*95c635efSGarrett D'Amore 			sp->first = dp->next;
112*95c635efSGarrett D'Amore 			if (dp->string)
113*95c635efSGarrett D'Amore 				free(dp->string);
114*95c635efSGarrett D'Amore 			free(dp);
115*95c635efSGarrett D'Amore 		}
116*95c635efSGarrett D'Amore 		free(sp);
117*95c635efSGarrett D'Amore 	}
118*95c635efSGarrett D'Amore 
119*95c635efSGarrett D'Amore 	while (NULL != (hp = p->first_head)) {
120*95c635efSGarrett D'Amore 		p->first_head = hp->next;
121*95c635efSGarrett D'Amore 		free(hp);
122*95c635efSGarrett D'Amore 	}
123*95c635efSGarrett D'Amore 
124*95c635efSGarrett D'Amore 	free(p);
125*95c635efSGarrett D'Amore }
126*95c635efSGarrett D'Amore 
127*95c635efSGarrett D'Amore void
128*95c635efSGarrett D'Amore tbl_restart(int line, int pos, struct tbl_node *tbl)
129*95c635efSGarrett D'Amore {
130*95c635efSGarrett D'Amore 	if (TBL_PART_CDATA == tbl->part)
131*95c635efSGarrett D'Amore 		mandoc_msg(MANDOCERR_TBLBLOCK, tbl->parse,
132*95c635efSGarrett D'Amore 				tbl->line, tbl->pos, NULL);
133*95c635efSGarrett D'Amore 
134*95c635efSGarrett D'Amore 	tbl->part = TBL_PART_LAYOUT;
135*95c635efSGarrett D'Amore 	tbl->line = line;
136*95c635efSGarrett D'Amore 	tbl->pos = pos;
137*95c635efSGarrett D'Amore 
138*95c635efSGarrett D'Amore 	if (NULL == tbl->first_span || NULL == tbl->first_span->first)
139*95c635efSGarrett D'Amore 		mandoc_msg(MANDOCERR_TBLNODATA, tbl->parse,
140*95c635efSGarrett D'Amore 				tbl->line, tbl->pos, NULL);
141*95c635efSGarrett D'Amore }
142*95c635efSGarrett D'Amore 
143*95c635efSGarrett D'Amore const struct tbl_span *
144*95c635efSGarrett D'Amore tbl_span(struct tbl_node *tbl)
145*95c635efSGarrett D'Amore {
146*95c635efSGarrett D'Amore 	struct tbl_span	 *span;
147*95c635efSGarrett D'Amore 
148*95c635efSGarrett D'Amore 	assert(tbl);
149*95c635efSGarrett D'Amore 	span = tbl->current_span ? tbl->current_span->next
150*95c635efSGarrett D'Amore 				 : tbl->first_span;
151*95c635efSGarrett D'Amore 	if (span)
152*95c635efSGarrett D'Amore 		tbl->current_span = span;
153*95c635efSGarrett D'Amore 	return(span);
154*95c635efSGarrett D'Amore }
155*95c635efSGarrett D'Amore 
156*95c635efSGarrett D'Amore void
157*95c635efSGarrett D'Amore tbl_end(struct tbl_node **tblp)
158*95c635efSGarrett D'Amore {
159*95c635efSGarrett D'Amore 	struct tbl_node	*tbl;
160*95c635efSGarrett D'Amore 
161*95c635efSGarrett D'Amore 	tbl = *tblp;
162*95c635efSGarrett D'Amore 	*tblp = NULL;
163*95c635efSGarrett D'Amore 
164*95c635efSGarrett D'Amore 	if (NULL == tbl->first_span || NULL == tbl->first_span->first)
165*95c635efSGarrett D'Amore 		mandoc_msg(MANDOCERR_TBLNODATA, tbl->parse,
166*95c635efSGarrett D'Amore 				tbl->line, tbl->pos, NULL);
167*95c635efSGarrett D'Amore 
168*95c635efSGarrett D'Amore 	if (tbl->last_span)
169*95c635efSGarrett D'Amore 		tbl->last_span->flags |= TBL_SPAN_LAST;
170*95c635efSGarrett D'Amore 
171*95c635efSGarrett D'Amore 	if (TBL_PART_CDATA == tbl->part)
172*95c635efSGarrett D'Amore 		mandoc_msg(MANDOCERR_TBLBLOCK, tbl->parse,
173*95c635efSGarrett D'Amore 				tbl->line, tbl->pos, NULL);
174*95c635efSGarrett D'Amore }
175*95c635efSGarrett D'Amore 
176