1*698f87a4SGarrett D'Amore /* $Id: tbl.c,v 1.27 2013/05/31 22:08:09 schwarze Exp $ */ 295c635efSGarrett D'Amore /* 395c635efSGarrett D'Amore * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> 495c635efSGarrett D'Amore * Copyright (c) 2011 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 #ifdef HAVE_CONFIG_H 1995c635efSGarrett D'Amore #include "config.h" 2095c635efSGarrett D'Amore #endif 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" 2995c635efSGarrett D'Amore #include "libmandoc.h" 3095c635efSGarrett D'Amore #include "libroff.h" 3195c635efSGarrett D'Amore 3295c635efSGarrett D'Amore enum rofferr 3395c635efSGarrett D'Amore tbl_read(struct tbl_node *tbl, int ln, const char *p, int offs) 3495c635efSGarrett D'Amore { 3595c635efSGarrett D'Amore int len; 3695c635efSGarrett D'Amore const char *cp; 3795c635efSGarrett D'Amore 3895c635efSGarrett D'Amore cp = &p[offs]; 3995c635efSGarrett D'Amore len = (int)strlen(cp); 4095c635efSGarrett D'Amore 4195c635efSGarrett D'Amore /* 4295c635efSGarrett D'Amore * If we're in the options section and we don't have a 4395c635efSGarrett D'Amore * terminating semicolon, assume we've moved directly into the 4495c635efSGarrett D'Amore * layout section. No need to report a warning: this is, 4595c635efSGarrett D'Amore * apparently, standard behaviour. 4695c635efSGarrett D'Amore */ 4795c635efSGarrett D'Amore 4895c635efSGarrett D'Amore if (TBL_PART_OPTS == tbl->part && len) 4995c635efSGarrett D'Amore if (';' != cp[len - 1]) 5095c635efSGarrett D'Amore tbl->part = TBL_PART_LAYOUT; 5195c635efSGarrett D'Amore 5295c635efSGarrett D'Amore /* Now process each logical section of the table. */ 5395c635efSGarrett D'Amore 5495c635efSGarrett D'Amore switch (tbl->part) { 5595c635efSGarrett D'Amore case (TBL_PART_OPTS): 5695c635efSGarrett D'Amore return(tbl_option(tbl, ln, p) ? ROFF_IGN : ROFF_ERR); 5795c635efSGarrett D'Amore case (TBL_PART_LAYOUT): 5895c635efSGarrett D'Amore return(tbl_layout(tbl, ln, p) ? ROFF_IGN : ROFF_ERR); 5995c635efSGarrett D'Amore case (TBL_PART_CDATA): 6095c635efSGarrett D'Amore return(tbl_cdata(tbl, ln, p) ? ROFF_TBL : ROFF_IGN); 6195c635efSGarrett D'Amore default: 6295c635efSGarrett D'Amore break; 6395c635efSGarrett D'Amore } 6495c635efSGarrett D'Amore 6595c635efSGarrett D'Amore /* 6695c635efSGarrett D'Amore * This only returns zero if the line is empty, so we ignore it 6795c635efSGarrett D'Amore * and continue on. 6895c635efSGarrett D'Amore */ 6995c635efSGarrett D'Amore return(tbl_data(tbl, ln, p) ? ROFF_TBL : ROFF_IGN); 7095c635efSGarrett D'Amore } 7195c635efSGarrett D'Amore 7295c635efSGarrett D'Amore struct tbl_node * 7395c635efSGarrett D'Amore tbl_alloc(int pos, int line, struct mparse *parse) 7495c635efSGarrett D'Amore { 75*698f87a4SGarrett D'Amore struct tbl_node *tbl; 7695c635efSGarrett D'Amore 77*698f87a4SGarrett D'Amore tbl = mandoc_calloc(1, sizeof(struct tbl_node)); 78*698f87a4SGarrett D'Amore tbl->line = line; 79*698f87a4SGarrett D'Amore tbl->pos = pos; 80*698f87a4SGarrett D'Amore tbl->parse = parse; 81*698f87a4SGarrett D'Amore tbl->part = TBL_PART_OPTS; 82*698f87a4SGarrett D'Amore tbl->opts.tab = '\t'; 83*698f87a4SGarrett D'Amore tbl->opts.linesize = 12; 84*698f87a4SGarrett D'Amore tbl->opts.decimal = '.'; 85*698f87a4SGarrett D'Amore return(tbl); 8695c635efSGarrett D'Amore } 8795c635efSGarrett D'Amore 8895c635efSGarrett D'Amore void 89*698f87a4SGarrett D'Amore tbl_free(struct tbl_node *tbl) 9095c635efSGarrett D'Amore { 9195c635efSGarrett D'Amore struct tbl_row *rp; 9295c635efSGarrett D'Amore struct tbl_cell *cp; 9395c635efSGarrett D'Amore struct tbl_span *sp; 9495c635efSGarrett D'Amore struct tbl_dat *dp; 9595c635efSGarrett D'Amore struct tbl_head *hp; 9695c635efSGarrett D'Amore 97*698f87a4SGarrett D'Amore while (NULL != (rp = tbl->first_row)) { 98*698f87a4SGarrett D'Amore tbl->first_row = rp->next; 9995c635efSGarrett D'Amore while (rp->first) { 10095c635efSGarrett D'Amore cp = rp->first; 10195c635efSGarrett D'Amore rp->first = cp->next; 10295c635efSGarrett D'Amore free(cp); 10395c635efSGarrett D'Amore } 10495c635efSGarrett D'Amore free(rp); 10595c635efSGarrett D'Amore } 10695c635efSGarrett D'Amore 107*698f87a4SGarrett D'Amore while (NULL != (sp = tbl->first_span)) { 108*698f87a4SGarrett D'Amore tbl->first_span = sp->next; 10995c635efSGarrett D'Amore while (sp->first) { 11095c635efSGarrett D'Amore dp = sp->first; 11195c635efSGarrett D'Amore sp->first = dp->next; 11295c635efSGarrett D'Amore if (dp->string) 11395c635efSGarrett D'Amore free(dp->string); 11495c635efSGarrett D'Amore free(dp); 11595c635efSGarrett D'Amore } 11695c635efSGarrett D'Amore free(sp); 11795c635efSGarrett D'Amore } 11895c635efSGarrett D'Amore 119*698f87a4SGarrett D'Amore while (NULL != (hp = tbl->first_head)) { 120*698f87a4SGarrett D'Amore tbl->first_head = hp->next; 12195c635efSGarrett D'Amore free(hp); 12295c635efSGarrett D'Amore } 12395c635efSGarrett D'Amore 124*698f87a4SGarrett D'Amore free(tbl); 12595c635efSGarrett D'Amore } 12695c635efSGarrett D'Amore 12795c635efSGarrett D'Amore void 12895c635efSGarrett D'Amore tbl_restart(int line, int pos, struct tbl_node *tbl) 12995c635efSGarrett D'Amore { 13095c635efSGarrett D'Amore if (TBL_PART_CDATA == tbl->part) 13195c635efSGarrett D'Amore mandoc_msg(MANDOCERR_TBLBLOCK, tbl->parse, 13295c635efSGarrett D'Amore tbl->line, tbl->pos, NULL); 13395c635efSGarrett D'Amore 13495c635efSGarrett D'Amore tbl->part = TBL_PART_LAYOUT; 13595c635efSGarrett D'Amore tbl->line = line; 13695c635efSGarrett D'Amore tbl->pos = pos; 13795c635efSGarrett D'Amore 13895c635efSGarrett D'Amore if (NULL == tbl->first_span || NULL == tbl->first_span->first) 13995c635efSGarrett D'Amore mandoc_msg(MANDOCERR_TBLNODATA, tbl->parse, 14095c635efSGarrett D'Amore tbl->line, tbl->pos, NULL); 14195c635efSGarrett D'Amore } 14295c635efSGarrett D'Amore 14395c635efSGarrett D'Amore const struct tbl_span * 14495c635efSGarrett D'Amore tbl_span(struct tbl_node *tbl) 14595c635efSGarrett D'Amore { 14695c635efSGarrett D'Amore struct tbl_span *span; 14795c635efSGarrett D'Amore 14895c635efSGarrett D'Amore assert(tbl); 14995c635efSGarrett D'Amore span = tbl->current_span ? tbl->current_span->next 15095c635efSGarrett D'Amore : tbl->first_span; 15195c635efSGarrett D'Amore if (span) 15295c635efSGarrett D'Amore tbl->current_span = span; 15395c635efSGarrett D'Amore return(span); 15495c635efSGarrett D'Amore } 15595c635efSGarrett D'Amore 15695c635efSGarrett D'Amore void 15795c635efSGarrett D'Amore tbl_end(struct tbl_node **tblp) 15895c635efSGarrett D'Amore { 15995c635efSGarrett D'Amore struct tbl_node *tbl; 16095c635efSGarrett D'Amore 16195c635efSGarrett D'Amore tbl = *tblp; 16295c635efSGarrett D'Amore *tblp = NULL; 16395c635efSGarrett D'Amore 16495c635efSGarrett D'Amore if (NULL == tbl->first_span || NULL == tbl->first_span->first) 16595c635efSGarrett D'Amore mandoc_msg(MANDOCERR_TBLNODATA, tbl->parse, 16695c635efSGarrett D'Amore tbl->line, tbl->pos, NULL); 16795c635efSGarrett D'Amore 16895c635efSGarrett D'Amore if (tbl->last_span) 16995c635efSGarrett D'Amore tbl->last_span->flags |= TBL_SPAN_LAST; 17095c635efSGarrett D'Amore 17195c635efSGarrett D'Amore if (TBL_PART_CDATA == tbl->part) 17295c635efSGarrett D'Amore mandoc_msg(MANDOCERR_TBLBLOCK, tbl->parse, 17395c635efSGarrett D'Amore tbl->line, tbl->pos, NULL); 17495c635efSGarrett D'Amore } 17595c635efSGarrett D'Amore 176