2 * Copyright (c) 2014 - 2017 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
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 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 * This 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.
30 #include "file_case.h"
32 #include "searchpath.h"
35 # include "relocate.h"
37 # define relocate(path) strsave(path)
40 static file_case
* _try_iter(char const *dirs
, char const *name
,
44 _try_iter(char const *dirs
, char const *name
, uint32_t flags
)
47 bool delname
= ((flags
& fcp
->fc_take_path
) != 0);
48 flags
= (flags
& ~(fcp
->fc_const_path
)) | fcp
->fc_take_path
;
49 unsigned namelen
= strlen(name
);
53 char *end
= strchr(p
, PATH_SEP_CHAR
);
55 end
= strchr(p
, '\0');
56 int need_slash
= (end
> p
&& strchr(DIR_SEPS
, end
[-1]) == NULL
);
57 char *origpath
= new char[(end
- p
) + need_slash
+ namelen
+ 1];
58 memcpy(origpath
, p
, end
- p
);
60 origpath
[end
- p
] = '/';
61 strcpy(origpath
+ (end
- p
) + need_slash
, name
);
63 fprintf(stderr
, "origpath `%s'\n", origpath
);
65 char *path
= relocate(origpath
);
68 fprintf(stderr
, "trying `%s'\n", path
);
70 if ((fcp
= file_case::muxer(path
, flags
)) != NULL
)
85 search_path::search_path(const char *envvar
, const char *standard
,
86 int add_home
, int add_current
)
90 home
= getenv("HOME");
94 dirs
= new char[((e
&& *e
) ? strlen(e
) + 1 : 0)
95 + (add_current
? 1 + 1 : 0)
96 + ((home
&& *home
) ? strlen(home
) + 1 : 0)
97 + ((standard
&& *standard
) ? strlen(standard
) : 0)
102 strcat(dirs
, PATH_SEP
);
106 strcat(dirs
, PATH_SEP
);
110 strcat(dirs
, PATH_SEP
);
112 if (standard
&& *standard
)
113 strcat(dirs
, standard
);
114 init_len
= strlen(dirs
);
117 search_path::~search_path()
119 // dirs is always allocated
123 void search_path::command_line_dir(const char *s
)
126 unsigned old_len
= strlen(old
);
127 unsigned slen
= strlen(s
);
128 dirs
= new char[old_len
+ 1 + slen
+ 1];
129 memcpy(dirs
, old
, old_len
- init_len
);
131 p
+= old_len
- init_len
;
133 *p
++ = PATH_SEP_CHAR
;
137 *p
++ = PATH_SEP_CHAR
;
138 memcpy(p
, old
+ old_len
- init_len
, init_len
);
145 file_case
*search_path::open_file(char const *name
, uint32_t flags
)
147 assert(name
!= NULL
);
150 if (IS_ABSOLUTE(name
) || *dirs
== '\0')
151 fcp
= file_case::muxer(name
, flags
);
153 fcp
= _try_iter(dirs
, name
, flags
);
157 file_case
*search_path::open_file_cautious(char const *name
, uint32_t flags
)
160 if (name
== NULL
|| strcmp(name
, "-") == 0) {
164 if (IS_ABSOLUTE(name
) || *dirs
== '\0')
166 fcp
= file_case::muxer(name
, flags
);
168 fcp
= _try_iter(dirs
, name
, flags
);