4 /* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2003, 2005
5 Free Software Foundation, Inc.
6 Written by James Clark (jjc@jclark.com)
8 This file is part of groff.
10 groff is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 2, or (at your option) any later
15 groff is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License along
21 with groff; see the file COPYING. If not, write to the Free Software
22 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
30 #include "searchpath.h"
34 # include "relocate.h"
36 # define relocate(path) strsave(path)
39 search_path::search_path(const char *envvar
, const char *standard
,
40 int add_home
, int add_current
)
44 home
= getenv("HOME");
48 dirs
= new char[((e
&& *e
) ? strlen(e
) + 1 : 0)
49 + (add_current
? 1 + 1 : 0)
50 + ((home
&& *home
) ? strlen(home
) + 1 : 0)
51 + ((standard
&& *standard
) ? strlen(standard
) : 0)
56 strcat(dirs
, PATH_SEP
);
60 strcat(dirs
, PATH_SEP
);
64 strcat(dirs
, PATH_SEP
);
66 if (standard
&& *standard
)
67 strcat(dirs
, standard
);
68 init_len
= strlen(dirs
);
71 search_path::~search_path()
73 // dirs is always allocated
77 void search_path::command_line_dir(const char *s
)
80 unsigned old_len
= strlen(old
);
81 unsigned slen
= strlen(s
);
82 dirs
= new char[old_len
+ 1 + slen
+ 1];
83 memcpy(dirs
, old
, old_len
- init_len
);
85 p
+= old_len
- init_len
;
92 memcpy(p
, old
+ old_len
- init_len
, init_len
);
99 FILE *search_path::open_file(const char *name
, char **pathp
)
102 if (IS_ABSOLUTE(name
) || *dirs
== '\0') {
103 FILE *fp
= fopen(name
, "r");
106 *pathp
= strsave(name
);
112 unsigned namelen
= strlen(name
);
115 char *end
= strchr(p
, PATH_SEP_CHAR
);
117 end
= strchr(p
, '\0');
118 int need_slash
= end
> p
&& strchr(DIR_SEPS
, end
[-1]) == 0;
119 char *origpath
= new char[(end
- p
) + need_slash
+ namelen
+ 1];
120 memcpy(origpath
, p
, end
- p
);
122 origpath
[end
- p
] = '/';
123 strcpy(origpath
+ (end
- p
) + need_slash
, name
);
125 fprintf(stderr
, "origpath `%s'\n", origpath
);
127 char *path
= relocate(origpath
);
130 fprintf(stderr
, "trying `%s'\n", path
);
132 FILE *fp
= fopen(path
, "r");
148 FILE *search_path::open_file_cautious(const char *name
, char **pathp
,
153 bool reading
= (strchr(mode
, 'r') != 0);
154 if (name
== 0 || strcmp(name
, "-") == 0) {
156 *pathp
= strsave(reading
? "stdin" : "stdout");
157 return (reading
? stdin
: stdout
);
159 if (!reading
|| IS_ABSOLUTE(name
) || *dirs
== '\0') {
160 FILE *fp
= fopen(name
, mode
);
163 *pathp
= strsave(name
);
169 unsigned namelen
= strlen(name
);
172 char *end
= strchr(p
, PATH_SEP_CHAR
);
174 end
= strchr(p
, '\0');
175 int need_slash
= end
> p
&& strchr(DIR_SEPS
, end
[-1]) == 0;
176 char *origpath
= new char[(end
- p
) + need_slash
+ namelen
+ 1];
177 memcpy(origpath
, p
, end
- p
);
179 origpath
[end
- p
] = '/';
180 strcpy(origpath
+ (end
- p
) + need_slash
, name
);
182 fprintf(stderr
, "origpath `%s'\n", origpath
);
184 char *path
= relocate(origpath
);
187 fprintf(stderr
, "trying `%s'\n", path
);
189 FILE *fp
= fopen(path
, mode
);