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 "file_case.h"
29 #include "searchpath.h"
33 # include "relocate.h"
35 # define relocate(path) strsave(path)
38 static file_case
* _try_iter(char const *dirs
, char const *name
,
42 _try_iter(char const *dirs
, char const *name
, uint32_t flags
)
45 bool delname
= ((flags
& fcp
->fc_take_path
) != 0);
46 flags
= (flags
& ~(fcp
->fc_const_path
)) | fcp
->fc_take_path
;
47 unsigned namelen
= strlen(name
);
51 char *end
= strchr(p
, PATH_SEP_CHAR
);
53 end
= strchr(p
, '\0');
54 int need_slash
= (end
> p
&& strchr(DIR_SEPS
, end
[-1]) == NULL
);
55 char *origpath
= new char[(end
- p
) + need_slash
+ namelen
+ 1];
56 memcpy(origpath
, p
, end
- p
);
58 origpath
[end
- p
] = '/';
59 strcpy(origpath
+ (end
- p
) + need_slash
, name
);
61 fprintf(stderr
, "origpath `%s'\n", origpath
);
63 char *path
= relocate(origpath
);
66 fprintf(stderr
, "trying `%s'\n", path
);
68 if ((fcp
= file_case::muxer(path
, flags
)) != NULL
)
83 search_path::search_path(const char *envvar
, const char *standard
,
84 int add_home
, int add_current
)
88 home
= getenv("HOME");
92 dirs
= new char[((e
&& *e
) ? strlen(e
) + 1 : 0)
93 + (add_current
? 1 + 1 : 0)
94 + ((home
&& *home
) ? strlen(home
) + 1 : 0)
95 + ((standard
&& *standard
) ? strlen(standard
) : 0)
100 strcat(dirs
, PATH_SEP
);
104 strcat(dirs
, PATH_SEP
);
108 strcat(dirs
, PATH_SEP
);
110 if (standard
&& *standard
)
111 strcat(dirs
, standard
);
112 init_len
= strlen(dirs
);
115 search_path::~search_path()
117 // dirs is always allocated
121 void search_path::command_line_dir(const char *s
)
124 unsigned old_len
= strlen(old
);
125 unsigned slen
= strlen(s
);
126 dirs
= new char[old_len
+ 1 + slen
+ 1];
127 memcpy(dirs
, old
, old_len
- init_len
);
129 p
+= old_len
- init_len
;
131 *p
++ = PATH_SEP_CHAR
;
135 *p
++ = PATH_SEP_CHAR
;
136 memcpy(p
, old
+ old_len
- init_len
, init_len
);
143 file_case
*search_path::open_file(char const *name
, uint32_t flags
)
145 assert(name
!= NULL
);
148 if (IS_ABSOLUTE(name
) || *dirs
== '\0')
149 fcp
= file_case::muxer(name
, flags
);
151 fcp
= _try_iter(dirs
, name
, flags
);
155 file_case
*search_path::open_file_cautious(char const *name
, uint32_t flags
)
158 if (name
== NULL
|| strcmp(name
, "-") == 0) {
162 if (IS_ABSOLUTE(name
) || *dirs
== '\0')
164 fcp
= file_case::muxer(name
, flags
);
166 fcp
= _try_iter(dirs
, name
, flags
);