diff options
Diffstat (limited to 'contrib/groff/src/libs/libgroff/searchpath.cpp')
-rw-r--r-- | contrib/groff/src/libs/libgroff/searchpath.cpp | 94 |
1 files changed, 85 insertions, 9 deletions
diff --git a/contrib/groff/src/libs/libgroff/searchpath.cpp b/contrib/groff/src/libs/libgroff/searchpath.cpp index 1f8b233cd6b8..6b9b81cc2543 100644 --- a/contrib/groff/src/libs/libgroff/searchpath.cpp +++ b/contrib/groff/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, 2005 Free Software Foundation, Inc. Written by James Clark (jjc@jclark.com) @@ -17,16 +17,23 @@ for more details. 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. */ +Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */ #include "lib.h" #include <stdlib.h> #include <assert.h> +#include <errno.h> #include "searchpath.h" #include "nonposix.h" +#ifdef _WIN32 +# include "relocate.h" +#else +# define relocate(path) strsave(path) +#endif + search_path::search_path(const char *envvar, const char *standard, int add_home, int add_current) { @@ -75,11 +82,11 @@ void search_path::command_line_dir(const char *s) char *p = dirs; p += old_len - init_len; if (init_len == 0) - *p++ = PATH_SEP[0]; + *p++ = PATH_SEP_CHAR; memcpy(p, s, slen); p += slen; if (init_len > 0) { - *p++ = PATH_SEP[0]; + *p++ = PATH_SEP_CHAR; memcpy(p, old + old_len - init_len, init_len); p += init_len; } @@ -103,15 +110,20 @@ FILE *search_path::open_file(const char *name, char **pathp) unsigned namelen = strlen(name); char *p = dirs; for (;;) { - char *end = strchr(p, PATH_SEP[0]); + char *end = strchr(p, PATH_SEP_CHAR); 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); + char *origpath = new char[(end - p) + need_slash + namelen + 1]; + memcpy(origpath, p, end - p); if (need_slash) - path[end - p] = '/'; - strcpy(path + (end - p) + need_slash, name); + origpath[end - p] = '/'; + strcpy(origpath + (end - p) + need_slash, name); +#if 0 + fprintf(stderr, "origpath `%s'\n", origpath); +#endif + char *path = relocate(origpath); + a_delete origpath; #if 0 fprintf(stderr, "trying `%s'\n", path); #endif @@ -130,3 +142,67 @@ 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_CHAR); + if (!end) + end = strchr(p, '\0'); + int need_slash = end > p && strchr(DIR_SEPS, end[-1]) == 0; + char *origpath = new char[(end - p) + need_slash + namelen + 1]; + memcpy(origpath, p, end - p); + if (need_slash) + origpath[end - p] = '/'; + strcpy(origpath + (end - p) + need_slash, name); +#if 0 + fprintf(stderr, "origpath `%s'\n", origpath); +#endif + char *path = relocate(origpath); + a_delete origpath; +#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; +} |