From f9b9ca9e8b8d0314e2e380ac26c330739943a3f7 Mon Sep 17 00:00:00 2001 From: Werner LEMBERG Date: Mon, 13 Oct 2003 19:53:52 +0000 Subject: [PATCH] * src/roff/groff/groff.cpp (help), src/devices/grops/ps.cpp (usage), src/roff/troff/input.cc (usage): Updated. * NEWS, doc/groff.texinfo: Updated. * src/libs/libgroff/searchpath.cpp (search_path::open_file_cautious): New function which also handles `-' as stdin and stdout depending on the access mode. * src/include/searchpath.h (search_path): Updated. * src/devices/grops/ps.cpp (main): Handle new `-I' switch. * src/devices/grops/ps.h: Include `searchpath.h'. * src/devices/grops/psrm.cpp (resource_manager::supply_resource): Open resource file with `include_search_path.open_file_cautious'. * src/devices/grops/grops.man: Document new `-I' switch. * src/devices/grodvi/dvi.cpp (main), src/devices/grolbp/lbp.cpp (main), src/devices/grolj4/lj4.cpp (main), src/devices/grotty/tty.cpp (main): Ignore new `-I' switch. * src/preproc/soelim/soelim.cpp (include_list_length, include_list): Replaced with... (include_search_path): New global variable. (include_path_append): Removed. (main): Use `include_search_path.command_line_dir' to handle `-I'. (do_file): Simplify, using new `include_search_path.open_file_cautious'. * src/roff/groff/groff.cpp (print_commands): Accept file handle as parameter. (main): Pass arguments to `-I' to both troff and devices. Improve handling of `-V'. * src/roff/groff/groff.man: Document changes to -I and -V. * src/roff/troff/input.cpp (include_search_path): New global variable. (next_file, source, ps_bbox_request, transparent_file, process_input_file): Use new `include_search_path.open_file_cautious'. (main) Handle `-I' switch. * src/roff/troff/node.cpp (troff_output_file::really_copy_file): Use new `include_search_path.open_file_cautious'. * src/roff/troff/node.h: New extern symbol `include_search_path'. * src/roff/troff/troff.man: Document new `-I' switch. --- ChangeLog | 49 +++++++++++++++++++++++++ NEWS | 23 ++++++++++++ doc/groff.texinfo | 31 ++++++++++++++-- man/roff.man | 2 +- src/devices/grodvi/dvi.cpp | 5 ++- src/devices/grolbp/lbp.cpp | 5 ++- src/devices/grolj4/lj4.cpp | 5 ++- src/devices/grops/grops.man | 14 +++++++ src/devices/grops/ps.cpp | 11 +++++- src/devices/grops/ps.h | 4 ++ src/devices/grops/psrm.cpp | 2 +- src/devices/grotty/tty.cpp | 5 ++- src/include/searchpath.h | 4 +- src/libs/libgroff/searchpath.cpp | 62 ++++++++++++++++++++++++++++++- src/preproc/soelim/soelim.cpp | 79 +++++++--------------------------------- src/preproc/soelim/soelim.man | 2 +- src/roff/groff/groff.cpp | 22 +++++++---- src/roff/groff/groff.man | 22 +++++++++-- src/roff/troff/input.cpp | 23 ++++++++---- src/roff/troff/node.cpp | 5 ++- src/roff/troff/node.h | 2 +- src/roff/troff/troff.man | 14 ++++++- 22 files changed, 289 insertions(+), 102 deletions(-) diff --git a/ChangeLog b/ChangeLog index ada7bfc5..c334a0d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,52 @@ +2003-10-12 Werner LEMBERG + + * src/roff/groff/groff.cpp (help), src/devices/grops/ps.cpp (usage), + src/roff/troff/input.cc (usage): Updated. + + * NEWS, doc/groff.texinfo: Updated. + +2003-10-12 Peter Miller + + * src/libs/libgroff/searchpath.cpp + (search_path::open_file_cautious): New function which also handles + `-' as stdin and stdout depending on the access mode. + * src/include/searchpath.h (search_path): Updated. + + * src/devices/grops/ps.cpp (main): Handle new `-I' switch. + * src/devices/grops/ps.h: Include `searchpath.h'. + * src/devices/grops/psrm.cpp (resource_manager::supply_resource): + Open resource file with `include_search_path.open_file_cautious'. + * src/devices/grops/grops.man: Document new `-I' switch. + + * src/devices/grodvi/dvi.cpp (main), src/devices/grolbp/lbp.cpp + (main), src/devices/grolj4/lj4.cpp (main), + src/devices/grotty/tty.cpp (main): Ignore new `-I' switch. + + * src/preproc/soelim/soelim.cpp (include_list_length, include_list): + Replaced with... + (include_search_path): New global variable. + (include_path_append): Removed. + (main): Use `include_search_path.command_line_dir' to handle `-I'. + (do_file): Simplify, using new + `include_search_path.open_file_cautious'. + + * src/roff/groff/groff.cpp (print_commands): Accept file handle as + parameter. + (main): Pass arguments to `-I' to both troff and devices. + Improve handling of `-V'. + * src/roff/groff/groff.man: Document changes to -I and -V. + + * src/roff/troff/input.cpp (include_search_path): New global + variable. + (next_file, source, ps_bbox_request, transparent_file, + process_input_file): Use new + `include_search_path.open_file_cautious'. + (main) Handle `-I' switch. + * src/roff/troff/node.cpp (troff_output_file::really_copy_file): + Use new `include_search_path.open_file_cautious'. + * src/roff/troff/node.h: New extern symbol `include_search_path'. + * src/roff/troff/troff.man: Document new `-I' switch. + 2003-09-15 Ruslan Ermilov Support multiple calls of .Lb in LIBRARY section. diff --git a/NEWS b/NEWS index 785d9f07..0b008abd 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,17 @@ described. There are more details in the man and info pages. VERSION 1.19.1 ============== +Groff +----- + +o The argument of the command line option `-I' is now also passed to troff + and grops, specifying a directory to search for files on the command line, + files named in `so' and `psbb' requests, and files named in \X'ps: file' + and \X'ps: import' escapes. + +o If option `-V' is used more than once, the commands will be both printed + on standard error and run. + Troff ----- @@ -15,6 +26,10 @@ o For completeness, two new requests have been added: `dei1' and `ami1'. They are equivalent to `dei' and `ami', respectively, but the macros are executed with compatibility mode off (similar to `de1' and `am1'). +o New command line option `-I' to specify a directory for files (both + those on the command line and those named in `psbb' requests. This is + also handled by the groff wrapper program. + Pic ___ @@ -38,6 +53,14 @@ Grohtml o New option `-j' to emit output splitted into multiple files. + +Grops +----- + +o New command line option `-I' to specify a directory to search for files + on the command line and files named in \X'ps: import' and \X'ps: file' + escapes. This is also handled by the groff wrapper program. + Macro Packages -------------- diff --git a/doc/groff.texinfo b/doc/groff.texinfo index 0d156ddf..668f2a94 100644 --- a/doc/groff.texinfo +++ b/doc/groff.texinfo @@ -914,7 +914,8 @@ accessible via @code{groff}. This option prevents the loading of the Make programs run by @code{groff} print out their version number. @item -V -Print the pipeline on @code{stdout} instead of executing it. +Print the pipeline on @code{stdout} instead of executing it. If specified +more than once, print the pipeline on @code{stderr} and execute it. @item -z Suppress output from @code{gtroff}. Only error messages are printed. @@ -1153,8 +1154,26 @@ Search directory @file{@var{dir}} for macro files before the standard directories (@pxref{Macro Directories}). @item -I@var{dir} -This option is as described in @ref{gsoelim}. It implies the -@option{-s} option. +This option may be used to specify a directory to search for files. +It is passed to the following programs: + +@itemize +@item +@code{gsoelim} (see @ref{gsoelim} for more details); +it also implies @code{groff}'s @option{-s} option. + +@item +@code{gtroff}; it is used to search files named in the @code{psbb} and +@code{so} requests. + +@item +@code{grops}; it is used to search files named in the +@w{@code{\X'ps: import}} and @w{@code{\X'ps: file}} escapes. +@end itemize + +The current directory is always searched first. This option may be specified +more than once; the directories will be searched in the order specified. No +directory search is performed for files specified using an absolute path. @end table @@ -12264,6 +12283,9 @@ bar @noindent yields @samp{This is foobar}. + +The search path for @var{file} can be controlled with the @option{-I} command +line option. @endDefreq @Defreq {pso, command} @@ -12796,6 +12818,9 @@ and extracts the bounding box values into the number registers If an error occurs (for example, @code{psbb} cannot find the @code{%%BoundingBox} comment), it sets the four number registers to zero. + +The search path for @var{filename} can be controlled with the @option{-I} +command line option. @endDefreq diff --git a/man/roff.man b/man/roff.man index 02f3b3c5..a6011aca 100644 --- a/man/roff.man +++ b/man/roff.man @@ -1247,7 +1247,7 @@ might be a good starting point. .SH AUTHORS .\" -------------------------------------------------------------------- . -Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. +Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. . .P This document is distributed under the terms of the FDL (GNU Free diff --git a/src/devices/grodvi/dvi.cpp b/src/devices/grodvi/dvi.cpp index df169390..7a567412 100644 --- a/src/devices/grodvi/dvi.cpp +++ b/src/devices/grodvi/dvi.cpp @@ -915,7 +915,7 @@ int main(int argc, char **argv) { "version", no_argument, 0, 'v' }, { NULL, 0, 0, 0 } }; - while ((c = getopt_long(argc, argv, "dF:lp:vw:", long_options, NULL)) + while ((c = getopt_long(argc, argv, "dF:I:lp:vw:", long_options, NULL)) != EOF) switch(c) { case 'd': @@ -927,6 +927,9 @@ int main(int argc, char **argv) case 'F': font::command_line_font_dir(optarg); break; + case 'I': + // ignore include search path + break; case 'p': if (!font::scan_papersize(optarg, 0, &user_paper_length, &user_paper_width)) diff --git a/src/devices/grolbp/lbp.cpp b/src/devices/grolbp/lbp.cpp index b34a1e08..1fb6fcc8 100644 --- a/src/devices/grolbp/lbp.cpp +++ b/src/devices/grolbp/lbp.cpp @@ -663,12 +663,15 @@ int main(int argc, char **argv) int c = 0; int option_index = 0; while (c >= 0) { - c = getopt_long (argc, argv, "F:p:lvo:c:hw:", + c = getopt_long (argc, argv, "c:F:hI:lo:p:vw:", long_options, &option_index); switch (c) { case 'F': font::command_line_font_dir(optarg); break; + case 'I': + // ignore include path arguments + break; case 'p': { const char *s; diff --git a/src/devices/grolj4/lj4.cpp b/src/devices/grolj4/lj4.cpp index 1332e198..99a675df 100644 --- a/src/devices/grolj4/lj4.cpp +++ b/src/devices/grolj4/lj4.cpp @@ -611,12 +611,15 @@ int main(int argc, char **argv) { "version", no_argument, 0, 'v' }, { NULL, 0, 0, 0 } }; - while ((c = getopt_long(argc, argv, ":F:p:d:lvw:c:", long_options, NULL)) + while ((c = getopt_long(argc, argv, ":c:d:F:I:l:p:vw:", long_options, NULL)) != EOF) switch(c) { case 'l': landscape_flag = 1; break; + case 'I': + // ignore include search path + break; case ':': if (optopt == 'd') { fprintf(stderr, "duplex assumed to be long-side\n"); diff --git a/src/devices/grops/grops.man b/src/devices/grops/grops.man index 84bf9fa4..29baf2ce 100644 --- a/src/devices/grops/grops.man +++ b/src/devices/grops/grops.man @@ -65,6 +65,7 @@ grops \- PostScript driver for groff .OP \-b n .OP \-c n .OP \-F dir +.OP \-I dir .OP \-p papersize .OP \-P prologue .OP \-w n @@ -231,6 +232,19 @@ This option allows you to generate documents that can be printed both on letter (8.5\(mu11) paper and on A4 paper without change. . .TP +.BI \-I dir +This option may be used to specify a directory to search for +files on the command line and files named in +.B \eX'ps: import' +and +.B \eX'ps: file' +escapes. +The current directory is always searched first. +This option may be specified more than once; +the directories will be searched in the order specified. +No directory search is performed for files specified using an absolute path. +. +.TP .B \-l Print the document in landscape format. . diff --git a/src/devices/grops/ps.cpp b/src/devices/grops/ps.cpp index f1c094b4..4084c85e 100644 --- a/src/devices/grops/ps.cpp +++ b/src/devices/grops/ps.cpp @@ -42,6 +42,9 @@ extern "C" { extern "C" const char *Version_string; +// search path defaults to the current directory +search_path include_search_path(0, 0, 0, 1); + static int landscape_flag = 0; static int manual_feed_flag = 0; static int ncopies = 1; @@ -1790,7 +1793,7 @@ int main(int argc, char **argv) { "version", no_argument, 0, 'v' }, { NULL, 0, 0, 0 } }; - while ((c = getopt_long(argc, argv, "b:c:F:glmp:P:vw:", long_options, NULL)) + while ((c = getopt_long(argc, argv, "b:c:F:gI:lmp:P:vw:", long_options, NULL)) != EOF) switch(c) { case 'b': @@ -1810,6 +1813,9 @@ int main(int argc, char **argv) case 'g': guess_flag = 1; break; + case 'I': + include_search_path.command_line_dir(optarg); + break; case 'l': landscape_flag = 1; break; @@ -1864,6 +1870,7 @@ int main(int argc, char **argv) static void usage(FILE *stream) { fprintf(stream, - "usage: %s [-glmv] [-b n] [-c n] [-w n] [-P prologue] [-F dir] [files ...]\n", +"usage: %s [-glmv] [-b n] [-c n] [-w n] [-I dir] [-P prologue]\n" +" [-F dir] [files ...]\n", program_name); } diff --git a/src/devices/grops/ps.h b/src/devices/grops/ps.h index a4b4169b..04330b6e 100644 --- a/src/devices/grops/ps.h +++ b/src/devices/grops/ps.h @@ -123,3 +123,7 @@ enum { USE_PS_ADOBE_2_0 = 010, NO_PAPERSIZE = 020 }; + +#include "searchpath.h" + +extern search_path include_search_path; diff --git a/src/devices/grops/psrm.cpp b/src/devices/grops/psrm.cpp index ab94ffee..03e38bb4 100644 --- a/src/devices/grops/psrm.cpp +++ b/src/devices/grops/psrm.cpp @@ -360,7 +360,7 @@ void resource_manager::supply_resource(resource *r, int rank, FILE *outfp, } else { errno = 0; - fp = fopen(r->filename, "r"); + fp = include_search_path.open_file_cautious(r->filename); if (!fp) { error("can't open `%1': %2", r->filename, strerror(errno)); a_delete r->filename; diff --git a/src/devices/grotty/tty.cpp b/src/devices/grotty/tty.cpp index e7bab6c1..aab195d0 100644 --- a/src/devices/grotty/tty.cpp +++ b/src/devices/grotty/tty.cpp @@ -805,7 +805,7 @@ int main(int argc, char **argv) { "version", no_argument, 0, 'v' }, { NULL, 0, 0, 0 } }; - while ((c = getopt_long(argc, argv, "bBcdfF:hioruUv", long_options, NULL)) + while ((c = getopt_long(argc, argv, "bBcdfF:hiI:oruUv", long_options, NULL)) != EOF) switch(c) { case 'v': @@ -816,6 +816,9 @@ int main(int argc, char **argv) // Use italic font instead of underlining. italic_flag_option = 1; break; + case 'I': + // ignore include search path + break; case 'b': // Do not embolden by overstriking. bold_flag_option = 0; diff --git a/src/include/searchpath.h b/src/include/searchpath.h index 4d89a8d0..6568cd83 100644 --- a/src/include/searchpath.h +++ b/src/include/searchpath.h @@ -1,5 +1,6 @@ // -*- C++ -*- -/* Copyright (C) 1989, 1990, 1991, 1992, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2003 + Free Software Foundation, Inc. Written by James Clark (jjc@jclark.com) This file is part of groff. @@ -27,4 +28,5 @@ public: ~search_path(); void command_line_dir(const char *); FILE *open_file(const char *, char **); + FILE *open_file_cautious(const char *, char ** = 0, const char * = 0); }; diff --git a/src/libs/libgroff/searchpath.cpp b/src/libs/libgroff/searchpath.cpp index 1f8b233c..ce08cdf2 100644 --- a/src/libs/libgroff/searchpath.cpp +++ b/src/libs/libgroff/searchpath.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001 +/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2003 Free Software Foundation, Inc. Written by James Clark (jjc@jclark.com) @@ -23,6 +23,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include +#include #include "searchpath.h" #include "nonposix.h" @@ -130,3 +131,62 @@ FILE *search_path::open_file(const char *name, char **pathp) } return 0; } + +FILE *search_path::open_file_cautious(const char *name, char **pathp, + const char *mode) +{ + if (!mode) + mode = "r"; + bool reading = (strchr(mode, 'r') != 0); + if (name == 0 || strcmp(name, "-") == 0) { + if (pathp) + *pathp = strsave(reading ? "stdin" : "stdout"); + return (reading ? stdin : stdout); + } + if (!reading || IS_ABSOLUTE(name) || *dirs == '\0') { + FILE *fp = fopen(name, mode); + if (fp) { + if (pathp) + *pathp = strsave(name); + return fp; + } + else + return 0; + } + unsigned namelen = strlen(name); + char *p = dirs; + for (;;) { + char *end = strchr(p, PATH_SEP[0]); + if (!end) + end = strchr(p, '\0'); + int need_slash = end > p && strchr(DIR_SEPS, end[-1]) == 0; + char *path = new char[(end - p) + need_slash + namelen + 1]; + memcpy(path, p, end - p); + if (need_slash) + path[end - p] = '/'; + strcpy(path + (end - p) + need_slash, name); +#if 0 + fprintf(stderr, "trying `%s'\n", path); +#endif + FILE *fp = fopen(path, mode); + if (fp) { + if (pathp) + *pathp = path; + else + a_delete path; + return fp; + } + int err = errno; + a_delete path; + if (err != ENOENT) + { + errno = err; + return 0; + } + if (*end == '\0') + break; + p = end + 1; + } + errno = ENOENT; + return 0; +} diff --git a/src/preproc/soelim/soelim.cpp b/src/preproc/soelim/soelim.cpp index 96ad6dd1..ec9ee6bc 100644 --- a/src/preproc/soelim/soelim.cpp +++ b/src/preproc/soelim/soelim.cpp @@ -28,9 +28,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "error.h" #include "stringclass.h" #include "nonposix.h" +#include "searchpath.h" -static size_t include_list_length; -static const char **include_list; +// The include search path initially contains only the current directory. +static search_path include_search_path(0, 0, 0, 1); int compatible_flag = 0; int raw_flag = 0; @@ -42,24 +43,6 @@ extern "C" const char *Version_string; int do_file(const char *filename); -static void -include_path_append(const char *path) -{ - ++include_list_length; - size_t nbytes = include_list_length * sizeof(char *); - if (include_list) - include_list = (const char **)realloc((void *)include_list, nbytes); - else - include_list = (const char **)malloc(nbytes); - if (include_list == NULL) - { - fprintf(stderr, "%s: out of memory\n", program_name); - exit(2); - } - include_list[include_list_length - 1] = path; -} - - void usage(FILE *stream) { fprintf(stream, "usage: %s [ -Crtv ] [ -I file ] [ files ]\n", program_name); @@ -68,7 +51,6 @@ void usage(FILE *stream) int main(int argc, char **argv) { program_name = argv[0]; - include_path_append("."); int opt; static const struct option long_options[] = { { "help", no_argument, 0, CHAR_MAX + 1 }, @@ -87,7 +69,7 @@ int main(int argc, char **argv) compatible_flag = 1; break; case 'I': - include_path_append(optarg); + include_search_path.command_line_dir(optarg); break; case 'r': raw_flag = 1; @@ -172,50 +154,17 @@ void do_so(const char *line) int do_file(const char *filename) { - FILE *fp; - string whole_filename; - if (strcmp(filename, "-") == 0) { - fp = stdin; - whole_filename = filename; - whole_filename += '\0'; - } - else if (IS_ABSOLUTE(filename)) { - whole_filename = filename; - whole_filename += '\0'; - errno = 0; - fp = fopen(filename, "r"); - if (fp == 0) { - error("can't open `%1': %2", filename, strerror(errno)); - return 0; - } - } - else { - size_t j; - for (j = 0; j < include_list_length; ++j) - { - const char *path = include_list[j]; - if (0 == strcmp(path, ".")) - whole_filename = filename; - else - whole_filename = string(path) + "/" + filename; - whole_filename += '\0'; - errno = 0; - fp = fopen(whole_filename.contents(), "r"); - if (fp != 0) - break; - if (errno != ENOENT) { - error("can't open `%1': %2", - whole_filename.contents(), strerror(errno)); - return 0; - } - } - if (j >= include_list_length) - { - errno = ENOENT; - error("can't open `%1': %2", filename, strerror(errno)); - return 0; - } + char *file_name_in_path = 0; + FILE *fp = include_search_path.open_file_cautious(filename, + &file_name_in_path); + int err = errno; + string whole_filename(file_name_in_path ? file_name_in_path : filename); + a_delete file_name_in_path; + if (fp == 0) { + error("can't open `%1': %2", whole_filename.contents(), strerror(err)); + return 0; } + whole_filename += '\0'; current_filename = whole_filename.contents(); current_lineno = 1; set_location(); diff --git a/src/preproc/soelim/soelim.man b/src/preproc/soelim/soelim.man index 7663e3bf..f68e0b0b 100644 --- a/src/preproc/soelim/soelim.man +++ b/src/preproc/soelim/soelim.man @@ -80,7 +80,7 @@ even when followed by a character other than space or newline. This option may be used to specify a directory to search for files (both those on the command line and those named in .B \&.so -lines). +requests). The current directory is always searched first. This option may be specified more than once, the directories will be searched in the order specified. diff --git a/src/roff/groff/groff.cpp b/src/roff/groff/groff.cpp index 49104b2f..e821f8cc 100644 --- a/src/roff/groff/groff.cpp +++ b/src/roff/groff/groff.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -/* Copyright (C) 1989-2000, 2001, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1989-2000, 2001, 2002, 2003 Free Software Foundation, Inc. Written by James Clark (jjc@jclark.com) This file is part of groff. @@ -93,7 +93,7 @@ char *predriver = 0; possible_command commands[NCOMMANDS]; int run_commands(int no_pipe); -void print_commands(); +void print_commands(FILE *); void append_arg_to_string(const char *arg, string &str); void handle_unknown_desc_command(const char *command, const char *arg, const char *filename, int lineno); @@ -140,6 +140,12 @@ int main(int argc, char **argv) case 'I': commands[SOELIM_INDEX].set_name(command_prefix, "soelim"); commands[SOELIM_INDEX].append_arg(buf, optarg); + // .psbb may need to search for files + commands[TROFF_INDEX].append_arg(buf, optarg); + // \X'ps:import' may need to search for files + Pargs += buf; + Pargs += optarg; + Pargs += '\0'; break; case 't': commands[TBL_INDEX].set_name(command_prefix, "tbl"); @@ -405,10 +411,10 @@ int main(int argc, char **argv) if (putenv(strsave(f.contents()))) fatal("putenv failed"); } - if (Vflag) { - print_commands(); + if (Vflag) + print_commands(Vflag == 1 ? stdout : stderr); + if (Vflag == 1) exit(0); - } return run_commands(vflag); } @@ -474,7 +480,7 @@ void handle_unknown_desc_command(const char *command, const char *arg, } } -void print_commands() +void print_commands(FILE *fp) { int last; for (last = SPOOL_INDEX; last >= 0; last--) @@ -482,7 +488,7 @@ void print_commands() break; for (int i = 0; i <= last; i++) if (commands[i].get_name() != 0) - commands[i].print(i == last, stdout); + commands[i].print(i == last, fp); } // Run the commands. Return the code with which to exit. @@ -724,7 +730,7 @@ void help() "-N\tdon't allow newlines within eqn delimiters\n" "-S\tenable safer mode (the default)\n" "-U\tenable unsafe mode\n" -"-Idir\tsearch dir for soelim. Implies -s\n" +"-Idir\tsearch dir for soelim, troff, and grops. Implies -s\n" "\n", stdout); exit(0); diff --git a/src/roff/groff/groff.man b/src/roff/groff/groff.man index 9d0d5c3e..ea534140 100644 --- a/src/roff/groff/groff.man +++ b/src/roff/groff/groff.man @@ -1,7 +1,7 @@ .ig groff.man -Last update: 18 Jul 2003 +Last update: 12 Oct 2003 Copyright (C) 1989, 2002, 2003 Free Software Foundation, Inc. Rewritten in 2002 by Bernd Warken @@ -376,8 +376,20 @@ Print a help message. . . .OptDef I "" dir -Add search directory for -.BR \%@g@soelim (@MAN1EXT@). +This option may be used to specify a directory to search for +files (both those on the command line and those named in +.B \&.psbb +and +.B \&.so +requests, and +.B \eX'ps: import' +and +.B \eX'ps: file' +escapes). +The current directory is always searched first. +This option may be specified more than once; +the directories will be searched in the order specified. +No directory search is performed for files specified using an absolute path. This option implies the .ShortOpt s option. @@ -604,7 +616,9 @@ to all subprograms. .OptDef V Output the pipeline that would be run by .BR groff -(as a wrapper program), but do not execute it. +(as a wrapper program) on the standard output, but do not execute it. +If given more than once, +the commands will be both printed on the standard error and run. . . .OptDef X diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp index 1e4b152d..26d11687 100644 --- a/src/roff/troff/input.cpp +++ b/src/roff/troff/input.cpp @@ -122,6 +122,9 @@ char warn_scaling_indicator; search_path *mac_path = &safer_macro_path; +// Defaults to the current directory. +search_path include_search_path(0, 0, 0, 1); + static int get_copy(node**, int = 0); static void copy_mode_error(const char *, const errarg & = empty_errarg, @@ -666,7 +669,7 @@ void next_file() input_stack::end_file(); else { errno = 0; - FILE *fp = fopen(nm.contents(), "r"); + FILE *fp = include_search_path.open_file_cautious(nm.contents()); if (!fp) error("can't open `%1': %2", nm.contents(), strerror(errno)); else @@ -5437,7 +5440,7 @@ void source() while (!tok.newline() && !tok.eof()) tok.next(); errno = 0; - FILE *fp = fopen(nm.contents(), "r"); + FILE *fp = include_search_path.open_file_cautious(nm.contents()); if (fp) input_stack::push(new file_iterator(fp, nm.contents())); else @@ -5676,7 +5679,8 @@ void ps_bbox_request() errno = 0; // PS files might contain non-printable characters, such as ^Z // and CRs not followed by an LF, so open them in binary mode. - FILE *fp = fopen(nm.contents(), FOPEN_RB); + FILE *fp = include_search_path.open_file_cautious(nm.contents(), + 0, FOPEN_RB); if (fp) { do_ps_file(fp, nm.contents()); fclose(fp); @@ -6643,7 +6647,7 @@ void transparent_file() curenv->do_break(); if (!filename.is_null()) { errno = 0; - FILE *fp = fopen(filename.contents(), "r"); + FILE *fp = include_search_path.open_file_cautious(filename.contents()); if (!fp) error("can't open `%1': %2", filename.contents(), strerror(errno)); else { @@ -6837,7 +6841,7 @@ static void process_input_file(const char *name) } else { errno = 0; - fp = fopen(name, "r"); + fp = include_search_path.open_file_cautious(name); if (!fp) fatal("can't open `%1': %2", name, strerror(errno)); } @@ -6933,7 +6937,7 @@ void usage(FILE *stream, const char *prog) { fprintf(stream, "usage: %s -abcivzCERU -wname -Wname -dcs -ffam -mname -nnum -olist\n" -" -rcn -Tname -Fdir -Mdir [files...]\n", +" -rcn -Tname -Fdir -Idir -Mdir [files...]\n", prog); } @@ -6970,7 +6974,7 @@ int main(int argc, char **argv) { "version", no_argument, 0, 'v' }, { 0, 0, 0, 0 } }; - while ((c = getopt_long(argc, argv, "abcivw:W:zCEf:m:n:o:r:d:F:M:T:tqs:RU", + while ((c = getopt_long(argc, argv, "abciI:vw:W:zCEf:m:n:o:r:d:F:M:T:tqs:RU", long_options, 0)) != EOF) switch(c) { @@ -6980,6 +6984,11 @@ int main(int argc, char **argv) exit(0); break; } + case 'I': + // Search path for .psbb files + // and most other non-system input files. + include_search_path.command_line_dir(optarg); + break; case 'T': device = optarg; tflag = 1; diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp index 73776b1b..320358fe 100644 --- a/src/roff/troff/node.cpp +++ b/src/roff/troff/node.cpp @@ -1456,13 +1456,14 @@ void troff_output_file::really_begin_page(int pageno, vunits page_length) put('\n'); } -void troff_output_file::really_copy_file(hunits x, vunits y, const char *filename) +void troff_output_file::really_copy_file(hunits x, vunits y, + const char *filename) { moveto(x, y); flush_tbuf(); do_motion(); errno = 0; - FILE *ifp = fopen(filename, "r"); + FILE *ifp = include_search_path.open_file_cautious(filename); if (ifp == 0) error("can't open `%1': %2", filename, strerror(errno)); else { diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h index 54f8822a..86382b7f 100644 --- a/src/roff/troff/node.h +++ b/src/roff/troff/node.h @@ -19,7 +19,6 @@ You should have received a copy of the GNU General Public License along with groff; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - struct hyphen_list { unsigned char hyphen; unsigned char breakable; @@ -597,3 +596,4 @@ public: font_family *lookup_family(symbol); symbol get_font_name(int, environment *); +extern search_path include_search_path; diff --git a/src/roff/troff/troff.man b/src/roff/troff/troff.man index e91f8dc4..064a03fa 100644 --- a/src/roff/troff/troff.man +++ b/src/roff/troff/troff.man @@ -2,7 +2,7 @@ .ig troff.man -Last update : 18 Jul 2003 +Last update : 12 Oct 2003 This file is part of groff, the GNU roff type-setting system. @@ -84,6 +84,7 @@ FDL in the main directory of the groff source package. .OP \-d cs .OP \-f fam .OP \-F dir +.OP \-I dir .OP \-m name .OP \-M dir .OP \-n num @@ -198,6 +199,17 @@ Read the standard input after all the named input files have been processed. . .TP +.BI \-I dir +This option may be used to specify a directory to search for +files (both those on the command line and those named in +.B \&.psbb +requests). +The current directory is always searched first. +This option may be specified more than once; +the directories will be searched in the order specified. +No directory search is performed for files specified using an absolute path. +. +.TP .BI \-m name Read in the file .IB name .tmac\fR. -- 2.11.4.GIT