summaryrefslogtreecommitdiffstats
path: root/roff.c
Commit message (Collapse)AuthorAgeFilesLines
...
* The previous commit to this file broke the control flow keywords \{ and \}Ingo Schwarze2014-07-011-1/+3
| | | | | | | | when they immediately follow a request or macro name, without intervening whitespace. Minimal fix. The lesson learnt here is that, despite their appearance, \{ and \} are not escape sequences, so never skip them when parsing for names.
* Use the freshly improved roff_getname() functionIngo Schwarze2014-06-291-16/+15
| | | | | | | | for the main roff request parsing routine, roff_parse(). In request or macro invocations, escape sequences now terminate the request or macro name; what follows is treated as arguments. Besides, the names of user-defined macros can now contain backslashes (eek!).
* Use the freshly improved roff_getname() functionIngo Schwarze2014-06-291-38/+18
| | | | | | for the .de parsing routine, roff_block(), to correctly handle names terminated by escape sequences. Besides, this saves us 20 lines of code.
* Major roff_getname() cleanup.Ingo Schwarze2014-06-291-35/+51
| | | | | | | | | * Return the name even if it is terminated by an escape sequence, not a blank. * Skip the full escape sequence using mandoc_escape(), not just the first byte. * Make it non-destructive, return the length instead of writing a '\0'. * Let .ds and .as cope with the above changes to the internal interface. * Fix .rm and .rr to accept an escape sequence as the end of a name. * Fix .nr and .rr to not set/delete a register with an empty name.
* Bugfix in roff_setstrn():Ingo Schwarze2014-06-291-1/+2
| | | | Do not call strcmp() on an array of char that might not be NUL-terminated.
* Improve messages related to the roff(7) .so request.Ingo Schwarze2014-06-251-3/+4
| | | | | | | | | | | | | In all these messages, show the filename argument that was passed to the .so request. In case of failure, show an additional message reporting the file and the line number where the failing request was found. The existing message reporting the reason for the failure - for example, "Permission denied" - is left in place, unchanged. Inspired by a question asked by Nick@ after he saw the confusing old messages that used to be emitted in this area.
* Audit strlcpy(3)/strlcat(3) usage.Ingo Schwarze2014-04-231-19/+9
| | | | | | | | | | | | | * Repair three instances of silent truncation, use asprintf(3). * Change two instances of strlen(3)+malloc(3)+strlcpy(3)+strlcat(3)+... to use asprintf(3) instead to make them less error prone. * Cast the return value of four instances where the destination buffer is known to be large enough to (void). * Completely remove three useless instances of strlcpy(3)/strlcat(3). * Mark two places in -Thtml with XXX that can cause information loss and crashes but are not easy to fix, requiring design changes of some internal interfaces. * The file mandocdb.c remains to be audited.
* make sure static buffers for snprintf(3) are large enoughIngo Schwarze2014-04-201-3/+3
| | | | and cast snprintf return value to (void) where they are
* KNF: case (FOO): -> case FOO:, remove /* LINTED */ and /* ARGSUSED */,Ingo Schwarze2014-04-201-162/+120
| | | | | remove trailing whitespace and blanks before tabs, improve some indenting; no functional change
* Fully implement the \B (validate numerical expression) andIngo Schwarze2014-04-081-27/+70
| | | | | | | | | | | partially implement the \w (measure text width) escape sequence in a way that makes them usable in numerical expressions and in conditional requests, similar to how \n (interpolate number register) and \* (expand user-defined string) are implemented. This lets mandoc(1) handle the baroque low-level roff code found at the beginning of the ggrep(1) manual. Thanks to pascal@ for the report.
* We already supported (outer) user-defined strings containing referencesIngo Schwarze2014-04-071-36/+44
| | | | | | | | to other (inner) user-defined strings in their values, such that the inner ones get expanded at expansion time of the outer ones (delayed evaluation). Now we also support specifying the name of an (outer) user-defined string to expand using the expanded values of some other (inner) user-defined strings (indirect reference).
* Almost complete implementation of roff(7) numerical expressions.Ingo Schwarze2014-04-071-57/+207
| | | | | | | Support all binary operators except ';' (scale conversion). Fully support chained operations and nested parentheses. Use this for the .nr, .if, and .ie requests. While here, fix parsing of integer numbers in roff_getnum().
* Implement the roff(7) .rr (remove register) request.Ingo Schwarze2014-04-051-0/+28
| | | | | As reported by sthen@, the perl-5.18 pod2man(1) preamble thinks cool kids use that in manuals. I hope *you* know better.
* avoid repetitive code for asprintf error handlingIngo Schwarze2014-03-231-5/+1
|
* The files mandoc.c and mandoc.h contained both specialised low-levelIngo Schwarze2014-03-231-0/+1
| | | | | | | functions used for multiple languages (mdoc, man, roff), for example mandoc_escape(), mandoc_getarg(), mandoc_eos(), and generic auxiliary functions. Split the auxiliaries out into their own file and header. While here, do some #include cleanup.
* Remove currently unimplemented macros from the lists of used-definedIngo Schwarze2014-03-201-14/+16
| | | | | | | macros to be cleared during .Dd and .TH because clearing them at that point defeats the purpose of backup implementations provided in the manual page itself, some of which _do_ work with mandoc(1). While here, add the new .%C macro to the list to be cleared.
* Generalize the mparse_alloc() and roff_alloc() functions by givingIngo Schwarze2014-03-191-7/+5
| | | | | | | | them an "options" argument, replacing the existing "inttype" and "quick" arguments, preparing for a future MPARSE_SO option. Store this argument in struct mparse and struct roff, replacing the existing "inttype", "parsetype", and "quick" members. No functional change except one tiny cosmetic fix in roff_TH().
* Improve .if/.ie condition handling.Ingo Schwarze2014-03-081-55/+86
| | | | | | | | | | | | | | * 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.
* In roff_cond_sub(), make sure that the incorrect input sequence `\\}',Ingo Schwarze2014-03-071-11/+12
| | | | | | | 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.
* Even on macro lines, \} must not cause whitespace.Ingo Schwarze2014-03-071-14/+10
|
* Three bugfixes related to the closing of conditional blocks:Ingo Schwarze2014-03-071-25/+12
| | | | | | | | | | 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.
* Parse and ignore the roff(7) .ce request (center some lines).Ingo Schwarze2014-02-141-0/+2
| | | | | | | | 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).
* Implement the roff(7) .as request (append to user-defined string).Ingo Schwarze2014-02-141-13/+15
| | | | | | | | | 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.
* Handle some predefined read-only number registers, e.g. .H and .V.Ingo Schwarze2014-02-141-0/+43
| | | | | | | | 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.
* Gprof(1) is fun. You should use it more often.Ingo Schwarze2014-01-061-9/+6
| | | | | | | | | | 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.
* Another 25% speedup for mandocdb(8) -Q mode, found with gprof(1).Ingo Schwarze2014-01-061-4/+6
| | | | | | | | | | | | | | | | | | | | | | | 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.
* Oops, missed one:Ingo Schwarze2013-12-301-2/+1
| | | | | | Remove duplicate const specifier from a call to mandoc_escape(). Found by Thomas Klausner <wiz at NetBSD dot org> using clang. No functional change.
* s/[Nn]ull/NUL/ in comments where appropriate;Ingo Schwarze2013-12-251-1/+1
| | | | suggested by Thomas Klausner <wiz @ NetBSD dot org>.
* The "value" argument to the roff(7) .nr requests ends right beforeIngo Schwarze2013-12-151-4/+17
| | | | | | | | 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@.
* Parse and ignore .hw (hyphenation points in words); this is safe becauseIngo Schwarze2013-10-221-0/+2
| | | | | | 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).
* Parse and ignore the .fam (font family) request.Ingo Schwarze2013-10-141-0/+2
| | | | | Fixes irunner(1) in devel/ipython and uim-xim(1) in inputmethods/uim. Thanks to naddy@ for bringing these to my attention.
* Support simple numerical conditions.Ingo Schwarze2013-10-051-3/+91
| | | | | | | | | | | 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.
* ROFFRULE_ALLOW = 0, ROFFRULE_DENY = 1 was confusing,Ingo Schwarze2013-10-051-2/+2
| | | | | so exchange the two entries in enum roffrule; no functional change; from Christos Zoulas, NetBSD rev. 1.11, April 4, 2013.
* Avoid code duplication in roff_parseln() as suggested byIngo Schwarze2013-10-051-10/+5
| | | | | | Christos Zoulas in NetBSD rev. 1.11; i'm even going a step further and making this yet a bit shorter. No functional change.
* Expand references to number registers in exactly the same way asIngo Schwarze2013-10-051-31/+52
| | | | | | | | | | 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.
* Support setting arbitrary roff(7) number registers,Ingo Schwarze2013-10-051-27/+56
| | | | | | | | | | | | | | preserving read support for the ".nr nS" SYNOPSIS state register. 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.
* Cleanup suggested by gcc-4.8.1, following hints by Christos Zoulas:Ingo Schwarze2013-10-051-1/+1
| | | | | | | | - 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() - do not complain about unused variables in test-*.c - garbage collect a few unused variables elsewhere
* Rudimentary implementation of the .it request (input line trap).Ingo Schwarze2013-07-131-10/+57
| | | | | | | | | | 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.
* Parse for the closing delimiter `\}' for conditionalsIngo Schwarze2013-06-271-43/+31
| | | | | | | | | | | 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.
* More cleanup: Consistently use the name "struct tbl_node *tbl"Ingo Schwarze2013-05-311-9/+9
| | | | | that is already used almost everywhere instead of gratuitiously inventing different names at four places. No functional change.
* In groff, trying to redefine standard man(7) macros before .TH has no effect;Ingo Schwarze2012-11-191-2/+67
| | | | | | | | | | | | | | 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). Merging from OpenBSD libmandoc.h 1.18, read.c 1.8, roff.c 1.47, June 2, 2012.
* Add `cc' support.Kristaps Dzonsons2012-06-121-1/+58
| | | | | | | | | | | | | | | This was reported by espie@ and in the TODO. Caveat: `cc' has buggy behaviour when invoked in groff(1) and followed by a line-breaking control character macro, e.g., in a -man doc, .cc | .B foo 'B foo |cc 'B foo will cause groff(1) to behave properly for `.B' but inline the macro definition for `B' when invoked with the line-breaking macro.
* Fix blank line handling in .if.Ingo Schwarze2012-05-311-33/+24
| | | | | | | | | | 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. "good one" kristaps@
* Handle infinite recursion the same way as groff:Ingo Schwarze2011-10-241-8/+12
| | | | | | | When string expansion exceeds the recursion limit, drop the whole input line, instead of leaving just the string unexpanded. ok kristaps@
* Breaking the line at a hyphen is only allowed if the hyphenIngo Schwarze2011-09-191-9/+2
| | | | | is both preceded and followed by an alphabetic character. ok kristaps@
* Fix another regression introduced in 1.11.7:Ingo Schwarze2011-09-181-2/+13
| | | | | | | | | | | | | | | | | 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. ok kristaps@
* forgotten Copyright bumps; no code changeIngo Schwarze2011-09-181-1/+1
| | | | found while syncing to OpenBSD
* Lint check.Kristaps Dzonsons2011-08-161-7/+0
|
* Use a character-table for quick per-character substitution in `tr'. AsKristaps Dzonsons2011-07-291-42/+71
| | | | suggested by joerg@.
* Renamed roffstr as roffkv (key-value) and split out char/size_t intoKristaps Dzonsons2011-07-291-43/+50
| | | | roffstr.