> Date: Sat, 08 Nov 2014 15:25:17 +0100 (CET) > Cc: groff@gnu.org > From: Werner LEMBERG <w...@gnu.org> > > >> > One possible solution to this is to convert all backslashes to > >> > forward slashes '/' when writing the .lf directive. > > > > Is there a good place to put the function that will do this? > > I suggest `libs/libgroff/lf.cpp'. > > > Or should I just have it in each place that needs it? > > Whatever you think is more appropriate.
OK, here's the proposed patch and the log entries: 2014-11-08 Eli Zaretskii <e...@gnu.org> Fix handling of MS-Windows quoting and file names with backslashes. * src/preproc/soelim/soelim.cpp (do_file): * src/preproc/refer/refer.cpp (do_file): * src/preproc/preconv/preconv.cpp (do_file): * src/preproc/pic/main.cpp (do_file): * src/preproc/eqn/main.cpp (do_file) [__MSDOS__ || (_WIN32 && !__CYGWIN__)]: Call dos2unix_filename to convert backslashes in the file name being processed to forward slashes. * src/include/lib.h (dos2unix_filename): Add prototype. * src/libs/libgroff/lf.cpp (dos2unix_filename): New function. * src/roff/groff/groff.cpp (append_arg_to_string) [_WIN32 && !__CYGWIN__]: Use only ".." for quoting in native Windows builds. --- src/include/lib.h~0 2014-11-04 10:38:35.161524000 +0200 +++ src/include/lib.h 2014-11-08 17:14:19.129125000 +0200 @@ -99,6 +99,9 @@ size_t path_name_max(); int interpret_lf_args(const char *p); +#if defined(__MSDOS__) || (defined(_WIN32) && !defined(__CYGWIN__)) +void dos2unix_filename (char *fn); +#endif extern char invalid_char_table[]; --- src/libs/libgroff/lf.cpp~0 2014-11-04 10:38:35.170524000 +0200 +++ src/libs/libgroff/lf.cpp 2014-11-08 17:14:03.097875000 +0200 @@ -60,3 +60,17 @@ int interpret_lf_args(const char *p) change_lineno(ln); return 1; } + +#if defined(__MSDOS__) || (defined(_WIN32) && !defined(__CYGWIN__)) +void dos2unix_filename (char *fn) +{ + char *p = fn; + + while (*p) + { + if (*p == '\\') + *p = '/'; + p++; + } +} +#endif --- src/preproc/eqn/main.cpp~0 2014-11-04 10:38:35.232523000 +0200 +++ src/preproc/eqn/main.cpp 2014-11-08 17:25:52.691625000 +0200 @@ -66,9 +66,15 @@ void do_file(FILE *fp, const char *filen { string linebuf; string str; - if (output_format == troff) - printf(".lf 1 %s\n", filename); +#if defined(__MSDOS__) || (defined(_WIN32) && !defined(__CYGWIN__)) + char *fn = strsave(filename); + dos2unix_filename(fn); + current_filename = fn; +#else current_filename = filename; +#endif + if (output_format == troff) + printf(".lf 1 %s\n", current_filename); current_lineno = 0; while (read_line(fp, &linebuf)) { if (linebuf.length() >= 4 --- src/preproc/pic/main.cpp~0 2014-11-04 10:38:35.226523000 +0200 +++ src/preproc/pic/main.cpp 2014-11-08 17:27:19.316625000 +0200 @@ -309,8 +309,14 @@ void do_file(const char *filename) fatal("can't open `%1': %2", filename, strerror(errno)); } } - out->set_location(filename, 1); +#if defined(__MSDOS__) || (defined(_WIN32) && !defined(__CYGWIN__)) + char *fn = strsave(filename); + dos2unix_filename(fn); + current_filename = fn; +#else current_filename = filename; +#endif + out->set_location(current_filename, 1); current_lineno = 1; enum { START, MIDDLE, HAD_DOT, HAD_P, HAD_PS, HAD_l, HAD_lf } state = START; for (;;) { --- src/preproc/preconv/preconv.cpp~0 2014-11-04 10:38:35.214524000 +0200 +++ src/preproc/preconv/preconv.cpp 2014-11-08 17:30:56.894750000 +0200 @@ -1065,8 +1065,16 @@ do_file(const char *filename) } if (debug_flag) fprintf(stderr, " encoding used: `%s'\n", encoding); - if (!raw_flag) + if (!raw_flag) { +#if defined(__MSDOS__) || (defined(_WIN32) && !defined(__CYGWIN__)) + char fn[FILENAME_MAX]; + strcpy(fn, filename); + dos2unix_filename(fn); + printf(".lf 1 %s\n", fn); +#else printf(".lf 1 %s\n", filename); +#endif + } int success = 1; // Call converter (converters write to stdout). if (!strcasecmp(encoding, "ISO-8859-1")) --- src/preproc/refer/refer.cpp~0 2014-11-04 10:38:35.245523000 +0200 +++ src/preproc/refer/refer.cpp 2014-11-08 17:25:42.394750000 +0200 @@ -432,8 +432,14 @@ static void do_file(const char *filename return; } } +#if defined(__MSDOS__) || (defined(_WIN32) && !defined(__CYGWIN__)) + char *fn = strsave(filename); + dos2unix_filename(fn); + current_filename = fn; +#else current_filename = filename; - fprintf(outfp, ".lf 1 %s\n", filename); +#endif + fprintf(outfp, ".lf 1 %s\n", current_filename); string line; current_lineno = 0; for (;;) { --- src/preproc/soelim/soelim.cpp~0 2014-11-04 10:38:35.250523000 +0200 +++ src/preproc/soelim/soelim.cpp 2014-11-08 17:39:08.160375000 +0200 @@ -154,7 +154,18 @@ int do_file(const char *filename) FILE *fp = include_search_path.open_file_cautious(filename, &file_name_in_path); int err = errno; +#if defined(__MSDOS__) || (defined(_WIN32) && !defined(__CYGWIN__)) + char fn[FILENAME_MAX]; + if (file_name_in_path) + dos2unix_filename(file_name_in_path); + else { + strcpy(fn, filename); + dos2unix_filename(fn); + } + string whole_filename(file_name_in_path ? file_name_in_path : fn); +#else string whole_filename(file_name_in_path ? file_name_in_path : filename); +#endif whole_filename += '\0'; a_delete file_name_in_path; if (fp == 0) { --- src/preproc/tbl/main.cpp~0 2014-11-04 10:38:35.220524000 +0200 +++ src/preproc/tbl/main.cpp 2014-11-08 17:42:18.660375000 +0200 @@ -1615,7 +1615,13 @@ int main(int argc, char **argv) fatal("can't open `%1': %2", argv[i], strerror(errno)); else { current_lineno = 1; +#if defined(__MSDOS__) || (defined(_WIN32) && !defined(__CYGWIN__)) + char *fn = strsave(argv[i]); + dos2unix_filename(fn); + current_filename = fn; +#else current_filename = argv[i]; +#endif printf(".lf 1 %s\n", current_filename); process_input_file(fp); } --- src/preproc/tbl/table.cpp~0 2014-11-04 10:38:35.221524000 +0200 +++ src/preproc/tbl/table.cpp 2014-11-08 17:47:03.176000000 +0200 @@ -2966,7 +2966,14 @@ void set_troff_location(const char *fn, && strcmp(fn, last_filename) == 0) printfs(".lf %1\n", as_string(ln)); else { +#if defined(__MSDOS__) || (defined(_WIN32) && !defined(__CYGWIN__)) + char filename[FILENAME_MAX]; + strcpy(filename, fn); + dos2unix_filename(filename); + printfs(".lf %1 %2\n", as_string(ln), filename); +#else printfs(".lf %1 %2\n", as_string(ln), fn); +#endif last_filename = fn; location_force_filename = 0; } --- src/roff/groff/groff.cpp~0 2014-11-04 10:38:35.195524000 +0200 +++ src/roff/groff/groff.cpp 2014-11-08 11:45:38.738500000 +0200 @@ -701,7 +701,13 @@ void append_arg_to_string(const char *ar { str += ' '; int needs_quoting = 0; + // Native Windows programs don't support '..' style of quoting, so + // always behave as if ARG included the single quote character. +#if defined(_WIN32) && !defined(__CYGWIN__) + int contains_single_quote = 1; +#else int contains_single_quote = 0; +#endif const char*p; for (p = arg; *p != '\0'; p++) switch (*p) { @@ -731,10 +737,17 @@ void append_arg_to_string(const char *ar str += '"'; for (p = arg; *p != '\0'; p++) switch (*p) { +#if !(defined(_WIN32) && !defined(__CYGWIN__)) case '"': case '\\': case '$': str += '\\'; +#else + case '"': + case '\\': + if (*p == '"' || (*p == '\\' && p[1] == '"')) + str += '\\'; +#endif // fall through default: str += *p;