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