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