summaryrefslogtreecommitdiff
path: root/usr.bin/mandoc/roff.c
AgeCommit message (Collapse)Author
2014-03-08Improve .if/.ie condition handling.Ingo Schwarze
* Support string comparisons. * Support negation not only for numerical, but for all conditions. * Switch the `o' condition from false to true. * Handle the `c', `d', and `r' conditions as false for now. * Use int for boolean data instead of rolling our own "enum roffrule"; needed such that we can use the standard ! and == operators. Havard Eidnes reported via the NetBSD bug tracking system that some Tcl*(3) manuals need this, and Thomas Klausner <wiz at NetBSD> forwarded the report to me. This doesn't make the crazy Tcl*(3) macrology maze happy yet, but brings us a bit closer.
2014-03-07In roff_cond_sub(), make sure that the incorrect input sequence `\\}',Ingo Schwarze
when found on a macro line, does not close a conditional block. The companion function roff_cond_text() already did this correctly, but make the code more readable without functional change. While here, report the correct column number in related error messages.
2014-03-07Even on macro lines, \} must not cause whitespace.Ingo Schwarze
2014-03-07Three bugfixes related to the closing of conditional blocks:Ingo Schwarze
1. Handle more than one `\}' on macro lines, as it was already done for text lines. 2. Do not treat `\}' as a macro invocation after a dot at the beginning of a line. That allows more than one `\}' to work on lines starting with `.\}'. It also simplifies the code. 3. Do not complain about characters following `\}'. Those are not lost, but handled normally both on text and macro lines.
2014-02-14Parse and ignore the roff(7) .ce request (center some lines).Ingo Schwarze
We even parse and ignore the .ad request (adjustment mode), and it doesn't make sense to more prominently warn about temporary than about permanent adjustment changes. Request found by naddy@ in xloadimage(1) and by juanfra@ in racket(1).
2014-02-14Implement the roff(7) .as request (append to user-defined string).Ingo Schwarze
Missing feature found by jca@ in ratpoison(1). The ratpoison(1) manual still doesn't work because it uses .shift and .while, too (apparently, ratpoison is so complex that it needs a Turing-complete language to even format its manual :-). Written at Christchurch International Airport.
2014-02-14Handle some predefined read-only number registers, e.g. .H and .V.Ingo Schwarze
In particular, this improves handling of the pod2man(1) preamble; for examples of the effect, see some author names in perlthrtut(1). Missing feature reported by Andreas Voegele <mail at andreasvoegele dot com> more than two years ago. Written at Christchurch International Airport.
2014-01-06Gprof(1) is fun. You should use it more often.Ingo Schwarze
Another 10% speedup for mandocdb(8) -Q, and even 3% without -Q. With -Q, we are now at 41% of the time required by makewhatis(8). Do not copy predefined strings into the dynamic string table, just leave them in their own static table and use that one as a fallback at lookup time. This saves us copying and deleting them for each manual. No functional change.
2014-01-06Another 25% speedup for mandocdb(8) -Q mode, found with gprof(1).Ingo Schwarze
For /usr/share/man, we only need 56% of the time of makewhatis(8) now. In groff, user-defined macros clashing with mdoc(7) or man(7) standard macros are cleared when parsing the .Dd or .TH macro, respectively. Of course, we continue doing that in standard mode to assure full groff bug compatibility. However, in -Q mode, full groff bug compatibility makes no sense when it's unreasonably expensive, so skip this step in -Q mode. Real-world manuals hardly ever redefine standard macros, that's terrible style, and if they do, it's pointless to do so before .Dd or .TH because it has no effect. Even if someone does, it's extremely unlikely to break mandocdb(8) -Q parsing because we abort the parse sequence after the NAME section, anyway. So if you manually redefine .Sh, .Nm, .Nd, or .SH in a way that doesn't work at all and rely on .Dd or .TH to fix it up for you, your broken manual will no longer get a perfect apropos(1) entry until you re-run mandocdb(8) without -Q. It think that consequence is acceptable in order to get a 25% speedup for everyone else.
2013-12-30Oops, missed one:Ingo Schwarze
Remove duplicate const specifier from a call to mandoc_escape(). Found by Thomas Klausner <wiz at NetBSD dot org> using clang. No functional change.
2013-12-25s/[Nn]ull/NUL/ in comments where appropriate;Ingo Schwarze
suggested by Thomas Klausner <wiz @ NetBSD dot org>.
2013-12-15The "value" argument to the roff(7) .nr requests ends right beforeIngo Schwarze
the first non-digit character. While here, implement and document an optional sign, requesting increment or decrement, as documented in the Ossanna/Kernighan/Ritter troff manual and supported by groff. Reported by bentley@ on discuss at mdocml.
2013-10-22Parse and ignore .hw (hyphenation points in words); this is safe becauseIngo Schwarze
we don't do hyphenation anyway, so there is no point in throwing an ERROR when encountering .hw. Real-world usage of the request found by naddy@ in sysutils/dwdiff(1).
2013-10-14Parse and ignore the .fam (font family) request.Ingo Schwarze
Fixes irunner(1) in devel/ipython and uim-xim(1) in inputmethods/uim. Thanks to naddy@ for bringing these to my attention.
2013-10-05Cleanup suggested by gcc-4.8.1, following hints by Christos Zoulas:Ingo Schwarze
- avoid bad qualifier casting in roff.c, roff_parsetext() by changing the mandoc_escape arguments to "const char const **" - avoid bad qualifier casting in mandocdb.c, index_merge() - garbage collect a few unused variables elsewhere
2013-10-04Support simple numerical conditions.Ingo Schwarze
Original code from Christos Zoulas, NetBSD rev. 1.11-1.13, April 3, 2013. I tweaked the code as follows: * In roff_getnum(), don't skip a minus that isn't followed by a digit. * In roff_getop(), do not handle "!=", groff doesn't support it either. * In roff_evalcond(), treat negative numbers as false, like groff. Besides, make the interfaces of roff_getnum() and roff_getop() more similar to each other and simplify parts of the code a bit.
2013-10-03ROFFRULE_ALLOW = 0, ROFFRULE_DENY = 1 was confusing, so exchange theIngo Schwarze
two entries in enum roffrule; no functional change. From Christos Zoulas, NetBSD rev. 1.11, April 4, 2013.
2013-10-03Avoid code duplication in roff_parseln() as suggested byIngo Schwarze
Christos Zoulas in NetBSD rev. 1.11; i'm even going a step further and making this yet a bit shorter. No functional change.
2013-10-03Expand references to number registers in exactly the same way asIngo Schwarze
references to user-defined strings. While here, make number registers signed int, like in groff. Inspired by NetBSD roff.c rev. 1.8 and read.c rev. 1.7 written by Christos Zoulas on March 21, 2013, but implemented in a completely different way, without hacking into read.c, where this functionality really doesn't belong.
2013-10-03Support setting arbitrary roff(7) number registers,Ingo Schwarze
preserving read support for the ".nr nS" SYNOPSIS state register; read support for arbitrary registers is still not available. Inspired by NetBSD roff.c rev. 1.18 (Christos Zoulas, March 21, 2013), but implemented differently. I don't want to have yet another different implementation of a hash table in mandoc - it would be the second one in roff.c alone and the fifth one in mandoc grand total. Instead, i designed and implemented roff_setreg() and roff_getreg() to be similar to roff_setstrn() and roff_getstrn(). Once we feel the need to optimize, we can introduce one common hash table implementation for everything in mandoc.
2013-07-13Rudimentary implementation of the .it request (input line trap).Ingo Schwarze
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.
2013-06-27Parse for the closing delimiter `\}' for conditionalsIngo Schwarze
even when the conditional evaluated to false. While here, reshuffle the code to reduce indentation and make it more readable; that way, we can even trim down the comments because it becomes obvious what the code does. Found in zipinfo(1) - thanks to espie@ and naddy@ for making me look at that manual page.
2013-05-31More cleanup: Consistently use the name "struct tbl_node *tbl"Ingo Schwarze
that is already used almost everywhere instead of gratuitiously inventing different names at four places. No functional change.
2012-07-07Support the .cc request; code by kristaps@, tests by me.Ingo Schwarze
Needed for sqlite3(1) as reported by espie@.
2012-06-02In groff, trying to redefine standard man(7) macros before .TH has no effect;Ingo Schwarze
after .TH, it works. Trying to redefine standard mdoc(7) macros before .Dd works when calling groff with the -mdoc command line option, but does not when calling groff with -mandoc; after .Dd, it always works. Arguably, one might call that buggy behaviour in groff, but it is very unlikely that anybody will change groff in this respect (certainly, i'm not volunteering). So let's be bug-compatible. This fixes the vertical spacing in sox(1).
2012-05-31Fix blank line handling in .if.Ingo Schwarze
In particular, two cases were wrong: - single-line .if with trailing whitespace gave no blank line - multiline .if with \{ but without \{\ gave no blank line While here, simplify roff_cond() by partially reordering the code.
2011-10-24Handle infinite recursion the same way as groff:Ingo Schwarze
When string expansion exceeds the recursion limit, drop the whole input line, instead of leaving just the string unexpanded. This fixes src/regress/usr.bin/mandoc/roff/string/infinite.in. ok kristaps@
2011-09-19Breaking the line at a hyphen is only allowed if the hyphenIngo Schwarze
is both preceded and followed by an alphabetic character. This fixes about a dozen places in base.
2011-09-18Fix another regression introduced in 1.11.7:Ingo Schwarze
If a string is defined in terms of itself, the REPARSE_LIMIT in read.c used to break the cycle. This no longer works since all the work is now done in the function roff_res(), looping indefinitely. Make this loop finite by arbitrarily limiting the number of times one string may be expanded; when that limit is reached, leave the remaining string references unexpanded. This changes behaviour compared to 1.11.5, where the whole line would have been dropped. The new behaviour is better because it loses less information. We don't want to imitate groff-1.20.1 behaviour anyway because groff aborts parsing of the whole file.
2011-09-18sync to version 1.11.7 from kristaps@Ingo Schwarze
main new feature: support the roff(7) .tr request plus various bugfixes and some refactoring regressions are so minor that it's better to get this in and fix them in the tree
2011-09-18sync to version 1.11.5:Ingo Schwarze
adding an implementation of the eqn(7) language by kristaps@ So far, only .EQ/.EN blocks are handled, in-line equations are not, and rendering is not yet very pretty, but the parser is fairly complete.
2011-07-31Workaround to prevent misrendering of \*(-- as "O-" in pod2man(1)-Ingo Schwarze
generated manuals; this fixes more than 500 manuals in base alone. As a real fix, .tr will be supported after unlock. OK kristaps@ to put in the workaround for now
2011-07-07Fix a bogus "unknown macro" error reported in the pod2man(1) preamble:Ingo Schwarze
- Actually let roff_parse() recognize ".\}" as a cond block end request. - Do not rewrite "\}" to the zero-width space "\&" because that prevents recognition of immediately preceding macros; use normal blanks instead. - To avoid a vertical spacing regression in pod2man(1) manuals, drop one vertical spacing request just before NAME. From kristaps@.
2011-07-05Sync to bsd.lv (all coded by kristaps@):Ingo Schwarze
- mdoc(7): fix an assertion if the first line after .Bd -column starts with a blank, and some simplifications in mdoc_argv.c - man(7): literal mode ends at .SH and .SS (bug reported by naddy@) - allow .RS/.RE blocks to nest (bug reported by dcoppa@ and gsoares@) - improve vertical spacing of man(7) blocks - roff(7): clear user-defined strings when starting a new file - correct ID tags in -T[x]html
2011-05-29Merge release 1.11.3, almost all code by kristaps@:Ingo Schwarze
* Unicode output support (no Unicode input yet, though). * Refactoring: completely handle predefined strings in roff.c. - New function mandoc_escape() replaces a2roffdeco() and mandoc_special(). - Start using mandoc_getarg() in mdoc_argv.c. - Clean up parsing of delimiters in mdoc(7). * And many minor fixes and lots of cleanup.
2011-04-24User defined macros may invoke high-level macros.Ingo Schwarze
The latter got lost due to a regression in bsd.lv rev. 1.130.
2011-04-24Merge version 1.11.1:Ingo Schwarze
Again lots of cleanup and maintenance work by kristaps@. - simplify error reporting: less function pointers, more mandoc_[v]msg - main: split document parsing out of main.c into read.c - roff, mdoc, man: improved recognition of control characters - roff: better handling of if/else stack overflows - roff: add some predefined strings for backward compatibility - mdoc, man: empty sections are not errors - mdoc: move delimiter handling to libmdoc - some header restructuring and some minor features and fixes This merge causes two minor regressions that i will fix in separate commits right afterwards.
2011-04-21Merge version 1.10.10:Ingo Schwarze
lots of cleanup and maintenance work by kristaps@. - move some main.c globals into struct curparse - move mandoc_*alloc to mandoc.h such that all code can use them - make mandoc_isdelim available to formatting frontends - dissolve mdoc_strings.c, move the code where it is used - make all error reporting functions void, their return values were useless - and various minor cleanups and fixes
2011-04-05On .de macro lines, after the new macro name, space and tab are equivalent.Ingo Schwarze
Bug reported by Tristan dot LeGuern at gmail dot com in fvwm(1). tweaks and ok kristaps@; earlier version looked good to espie@ as well
2011-03-20Import the foundation for eqn(7) support.Ingo Schwarze
Written by kristaps@. For now, i'm adding one line to each of the four frontends to just pass the input text through to the output, not yet interpreting any of then eqn keywords.
2011-01-25Ignore .ns (no-space mode), .ps (change point size), .ta (tab control)Ingo Schwarze
for now. All of these just cause a bit too much or too little whitespace, but no serious formatting problems.
2011-01-20When finding the roff .it request (line trap),Ingo Schwarze
make it clear that you cannot use mandoc to format that page (yet). Triggered by a report from brad@.
2011-01-12Implement the roff .rm request (remove macro).Ingo Schwarze
Using the new roff_getname() function, this is really simple. Breaks mandoc of the habit of reporting an error in each pod2man(1) preamble. Reminded by a report from brad@.
2011-01-10Refactoring in preparation for .rm support:Ingo Schwarze
Unify parsing of names given as roff request arguments into a new function roff_getname(), which is rather different from the parsing function for normal arguments, mandoc_getarg(), because names cannot be quoted and cannot contain whitespace or escaped characters. The new function now throws an ERROR when finding escaped characters in a name. "I'm fine with this." kristaps@
2011-01-04Merge kristaps@' cleaner tbl integration, removing mine;Ingo Schwarze
there are still a few bugs, but fixing these will be easier in tree.
2011-01-03Calling a macro with fewer arguments than it is defined with is OK;Ingo Schwarze
the remaining ones default to the empty string, not to NULL. Regression reported and fix tested by kristaps@.
2011-01-03Unify roff macro argument parsing (in roff.c, roff_userdef()) and man macroIngo Schwarze
argument parsing (in man_argv.c, man_args()), both having different bugs, to use one common macro argument parser (in mandoc.c, mandoc_getarg()), because from the point of view of roff, man macros are just roff macros, hence their arguments are parsed in exactly the same way. While doing so, fix these bugs: * Escaped blanks (i.e. those preceded by an odd number of backslashes) were mishandled as argument separators in unquoted arguments to user-defined roff macros. * Unescaped blanks preceded by an even number of backslashes were not recognized as argument separators in unquoted arguments to man macros. * Escaped backslashes (i.e. pairs of backslashes) were not reduced to single backslashes both in unquoted and quoted arguments both to user-defined roff macros and to man macros. * Escaped quotes (i.e. pairs of quotes inside quoted arguments) were not reduced to single quotes in man macros. OK kristaps@ Note that mdoc macro argument parsing is yet another beast for no good reason and is probably afflicted by similar bugs. But i don't attempt to fix that right now because it is intricately entangled with lots of unrelated high-level mdoc(7) functionality, like delimiter handling and column list phrase handling. Disentagling that would waste too much time now.
2010-12-21Kristaps questioned the efficiency of the algorithm used in roff.c r1.23.Ingo Schwarze
An indeed, this optimization (using suggestions by Joerg Sonnenberger) saves about 40% of the processing time needed for the roff_res() function when processing typical manuals. No functional change, and the new code is not harder to understand. ok kristaps@
2010-12-09Roff only interpolates \* strings when the leading backslash is not escaped.Ingo Schwarze
Kristaps@ agrees with the idea, even though he didn't review the final patch.
2010-12-07Complete the merge of bsd.lv version 1.10.7:Ingo Schwarze
No more functional changes, just sync ordering, comments and white space.