summaryrefslogtreecommitdiffstats
path: root/main.c
Commit message (Collapse)AuthorAgeFilesLines
* Support -T html -O tag by passing a file:// URI to the pager.Ingo Schwarze2020-06-151-16/+23
| | | | | Feature suggested by and implementation based on a patch from Abel Romero Perez <romeroperezabel at gmail dot com>.
* Fix a regression in rev. 1.319 (2019/03/03):Ingo Schwarze2020-06-141-1/+1
| | | | | | | Pass the right object to html_reset() or it will crash when rendering more than one manual page to HTML in a row. Bug reported by Abel Romero Perez <romeroperezabel at gmail dot com>. Patch from otto@.
* When the last file formatted yielded no tags, the tags file gotIngo Schwarze2020-04-021-25/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | deleted before starting the pager, even when earlier input files had written to it; thanks to weerd@ for reporting that bug. Since we now generate tags for section headers, we almost always generate at least some. Consequently, while fixing the above bug, simplify the code by never deleting the tags file before the pager exits, not even in the rare case that the file happens to be empty. Hence, this patch is -75 +63 LOC even though it fixes two bugs. While deleting the output files belongs after exit from the pager, closing them should be done before it is started. Collect the related code, which was scattered in various places, to where it belongs, in a dedicated function in the term_tag.c module. As a side benefit, never fclose(2) stdout, only dup2(2) to it. Similarly, when the -O tag argument wasn't found in the last file formatted, there was a complaint about "no such tag" even when the argument did occur in earlier files. Fix that by looking for a matching tag after every formatted file rather than just once at the very end. Given that command line arguments aren't properties of the file(s) being formatted, that check is a job for the main program, not for the formatters, so while fixing the check, move it from term_tag.c to main.c.
* Even though the HTML, man, markdown, PDF, PostScript, and tree formattersIngo Schwarze2020-03-281-12/+9
| | | | | | never write a ctags(1) file, using a pager still requires writing the main output file and passing the file name to the pager. Recent regression mentioned on IRC and reported by kn@.
* The tag file always needs to be closed before starting the pager,Ingo Schwarze2020-03-191-1/+2
| | | | | | even when no output formatter was allocated because all pages shown were preformatted. Regression in previous reported by <Andreas dot Kahari at abc dot se> on bugs@.
* Split tagging into a validation part including prioritizationIngo Schwarze2020-03-131-18/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | in tag.{h,c} and {mdoc,man}_validate.c and into a formatting part including command line argument checking in term_tag.{h,c}, html.c, and {mdoc|man}_{term|html}.c. Immediate functional benefits include: * Improved prioritization of automatic tags for .Em and .Sy. * Avoiding bogus automatic tags when .Em, .Fn, or .Sy are explicitly tagged. * Explicit tagging of .Er and .Fl now works in HTML output. * Automatic tagging of .IP and .TP now works in HTML output. But mainly, this patch provides clean earth to build further improvements on. Technical changes: * Main program: Write a tag file for ASCII and UTF-8 output only. * All formatters: There is no more need to delay writing the tags. * mdoc(7)+man(7) formatters: No more need for elaborate syntax tree inspection. * HTML formatter: If available, use the "string" attribute as the tag. * HTML formatter: New function to write permalinks, to reduce code duplication. Style cleanup in the vicinity while here: * mdoc(7) terminal formatter: To set up bold font for children, defer to termp_bold_pre() rather than calling term_fontpush() manually. * mdoc(7) terminal formatter: Garbage collect some duplicate functions. * mdoc(7) HTML formatter: Unify <code> handling, delete redundant functions. * Where possible, use switch statements rather than if cascades. * Get rid of some more Yoda notation. The necessity for such changes was first discussed with kn@, but i didn't bother him with a request to review the resulting -673/+782 line patch.
* Marc Espie reported that "man p*ipc" displayed the perlipc(1) manual.Ingo Schwarze2020-02-241-3/+25
| | | | | | | | | | | | | | The reason was that as a last resort when failing to find a page name in mandoc.db(5) or at a few well well-defined fully qualified file names, man(1) uses glob(3) to look for candidate files in relevant directories, because some operating systems have weird file name extensions, for example pcap.3pcap and BF_set_key.3ssl on Linux. But during that globbing, the metacharacters "*?[" need to be escaped in the name, section, and path supplied by the user, or you would get weird false positives and misleading warning messages and would be unable to use the fallback for path or file names that actually contain an opening bracket. Feedback and OK espie@.
* For compatibility with the man(1) implementations of the man-1.6Ingo Schwarze2020-02-101-2/+14
| | | | | | | | | | | | | | | | | | and man-db packages, print the manpath if the -w option is given without a following name argument. This quirk has been in man-1.6 since at least man-1.5e (1998) and in man-db since 2012. Using this feature in portable software is a dubious idea because the internal organization of manual page directories varies in about a dozen respects among operating systems, so even if you get the answer, there is no portable way to use it for looking up anything inside. However, Matej Cepl <mcepl at suse dot cz> made me aware that some software, for example the manual viewing functionality in the newest editors/neovim code, unwisely relies on this feature anyway. No objections were raised when this patch was shown on tech@.
* Make sure that -l always causes -w to be ignored, as documentedIngo Schwarze2020-02-061-2/+13
| | | | | in the man(1) manual page. This bugfix is needed to prevent the command "man -lw" from dereferencing a NULL pointer.
* Make the code more readable by introducingIngo Schwarze2020-01-201-0/+1
| | | | | | symbolic constants for tagging priorities. This review also made me find a minor bug: do not upgrade TAG_FALLBACK to TAG_WEAK when there is trailing whitespace.
* Simplification, no functional change:Ingo Schwarze2019-07-281-36/+29
| | | | | | Delete the "argc" argument from fs_search() which is now always 1, and move error reporting to the main() program where it is more logically placed and easier to see.
* There is no point in pledge(2)ing literally the same list twice,Ingo Schwarze2019-07-281-16/+0
| | | | so delete the second copy. No functional change.
* In man(1) mode, do the search for each name independently, andIngo Schwarze2019-07-281-81/+79
| | | | | | | | show the results in the order of the command line arguments. Implemented by separating the code for man(1) and apropos(1) in the main() program. Surprisingly, the number of lines of code remains unchanged. Issue reported by deraadt@, additional input from millert@.
* Improve structure, no functional change:Ingo Schwarze2019-07-281-80/+90
| | | | | Unify code to process one single input file and move it into a dedicated new function.
* Move two more output state variables into the new struct outstate.Ingo Schwarze2019-07-271-26/+21
| | | | | Also, move setting of tag_files.tagname into tag_init(). No functional change.
* Cleanup, no functional change:Ingo Schwarze2019-07-261-59/+61
| | | | | | For clarity, stop storing the same information (in this case, -O settings) in two structs. Give the local struct in main.c a more descriptive name (output state).
* Structural cleanup, no functional change:Ingo Schwarze2019-07-261-37/+43
| | | | | | | | Mixing parser and formatter state in the same struct was a bad idea, so pull the parser state and configuration out of it. This makes sure output options are not passed into parser functions and parser options are not passed into output functions. While here, add comments to the important local variables in main().
* Structural cleanup, no functional change:Ingo Schwarze2019-07-261-54/+60
| | | | | Move process group management out of main() into its own function because it has its own, self-contained logic and its own local variables.
* If no tags were generated at all, unlink(2) the empty tags file asIngo Schwarze2019-07-191-1/+1
| | | | | | | | | | | | soon as the condition can be detected and do not pass it to less(1). This may happen for man(7) pages, for preformatted pages, and for very simple pages like true(1). The main benefit is that :t inside less(1) yields the clearer diagnostic message "No tags file" rather than the mildly confusing "No such tag in tags file": the latter might encourage further, futile attempts to jump to other tags. Improvement suggested by Leah Neukirchen <leah at vuxu dot org> from The Void.
* don't print the final heads-up about messagesIngo Schwarze2019-07-151-1/+2
| | | | | when a search did not yield any manual pages to display; issue found with regress/usr.bin/mandoc/db/
* If messages are shown and output is printed without a pager, displayIngo Schwarze2019-07-141-1/+3
| | | | | | | | | | a heads-up on stderr at the end because otherwise, users may easily miss the messages: because messages typically occur while parsing, they typically preceed the output. This is most useful with flag combinations like "-c -W all" but may also help in some unusual error scenarios. Inconvenient ordering of output originally pointed out by espie@ for the example situation that /tmp/ is not writeable.
* Some time ago, i simplified mandoc_msg() such that it can be usedIngo Schwarze2019-07-101-156/+141
| | | | | | | | | everywhere and not only in the parsers. For more uniform messages, use it at more places instead of err(3), in particular in the main program. While here, integrate a few trivial functions called at exactly one place into the main option parser, and let a few more functions use the normal convention of returning 0 for success and -1 for error.
* prevent mandoc from segfaulting if /tmp is not writable;Ingo Schwarze2019-07-061-2/+4
| | | | patch from espie@
* avoid duplicate "bad argument" error message, also shortening the codeIngo Schwarze2019-05-031-5/+2
|
* In fs_lookup(), use stat(2) rather than access(2) to check file existence.Ingo Schwarze2019-05-031-6/+11
| | | | | | | | | | | Some mildly broken real-world packages on some operating systems contain dangling symlinks in manual page directories: pestering the user to run makewhatis(8) makes no sense because that won't help. On the other hand, missing read permissions deserve ugly error messages and are unlikely to occur in practice anyway. Fixing an issue reported by Lorenzo Beretta <loreb at github> as part of https://github.com/void-linux/void-packages/issues/9868 .
* In man(1) mode with a specific section requested,Ingo Schwarze2019-05-031-5/+16
| | | | | | | | | | | | | | | | try harder to find the best match. Use this order of preference: 1. The section in both the directory name and the file name matches exactly. 2. The section in the file name matches exactly. 3. The section in the directory name matches exactly. 4. Neither of them matches exactly. The latter can happen when mansearch() finds substring matches or when the second .Dt argument mismatches the dir and file names. Lorenzo Beretta <loreb at github> reported that this caused real problems on Void Linux, like "man 3 readline" showing readline(3m). See https://github.com/void-linux/void-packages/issues/9868 for details.
* In man(1) mode, when the first argument starts with a digit,Ingo Schwarze2019-05-031-1/+1
| | | | | | | | | | | | | | | | | | | | optionally followed by a letter, and at least one more argument follows, interpret the first argument as a section name even when additional characters follow after the digit and letter. This is needed because many operating systems have section names consisting of a digit followed by more than one letter - for example Illumos, Solaris, Linux, even NetBSD. There is very little risk of regressions: in the whole corpus of manual pages on man.openbsd.org, there isn't a single manual page name starting with a digit. And even if programs like "0ad" or "4channels" had manual pages, "man 0ad" and "man -a cat 0ad" would still work, only "man -a 0ad cat" will fail with "man: No entry for cat in section 0ad of the manual." Fixing one of the issues reported by Lorenzo Beretta <loreb at github> as part of https://github.com/void-linux/void-packages/issues/9868 .
* In man(1) mode, i.e. when asking for a single manual page by name,Ingo Schwarze2019-04-301-0/+2
| | | | | | | | | | | | prefer file name matches over .Dt/.TH matches over first NAME matches over later NAME matches, but do not change the ordering for apropos(1) nor for man -a. This reverts main.c rev. 1.310 and mansearch.h rev. 1.29 and includes a partial revert of mansearch.c rev. 1.79. Regression reported by Lorenzo Beretta <loreb at github> as part of https://github.com/void-linux/void-packages/issues/9868 .
* autoconfiguration test whether less(1) supports the -T option;Ingo Schwarze2019-03-061-0/+4
| | | | | needed for Alpine Linux because it uses busybox less(1) by default; based on a patch from Daniel Sabogal explained to me by Natanael Copa
* For TIOCGWINSZ, #include <termios.h> rather than <sys/termios.h>Ingo Schwarze2019-03-041-1/+1
| | | | | | like almost all other userland programs. This also improves portability: for example, it looks like <sys/termios.h> does not work on FreeBSD, or at least bapt@ did the same change over there.
* When the -S option is given to man(1) and the requested manual pageIngo Schwarze2019-03-041-1/+5
| | | | | | | | | | | | name is not found and the requested architecture is unknown, complain about the architecture rather than about the manual page name: $ man -S vax cpu man: Unknown architecture "vax". $ man -S sparc64 foobar man: No entry for foobar in the manual. Friendlier error message suggested by jmc@, who also OK'ed the patch.
* Reset HTML formatter state, in particular the id_unique hash,Ingo Schwarze2019-03-031-0/+2
| | | | | | | | after processing each manual page, such that the next page starts from a clean state and doesn't continue suffix numbering. Issue found while looking at https://github.com/Debian/debiman/issues/48 which was brought up by Orestis Ioannou <oorestisime at github>.
* Improve error reporting when a file given on the command lineIngo Schwarze2019-01-111-1/+1
| | | | | | cannot be opened: * Mention the filename. * Report the errno for the file itself, not the one with .gz appended.
* Initializers for file-scope static variables should be compile-timeIngo Schwarze2019-01-101-1/+2
| | | | | | | | constants, and while stderr is a compile-time constant in OpenBSD, Kelvin Sherlock <ksherlock at gmail dot com> reports that it isn't on some other systems, for example on FreeBSD or Linux. So do the initialization by calling mandoc_msg_setoutfile() from main() instead.
* Support taking the -O tag value from apropos(1) key=value search terms;Ingo Schwarze2019-01-011-7/+16
| | | | | | feature improvement suggested by kn@. While here, also make "-O value" work from standard input. OK kn@
* Cleanup, no functional change:Ingo Schwarze2018-12-301-19/+16
| | | | | | | | | | | | | | The struct roff_man used to be a bad mixture of internal parser state and public parsing results. Move the public results to the parsing result struct roff_meta, which is already public. Move the rest of struct roff_man to the parser-internal header roff_int.h. Since the validators need access to the parser state, call them from the top level parser during mparse_result() rather than from the main programs, also reducing code duplication. This keeps parser internal state out of thee main programs (five in mandoc portable) and out of eight formatters.
* Move the full responsibility for reporting open(2) errors fromIngo Schwarze2018-12-201-3/+5
| | | | | | | | | | | | | | | | | | | | | | | | mparse_open() to the caller. That is better because only the caller knows its preferred reporting method and format and only the caller has access to all the data that should be included - like the column number in .so processing or the current manpath in makewhatis(8). Moving the mandoc_msg() call out is possible because the caller can call strerror(3) just as easily as mparse_open() can. Move mandoc_msg_setinfilename() closer to the parsing of the file contents, to avoid problems *with* the file (like non-existence, lack of permissions, etc.) getting misreported as problems *in* the file. Fix the column number reported for .so failure: let it point to the beginning of the filename. Taken together, this prevents makewhatis(8) from spewing confusing messages about .so failures to stderr, a bug reported by Raf Czlonka <rczlonka at gmail dot com> on ports@. It also prevents mandoc(1) from issuing *two* messages for every single .so failure.
* Almost mechanical diff to remove the "struct mparse *" argumentIngo Schwarze2018-12-141-5/+4
| | | | | | | | from mandoc_msg(), where it is no longer used. While here, rename mandoc_vmsg() to mandoc_msg() and retire the old version: There is really no point in having another function merely to save "%s" in a few places. Minus 140 lines of code.
* Major cleanup; may imply minor changes in edge cases of error reporting.Ingo Schwarze2018-12-141-73/+37
| | | | | | | | | | | Finally, drop support for the run-time configurable mandocmsg() callback. It was over-engineered from the start, never used for anything in a decade, and repeatedly caused maintenance headaches. Consolidate reporting infrastructure into two files, mandoc.h and mandoc_msg.c, mopping up the bits and pieces that were scattered around main.c, read.c, mandoc_parse.h, libmandoc.h, the prototypes of four parsing-related functions, and both parser structs.
* Cleanup, no functional change:Ingo Schwarze2018-12-131-0/+1
| | | | | | | | | | Split the top level parser interface out of the utility header mandoc.h, into a new header mandoc_parse.h, for use in the main program and in the main parser only. Move enum mandoc_os into roff.h because struct roff_man is the place where it is stored. This allows removal of mandoc.h from seven files in low-level parsers and in formatters.
* In apropos(1) output, stop sorting .Nm search results by nameIngo Schwarze2018-11-221-2/+0
| | | | | | | | | | priorities (bits). The obscure feature wasn't documented and merely confused people - for example Edward Tomasz Napierala <trasz at FreeBSD>, see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=227408. Smaller patch provided by Yuri Pankov <yuripv at FreeBSD>, but i'm also retiring the now unused "bits" member from struct manpage. Simplification is good.
* In -T locale (the default), -T ascii, and -T utf8 mode, provide a newIngo Schwarze2018-11-221-4/+16
| | | | | | | | | | | | | | | output option -O tag[=term] to move right to the definition of "term" when opening the manual page in a pager, effectively porting the -T html fragment name feature - https://man.openbsd.org/ksh#ulimit - to the terminal. Try: $ man -O tag uvm_sysctl $ man -O tag=ulimit ksh $ man -O tag 3 compress Feature development triggered by a question from kn@. Klemens also tested, provided feedback that resulted in improvements, and provided an OK.
* The upcoming .while request will have to re-execute roff(7) linesIngo Schwarze2018-08-231-7/+1
| | | | | | | parsed earlier, so they will have to be saved for reuse - but the read.c preparser does not know yet whether a line contains a .while request before passing it to the roff parser. To cope with that, save all parsed lines for now. Even shortens the code by 20 lines.
* If somebody asks "man 3 chmod",Ingo Schwarze2018-08-091-2/+8
| | | | | | don't respond with the lie: "No entry for chmod in the manual." Instead, say "No entry for chmod in section 3 of the manual." Came up after a question from kn@; OK kn@.
* Some broken terminal emulators (e.g. sakura) do the equivalentIngo Schwarze2018-05-141-1/+2
| | | | | | of "stty cols 0". Ignore that insanity rather than setting conf.output.width to an invalid value and embarking on infinite loops. Issue reported by Jesper Wallin <jesper at ifconfig dot se>, thanks!
* Compatibility with man-db:Ingo Schwarze2018-04-191-12/+56
| | | | | | | | | In page name mode (= man(1) default mode), also try to interpret names containing slashes as absolute or relative file names. Missing feature reported by Nate Bargmann on <groff at gnu dot org>, and the man-db maintainer Colin Watson <cjwatson at debian dot org> kindly explained to me how this is supposed to work.
* Use TIOCGWINSZ to reduce the default -Owidth during interactive useIngo Schwarze2018-04-131-1/+13
| | | | | | | on terminals narrower than 79 columns and the default -Oindent on terminals narrower than 66 columns. Requested by and feedback from pirofti@; mpi@ and juanfra@ also like the general direction.
* Invalidate the tag_files.tfd after fclose(3)ing the stram associatedIngo Schwarze2018-02-231-1/+1
| | | | | | with it. In main() assert that the tfd was actually invalidated. This avoids closing an invalid fd. From tb@; OK deraadt@ on an earlier version.
* When the stdout stream gets broken, there is no point in readingIngo Schwarze2017-08-211-0/+11
| | | | | | | | | any more input files, and it would be misleading to start a parser, because that would show randomly truncated text. Instead, print an error message and exit the program. Issue found by Leah Neukirchen <leah at vuxu dot org>, who was surprised to see half a manpage when her /tmp/ overflew.
* Cast the return value of chdir(2) to void. We already have a commentIngo Schwarze2017-07-261-1/+1
| | | | | | above explaining to human auditors why no error checking is needed here, so it's only fair to tell the compiler, too. Worried compiler reported by Michael <Stapelberg at debian>.