1*7295610fSBaptiste Daroussin /* $Id: tbl.c,v 1.46 2018/12/14 06:33:14 schwarze Exp $ */
261d06d6bSBaptiste Daroussin /*
361d06d6bSBaptiste Daroussin * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
461d06d6bSBaptiste Daroussin * Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org>
561d06d6bSBaptiste Daroussin *
661d06d6bSBaptiste Daroussin * Permission to use, copy, modify, and distribute this software for any
761d06d6bSBaptiste Daroussin * purpose with or without fee is hereby granted, provided that the above
861d06d6bSBaptiste Daroussin * copyright notice and this permission notice appear in all copies.
961d06d6bSBaptiste Daroussin *
1061d06d6bSBaptiste Daroussin * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1161d06d6bSBaptiste Daroussin * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1261d06d6bSBaptiste Daroussin * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1361d06d6bSBaptiste Daroussin * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1461d06d6bSBaptiste Daroussin * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1561d06d6bSBaptiste Daroussin * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1661d06d6bSBaptiste Daroussin * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1761d06d6bSBaptiste Daroussin */
1861d06d6bSBaptiste Daroussin #include "config.h"
1961d06d6bSBaptiste Daroussin
2061d06d6bSBaptiste Daroussin #include <sys/types.h>
2161d06d6bSBaptiste Daroussin
2261d06d6bSBaptiste Daroussin #include <assert.h>
2361d06d6bSBaptiste Daroussin #include <stdio.h>
2461d06d6bSBaptiste Daroussin #include <stdlib.h>
2561d06d6bSBaptiste Daroussin #include <string.h>
2661d06d6bSBaptiste Daroussin #include <time.h>
2761d06d6bSBaptiste Daroussin
2861d06d6bSBaptiste Daroussin #include "mandoc_aux.h"
29*7295610fSBaptiste Daroussin #include "mandoc.h"
30*7295610fSBaptiste Daroussin #include "tbl.h"
3161d06d6bSBaptiste Daroussin #include "libmandoc.h"
32*7295610fSBaptiste Daroussin #include "tbl_parse.h"
33*7295610fSBaptiste Daroussin #include "tbl_int.h"
3461d06d6bSBaptiste Daroussin
3561d06d6bSBaptiste Daroussin
3661d06d6bSBaptiste Daroussin void
tbl_read(struct tbl_node * tbl,int ln,const char * p,int pos)3761d06d6bSBaptiste Daroussin tbl_read(struct tbl_node *tbl, int ln, const char *p, int pos)
3861d06d6bSBaptiste Daroussin {
3961d06d6bSBaptiste Daroussin const char *cp;
4061d06d6bSBaptiste Daroussin int active;
4161d06d6bSBaptiste Daroussin
4261d06d6bSBaptiste Daroussin /*
4361d06d6bSBaptiste Daroussin * In the options section, proceed to the layout section
4461d06d6bSBaptiste Daroussin * after a semicolon, or right away if there is no semicolon.
4561d06d6bSBaptiste Daroussin * Ignore semicolons in arguments.
4661d06d6bSBaptiste Daroussin */
4761d06d6bSBaptiste Daroussin
4861d06d6bSBaptiste Daroussin if (tbl->part == TBL_PART_OPTS) {
4961d06d6bSBaptiste Daroussin tbl->part = TBL_PART_LAYOUT;
5061d06d6bSBaptiste Daroussin active = 1;
5161d06d6bSBaptiste Daroussin for (cp = p + pos; *cp != '\0'; cp++) {
5261d06d6bSBaptiste Daroussin switch (*cp) {
5361d06d6bSBaptiste Daroussin case '(':
5461d06d6bSBaptiste Daroussin active = 0;
5561d06d6bSBaptiste Daroussin continue;
5661d06d6bSBaptiste Daroussin case ')':
5761d06d6bSBaptiste Daroussin active = 1;
5861d06d6bSBaptiste Daroussin continue;
5961d06d6bSBaptiste Daroussin case ';':
6061d06d6bSBaptiste Daroussin if (active)
6161d06d6bSBaptiste Daroussin break;
6261d06d6bSBaptiste Daroussin continue;
6361d06d6bSBaptiste Daroussin default:
6461d06d6bSBaptiste Daroussin continue;
6561d06d6bSBaptiste Daroussin }
6661d06d6bSBaptiste Daroussin break;
6761d06d6bSBaptiste Daroussin }
6861d06d6bSBaptiste Daroussin if (*cp == ';') {
6961d06d6bSBaptiste Daroussin tbl_option(tbl, ln, p, &pos);
7061d06d6bSBaptiste Daroussin if (p[pos] == '\0')
7161d06d6bSBaptiste Daroussin return;
7261d06d6bSBaptiste Daroussin }
7361d06d6bSBaptiste Daroussin }
7461d06d6bSBaptiste Daroussin
7561d06d6bSBaptiste Daroussin /* Process the other section types. */
7661d06d6bSBaptiste Daroussin
7761d06d6bSBaptiste Daroussin switch (tbl->part) {
7861d06d6bSBaptiste Daroussin case TBL_PART_LAYOUT:
7961d06d6bSBaptiste Daroussin tbl_layout(tbl, ln, p, pos);
8061d06d6bSBaptiste Daroussin break;
8161d06d6bSBaptiste Daroussin case TBL_PART_CDATA:
8261d06d6bSBaptiste Daroussin tbl_cdata(tbl, ln, p, pos);
8361d06d6bSBaptiste Daroussin break;
8461d06d6bSBaptiste Daroussin default:
8561d06d6bSBaptiste Daroussin tbl_data(tbl, ln, p, pos);
8661d06d6bSBaptiste Daroussin break;
8761d06d6bSBaptiste Daroussin }
8861d06d6bSBaptiste Daroussin }
8961d06d6bSBaptiste Daroussin
9061d06d6bSBaptiste Daroussin struct tbl_node *
tbl_alloc(int pos,int line,struct tbl_node * last_tbl)91*7295610fSBaptiste Daroussin tbl_alloc(int pos, int line, struct tbl_node *last_tbl)
9261d06d6bSBaptiste Daroussin {
9361d06d6bSBaptiste Daroussin struct tbl_node *tbl;
9461d06d6bSBaptiste Daroussin
9561d06d6bSBaptiste Daroussin tbl = mandoc_calloc(1, sizeof(*tbl));
96*7295610fSBaptiste Daroussin if (last_tbl != NULL)
97*7295610fSBaptiste Daroussin last_tbl->next = tbl;
9861d06d6bSBaptiste Daroussin tbl->line = line;
9961d06d6bSBaptiste Daroussin tbl->pos = pos;
10061d06d6bSBaptiste Daroussin tbl->part = TBL_PART_OPTS;
10161d06d6bSBaptiste Daroussin tbl->opts.tab = '\t';
10261d06d6bSBaptiste Daroussin tbl->opts.decimal = '.';
10361d06d6bSBaptiste Daroussin return tbl;
10461d06d6bSBaptiste Daroussin }
10561d06d6bSBaptiste Daroussin
10661d06d6bSBaptiste Daroussin void
tbl_free(struct tbl_node * tbl)10761d06d6bSBaptiste Daroussin tbl_free(struct tbl_node *tbl)
10861d06d6bSBaptiste Daroussin {
109*7295610fSBaptiste Daroussin struct tbl_node *old_tbl;
11061d06d6bSBaptiste Daroussin struct tbl_row *rp;
11161d06d6bSBaptiste Daroussin struct tbl_cell *cp;
11261d06d6bSBaptiste Daroussin struct tbl_span *sp;
11361d06d6bSBaptiste Daroussin struct tbl_dat *dp;
11461d06d6bSBaptiste Daroussin
115*7295610fSBaptiste Daroussin while (tbl != NULL) {
11661d06d6bSBaptiste Daroussin while ((rp = tbl->first_row) != NULL) {
11761d06d6bSBaptiste Daroussin tbl->first_row = rp->next;
11861d06d6bSBaptiste Daroussin while (rp->first != NULL) {
11961d06d6bSBaptiste Daroussin cp = rp->first;
12061d06d6bSBaptiste Daroussin rp->first = cp->next;
12161d06d6bSBaptiste Daroussin free(cp->wstr);
12261d06d6bSBaptiste Daroussin free(cp);
12361d06d6bSBaptiste Daroussin }
12461d06d6bSBaptiste Daroussin free(rp);
12561d06d6bSBaptiste Daroussin }
12661d06d6bSBaptiste Daroussin while ((sp = tbl->first_span) != NULL) {
12761d06d6bSBaptiste Daroussin tbl->first_span = sp->next;
12861d06d6bSBaptiste Daroussin while (sp->first != NULL) {
12961d06d6bSBaptiste Daroussin dp = sp->first;
13061d06d6bSBaptiste Daroussin sp->first = dp->next;
13161d06d6bSBaptiste Daroussin free(dp->string);
13261d06d6bSBaptiste Daroussin free(dp);
13361d06d6bSBaptiste Daroussin }
13461d06d6bSBaptiste Daroussin free(sp);
13561d06d6bSBaptiste Daroussin }
136*7295610fSBaptiste Daroussin old_tbl = tbl;
137*7295610fSBaptiste Daroussin tbl = tbl->next;
138*7295610fSBaptiste Daroussin free(old_tbl);
139*7295610fSBaptiste Daroussin }
14061d06d6bSBaptiste Daroussin }
14161d06d6bSBaptiste Daroussin
14261d06d6bSBaptiste Daroussin void
tbl_restart(int line,int pos,struct tbl_node * tbl)14361d06d6bSBaptiste Daroussin tbl_restart(int line, int pos, struct tbl_node *tbl)
14461d06d6bSBaptiste Daroussin {
14561d06d6bSBaptiste Daroussin if (tbl->part == TBL_PART_CDATA)
146*7295610fSBaptiste Daroussin mandoc_msg(MANDOCERR_TBLDATA_BLK, line, pos, "T&");
14761d06d6bSBaptiste Daroussin
14861d06d6bSBaptiste Daroussin tbl->part = TBL_PART_LAYOUT;
14961d06d6bSBaptiste Daroussin tbl->line = line;
15061d06d6bSBaptiste Daroussin tbl->pos = pos;
15161d06d6bSBaptiste Daroussin }
15261d06d6bSBaptiste Daroussin
153*7295610fSBaptiste Daroussin struct tbl_span *
tbl_span(struct tbl_node * tbl)15461d06d6bSBaptiste Daroussin tbl_span(struct tbl_node *tbl)
15561d06d6bSBaptiste Daroussin {
15661d06d6bSBaptiste Daroussin struct tbl_span *span;
15761d06d6bSBaptiste Daroussin
15861d06d6bSBaptiste Daroussin span = tbl->current_span ? tbl->current_span->next
15961d06d6bSBaptiste Daroussin : tbl->first_span;
160*7295610fSBaptiste Daroussin if (span != NULL)
16161d06d6bSBaptiste Daroussin tbl->current_span = span;
16261d06d6bSBaptiste Daroussin return span;
16361d06d6bSBaptiste Daroussin }
16461d06d6bSBaptiste Daroussin
16561d06d6bSBaptiste Daroussin int
tbl_end(struct tbl_node * tbl,int still_open)166*7295610fSBaptiste Daroussin tbl_end(struct tbl_node *tbl, int still_open)
16761d06d6bSBaptiste Daroussin {
16861d06d6bSBaptiste Daroussin struct tbl_span *sp;
16961d06d6bSBaptiste Daroussin
170*7295610fSBaptiste Daroussin if (still_open)
171*7295610fSBaptiste Daroussin mandoc_msg(MANDOCERR_BLK_NOEND, tbl->line, tbl->pos, "TS");
172*7295610fSBaptiste Daroussin else if (tbl->part == TBL_PART_CDATA)
173*7295610fSBaptiste Daroussin mandoc_msg(MANDOCERR_TBLDATA_BLK, tbl->line, tbl->pos, "TE");
17461d06d6bSBaptiste Daroussin
17561d06d6bSBaptiste Daroussin sp = tbl->first_span;
17661d06d6bSBaptiste Daroussin while (sp != NULL && sp->first == NULL)
17761d06d6bSBaptiste Daroussin sp = sp->next;
17861d06d6bSBaptiste Daroussin if (sp == NULL) {
179*7295610fSBaptiste Daroussin mandoc_msg(MANDOCERR_TBLDATA_NONE, tbl->line, tbl->pos, NULL);
18061d06d6bSBaptiste Daroussin return 0;
18161d06d6bSBaptiste Daroussin }
18261d06d6bSBaptiste Daroussin return 1;
18361d06d6bSBaptiste Daroussin }
184