2 /* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2003, 2005
3 Free Software Foundation, Inc.
4 Written by James Clark (jjc@jclark.com)
6 This file is part of groff.
8 groff is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 groff is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License along
19 with groff; see the file COPYING. If not, write to the Free Software
20 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
28 #include "searchpath.h"
32 # include "relocate.h"
34 # define relocate(path) strsave(path)
37 search_path::search_path(const char *envvar, const char *standard,
38 int add_home, int add_current)
42 home = getenv("HOME");
46 dirs = new char[((e && *e) ? strlen(e) + 1 : 0)
47 + (add_current ? 1 + 1 : 0)
48 + ((home && *home) ? strlen(home) + 1 : 0)
49 + ((standard && *standard) ? strlen(standard) : 0)
54 strcat(dirs, PATH_SEP);
58 strcat(dirs, PATH_SEP);
62 strcat(dirs, PATH_SEP);
64 if (standard && *standard)
65 strcat(dirs, standard);
66 init_len = strlen(dirs);
69 search_path::~search_path()
71 // dirs is always allocated
75 void search_path::command_line_dir(const char *s)
78 unsigned old_len = strlen(old);
79 unsigned slen = strlen(s);
80 dirs = new char[old_len + 1 + slen + 1];
81 memcpy(dirs, old, old_len - init_len);
83 p += old_len - init_len;
90 memcpy(p, old + old_len - init_len, init_len);
97 FILE *search_path::open_file(const char *name, char **pathp)
100 if (IS_ABSOLUTE(name) || *dirs == '\0') {
101 FILE *fp = fopen(name, "r");
104 *pathp = strsave(name);
110 unsigned namelen = strlen(name);
113 char *end = strchr(p, PATH_SEP_CHAR);
115 end = strchr(p, '\0');
116 int need_slash = end > p && strchr(DIR_SEPS, end[-1]) == 0;
117 char *origpath = new char[(end - p) + need_slash + namelen + 1];
118 memcpy(origpath, p, end - p);
120 origpath[end - p] = '/';
121 strcpy(origpath + (end - p) + need_slash, name);
123 fprintf(stderr, "origpath `%s'\n", origpath);
125 char *path = relocate(origpath);
128 fprintf(stderr, "trying `%s'\n", path);
130 FILE *fp = fopen(path, "r");
146 FILE *search_path::open_file_cautious(const char *name, char **pathp,
151 bool reading = (strchr(mode, 'r') != 0);
152 if (name == 0 || strcmp(name, "-") == 0) {
154 *pathp = strsave(reading ? "stdin" : "stdout");
155 return (reading ? stdin : stdout);
157 if (!reading || IS_ABSOLUTE(name) || *dirs == '\0') {
158 FILE *fp = fopen(name, mode);
161 *pathp = strsave(name);
167 unsigned namelen = strlen(name);
170 char *end = strchr(p, PATH_SEP_CHAR);
172 end = strchr(p, '\0');
173 int need_slash = end > p && strchr(DIR_SEPS, end[-1]) == 0;
174 char *origpath = new char[(end - p) + need_slash + namelen + 1];
175 memcpy(origpath, p, end - p);
177 origpath[end - p] = '/';
178 strcpy(origpath + (end - p) + need_slash, name);
180 fprintf(stderr, "origpath `%s'\n", origpath);
182 char *path = relocate(origpath);
185 fprintf(stderr, "trying `%s'\n", path);
187 FILE *fp = fopen(path, mode);