2 /* Copyright (C) 1989-2014 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.com)
5 This file is part of groff.
7 groff is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 groff is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
26 #include "searchpath.h"
30 # include "relocate.h"
32 # define relocate(path) strsave(path)
35 search_path::search_path(const char *envvar, const char *standard,
36 int add_home, int add_current)
40 home = getenv("HOME");
44 dirs = new char[((e && *e) ? strlen(e) + 1 : 0)
45 + (add_current ? 1 + 1 : 0)
46 + ((home && *home) ? strlen(home) + 1 : 0)
47 + ((standard && *standard) ? strlen(standard) : 0)
52 strcat(dirs, PATH_SEP);
56 strcat(dirs, PATH_SEP);
60 strcat(dirs, PATH_SEP);
62 if (standard && *standard)
63 strcat(dirs, standard);
64 init_len = strlen(dirs);
67 search_path::~search_path()
69 // dirs is always allocated
73 void search_path::command_line_dir(const char *s)
76 unsigned old_len = strlen(old);
77 unsigned slen = strlen(s);
78 dirs = new char[old_len + 1 + slen + 1];
79 memcpy(dirs, old, old_len - init_len);
81 p += old_len - init_len;
88 memcpy(p, old + old_len - init_len, init_len);
95 FILE *search_path::open_file(const char *name, char **pathp)
98 if (IS_ABSOLUTE(name) || *dirs == '\0') {
99 FILE *fp = fopen(name, "r");
102 *pathp = strsave(name);
108 unsigned namelen = strlen(name);
111 char *end = strchr(p, PATH_SEP_CHAR);
113 end = strchr(p, '\0');
114 int need_slash = end > p && strchr(DIR_SEPS, end[-1]) == 0;
115 char *origpath = new char[(end - p) + need_slash + namelen + 1];
116 memcpy(origpath, p, end - p);
118 origpath[end - p] = '/';
119 strcpy(origpath + (end - p) + need_slash, name);
121 fprintf(stderr, "origpath `%s'\n", origpath);
123 char *path = relocate(origpath);
126 fprintf(stderr, "trying `%s'\n", path);
128 FILE *fp = fopen(path, "r");
144 FILE *search_path::open_file_cautious(const char *name, char **pathp,
149 bool reading = (strchr(mode, 'r') != 0);
150 if (name == 0 || strcmp(name, "-") == 0) {
152 *pathp = strsave(reading ? "stdin" : "stdout");
153 return (reading ? stdin : stdout);
155 if (!reading || IS_ABSOLUTE(name) || *dirs == '\0') {
156 FILE *fp = fopen(name, mode);
159 *pathp = strsave(name);
165 unsigned namelen = strlen(name);
168 char *end = strchr(p, PATH_SEP_CHAR);
170 end = strchr(p, '\0');
171 int need_slash = end > p && strchr(DIR_SEPS, end[-1]) == 0;
172 char *origpath = new char[(end - p) + need_slash + namelen + 1];
173 memcpy(origpath, p, end - p);
175 origpath[end - p] = '/';
176 strcpy(origpath + (end - p) + need_slash, name);
178 fprintf(stderr, "origpath `%s'\n", origpath);
180 char *path = relocate(origpath);
183 fprintf(stderr, "trying `%s'\n", path);
185 FILE *fp = fopen(path, mode);