Return to tbl.c CVS log | Up to [cvsweb.bsd.lv] / mandoc |
version 1.28, 2014/03/23 11:25:26 | version 1.36, 2015/01/28 17:32:07 | ||
---|---|---|---|
|
|
||
/* $Id$ */ | /* $Id$ */ | ||
/* | /* | ||
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> | * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> | ||
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org> | * Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org> | ||
* | * | ||
* Permission to use, copy, modify, and distribute this software for any | * Permission to use, copy, modify, and distribute this software for any | ||
* purpose with or without fee is hereby granted, provided that the above | * purpose with or without fee is hereby granted, provided that the above | ||
|
|
||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | */ | ||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | #include "config.h" | ||
#endif | |||
#include <sys/types.h> | |||
#include <assert.h> | #include <assert.h> | ||
#include <stdio.h> | #include <stdio.h> | ||
#include <stdlib.h> | #include <stdlib.h> | ||
|
|
||
#include "libmandoc.h" | #include "libmandoc.h" | ||
#include "libroff.h" | #include "libroff.h" | ||
enum rofferr | enum rofferr | ||
tbl_read(struct tbl_node *tbl, int ln, const char *p, int offs) | tbl_read(struct tbl_node *tbl, int ln, const char *p, int pos) | ||
{ | { | ||
int len; | |||
const char *cp; | const char *cp; | ||
int active; | |||
cp = &p[offs]; | |||
len = (int)strlen(cp); | |||
/* | /* | ||
* If we're in the options section and we don't have a | * In the options section, proceed to the layout section | ||
* terminating semicolon, assume we've moved directly into the | * after a semicolon, or right away if there is no semicolon. | ||
* layout section. No need to report a warning: this is, | * Ignore semicolons in arguments. | ||
* apparently, standard behaviour. | |||
*/ | */ | ||
if (TBL_PART_OPTS == tbl->part && len) | if (tbl->part == TBL_PART_OPTS) { | ||
if (';' != cp[len - 1]) | tbl->part = TBL_PART_LAYOUT; | ||
tbl->part = TBL_PART_LAYOUT; | active = 1; | ||
for (cp = p + pos; *cp != '\0'; cp++) { | |||
switch (*cp) { | |||
case '(': | |||
active = 0; | |||
continue; | |||
case ')': | |||
active = 1; | |||
continue; | |||
case ';': | |||
if (active) | |||
break; | |||
continue; | |||
default: | |||
continue; | |||
} | |||
break; | |||
} | |||
if (*cp == ';') { | |||
tbl_option(tbl, ln, p, &pos); | |||
if (p[pos] == '\0') | |||
return(ROFF_IGN); | |||
} | |||
} | |||
/* Now process each logical section of the table. */ | /* Process the other section types. */ | ||
switch (tbl->part) { | switch (tbl->part) { | ||
case (TBL_PART_OPTS): | case TBL_PART_LAYOUT: | ||
return(tbl_option(tbl, ln, p) ? ROFF_IGN : ROFF_ERR); | tbl_layout(tbl, ln, p, pos); | ||
case (TBL_PART_LAYOUT): | return(ROFF_IGN); | ||
return(tbl_layout(tbl, ln, p) ? ROFF_IGN : ROFF_ERR); | case TBL_PART_CDATA: | ||
case (TBL_PART_CDATA): | return(tbl_cdata(tbl, ln, p, pos) ? ROFF_TBL : ROFF_IGN); | ||
return(tbl_cdata(tbl, ln, p) ? ROFF_TBL : ROFF_IGN); | |||
default: | default: | ||
break; | break; | ||
} | } | ||
/* | tbl_data(tbl, ln, p, pos); | ||
* This only returns zero if the line is empty, so we ignore it | return(ROFF_TBL); | ||
* and continue on. | |||
*/ | |||
return(tbl_data(tbl, ln, p) ? ROFF_TBL : ROFF_IGN); | |||
} | } | ||
struct tbl_node * | struct tbl_node * | ||
|
|
||
tbl->parse = parse; | tbl->parse = parse; | ||
tbl->part = TBL_PART_OPTS; | tbl->part = TBL_PART_OPTS; | ||
tbl->opts.tab = '\t'; | tbl->opts.tab = '\t'; | ||
tbl->opts.linesize = 12; | |||
tbl->opts.decimal = '.'; | tbl->opts.decimal = '.'; | ||
return(tbl); | return(tbl); | ||
} | } | ||
|
|
||
void | void | ||
tbl_restart(int line, int pos, struct tbl_node *tbl) | tbl_restart(int line, int pos, struct tbl_node *tbl) | ||
{ | { | ||
if (TBL_PART_CDATA == tbl->part) | if (tbl->part == TBL_PART_CDATA) | ||
mandoc_msg(MANDOCERR_TBLBLOCK, tbl->parse, | mandoc_msg(MANDOCERR_TBLDATA_BLK, tbl->parse, | ||
tbl->line, tbl->pos, NULL); | line, pos, "T&"); | ||
tbl->part = TBL_PART_LAYOUT; | tbl->part = TBL_PART_LAYOUT; | ||
tbl->line = line; | tbl->line = line; | ||
tbl->pos = pos; | tbl->pos = pos; | ||
if (NULL == tbl->first_span || NULL == tbl->first_span->first) | |||
mandoc_msg(MANDOCERR_TBLNODATA, tbl->parse, | |||
tbl->line, tbl->pos, NULL); | |||
} | } | ||
const struct tbl_span * | const struct tbl_span * | ||
|
|
||
return(span); | return(span); | ||
} | } | ||
void | int | ||
tbl_end(struct tbl_node **tblp) | tbl_end(struct tbl_node **tblp) | ||
{ | { | ||
struct tbl_node *tbl; | struct tbl_node *tbl; | ||
struct tbl_span *sp; | |||
tbl = *tblp; | tbl = *tblp; | ||
*tblp = NULL; | *tblp = NULL; | ||
if (NULL == tbl->first_span || NULL == tbl->first_span->first) | if (tbl->part == TBL_PART_CDATA) | ||
mandoc_msg(MANDOCERR_TBLNODATA, tbl->parse, | mandoc_msg(MANDOCERR_TBLDATA_BLK, tbl->parse, | ||
tbl->line, tbl->pos, NULL); | tbl->line, tbl->pos, "TE"); | ||
if (tbl->last_span) | sp = tbl->first_span; | ||
while (sp != NULL && sp->first == NULL) | |||
sp = sp->next; | |||
if (sp == NULL) { | |||
mandoc_msg(MANDOCERR_TBLDATA_NONE, tbl->parse, | |||
tbl->line, tbl->pos, NULL); | |||
return(0); | |||
} | |||
if (tbl->last_span != NULL) | |||
tbl->last_span->flags |= TBL_SPAN_LAST; | tbl->last_span->flags |= TBL_SPAN_LAST; | ||
if (TBL_PART_CDATA == tbl->part) | return(1); | ||
mandoc_msg(MANDOCERR_TBLBLOCK, tbl->parse, | |||
tbl->line, tbl->pos, NULL); | |||
} | } | ||