aboutsummaryrefslogtreecommitdiff
path: root/contrib/groff/src/libs/libgroff/searchpath.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/groff/src/libs/libgroff/searchpath.cpp')
-rw-r--r--contrib/groff/src/libs/libgroff/searchpath.cpp94
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;
+}