diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2013-07-13 12:51:39 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2013-07-13 12:51:39 +0000 |
commit | 9b444726ceb69ae4c00fb4f16f7350473793bf58 (patch) | |
tree | bcad5c21a8471c0b08992cb5e191d812d7c70f6d | |
parent | 499872abba34ea93041507d26ea0092689138a40 (diff) |
Rudimentary implementation of the .it request (input line trap).
As with any low-level roff request involving subtle interactions
with macro internals, this implementation is not exact, but it
does handle the simplest cases.
This request occurs in man(7) code generated from DocBook,
for example mysql(1) and yasm_arch(7).
Thanks to brad@ for reporting the issue back in January 2011.
-rw-r--r-- | regress/usr.bin/mandoc/roff/Makefile | 4 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/it/Makefile | 5 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/it/double.in | 16 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/it/double.out_ascii | 13 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/it/text.in | 18 | ||||
-rw-r--r-- | regress/usr.bin/mandoc/roff/it/text.out_ascii | 11 | ||||
-rw-r--r-- | usr.bin/mandoc/mandoc.h | 5 | ||||
-rw-r--r-- | usr.bin/mandoc/read.c | 3 | ||||
-rw-r--r-- | usr.bin/mandoc/roff.c | 69 |
9 files changed, 128 insertions, 16 deletions
diff --git a/regress/usr.bin/mandoc/roff/Makefile b/regress/usr.bin/mandoc/roff/Makefile index 28a1dc82a47..9bda8849053 100644 --- a/regress/usr.bin/mandoc/roff/Makefile +++ b/regress/usr.bin/mandoc/roff/Makefile @@ -1,7 +1,7 @@ -# $OpenBSD: Makefile,v 1.12 2012/07/18 16:55:54 schwarze Exp $ +# $OpenBSD: Makefile,v 1.13 2013/07/13 12:51:38 schwarze Exp $ SUBDIR = args cond esc string -SUBDIR += br cc de ds na ps rm sp +SUBDIR += br cc de ds it na ps rm sp ascii groff groff-clean obj-clean tman: _SUBDIRUSE diff --git a/regress/usr.bin/mandoc/roff/it/Makefile b/regress/usr.bin/mandoc/roff/it/Makefile new file mode 100644 index 00000000000..351d1cde730 --- /dev/null +++ b/regress/usr.bin/mandoc/roff/it/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD: Makefile,v 1.1 2013/07/13 12:51:38 schwarze Exp $ + +REGRESS_TARGETS = text double + +.include <bsd.regress.mk> diff --git a/regress/usr.bin/mandoc/roff/it/double.in b/regress/usr.bin/mandoc/roff/it/double.in new file mode 100644 index 00000000000..d0a93e1ebac --- /dev/null +++ b/regress/usr.bin/mandoc/roff/it/double.in @@ -0,0 +1,16 @@ +.TH IT-DOUBLE 1 2013-07-13 OpenBSD +.SH NAME +it-double \- double input line trap +.SH DESCRIPTION +.de firstmacro +firstmacro +.. +.de secondmacro +secondmacro +.. +initial text +.it 1 firstmacro +.it 2 secondmacro +first line +second line +third line diff --git a/regress/usr.bin/mandoc/roff/it/double.out_ascii b/regress/usr.bin/mandoc/roff/it/double.out_ascii new file mode 100644 index 00000000000..c8c285da8fc --- /dev/null +++ b/regress/usr.bin/mandoc/roff/it/double.out_ascii @@ -0,0 +1,13 @@ +IT-DOUBLE(1) OpenBSD Reference Manual IT-DOUBLE(1) + + + +NNAAMMEE + it-double - double input line trap + +DDEESSCCRRIIPPTTIIOONN + initial text first line second line secondmacro third line + + + +OpenBSD 2013-07-13 IT-DOUBLE(1) diff --git a/regress/usr.bin/mandoc/roff/it/text.in b/regress/usr.bin/mandoc/roff/it/text.in new file mode 100644 index 00000000000..4eeac2bdf44 --- /dev/null +++ b/regress/usr.bin/mandoc/roff/it/text.in @@ -0,0 +1,18 @@ +.Dd $Mdocdate: July 13 2013 $ +.Dt IT-TEXT 1 +.Os OpenBSD +.Sh NAME +.Nm it-text +.Nd what an input line trap counts as text +.Sh DESCRIPTION +.de mytrap +traptext +.. +initial text +.it 1 mytrap +plain text line +another plain text line +.it 1 mytrap +.Pp +first line after .Pp +second line after .Pp diff --git a/regress/usr.bin/mandoc/roff/it/text.out_ascii b/regress/usr.bin/mandoc/roff/it/text.out_ascii new file mode 100644 index 00000000000..3eab2c4efc5 --- /dev/null +++ b/regress/usr.bin/mandoc/roff/it/text.out_ascii @@ -0,0 +1,11 @@ +IT-TEXT(1) OpenBSD Reference Manual IT-TEXT(1) + +NNAAMMEE + iitt--tteexxtt - what an input line trap counts as text + +DDEESSCCRRIIPPTTIIOONN + initial text plain text line traptext another plain text line + + first line after .Pp traptext second line after .Pp + +OpenBSD July 13, 2013 OpenBSD diff --git a/usr.bin/mandoc/mandoc.h b/usr.bin/mandoc/mandoc.h index 32b56ce5670..f1e8ef80c0e 100644 --- a/usr.bin/mandoc/mandoc.h +++ b/usr.bin/mandoc/mandoc.h @@ -1,7 +1,7 @@ -/* $Id: mandoc.h,v 1.51 2013/05/31 21:37:08 schwarze Exp $ */ +/* $Id: mandoc.h,v 1.52 2013/07/13 12:51:37 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2012 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2012, 2013 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 @@ -145,6 +145,7 @@ enum mandocerr { MANDOCERR_NOARGS, /* macro requires line argument(s) */ MANDOCERR_NOBODY, /* macro requires body argument(s) */ MANDOCERR_NOARGV, /* macro requires argument(s) */ + MANDOCERR_NUMERIC, /* request requires a numeric argument */ MANDOCERR_LISTTYPE, /* missing list type */ MANDOCERR_ARGSLOST, /* line argument(s) will be lost */ MANDOCERR_BODYLOST, /* body argument(s) will be lost */ diff --git a/usr.bin/mandoc/read.c b/usr.bin/mandoc/read.c index f2e03cf11bf..bb85374e636 100644 --- a/usr.bin/mandoc/read.c +++ b/usr.bin/mandoc/read.c @@ -1,4 +1,4 @@ -/* $Id: read.c,v 1.15 2013/06/02 03:35:21 schwarze Exp $ */ +/* $Id: read.c,v 1.16 2013/07/13 12:51:38 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org> @@ -177,6 +177,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "macro requires line argument(s)", "macro requires body argument(s)", "macro requires argument(s)", + "request requires a numeric argument", "missing list type", "line argument(s) will be lost", "body argument(s) will be lost", diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c index c6341b52fa4..c5fb1043eb1 100644 --- a/usr.bin/mandoc/roff.c +++ b/usr.bin/mandoc/roff.c @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.50 2013/06/27 09:48:22 schwarze Exp $ */ +/* $Id: roff.c,v 1.51 2013/07/13 12:51:38 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010, 2011, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org> @@ -17,6 +17,7 @@ */ #include <assert.h> #include <ctype.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -182,12 +183,13 @@ static void roff_freestr(struct roffkv *); static char *roff_getname(struct roff *, char **, int, int); static const char *roff_getstrn(const struct roff *, const char *, size_t); +static enum rofferr roff_it(ROFF_ARGS); static enum rofferr roff_line_ignore(ROFF_ARGS); static enum rofferr roff_nr(ROFF_ARGS); static void roff_openeqn(struct roff *, const char *, int, int, const char *); static enum rofft roff_parse(struct roff *, const char *, int *); -static enum rofferr roff_parsetext(char *); +static enum rofferr roff_parsetext(char **, size_t *, int, int *); static enum rofferr roff_res(struct roff *, char **, size_t *, int, int); static enum rofferr roff_rm(ROFF_ARGS); @@ -229,7 +231,7 @@ static struct roffmac roffs[ROFF_MAX] = { { "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL }, { "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL }, { "ig", roff_block, roff_block_text, roff_block_sub, 0, NULL }, - { "it", roff_line_ignore, NULL, NULL, 0, NULL }, + { "it", roff_it, NULL, NULL, 0, NULL }, { "ne", roff_line_ignore, NULL, NULL, 0, NULL }, { "nh", roff_line_ignore, NULL, NULL, 0, NULL }, { "nr", roff_nr, NULL, NULL, 0, NULL }, @@ -291,6 +293,9 @@ static const struct predef predefs[PREDEFS_MAX] = { /* See roffhash_find() */ #define ROFF_HASH(p) (p[0] - ASCII_LO) +static int roffit_lines; /* number of lines to delay */ +static char *roffit_macro; /* nil-terminated macro line */ + static void roffhash_init(void) { @@ -592,16 +597,20 @@ again: } /* - * Process text streams: convert all breakable hyphens into ASCII_HYPH. + * Process text streams: + * Convert all breakable hyphens into ASCII_HYPH. + * Decrement and spring input line trap. */ static enum rofferr -roff_parsetext(char *p) +roff_parsetext(char **bufp, size_t *szp, int pos, int *offs) { size_t sz; const char *start; + char *p; + int isz; enum mandoc_esc esc; - start = p; + start = p = *bufp + pos; while ('\0' != *p) { sz = strcspn(p, "-\\"); @@ -629,6 +638,22 @@ roff_parsetext(char *p) p++; } + /* Spring the input line trap. */ + if (1 == roffit_lines) { + isz = asprintf(&p, "%s\n.%s", *bufp, roffit_macro); + if (-1 == isz) { + perror(NULL); + exit((int)MANDOCLEVEL_SYSERR); + } + free(*bufp); + *bufp = p; + *szp = isz + 1; + *offs = 0; + free(roffit_macro); + roffit_lines = 0; + return(ROFF_REPARSE); + } else if (1 < roffit_lines) + --roffit_lines; return(ROFF_CONT); } @@ -673,13 +698,13 @@ roff_parseln(struct roff *r, int ln, char **bufp, return(eqn_read(&r->eqn, ln, *bufp, pos, offs)); if (r->tbl) return(tbl_read(r->tbl, ln, *bufp, pos)); - return(roff_parsetext(*bufp + pos)); + return(roff_parsetext(bufp, szp, pos, offs)); } else if ( ! ctl) { if (r->eqn) return(eqn_read(&r->eqn, ln, *bufp, pos, offs)); if (r->tbl) return(tbl_read(r->tbl, ln, *bufp, pos)); - return(roff_parsetext(*bufp + pos)); + return(roff_parsetext(bufp, szp, pos, offs)); } else if (r->eqn) return(eqn_read(&r->eqn, ln, *bufp, ppos, offs)); @@ -1116,9 +1141,6 @@ static enum rofferr roff_line_ignore(ROFF_ARGS) { - if (ROFF_it == tok) - mandoc_msg(MANDOCERR_REQUEST, r->parse, ln, ppos, "it"); - return(ROFF_IGN); } @@ -1293,6 +1315,31 @@ roff_rm(ROFF_ARGS) /* ARGSUSED */ static enum rofferr +roff_it(ROFF_ARGS) +{ + char *cp; + size_t len; + int iv; + + /* Parse the number of lines. */ + cp = *bufp + pos; + len = strcspn(cp, " \t"); + cp[len] = '\0'; + if ((iv = mandoc_strntoi(cp, len, 10)) <= 0) { + mandoc_msg(MANDOCERR_NUMERIC, r->parse, + ln, ppos, *bufp + 1); + return(ROFF_IGN); + } + cp += len + 1; + + /* Arm the input line trap. */ + roffit_lines = iv; + roffit_macro = mandoc_strdup(cp); + return(ROFF_IGN); +} + +/* ARGSUSED */ +static enum rofferr roff_Dd(ROFF_ARGS) { const char *const *cp; |