From 1481c0648531c03ad8b53843797e3c269032f43c Mon Sep 17 00:00:00 2001 From: Ingo Schwarze <schwarze@openbsd.org> Date: Fri, 5 May 2017 02:06:19 +0000 Subject: [PATCH] Move handling of the roff(7) .ft request from the man(7) modules to the new roff(7) modules. As a side effect, mdoc(7) now handles .ft, too. Of course, do not use that. --- Makefile | 4 +- Makefile.depend | 3 + man_html.c | 3 +- man_macro.c | 5 +- man_term.c | 39 +---------- man_validate.c | 46 +------------ mandoc_headers.3 | 3 +- mdoc_html.c | 3 +- mdoc_man.c | 23 +++++-- mdoc_markdown.c | 7 +- mdoc_term.c | 3 +- mdoc_validate.c | 5 +- regress/roff/ft/Makefile | 6 +- regress/roff/ft/badargs-mdoc.in | 18 ++++++ regress/roff/ft/badargs-mdoc.out_ascii | 9 +++ regress/roff/ft/badargs-mdoc.out_lint | 2 + roff.c | 36 ++++++++++- roff.h | 6 +- roff_html.c | 5 +- roff_term.c | 30 ++++++++- roff_validate.c | 89 ++++++++++++++++++++++++++ 21 files changed, 235 insertions(+), 110 deletions(-) create mode 100644 regress/roff/ft/badargs-mdoc.in create mode 100644 regress/roff/ft/badargs-mdoc.out_ascii create mode 100644 regress/roff/ft/badargs-mdoc.out_lint create mode 100644 roff_validate.c diff --git a/Makefile b/Makefile index decfe75f..d2b9a8b5 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.510 2017/05/04 22:16:09 schwarze Exp $ +# $Id: Makefile,v 1.511 2017/05/05 02:06:19 schwarze Exp $ # # Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> # Copyright (c) 2011, 2013-2017 Ingo Schwarze <schwarze@openbsd.org> @@ -112,6 +112,7 @@ SRCS = att.c \ roff.c \ roff_html.c \ roff_term.c \ + roff_validate.c \ soelim.c \ st.c \ tag.c \ @@ -212,6 +213,7 @@ LIBMDOC_OBJS = att.o \ LIBROFF_OBJS = eqn.o \ roff.o \ + roff_validate.o \ tbl.o \ tbl_data.o \ tbl_layout.o \ diff --git a/Makefile.depend b/Makefile.depend index b8e5363b..b75befd8 100644 --- a/Makefile.depend +++ b/Makefile.depend @@ -57,6 +57,9 @@ out.o: out.c config.h mandoc_aux.h mandoc.h out.h preconv.o: preconv.c config.h mandoc.h libmandoc.h read.o: read.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h libmandoc.h roff_int.h roff.o: roff.c config.h mandoc.h mandoc_aux.h mandoc_ohash.h compat_ohash.h roff.h libmandoc.h roff_int.h libroff.h predefs.in +roff_html.o: roff_html.c roff.h out.h html.h +roff_term.o: roff_term.c roff.h out.h term.h +roff_validate.o: roff_validate.c mandoc.h roff.h libmandoc.h roff_int.h soelim.o: soelim.c config.h compat_stringlist.h st.o: st.c config.h roff.h mdoc.h libmdoc.h st.in tag.o: tag.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h tag.h diff --git a/man_html.c b/man_html.c index d9fc43f2..e895698f 100644 --- a/man_html.c +++ b/man_html.c @@ -1,4 +1,4 @@ -/* $Id: man_html.c,v 1.138 2017/05/04 22:16:09 schwarze Exp $ */ +/* $Id: man_html.c,v 1.139 2017/05/05 02:06:19 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -102,7 +102,6 @@ static const struct htmlman __mans[MAN_MAX - MAN_TH] = { { man_ign_pre, NULL }, /* PD */ { man_ign_pre, NULL }, /* AT */ { man_in_pre, NULL }, /* in */ - { man_ign_pre, NULL }, /* ft */ { man_OP_pre, NULL }, /* OP */ { NULL, NULL }, /* EX */ { NULL, NULL }, /* EE */ diff --git a/man_macro.c b/man_macro.c index 7d3a8d71..a2c3f68d 100644 --- a/man_macro.c +++ b/man_macro.c @@ -1,4 +1,4 @@ -/* $Id: man_macro.c,v 1.117 2017/05/04 17:48:28 schwarze Exp $ */ +/* $Id: man_macro.c,v 1.118 2017/05/05 02:06:19 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2012-2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -71,7 +71,6 @@ const struct man_macro __man_macros[MAN_MAX - MAN_TH] = { { in_line_eoln, MAN_NSCOPED }, /* PD */ { in_line_eoln, 0 }, /* AT */ { in_line_eoln, 0 }, /* in */ - { in_line_eoln, 0 }, /* ft */ { in_line_eoln, 0 }, /* OP */ { in_line_eoln, MAN_BSCOPE }, /* EX */ { in_line_eoln, MAN_BSCOPE }, /* EE */ @@ -334,7 +333,7 @@ in_line_eoln(MACRO_PROT_ARGS) break; } if (buf[*pos] != '\0' && man->last != n && - (tok == MAN_PD || tok == MAN_ft || tok == MAN_sp)) { + (tok == MAN_PD || tok == MAN_sp)) { mandoc_vmsg(MANDOCERR_ARG_EXCESS, man->parse, line, *pos, "%s ... %s", roff_name[tok], buf + *pos); diff --git a/man_term.c b/man_term.c index d6ddf762..ac04dd6f 100644 --- a/man_term.c +++ b/man_term.c @@ -1,4 +1,4 @@ -/* $Id: man_term.c,v 1.194 2017/05/04 22:16:09 schwarze Exp $ */ +/* $Id: man_term.c,v 1.195 2017/05/05 02:06:19 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -80,7 +80,6 @@ static int pre_SS(DECL_ARGS); static int pre_TP(DECL_ARGS); static int pre_UR(DECL_ARGS); static int pre_alternate(DECL_ARGS); -static int pre_ft(DECL_ARGS); static int pre_ign(DECL_ARGS); static int pre_in(DECL_ARGS); static int pre_literal(DECL_ARGS); @@ -126,7 +125,6 @@ static const struct termact __termacts[MAN_MAX - MAN_TH] = { { pre_PD, NULL, MAN_NOTEXT }, /* PD */ { pre_ign, NULL, 0 }, /* AT */ { pre_in, NULL, MAN_NOTEXT }, /* in */ - { pre_ft, NULL, MAN_NOTEXT }, /* ft */ { pre_OP, NULL, 0 }, /* OP */ { pre_literal, NULL, 0 }, /* EX */ { pre_literal, NULL, 0 }, /* EE */ @@ -361,41 +359,6 @@ pre_OP(DECL_ARGS) return 0; } -static int -pre_ft(DECL_ARGS) -{ - const char *cp; - - if (NULL == n->child) { - term_fontlast(p); - return 0; - } - - cp = n->child->string; - switch (*cp) { - case '4': - case '3': - case 'B': - term_fontrepl(p, TERMFONT_BOLD); - break; - case '2': - case 'I': - term_fontrepl(p, TERMFONT_UNDER); - break; - case 'P': - term_fontlast(p); - break; - case '1': - case 'C': - case 'R': - term_fontrepl(p, TERMFONT_NONE); - break; - default: - break; - } - return 0; -} - static int pre_in(DECL_ARGS) { diff --git a/man_validate.c b/man_validate.c index c038b887..812e7743 100644 --- a/man_validate.c +++ b/man_validate.c @@ -48,7 +48,6 @@ static void check_text(CHKARGS); static void post_AT(CHKARGS); static void post_IP(CHKARGS); static void post_vs(CHKARGS); -static void post_ft(CHKARGS); static void post_OP(CHKARGS); static void post_TH(CHKARGS); static void post_UC(CHKARGS); @@ -85,7 +84,6 @@ static const v_check __man_valids[MAN_MAX - MAN_TH] = { NULL, /* PD */ post_AT, /* AT */ NULL, /* in */ - post_ft, /* ft */ post_OP, /* OP */ NULL, /* EX */ NULL, /* EE */ @@ -131,7 +129,8 @@ man_node_validate(struct roff_man *man) post_vs(man, n); break; default: - abort(); + roff_validate(man); + break; } break; } @@ -211,47 +210,6 @@ post_UR(CHKARGS) check_part(man, n); } -static void -post_ft(CHKARGS) -{ - char *cp; - int ok; - - if (n->child == NULL) - return; - - ok = 0; - cp = n->child->string; - switch (*cp) { - case '1': - case '2': - case '3': - case '4': - case 'I': - case 'P': - case 'R': - if ('\0' == cp[1]) - ok = 1; - break; - case 'B': - if ('\0' == cp[1] || ('I' == cp[1] && '\0' == cp[2])) - ok = 1; - break; - case 'C': - if ('W' == cp[1] && '\0' == cp[2]) - ok = 1; - break; - default: - break; - } - - if (0 == ok) { - mandoc_vmsg(MANDOCERR_FT_BAD, man->parse, - n->line, n->pos, "ft %s", cp); - *cp = '\0'; - } -} - static void check_part(CHKARGS) { diff --git a/mandoc_headers.3 b/mandoc_headers.3 index ecb730f2..f061332c 100644 --- a/mandoc_headers.3 +++ b/mandoc_headers.3 @@ -144,8 +144,9 @@ and the functions .Fn deroff , .Fn roffhash_alloc , .Fn roffhash_find , +.Fn roffhash_free , and -.Fn roffhash_free . +.Fn roff_validate . .Pp Uses pointers to the types .Vt struct mdoc_arg diff --git a/mdoc_html.c b/mdoc_html.c index 38660bac..48e3b81c 100644 --- a/mdoc_html.c +++ b/mdoc_html.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_html.c,v 1.282 2017/05/04 22:16:09 schwarze Exp $ */ +/* $Id: mdoc_html.c,v 1.283 2017/05/05 02:06:19 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -395,6 +395,7 @@ print_mdoc_node(MDOC_ARGS) assert(h->tblt == NULL); if (n->tok < ROFF_MAX) { roff_html_pre(h, n); + child = 0; break; } assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX); diff --git a/mdoc_man.c b/mdoc_man.c index 38fb57e6..20796006 100644 --- a/mdoc_man.c +++ b/mdoc_man.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_man.c,v 1.110 2017/05/04 17:48:29 schwarze Exp $ */ +/* $Id: mdoc_man.c,v 1.111 2017/05/05 02:06:19 schwarze Exp $ */ /* * Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org> * @@ -94,6 +94,7 @@ static int pre_fl(DECL_ARGS); static int pre_fn(DECL_ARGS); static int pre_fo(DECL_ARGS); static int pre_ft(DECL_ARGS); +static int pre_Ft(DECL_ARGS); static int pre_in(DECL_ARGS); static int pre_it(DECL_ARGS); static int pre_lk(DECL_ARGS); @@ -148,14 +149,14 @@ static const struct manact __manacts[MDOC_MAX - MDOC_Dd] = { { NULL, pre_fd, post_fd, NULL, NULL }, /* Fd */ { NULL, pre_fl, post_fl, NULL, NULL }, /* Fl */ { NULL, pre_fn, post_fn, NULL, NULL }, /* Fn */ - { NULL, pre_ft, post_font, NULL, NULL }, /* Ft */ + { NULL, pre_Ft, post_font, NULL, NULL }, /* Ft */ { NULL, pre_sy, post_font, NULL, NULL }, /* Ic */ { NULL, pre_in, post_in, NULL, NULL }, /* In */ { NULL, pre_li, post_font, NULL, NULL }, /* Li */ { cond_head, pre_enc, NULL, "\\- ", NULL }, /* Nd */ { NULL, pre_nm, post_nm, NULL, NULL }, /* Nm */ { cond_body, pre_enc, post_enc, "[", "]" }, /* Op */ - { NULL, pre_ft, post_font, NULL, NULL }, /* Ot */ + { NULL, pre_Ft, post_font, NULL, NULL }, /* Ot */ { NULL, pre_em, post_font, NULL, NULL }, /* Pa */ { NULL, pre_ex, NULL, NULL, NULL }, /* Rv */ { NULL, NULL, NULL, NULL, NULL }, /* St */ @@ -654,7 +655,10 @@ print_node(DECL_ARGS) } else if (n->tok < ROFF_MAX) { switch (n->tok) { case ROFF_br: - pre_br(meta, n); + do_sub = pre_br(meta, n); + break; + case ROFF_ft: + do_sub = pre_ft(meta, n); break; default: abort(); @@ -1314,7 +1318,7 @@ post_fo(DECL_ARGS) } static int -pre_ft(DECL_ARGS) +pre_Ft(DECL_ARGS) { pre_syn(n); @@ -1322,6 +1326,15 @@ pre_ft(DECL_ARGS) return 1; } +static int +pre_ft(DECL_ARGS) +{ + print_line(".ft", 0); + print_word(n->child->string); + outflags |= MMAN_nl; + return 0; +} + static int pre_in(DECL_ARGS) { diff --git a/mdoc_markdown.c b/mdoc_markdown.c index 5d80cfe3..15430c44 100644 --- a/mdoc_markdown.c +++ b/mdoc_markdown.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_markdown.c,v 1.18 2017/05/04 17:48:29 schwarze Exp $ */ +/* $Id: mdoc_markdown.c,v 1.19 2017/05/05 02:06:19 schwarze Exp $ */ /* * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org> * @@ -323,7 +323,10 @@ md_node(struct roff_node *n) } else if (n->tok < ROFF_MAX) { switch (n->tok) { case ROFF_br: - md_pre_br(n); + process_children = md_pre_br(n); + break; + case ROFF_ft: + process_children = 0; break; default: abort(); diff --git a/mdoc_term.c b/mdoc_term.c index 327ecea3..4718448e 100644 --- a/mdoc_term.c +++ b/mdoc_term.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_term.c,v 1.352 2017/05/04 22:16:09 schwarze Exp $ */ +/* $Id: mdoc_term.c,v 1.353 2017/05/05 02:06:19 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org> @@ -366,6 +366,7 @@ print_mdoc_node(DECL_ARGS) default: if (n->tok < ROFF_MAX) { roff_term_pre(p, n); + chld = 0; break; } assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX); diff --git a/mdoc_validate.c b/mdoc_validate.c index 75ec2e35..f57c4e54 100644 --- a/mdoc_validate.c +++ b/mdoc_validate.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_validate.c,v 1.323 2017/05/04 17:48:29 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.324 2017/05/05 02:06:19 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org> @@ -332,7 +332,8 @@ mdoc_node_validate(struct roff_man *mdoc) post_par(mdoc); break; default: - abort(); + roff_validate(mdoc); + break; } break; } diff --git a/regress/roff/ft/Makefile b/regress/roff/ft/Makefile index f57fe72b..5d2accbb 100644 --- a/regress/roff/ft/Makefile +++ b/regress/roff/ft/Makefile @@ -1,6 +1,8 @@ # $OpenBSD: Makefile,v 1.1 2014/07/05 12:33:54 schwarze Exp $ -REGRESS_TARGETS = badargs -LINT_TARGETS = badargs +REGRESS_TARGETS = badargs badargs-mdoc +LINT_TARGETS = badargs badargs-mdoc + +SKIP_TMAN = badargs .include <bsd.regress.mk> diff --git a/regress/roff/ft/badargs-mdoc.in b/regress/roff/ft/badargs-mdoc.in new file mode 100644 index 00000000..06f463b5 --- /dev/null +++ b/regress/roff/ft/badargs-mdoc.in @@ -0,0 +1,18 @@ +.Dd May 5, 2017 +.Dt FT-BADARGS-MDOC 1 +.Os OpenBSD +.Sh NAME +.Nm ft-badargs-mdoc +.Nd font request with bad arguments +.Sh DESCRIPTION +default font +.ft B +bold +.ft foo +still bold +.ft I bogus +italic +.ft P +back to bold +.ft +back to italic diff --git a/regress/roff/ft/badargs-mdoc.out_ascii b/regress/roff/ft/badargs-mdoc.out_ascii new file mode 100644 index 00000000..bd4eaa09 --- /dev/null +++ b/regress/roff/ft/badargs-mdoc.out_ascii @@ -0,0 +1,9 @@ +FT-BADARGS-MDOC(1) General Commands Manual FT-BADARGS-MDOC(1) + +NNAAMMEE + fftt--bbaaddaarrggss--mmddoocc - font request with bad arguments + +DDEESSCCRRIIPPTTIIOONN + default font bboolldd ssttiillll bboolldd _i_t_a_l_i_c bbaacckk ttoo bboolldd _b_a_c_k _t_o _i_t_a_l_i_c + +OpenBSD May 5, 2017 OpenBSD diff --git a/regress/roff/ft/badargs-mdoc.out_lint b/regress/roff/ft/badargs-mdoc.out_lint new file mode 100644 index 00000000..d5f526e6 --- /dev/null +++ b/regress/roff/ft/badargs-mdoc.out_lint @@ -0,0 +1,2 @@ +mandoc: badargs-mdoc.in:13:7: ERROR: skipping excess arguments: ft ... bogus +mandoc: badargs-mdoc.in:11:2: WARNING: unknown font, skipping request: ft foo diff --git a/roff.c b/roff.c index ba7aae26..654ee90e 100644 --- a/roff.c +++ b/roff.c @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.296 2017/05/04 17:48:29 schwarze Exp $ */ +/* $Id: roff.c,v 1.297 2017/05/05 02:06:19 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -182,6 +182,7 @@ static enum rofferr roff_line_ignore(ROFF_ARGS); static void roff_man_alloc1(struct roff_man *); static void roff_man_free1(struct roff_man *); static enum rofferr roff_nr(ROFF_ARGS); +static enum rofferr roff_onearg(ROFF_ARGS); static enum roff_tok roff_parse(struct roff *, char *, int *, int, int); static enum rofferr roff_parsetext(struct buf *, int, int *); @@ -210,7 +211,7 @@ static enum rofferr roff_userdef(ROFF_ARGS); #define ROFFNUM_WHITE (1 << 1) /* Skip whitespace in roff_evalnum(). */ const char *__roff_name[MAN_MAX + 1] = { - "br", NULL, + "br", "ft", NULL, "ab", "ad", "af", "aln", "als", "am", "am1", "ami", "ami1", "as", "as1", "asciify", @@ -309,7 +310,7 @@ const char *__roff_name[MAN_MAX + 1] = { "B", "I", "IR", "RI", "sp", "nf", "fi", "RE", "RS", "DT", "UC", - "PD", "AT", "in", "ft", + "PD", "AT", "in", "OP", "EX", "EE", "UR", "UE", "ll", NULL }; @@ -317,6 +318,7 @@ const char *const *roff_name = __roff_name; static struct roffmac roffs[TOKEN_NONE] = { { roff_br, NULL, NULL, 0 }, /* br */ + { roff_onearg, NULL, NULL, 0 }, /* ft */ { NULL, NULL, NULL, 0 }, /* ROFF_MAX */ { roff_unsupp, NULL, NULL, 0 }, /* ab */ { roff_line_ignore, NULL, NULL, 0 }, /* ad */ @@ -2766,6 +2768,34 @@ roff_TS(ROFF_ARGS) return ROFF_IGN; } +static enum rofferr +roff_onearg(ROFF_ARGS) +{ + struct roff_node *n; + char *cp; + + roff_elem_alloc(r->man, ln, ppos, tok); + n = r->man->last; + + cp = buf->buf + pos; + if (*cp != '\0') { + while (*cp != '\0' && *cp != ' ') + cp++; + while (*cp == ' ') + *cp++ = '\0'; + if (*cp != '\0') + mandoc_vmsg(MANDOCERR_ARG_EXCESS, + r->parse, ln, cp - buf->buf, + "%s ... %s", roff_name[tok], cp); + roff_word_alloc(r->man, ln, pos, buf->buf + pos); + } + + n->flags |= NODE_LINE | NODE_VALID | NODE_ENDED; + r->man->last = n; + r->man->next = ROFF_NEXT_SIBLING; + return ROFF_IGN; +} + static enum rofferr roff_br(ROFF_ARGS) { diff --git a/roff.h b/roff.h index 59fd8ba9..928b97eb 100644 --- a/roff.h +++ b/roff.h @@ -1,4 +1,4 @@ -/* $Id: roff.h,v 1.43 2017/05/04 17:48:29 schwarze Exp $ */ +/* $Id: roff.h,v 1.44 2017/05/05 02:06:19 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -67,6 +67,7 @@ enum roff_type { enum roff_tok { ROFF_br = 0, + ROFF_ft, ROFF_MAX, ROFF_ab, ROFF_ad, @@ -156,7 +157,6 @@ enum roff_tok { ROFF_fschar, ROFF_fspacewidth, ROFF_fspecial, - /* MAN_ft; ignored in mdoc(7) */ ROFF_ftr, ROFF_fzoom, ROFF_gcolor, @@ -464,7 +464,6 @@ enum roff_tok { MAN_PD, MAN_AT, MAN_in, - MAN_ft, MAN_OP, MAN_EX, MAN_EE, @@ -576,3 +575,4 @@ void deroff(char **, const struct roff_node *); struct ohash *roffhash_alloc(enum roff_tok, enum roff_tok); enum roff_tok roffhash_find(struct ohash *, const char *, size_t); void roffhash_free(struct ohash *); +void roff_validate(struct roff_man *); diff --git a/roff_html.c b/roff_html.c index 533fb9b7..3e30aa14 100644 --- a/roff_html.c +++ b/roff_html.c @@ -17,6 +17,7 @@ #include <sys/types.h> #include <assert.h> +#include <stddef.h> #include "roff.h" #include "out.h" @@ -30,6 +31,7 @@ static void roff_html_pre_br(ROFF_HTML_ARGS); static const roff_html_pre_fp roff_html_pre_acts[ROFF_MAX] = { roff_html_pre_br, /* br */ + NULL, /* ft */ }; @@ -37,7 +39,8 @@ void roff_html_pre(struct html *h, const struct roff_node *n) { assert(n->tok < ROFF_MAX); - (*roff_html_pre_acts[n->tok])(h, n); + if (roff_html_pre_acts[n->tok] != NULL) + (*roff_html_pre_acts[n->tok])(h, n); } static void diff --git a/roff_term.c b/roff_term.c index d96d9dd8..cd9fba37 100644 --- a/roff_term.c +++ b/roff_term.c @@ -1,6 +1,6 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010, 2017 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -27,9 +27,11 @@ typedef void (*roff_term_pre_fp)(ROFF_TERM_ARGS); static void roff_term_pre_br(ROFF_TERM_ARGS); +static void roff_term_pre_ft(ROFF_TERM_ARGS); static const roff_term_pre_fp roff_term_pre_acts[ROFF_MAX] = { roff_term_pre_br, /* br */ + roff_term_pre_ft, /* ft */ }; @@ -50,3 +52,29 @@ roff_term_pre_br(ROFF_TERM_ARGS) p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND); } } + +static void +roff_term_pre_ft(ROFF_TERM_ARGS) +{ + switch (*n->child->string) { + case '4': + case '3': + case 'B': + term_fontrepl(p, TERMFONT_BOLD); + break; + case '2': + case 'I': + term_fontrepl(p, TERMFONT_UNDER); + break; + case 'P': + term_fontlast(p); + break; + case '1': + case 'C': + case 'R': + term_fontrepl(p, TERMFONT_NONE); + break; + default: + break; + } +} diff --git a/roff_validate.c b/roff_validate.c new file mode 100644 index 00000000..269de1c4 --- /dev/null +++ b/roff_validate.c @@ -0,0 +1,89 @@ +/* $OpenBSD: roff_html.c,v 1.1 2017/05/04 22:07:44 schwarze Exp $ */ +/* + * Copyright (c) 2010, 2017 Ingo Schwarze <schwarze@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include <sys/types.h> + +#include <assert.h> +#include <stddef.h> + +#include "mandoc.h" +#include "roff.h" +#include "libmandoc.h" +#include "roff_int.h" + +#define ROFF_VALID_ARGS struct roff_man *man, struct roff_node *n + +typedef void (*roff_valid_fp)(ROFF_VALID_ARGS); + +static void roff_valid_ft(ROFF_VALID_ARGS); + +static const roff_valid_fp roff_valids[ROFF_MAX] = { + NULL, /* br */ + roff_valid_ft, /* ft */ +}; + + +void +roff_validate(struct roff_man *man) +{ + struct roff_node *n; + + n = man->last; + assert(n->tok < ROFF_MAX); + if (roff_valids[n->tok] != NULL) + (*roff_valids[n->tok])(man, n); +} + +static void +roff_valid_ft(ROFF_VALID_ARGS) +{ + char *cp; + + if (n->child == NULL) { + man->next = ROFF_NEXT_CHILD; + roff_word_alloc(man, n->line, n->pos, "P"); + man->last = n; + return; + } + + cp = n->child->string; + switch (*cp) { + case '1': + case '2': + case '3': + case '4': + case 'I': + case 'P': + case 'R': + if (cp[1] == '\0') + return; + break; + case 'B': + if (cp[1] == '\0' || (cp[1] == 'I' && cp[2] == '\0')) + return; + break; + case 'C': + if (cp[1] == 'W' && cp[2] == '\0') + return; + break; + default: + break; + } + + mandoc_vmsg(MANDOCERR_FT_BAD, man->parse, + n->line, n->pos, "ft %s", cp); + roff_node_delete(man, n); +} -- 2.47.1