summaryrefslogtreecommitdiffstats
path: root/roff.c
Commit message (Collapse)AuthorAgeFilesLines
...
* Implement the \\$@ escape sequence (insert all macro arguments,Ingo Schwarze2018-08-211-4/+18
| | | | | | | | | | | | quoted) in addition to the already supported \\$* (similar, but unquoted). Then use \\$@ to improve the implementation of the .als request (macro alias). Needed by groff_hdtbl(7). Gosh, it feels like the manual pages of the groff package are exercising every bloody roff(7) feature under the sun. In the manual page source code itself, not merely in the implementation of the used macro packages, that is.
* Expand \n(.$ (the number of macro arguments) right in roff_userdef(),Ingo Schwarze2018-08-201-7/+34
| | | | | | | | before even reparsing the expanded macro. That is the least dirty way to fix the bug that \(.$ remained set after execution of the user-defined macro ended. Any other way to fix it would probably require changes to read.c, which really shouldn't be bothered with such roff(7) internals.
* Mostly complete implementation of the 'c' (character available)Ingo Schwarze2018-08-191-4/+43
| | | | | | | | | | | roff conditional, except that the .char request still isn't supported and that behaviour differs from groff in many edge cases. But at least valid character names and numbers are now distinguished from invalid ones. This also fixes the bug that parsing of the 'c' conditional was incomplete, which resulted in leaking the tested character to the input parser at the beginning of the body when the condition was inverted.
* Bugfix: When a line ends with '\ \"', don't strip the trailing spaceIngo Schwarze2018-08-181-1/+2
| | | | because that turned it into a bogus line continuation.
* support the highly surprising escape sequence \# (line continuationIngo Schwarze2018-08-181-1/+8
| | | | with comment); used for example by gropdf(1)
* implement the GNU man-ext .SY/.YS (synopsis block) macro in man(7),Ingo Schwarze2018-08-181-1/+2
| | | | used in most manual pages of the groff package
* implement the GNU man-ext .TQ macro in man(7),Ingo Schwarze2018-08-161-0/+1
| | | | used for example by groff_diff(7)
* Implement the \*(.T predefined string (interpolate device name)Ingo Schwarze2018-08-161-0/+13
| | | | | by allowing the preprocessor to pass it through to the formatters. Used for example by the groff_char(7) manual page.
* Implement the roff(7) .nop (no operation) request.Ingo Schwarze2018-08-101-1/+11
| | | | | Examples of manual pages (ab)using it include groff(7), chem(1), groff_mom(7), and groff_hdtbl(7).
* After rewriting the parse buffer from scratch, we also have to resetIngo Schwarze2018-08-011-0/+3
| | | | | | the parse point to the beginning of the new buffer or we risk out of bounds accesses. Bug found by Leah Neukirchen <leah at vuxu dot org> with valgrind on Void Linux.
* preserve comments before .Dd when converting mdoc(7) to man(7)Ingo Schwarze2018-04-111-6/+29
| | | | with mandoc -Tman; suggested by Thomas Klausner <wiz at NetBSD>
* Two new low-level roff(7) features:Ingo Schwarze2018-04-101-14/+43
| | | | | | * .nr optional third argument (auto-increment step size) * \n+ and \n- numerical register auto-increment and -decrement bentley@ reported on Dec 9, 2013 that lang/sbcl(1) uses these.
* When accessing an undefined number register, define it to be zero, likeIngo Schwarze2018-04-091-23/+19
| | | | | | the previous commit for strings and macros, only technically simpler. Desired behaviour also mentioned by Werner Lemberg in 2011. This diff adds functionality but is -21 +19 LOC. :-)
* Using an undefined string or macro will cause it to be defined as empty.Ingo Schwarze2018-04-091-42/+81
| | | | | Observed by Werner Lemberg on Nov 14, 2011 and rotting on my TODO list ever since.
* The .Dd and .TH macros must interrupt .ce, too;Ingo Schwarze2017-07-141-1/+2
| | | | fixing tree corruption and assertion failure found by jsg@ with afl(1)
* Explicitly initialize a variable where the compiler is (understandably)Ingo Schwarze2017-07-141-5/+6
| | | | | | unable to figure out that it is never used uninitialized. While here, tweak the content of the variable to make its usage easier to understand. No functional change.
* eqn(7) .EQ has to break man(7) next-line scope, or tree corruptionIngo Schwarze2017-07-131-0/+2
| | | | and use after free many ensue; again found by jsg@ with afl(1)
* Simplify by creating struct roff_node syntax tree nodes for tbl(7)Ingo Schwarze2017-07-081-36/+36
| | | | | | | | | | | | right from roff_parseln() rather than delegating to read.c, similar to what i just did for eqn(7). The interface function roff_span() becomes obsolete and is deleted, the former interface function roff_addtbl() becomes static, the interface functions tbl_read() and tbl_cdata() become void, and minus twelve linus of code. No functional change.
* fix an assertion failure triggered by .ce in next-line scope;Ingo Schwarze2017-07-081-1/+2
| | | | found by jsg@ with afl(1)
* 1. Eliminate struct eqn, instead use the existing membersIngo Schwarze2017-07-081-47/+37
| | | | | | of struct roff_node which is allocated for each equation anyway. 2. Do not keep a list of equation parsers, one parser is enough. Minus fifty lines of code, no functional change.
* Fix handling of \} on roff request lines.Ingo Schwarze2017-07-041-15/+21
| | | | Cures bogus error messages in pages generated with pod2man(1).
* add support for the MT and ME mailto macros, used for example in wg(8);Ingo Schwarze2017-06-251-1/+1
| | | | patch from bentley@
* Split -Wstyle into -Wstyle and the even lower -Wbase, and addIngo Schwarze2017-06-241-5/+5
| | | | | | | | | | | | | | | -Wopenbsd and -Wnetbsd to check conventions for the base system of a specific operating system. Mark operating system specific messages with "(OpenBSD)" at the end. Please use just "-Tlint" to check base system manuals (defaulting to -Wall, which is now -Wbase), but prefer "-Tlint -Wstyle" for the manuals of portable software projects you maintain that are not part of OpenBSD base, to avoid bogus recommendations about base system conventions that do not apply. Issue originally reported by semarie@, solution using an idea from tedu@, discussed with jmc@ and jca@.
* Implement appending to standard man(7) and mdoc(7) macros with .am.Ingo Schwarze2017-06-181-135/+185
| | | | | | | | | | | | | | | | | | With roff_getstrn(), provide finer control which definitions can be used for what: * All definitions can be used for .if d tests and .am appending. * User-defined for \* expansion, .dei expansion, and macro calling. * Predefined for \* expansion. * Standard macros, original or renamed, for macro calling. Several related improvements while here: * Do not return string table entries that have explicitly been removed. * Do not create a rentab entry when trying to rename a non-existent macro. * Clear an existing rentab entry when the external interface roff_setstr() is called with its name. * Avoid trailing blanks in macro lines generated from renamed and from aliased macros. * Delete the duplicate __m*_reserved[] tables, just use roff_name[].
* style message about duplicate RCS ids; inspired by mdoclintIngo Schwarze2017-06-171-1/+5
|
* style message about missing RCS ids; inspired by mdoclintIngo Schwarze2017-06-171-0/+18
|
* Naive implementation of the roff(7) .po (page offset) request.Ingo Schwarze2017-06-141-4/+4
| | | | | | This clearly works when .po is called on the top level, but might not be sophisticated enough if people call .po inside indentation-changing contexts, but i haven't seen that in manual pages (yet :).
* simple implementation of the roff(7) .als (macro alias) request,Ingo Schwarze2017-06-141-4/+35
| | | | sufficient for pages using po4a(1)
* implement the roff(7) d (macro or string defined) conditionalIngo Schwarze2017-06-141-5/+11
|
* implement roff(7) .rj (right justify) requestIngo Schwarze2017-06-141-8/+8
|
* Explicitly ignore .br, .ce, and .sp inside tbl(7) text blocks.Ingo Schwarze2017-06-131-2/+3
| | | | | | With the current code structure, they would appear at the wrong place in the syntax tree, so it is better to not insert them into the tree at all and issue an UNSUPP message instead.
* Properly reinitialize roffce_node between parses,Ingo Schwarze2017-06-081-0/+4
| | | | | or this may crash with use-after-free in makewhatis(8); reported by jmc@, thanks!
* Implement the roff(7) .rn (rename macro or string) request.Ingo Schwarze2017-06-071-5/+97
| | | | | | | | | | Renaming a user-defined macro is very simple: just copy the definition to the new name and delete the old name. Renaming high-level macros is a bit tricky: use a dedicated key-value-table, with non-standard names as keys and standard names as values. When a macro is found that is not user-defined, look it up in the "renamed" table and translate it back to the standard name before passing it on to the high-level parsers.
* Minimal implementation of the roff(7) .ce request (center a numberIngo Schwarze2017-06-061-9/+60
| | | | | of input lines without filling). Contrary to groff, high-level macros abort .ce mode for now.
* Implement the roff(7) .mc (right margin character) request.Ingo Schwarze2017-06-041-4/+4
| | | | | | The Tcl/Tk manual pages use this extensively. Delete the TERM_MAXMARGIN hack, it breaks .mc inside .nf; instead, implement a proper TERMP_BRNEVER flag.
* Pure preprocessor implementation of the roff(7) .ec and .eo requestsIngo Schwarze2017-06-041-13/+99
| | | | | | | | | | | | | | | | | (escape character control), touching nothing after the preprocessing stage and keeping even the state variable local to the preprocessor. Since the escape character is also used for line continuation, this requires pulling the implementation of line continuation from the input reader to the preprocessor, which also considerably shortens the code required for that. When the escape character is changed, simply let the preprocessor replace bare by escaped backslashes and instances of the non-standard escape character with bare backslashes - that's all we need. Oh, and if anybody dares to use these requests in OpenBSD manuals, sending a medium-sized pack of axe-murderers after them might be a worthwhile part of the punishment, but probably insuffient on its own.
* Line-breaking roff(7) requests also break man(7) next-line scope.Ingo Schwarze2017-05-081-1/+7
| | | | | | Considering that real roff implements next-line scope using input line traps, that isn't all that surprising. Issue found in the games/xbattle port.
* Basic implementation of the roff(7) .ti (temporary indent) request.Ingo Schwarze2017-05-081-3/+3
| | | | Needed by about four dozen ports (thanks to naddy@ for the research).
* Basic implementation of the roff(7) .ta (define tab stops) request.Ingo Schwarze2017-05-071-3/+27
| | | | | | This is the first feature made possible by the parser reorganization. Improves the formatting of the SYNOPSIS in many Xenocara GL manuals. Also important for ports, as reported by many, including naddy@.
* Move .sp to the roff modules. Enough infrastructure is in placeIngo Schwarze2017-05-051-4/+6
| | | | now that this actually saves code: -70 LOC.
* move .ll to the roff modulesIngo Schwarze2017-05-051-3/+4
|
* Move handling of the roff(7) .ft request from the man(7)Ingo Schwarze2017-05-051-2/+32
| | | | | modules to the new roff(7) modules. As a side effect, mdoc(7) now handles .ft, too. Of course, do not use that.
* Parser reorg:Ingo Schwarze2017-05-041-10/+21
| | | | | Generate the first node on the roff level: .br Fix some column numbers in diagnostic messages while here.
* Parser unification: use nice ohashes for all three request and macro tables;Ingo Schwarze2017-04-291-303/+297
| | | | no functional change, minus two source files, minus 200 lines of code.
* Continue parser unification:Ingo Schwarze2017-04-241-280/+131
| | | | | | | | * Make enum rofft an internal interface as enum roff_tok in "roff.h". * Represent mdoc and man macros in enum roff_tok. * Make TOKEN_NONE a proper enum value and use it throughout. * Put the prologue macros first in the macro tables. * Unify mdoc_macroname[] and man_macroname[] into roff_name[].
* Fix blunder in previous: we must keep the line parse bufferIngo Schwarze2017-03-091-0/+2
| | | | | | | | consistent even when aborting the parsing of the line. That buffer is not our own, but owned and reused by mparse_buf_r(), read.c. Returning without cleanup leaked memory and caused write overruns of the old, typically much smaller buffer in mparse_buf_r(). Promptly noticed by tb@ with afl(1), using MALLOC_OPTIONS=C.
* prevent infinite recursion while expanding the argumentsIngo Schwarze2017-03-081-2/+15
| | | | of a user-defined macro; issue found by tb@ with afl(1)
* remove a few redundant conditions that jsg@ found with cppcheckIngo Schwarze2017-03-031-1/+1
|
* Fix previous: do not access the byte before the string if the stringIngo Schwarze2017-03-031-1/+1
| | | | is empty; found by jsg@ with afl(1).
* Fix a read buffer overrun that copied random data from memory intoIngo Schwarze2017-02-171-3/+11
| | | | | | | | | | | text nodes when a string passed to deroff() ended in a backslash and the byte after the terminating NUL was non-NUL, found by tb@ with afl(1). Invalid bytes so copied with the high bit set could later sometimes trigger another out of bounds read access to static memory in roff_strdup(), so add an assertion there to abort safely in case of similar data corruption.