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
tbl_read(struct tbl_node * tbl,int ln,const char * p,int pos)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 *
tbl_alloc(int pos,int line,struct mparse * parse)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
tbl_free(struct tbl_node * tbl)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
tbl_restart(int line,int pos,struct tbl_node * tbl)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 *
tbl_span(struct tbl_node * tbl)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
tbl_end(struct tbl_node ** tblp)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