Mercurial > octave
annotate liboctave/util/kpse.cc @ 21868:e2796ea8feac
* kpse.cc: Use iostream for debug messages.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sat, 11 Jun 2016 18:07:23 -0400 |
parents | 0cdfd6d230e6 |
children | d79b7de9c413 |
rev | line source |
---|---|
21751
b571fc85953f
maint: Use two spaces after period to indicate sentence break.
Rik <rik@octave.org>
parents:
21732
diff
changeset
|
1 // This file is not compiled to a separate object file. |
b571fc85953f
maint: Use two spaces after period to indicate sentence break.
Rik <rik@octave.org>
parents:
21732
diff
changeset
|
2 // It is included in pathsearch.cc. |
4399 | 3 |
4 /* Look up a filename in a path. | |
4378 | 5 |
19697
4197fc428c7d
maint: Update copyright notices for 2015.
John W. Eaton <jwe@octave.org>
parents:
19410
diff
changeset
|
6 Copyright (C) 2003-2015 John W. Eaton |
4385 | 7 Copyright (C) 1993, 94, 95, 96, 97, 98 Karl Berry. |
4378 | 8 Copyright (C) 1993, 94, 95, 96, 97 Karl Berry & O. Weber. |
4399 | 9 Copyright (C) 1992, 93, 94, 95, 96, 97 Free Software Foundation, Inc. |
4378 | 10 |
16768 | 11 This file is part of Octave. |
12 | |
13 Octave is free software; you can redistribute it and/or modify it | |
14 under the terms of the GNU General Public License as published by the | |
15 Free Software Foundation; either version 3 of the License, or (at your | |
16 option) any later version. | |
17 | |
18 Octave is distributed in the hope that it will be useful, but WITHOUT | |
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
21 for more details. | |
22 | |
23 You should have received a copy of the GNU General Public License | |
24 along with Octave; see the file COPYING. If not, see | |
25 <http://www.gnu.org/licenses/>. | |
26 | |
27 */ | |
4378 | 28 |
21690
b6a686543080
Only include config.h in files that are compiled separately.
John W. Eaton <jwe@octave.org>
parents:
21562
diff
changeset
|
29 // This file should not include config.h. It is only included in other |
b6a686543080
Only include config.h in files that are compiled separately.
John W. Eaton <jwe@octave.org>
parents:
21562
diff
changeset
|
30 // C++ source files that should have included config.h before including |
b6a686543080
Only include config.h in files that are compiled separately.
John W. Eaton <jwe@octave.org>
parents:
21562
diff
changeset
|
31 // this file. |
4378 | 32 |
4390 | 33 #include <map> |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
34 #include <fstream> |
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
35 #include <iostream> |
4389 | 36 #include <string> |
37 | |
4399 | 38 /* System defines are for non-Unix systems only. (Testing for all Unix |
39 variations should be done in configure.) Presently the defines used | |
40 are: DOS OS2 WIN32. I do not use any of these systems | |
41 myself; if you do, I'd be grateful for any changes. --kb@mail.tug.org */ | |
42 | |
43 /* If we have either DOS or OS2, we are DOSISH. */ | |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14155
diff
changeset
|
44 #if defined (DOS) || defined (OS2) || defined (WIN32) || defined (__MSDOS__) |
4399 | 45 #define DOSISH |
46 #endif | |
47 | |
48 extern "C" { | |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14155
diff
changeset
|
49 #if defined (__MINGW32__) |
4399 | 50 #include <windows.h> |
51 #include <fcntl.h> | |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14155
diff
changeset
|
52 #elif defined (WIN32) |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
53 #if ! defined (_MSC_VER) |
4399 | 54 #define __STDC__ 1 |
55 #include "win32lib.h" | |
6106 | 56 #endif |
4399 | 57 #endif /* not WIN32 */ |
58 } | |
59 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
60 /* System dependencies that are figured out by 'configure'. If we are |
4399 | 61 compiling standalone, we get our c-auto.h. Otherwise, the package |
62 containing us must provide this (unless it can somehow generate ours | |
63 from c-auto.in). We use <...> instead of "..." so that the current | |
64 cpp directory (i.e., kpathsea/) won't be searched. */ | |
65 | |
66 /* If you want to find subdirectories in a directory with non-Unix | |
67 semantics (specifically, if a directory with no subdirectories does | |
5622 | 68 not have exactly two links), define this. */ |
21864
f3487b21e879
* kpse.cc: Remove obsolete and unused code.
John W. Eaton <jwe@octave.org>
parents:
21863
diff
changeset
|
69 #if ! defined (DOSISH) |
4399 | 70 #define ST_NLINK_TRICK |
21864
f3487b21e879
* kpse.cc: Remove obsolete and unused code.
John W. Eaton <jwe@octave.org>
parents:
21863
diff
changeset
|
71 #endif /* not DOSISH */ |
4399 | 72 |
11236 | 73 /* Define the characters which separate components of |
74 filenames and environment variable paths. */ | |
75 | |
76 /* What separates filename components? */ | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
77 #if ! defined (DIR_SEP) |
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
78 #if defined (DOSISH) |
11236 | 79 /* Either \'s or 's work. Wayne Sullivan's web2pc prefers /, so we'll |
80 go with that. */ | |
81 #define DIR_SEP '/' | |
82 #define DIR_SEP_STRING "/" | |
83 #define IS_DEVICE_SEP(ch) ((ch) == ':') | |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14155
diff
changeset
|
84 #define NAME_BEGINS_WITH_DEVICE(name) ((name.length ()>0) && IS_DEVICE_SEP((name)[1])) |
11236 | 85 /* On DOS, it's good to allow both \ and / between directories. */ |
86 #define IS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\') | |
87 #else | |
88 #define DIR_SEP '/' | |
89 #define DIR_SEP_STRING "/" | |
90 #endif /* not DOSISH */ | |
91 #endif /* not DIR_SEP */ | |
92 | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
93 #if ! defined (IS_DIR_SEP) |
11236 | 94 #define IS_DIR_SEP(ch) ((ch) == DIR_SEP) |
95 #endif | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
96 #if ! defined (IS_DEVICE_SEP) |
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
97 /* No 'devices' on, e.g., Unix. */ |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11501
diff
changeset
|
98 #define IS_DEVICE_SEP(ch) 0 |
11236 | 99 #endif |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
100 #if ! defined (NAME_BEGINS_WITH_DEVICE) |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11501
diff
changeset
|
101 #define NAME_BEGINS_WITH_DEVICE(name) 0 |
11236 | 102 #endif |
4378 | 103 |
21865 | 104 #include "file-stat.h" |
4396 | 105 #include "lo-error.h" |
4391 | 106 #include "oct-env.h" |
107 #include "oct-passwd.h" | |
4399 | 108 #include "str-vec.h" |
4385 | 109 |
110 /* Header files that essentially all of our sources need, and | |
111 that all implementations have. We include these first, to help with | |
112 NULL being defined multiple times. */ | |
113 #include <cstdarg> | |
114 #include <cstdlib> | |
115 #include <cerrno> | |
116 #include <cassert> | |
117 | |
118 #include <sys/types.h> | |
119 #include <unistd.h> | |
120 | |
21863
a25110491607
eliminate obsolete sysdir.h header file
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
121 #include <dirent.h> |
a25110491607
eliminate obsolete sysdir.h header file
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
122 |
4385 | 123 /* define NAME_MAX, the maximum length of a single |
124 component in a filename. No such limit may exist, or may vary | |
125 depending on the filesystem. */ | |
126 | |
127 /* Most likely the system will truncate filenames if it is not POSIX, | |
128 and so we can use the BSD value here. */ | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
129 #if ! defined (_POSIX_NAME_MAX) |
4385 | 130 #define _POSIX_NAME_MAX 255 |
131 #endif | |
132 | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
133 #if ! defined (NAME_MAX) |
4385 | 134 #define NAME_MAX _POSIX_NAME_MAX |
135 #endif | |
136 | |
137 #include <cctype> | |
138 | |
139 /* What separates elements in environment variable path lists? */ | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
140 #if ! defined (ENV_SEP) |
5451 | 141 #if defined (SEPCHAR) && defined (SEPCHAR_STR) |
142 #define ENV_SEP SEPCHAR | |
143 #define ENV_SEP_STRING SEPCHAR_STR | |
144 #elif defined (DOSISH) | |
4385 | 145 #define ENV_SEP ';' |
146 #define ENV_SEP_STRING ";" | |
147 #else | |
148 #define ENV_SEP ':' | |
149 #define ENV_SEP_STRING ":" | |
150 #endif /* not DOS */ | |
151 #endif /* not ENV_SEP */ | |
152 | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
153 #if ! defined (IS_ENV_SEP) |
4385 | 154 #define IS_ENV_SEP(ch) ((ch) == ENV_SEP) |
155 #endif | |
156 | |
157 /* If NO_DEBUG is defined (not recommended), skip all this. */ | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
158 #if ! defined (NO_DEBUG) |
4385 | 159 |
160 /* OK, we'll have tracing support. */ | |
161 #define KPSE_DEBUG | |
162 | |
163 /* Test if a bit is on. */ | |
164 #define KPSE_DEBUG_P(bit) (kpathsea_debug & (1 << (bit))) | |
165 | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
166 #define KPSE_DEBUG_STAT 0 /* stat calls */ |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
167 #define KPSE_DEBUG_EXPAND 1 /* path element expansion */ |
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
168 #define KPSE_DEBUG_SEARCH 2 /* searches */ |
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
169 #define KPSE_DEBUG_VARS 3 /* variable values */ |
4385 | 170 #define KPSE_LAST_DEBUG KPSE_DEBUG_VARS |
171 | |
172 #endif /* not NO_DEBUG */ | |
173 | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
174 #if defined (KPSE_DEBUG) |
4399 | 175 static unsigned int kpathsea_debug = 0; |
176 #endif | |
177 | |
20791
f7084eae3318
maint: Use Octave coding conventions for #if statements.
Rik <rik@octave.org>
parents:
20443
diff
changeset
|
178 #if defined (WIN32) && ! defined (__MINGW32__) |
4385 | 179 |
180 /* System description file for Windows NT. */ | |
181 | |
182 /* | |
183 * Define symbols to identify the version of Unix this is. | |
184 * Define all the symbols that apply correctly. | |
185 */ | |
186 | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
187 #if ! defined (DOSISH) |
4385 | 188 #define DOSISH |
189 #endif | |
190 | |
191 /* These have to be defined because our compilers treat __STDC__ as being | |
192 defined (most of them anyway). */ | |
193 | |
194 #define access _access | |
195 | |
196 /* Define this so that winsock.h definitions don't get included when | |
197 windows.h is... For this to have proper effect, config.h must | |
4391 | 198 always be included before windows.h. */ |
4385 | 199 #define _WINSOCKAPI_ 1 |
200 | |
201 #include <windows.h> | |
202 | |
203 /* For proper declaration of environ. */ | |
204 #include <io.h> | |
205 #include <fcntl.h> | |
206 #include <process.h> | |
207 | |
208 /* ============================================================ */ | |
209 | |
210 #endif /* WIN32 */ | |
211 | |
212 /* Define common sorts of messages. */ | |
213 | |
214 /* This should be called only after a system call fails. Don't exit | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
215 with status 'errno', because that might be 256, which would mean |
4385 | 216 success (exit statuses are truncated to eight bits). */ |
4396 | 217 #define FATAL_PERROR(str) \ |
218 do \ | |
219 { \ | |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
220 std::cerr << "pathsearch: "; \ |
4396 | 221 perror (str); exit (EXIT_FAILURE); \ |
222 } \ | |
223 while (0) | |
224 | |
225 #define FATAL(str) \ | |
226 do \ | |
227 { \ | |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
228 std::cerr << "pathsearch: fatal: " << str << "." << std::endl; \ |
4396 | 229 exit (1); \ |
230 } \ | |
231 while (0) | |
4385 | 232 |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
233 #if ! defined (WIN32) |
4385 | 234 static void xclosedir (DIR *d); |
4386 | 235 #endif |
4385 | 236 |
4399 | 237 /* It's a little bizarre to be using the same type for the list and the |
238 elements of the list, but no reason not to in this case, I think -- | |
239 we never need a NULL string in the middle of the list, and an extra | |
240 NULL/NULL element always at the end is inconsequential. */ | |
241 | |
242 struct str_llist_elt | |
243 { | |
11501
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
244 str_llist_elt (void) : str (), moved (0), next (0) { } |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
245 |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
246 ~str_llist_elt (void) { } |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
247 |
4399 | 248 std::string str; |
249 int moved; | |
250 struct str_llist_elt *next; | |
251 }; | |
252 | |
253 typedef str_llist_elt str_llist_elt_type; | |
254 typedef str_llist_elt *str_llist_type; | |
255 | |
256 #define STR_LLIST(sl) ((sl).str) | |
257 #define STR_LLIST_MOVED(sl) ((sl).moved) | |
258 #define STR_LLIST_NEXT(sl) ((sl).next) | |
259 | |
4390 | 260 static void str_llist_add (str_llist_type *l, const std::string& str); |
4385 | 261 |
262 static void str_llist_float (str_llist_type *l, str_llist_elt_type *mover); | |
263 | |
4389 | 264 static std::string kpse_var_expand (const std::string& src); |
4385 | 265 |
4399 | 266 static str_llist_type *kpse_element_dirs (const std::string& elt); |
267 | |
268 static std::string kpse_expand (const std::string& s); | |
269 | |
270 static std::string kpse_expand_default (const std::string& path, | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
271 const std::string& dflt); |
4399 | 272 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
273 #include <ctime> /* for 'time' */ |
4385 | 274 |
4399 | 275 static bool |
4394 | 276 kpse_is_env_sep (char c) |
277 { | |
278 return IS_ENV_SEP (c); | |
279 } | |
280 | |
4399 | 281 /* A way to step through a path, extracting one directory name at a |
282 time. */ | |
283 | |
284 class kpse_path_iterator | |
285 { | |
286 public: | |
287 | |
288 kpse_path_iterator (const std::string& p) | |
289 : path (p), b (0), e (0), len (path.length ()) { set_end (); } | |
290 | |
291 kpse_path_iterator (const kpse_path_iterator& pi) | |
292 : path (pi.path), b (pi.b), e (pi.e), len (pi.len) { } | |
293 | |
294 kpse_path_iterator operator ++ (int) | |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
295 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
296 kpse_path_iterator retval (*this); |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
297 next (); |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
298 return retval; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
299 } |
4399 | 300 |
301 std::string operator * (void) { return path.substr (b, e-b); } | |
302 | |
303 bool operator != (const size_t sz) { return b != sz; } | |
304 | |
305 private: | |
306 | |
307 const std::string& path; | |
308 size_t b; | |
309 size_t e; | |
310 size_t len; | |
311 | |
312 void set_end (void) | |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
313 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
314 e = b + 1; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
315 |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
316 if (e == len) |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
317 ; /* OK, we have found the last element. */ |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
318 else if (e > len) |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
319 b = e = std::string::npos; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
320 else |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
321 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
322 /* Find the next colon not enclosed by braces (or the end of |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
323 the path). */ |
20443
610c74748518
maint: Clean up code based on static analysis suggestions.
Rik <rik@octave.org>
parents:
20232
diff
changeset
|
324 while (e < len && ! kpse_is_env_sep (path[e])) |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
325 e++; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
326 } |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
327 } |
4399 | 328 |
329 void next (void) | |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
330 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
331 b = e + 1; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
332 |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
333 /* Skip any consecutive colons. */ |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
334 while (b < len && kpse_is_env_sep (path[b])) |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
335 b++; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
336 |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
337 if (b >= len) |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
338 b = e = std::string::npos; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
339 else |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
340 set_end (); |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
341 } |
5617 | 342 |
343 // No assignment. | |
344 kpse_path_iterator& operator = (const kpse_path_iterator&); | |
4399 | 345 }; |
346 | |
4391 | 347 /* Here's the simple one, when a program just wants a value. */ |
348 | |
349 static std::string | |
350 kpse_var_value (const std::string& var) | |
351 { | |
352 std::string ret; | |
353 | |
21732
6a1eded90355
use namespace for system env class
John W. Eaton <jwe@octave.org>
parents:
21729
diff
changeset
|
354 std::string tmp = octave::sys::env::getenv (var); |
4391 | 355 |
356 if (! tmp.empty ()) | |
357 ret = kpse_var_expand (tmp); | |
358 | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
359 #if defined (KPSE_DEBUG) |
4391 | 360 if (KPSE_DEBUG_P (KPSE_DEBUG_VARS)) |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
361 std::cerr << "kdebug: variable: " << var << " = " |
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
362 << (tmp.empty () ? "(nil)" : tmp) << std::endl; |
4391 | 363 #endif |
364 | |
365 return ret; | |
366 } | |
367 | |
368 /* Truncate any too-long components in NAME, returning the result. It's | |
369 too bad this is necessary. See comments in readable.c for why. */ | |
370 | |
4393 | 371 static std::string |
372 kpse_truncate_filename (const std::string& name) | |
4391 | 373 { |
374 unsigned c_len = 0; /* Length of current component. */ | |
375 unsigned ret_len = 0; /* Length of constructed result. */ | |
376 | |
4393 | 377 std::string ret = name; |
378 | |
379 size_t len = name.length (); | |
380 | |
381 for (size_t i = 0; i < len; i++) | |
4391 | 382 { |
4393 | 383 if (IS_DIR_SEP (name[i]) || IS_DEVICE_SEP (name[i])) |
4391 | 384 { |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
385 /* At a directory delimiter, reset component length. */ |
4391 | 386 c_len = 0; |
387 } | |
388 else if (c_len > NAME_MAX) | |
389 { | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
390 /* If past the max for a component, ignore this character. */ |
4391 | 391 continue; |
392 } | |
393 | |
394 /* Copy this character. */ | |
4393 | 395 ret[ret_len++] = name[i]; |
4391 | 396 c_len++; |
397 } | |
398 | |
4393 | 399 ret.resize (ret_len); |
4391 | 400 |
401 return ret; | |
402 } | |
403 | |
404 /* If access can read FN, run stat (assigning to stat buffer ST) and | |
405 check that fn is not a directory. Don't check for just being a | |
406 regular file, as it is potentially useful to read fifo's or some | |
407 kinds of devices. */ | |
408 | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
409 #if defined (WIN32) |
4391 | 410 static inline bool |
21865 | 411 READABLE (const std::string& fn) |
4391 | 412 { |
4393 | 413 const char *t = fn.c_str (); |
414 return (GetFileAttributes (t) != 0xFFFFFFFF | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
415 && ! (GetFileAttributes (t) & FILE_ATTRIBUTE_DIRECTORY)); |
4391 | 416 } |
417 #else | |
418 static inline bool | |
21865 | 419 READABLE (const std::string& fn) |
4391 | 420 { |
21865 | 421 bool retval = false; |
422 | |
4393 | 423 const char *t = fn.c_str (); |
21865 | 424 |
425 if (access (t, R_OK) == 0) | |
426 { | |
427 octave::sys::file_stat fs (fn); | |
428 | |
429 retval = fs && ! fs.is_dir (); | |
430 } | |
431 | |
432 return retval; | |
4391 | 433 } |
434 #endif | |
435 | |
436 /* POSIX invented the brain-damage of not necessarily truncating | |
437 filename components; the system's behavior is defined by the value of | |
438 the symbol _POSIX_NO_TRUNC, but you can't change it dynamically! | |
439 | |
440 Generic const return warning. See extend-fname.c. */ | |
441 | |
4393 | 442 static std::string |
443 kpse_readable_file (const std::string& name) | |
4391 | 444 { |
4393 | 445 std::string ret; |
4391 | 446 |
21865 | 447 if (READABLE (name)) |
4391 | 448 { |
4393 | 449 ret = name; |
4391 | 450 |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
451 #if defined (ENAMETOOLONG) |
4391 | 452 } |
453 else if (errno == ENAMETOOLONG) | |
454 { | |
455 ret = kpse_truncate_filename (name); | |
456 | |
457 /* Perhaps some other error will occur with the truncated name, | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
458 so let's call access again. */ |
4391 | 459 |
21865 | 460 if (! READABLE (ret)) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
461 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
462 /* Failed. */ |
21017
93748bcaec17
maint: Replace emtpy 'std::string ()' calls with "".
Rik <rik@octave.org>
parents:
20955
diff
changeset
|
463 ret = ""; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
464 } |
4391 | 465 #endif /* ENAMETOOLONG */ |
466 | |
467 } | |
468 else | |
469 { | |
470 /* Some other error. */ | |
471 if (errno == EACCES) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
472 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
473 /* Maybe warn them if permissions are bad. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
474 perror (name.c_str ()); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
475 } |
4393 | 476 |
21017
93748bcaec17
maint: Replace emtpy 'std::string ()' calls with "".
Rik <rik@octave.org>
parents:
20955
diff
changeset
|
477 ret = ""; |
4391 | 478 } |
479 | |
480 return ret; | |
481 } | |
482 | |
483 static bool | |
484 kpse_absolute_p (const std::string& filename, int relative_ok) | |
485 { | |
21865 | 486 return (octave::sys::env::absolute_pathname (filename) |
487 || (relative_ok | |
488 && octave::sys::env::rooted_relative_pathname (filename))); | |
4391 | 489 } |
490 | |
4378 | 491 /* The very first search is for texmf.cnf, called when someone tries to |
492 initialize the TFM path or whatever. init_path calls kpse_cnf_get | |
493 which calls kpse_all_path_search to find all the texmf.cnf's. We | |
494 need to do various special things in this case, since we obviously | |
495 don't yet have the configuration files when we're searching for the | |
496 configuration files. */ | |
497 static bool first_search = true; | |
498 | |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
499 /* This function is called after every search. */ |
4378 | 500 |
501 static void | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
502 log_search (const std::list<std::string>& filenames) |
4378 | 503 { |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
504 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) |
4391 | 505 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
506 for (const auto &filename : filenames) |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
507 std::cerr << time (0) << " " << filename << std::endl; |
4378 | 508 } |
509 } | |
4392 | 510 |
4378 | 511 /* Concatenate each element in DIRS with NAME (assume each ends with a |
512 /, to save time). If SEARCH_ALL is false, return the first readable | |
513 regular file. Else continue to search for more. In any case, if | |
514 none, return a list containing just NULL. | |
515 | |
516 We keep a single buffer for the potential filenames and reallocate | |
517 only when necessary. I'm not sure it's noticeably faster, but it | |
518 does seem cleaner. (We do waste a bit of space in the return | |
519 value, though, since we don't shrink it to the final size returned.) */ | |
520 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
521 static std::list<std::string> |
4390 | 522 dir_list_search (str_llist_type *dirs, const std::string& name, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
523 bool search_all) |
4378 | 524 { |
525 str_llist_elt_type *elt; | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
526 std::list<std::string> ret; |
4378 | 527 |
528 for (elt = *dirs; elt; elt = STR_LLIST_NEXT (*elt)) | |
529 { | |
4390 | 530 const std::string dir = STR_LLIST (*elt); |
4393 | 531 |
532 std::string potential = dir + name; | |
533 | |
534 std::string tmp = kpse_readable_file (potential); | |
535 | |
536 if (! tmp.empty ()) | |
4378 | 537 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
538 ret.push_back (potential); |
4391 | 539 |
4378 | 540 /* Move this element towards the top of the list. */ |
541 str_llist_float (dirs, elt); | |
4391 | 542 |
543 if (! search_all) | |
4378 | 544 return ret; |
545 } | |
546 } | |
4391 | 547 |
4378 | 548 return ret; |
549 } | |
4392 | 550 |
4378 | 551 /* This is called when NAME is absolute or explicitly relative; if it's |
552 readable, return (a list containing) it; otherwise, return NULL. */ | |
553 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
554 static std::list<std::string> |
4393 | 555 absolute_search (const std::string& name) |
4378 | 556 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
557 std::list<std::string> ret_list; |
4393 | 558 std::string found = kpse_readable_file (name); |
4391 | 559 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
560 /* Add 'found' to the return list even if it's null; that tells |
4378 | 561 the caller we didn't find anything. */ |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
562 ret_list.push_back (found); |
4391 | 563 |
4378 | 564 return ret_list; |
565 } | |
4392 | 566 |
4378 | 567 /* This is the hard case -- look for NAME in PATH. If ALL is false, |
568 return the first file found. Otherwise, search all elements of PATH. */ | |
569 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
570 static std::list<std::string> |
4394 | 571 path_search (const std::string& path, const std::string& name, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
572 bool /* must_exist */, bool all) |
4378 | 573 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
574 std::list<std::string> ret_list; |
4378 | 575 bool done = false; |
4390 | 576 |
8021 | 577 for (kpse_path_iterator pi (path); ! done && pi != std::string::npos; pi++) |
4390 | 578 { |
4394 | 579 std::string elt = *pi; |
580 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
581 std::list<std::string> found; |
4390 | 582 |
583 /* Do not touch the device if present */ | |
584 if (NAME_BEGINS_WITH_DEVICE (elt)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
585 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
586 while (elt.length () > 3 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
587 && IS_DIR_SEP (elt[2]) && IS_DIR_SEP (elt[3])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
588 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
589 elt[2] = elt[1]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
590 elt[1] = elt[0]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
591 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
592 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
593 } |
4390 | 594 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
595 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
596 /* We never want to search the whole disk. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
597 while (elt.length () > 1 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
598 && IS_DIR_SEP (elt[0]) && IS_DIR_SEP (elt[1])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
599 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
600 } |
4391 | 601 |
4390 | 602 /* Try ls-R, unless we're searching for texmf.cnf. Our caller |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
603 (search), also tests first_search, and does the resetting. */ |
21865 | 604 if (first_search) |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
605 found = std::list<std::string> (); |
21865 | 606 |
607 /* Search the filesystem. */ | |
608 | |
609 if (found.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
610 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
611 str_llist_type *dirs = kpse_element_dirs (elt); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
612 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
613 if (dirs && *dirs) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
614 found = dir_list_search (dirs, name, all); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
615 } |
4390 | 616 |
617 /* Did we find anything anywhere? */ | |
618 if (! found.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
619 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
620 if (all) |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
621 ret_list.splice (ret_list.end (), found); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
622 else |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
623 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
624 ret_list.push_back (found.front ()); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
625 done = true; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
626 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
627 } |
4378 | 628 } |
629 | |
630 return ret_list; | |
4390 | 631 } |
4392 | 632 |
4378 | 633 /* Search PATH for ORIGINAL_NAME. If ALL is false, or ORIGINAL_NAME is |
634 absolute_p, check ORIGINAL_NAME itself. Otherwise, look at each | |
635 element of PATH for the first readable ORIGINAL_NAME. | |
4391 | 636 |
4378 | 637 Always return a list; if no files are found, the list will |
638 contain just NULL. If ALL is true, the list will be | |
639 terminated with NULL. */ | |
640 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
641 static std::list<std::string> |
4390 | 642 search (const std::string& path, const std::string& original_name, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
643 bool must_exist, bool all) |
4378 | 644 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
645 std::list<std::string> ret_list; |
4378 | 646 bool absolute_p; |
647 | |
648 /* Make a leading ~ count as an absolute filename, and expand $FOO's. */ | |
4390 | 649 std::string name = kpse_expand (original_name); |
4391 | 650 |
4378 | 651 /* If the first name is absolute or explicitly relative, no need to |
652 consider PATH at all. */ | |
653 absolute_p = kpse_absolute_p (name, true); | |
4391 | 654 |
4378 | 655 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
656 std::cerr << "kdebug: start search (file=" << name |
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
657 << ", must_exist=" << must_exist |
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
658 << ", find_all=" << all << ", path=" << path << ")." |
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
659 << std::endl; |
4378 | 660 |
661 /* Find the file(s). */ | |
662 ret_list = absolute_p ? absolute_search (name) | |
663 : path_search (path, name, must_exist, all); | |
4391 | 664 |
4378 | 665 /* The very first search is for texmf.cnf. We can't log that, since |
666 we want to allow setting TEXMFLOG in texmf.cnf. */ | |
4391 | 667 if (first_search) |
668 { | |
669 first_search = false; | |
670 } | |
671 else | |
672 { | |
673 /* Record the filenames we found, if desired. And wrap them in a | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
674 debugging line if we're doing that. */ |
4391 | 675 |
676 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) | |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
677 std::cerr << "kdebug: search (" << original_name << ") =>"; |
4391 | 678 |
679 log_search (ret_list); | |
680 | |
681 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) | |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
682 std::cerr << std::endl; |
4391 | 683 } |
4378 | 684 |
4390 | 685 return ret_list; |
4378 | 686 } |
4392 | 687 |
4378 | 688 /* Search PATH for the first NAME. */ |
689 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
690 /* Call 'kpse_expand' on NAME. If the result is an absolute or |
4399 | 691 explicitly relative filename, check whether it is a readable |
692 (regular) file. | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11501
diff
changeset
|
693 |
4399 | 694 Otherwise, look in each of the directories specified in PATH (also do |
21865 | 695 tilde and variable expansion on elements in PATH). |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11501
diff
changeset
|
696 |
21751
b571fc85953f
maint: Use two spaces after period to indicate sentence break.
Rik <rik@octave.org>
parents:
21732
diff
changeset
|
697 The caller must expand PATH. This is because it makes more sense to |
4399 | 698 do this once, in advance, instead of for every search using it. |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11501
diff
changeset
|
699 |
4399 | 700 In any case, return the complete filename if found, otherwise NULL. */ |
701 | |
702 static std::string | |
4390 | 703 kpse_path_search (const std::string& path, const std::string& name, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
704 bool must_exist) |
4378 | 705 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
706 std::list<std::string> ret_list = search (path, name, must_exist, false); |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
707 |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
708 return ret_list.empty () ? "" : ret_list.front (); |
4378 | 709 } |
710 | |
711 /* Search all elements of PATH for files named NAME. Not sure if it's | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
712 right to assert 'must_exist' here, but it suffices now. */ |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
713 |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
714 /* Like 'kpse_path_search' with MUST_EXIST true, but return a list of |
4399 | 715 all the filenames (or NULL if none), instead of taking the first. */ |
716 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
717 static std::list<std::string> |
4390 | 718 kpse_all_path_search (const std::string& path, const std::string& name) |
4378 | 719 { |
4390 | 720 return search (path, name, true, true); |
4378 | 721 } |
4392 | 722 |
4378 | 723 /* This is the hard case -- look in each element of PATH for each |
724 element of NAMES. If ALL is false, return the first file found. | |
725 Otherwise, search all elements of PATH. */ | |
726 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
727 static std::list<std::string> |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
728 path_find_first_of (const std::string& path, |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
729 const std::list<std::string>& names, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
730 bool /* must_exist */, bool all) |
4378 | 731 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
732 std::list<std::string> ret_list; |
4378 | 733 bool done = false; |
4390 | 734 |
8021 | 735 for (kpse_path_iterator pi (path); ! done && pi != std::string::npos; pi++) |
4378 | 736 { |
4394 | 737 std::string elt = *pi; |
738 | |
4378 | 739 str_llist_type *dirs; |
740 str_llist_elt_type *dirs_elt; | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
741 std::list<std::string> found; |
4378 | 742 |
743 /* Do not touch the device if present */ | |
744 | |
745 if (NAME_BEGINS_WITH_DEVICE (elt)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
746 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
747 while (elt.length () > 3 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
748 && IS_DIR_SEP (elt[2]) && IS_DIR_SEP (elt[3])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
749 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
750 elt[2] = elt[1]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
751 elt[1] = elt[0]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
752 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
753 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
754 } |
4378 | 755 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
756 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
757 /* We never want to search the whole disk. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
758 while (elt.length () > 1 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
759 && IS_DIR_SEP (elt[0]) && IS_DIR_SEP (elt[1])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
760 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
761 } |
4378 | 762 |
763 /* We have to search one directory at a time. */ | |
764 dirs = kpse_element_dirs (elt); | |
765 for (dirs_elt = *dirs; dirs_elt; dirs_elt = STR_LLIST_NEXT (*dirs_elt)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
766 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
767 const std::string dir = STR_LLIST (*dirs_elt); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
768 |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
769 for (auto it = names.cbegin (); it != names.cend () && ! done; it++) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
770 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
771 std::string name = *it; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
772 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
773 /* Try ls-R, unless we're searching for texmf.cnf. Our caller |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
774 (find_first_of), also tests first_search, and does the |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
775 resetting. */ |
21865 | 776 if (first_search) |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
777 found = std::list<std::string> (); |
21865 | 778 |
779 /* Search the filesystem. */ | |
780 | |
781 if (found.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
782 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
783 static str_llist_type *tmp = 0; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
784 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
785 if (! tmp) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
786 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
787 tmp = new str_llist_type; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
788 *tmp = 0; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
789 str_llist_add (tmp, ""); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
790 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
791 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
792 STR_LLIST (*(*tmp)) = dir; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
793 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
794 found = dir_list_search (tmp, name, all); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
795 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
796 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
797 /* Did we find anything anywhere? */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
798 if (! found.empty ()) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
799 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
800 if (all) |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
801 ret_list.splice (ret_list.end (), found); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
802 else |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
803 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
804 ret_list.push_back (found.front ()); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
805 done = true; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
806 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
807 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
808 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
809 } |
4378 | 810 } |
811 | |
812 return ret_list; | |
4391 | 813 } |
4378 | 814 |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
815 static std::list<std::string> |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
816 find_first_of (const std::string& path, const std::list<std::string>& names, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
817 bool must_exist, bool all) |
4378 | 818 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
819 std::list<std::string> ret_list; |
4378 | 820 |
821 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) | |
822 { | |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
823 std::cerr << "kdebug: start find_first_of (("; |
4391 | 824 |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
825 for (auto p = names.cbegin (); p != names.cend (); p++) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
826 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
827 if (p == names.cbegin ()) |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
828 std::cerr << *p; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
829 else |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
830 std::cerr << ", " << *p; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
831 } |
4391 | 832 |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
833 std::cerr << "), path=" << path << ", must_exist=" |
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
834 << must_exist << "." << std::endl; |
4378 | 835 } |
836 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
837 for (const auto &name : names) |
4409 | 838 { |
839 if (kpse_absolute_p (name, true)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
840 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
841 /* If the name is absolute or explicitly relative, no need |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
842 to consider PATH at all. If we find something, then we |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
843 are done. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
844 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
845 ret_list = absolute_search (name); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
846 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
847 if (! ret_list.empty ()) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
848 return ret_list; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
849 } |
4409 | 850 } |
851 | |
4378 | 852 /* Find the file. */ |
853 ret_list = path_find_first_of (path, names, must_exist, all); | |
854 | |
855 /* The very first search is for texmf.cnf. We can't log that, since | |
856 we want to allow setting TEXMFLOG in texmf.cnf. */ | |
4391 | 857 if (first_search) |
858 { | |
859 first_search = false; | |
860 } | |
861 else | |
862 { | |
863 /* Record the filenames we found, if desired. And wrap them in a | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
864 debugging line if we're doing that. */ |
4391 | 865 |
866 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
867 { |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
868 std::cerr << "kdebug: find_first_of ("; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
869 |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
870 for (auto p = names.cbegin (); p != names.cend (); p++) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
871 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
872 if (p == names.cbegin ()) |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
873 std:: cerr << *p; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
874 else |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
875 std::cerr << ", " << *p; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
876 } |
10411 | 877 |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
878 std::cerr << ") =>"; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
879 } |
4391 | 880 |
881 log_search (ret_list); | |
882 | |
883 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) | |
10411 | 884 gnulib::putc ('\n', stderr); |
4391 | 885 } |
4378 | 886 |
4390 | 887 return ret_list; |
4378 | 888 } |
889 | |
890 /* Search each element of PATH for each element of NAMES. Return the | |
891 first one found. */ | |
892 | |
4399 | 893 /* Search each element of PATH for each element in the list of NAMES. |
894 Return the first one found. */ | |
895 | |
896 static std::string | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
897 kpse_path_find_first_of (const std::string& path, |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
898 const std::list<std::string>& names, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
899 bool must_exist) |
4378 | 900 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
901 std::list<std::string> ret_list |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
902 = find_first_of (path, names, must_exist, false); |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
903 |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
904 return ret_list.empty () ? "" : ret_list.front (); |
4378 | 905 } |
906 | |
907 /* Search each element of PATH for each element of NAMES and return a | |
908 list containing everything found, in the order found. */ | |
909 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
910 /* Like 'kpse_path_find_first_of' with MUST_EXIST true, but return a |
4399 | 911 list of all the filenames (or NULL if none), instead of taking the |
912 first. */ | |
913 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
914 static std::list<std::string> |
4390 | 915 kpse_all_path_find_first_of (const std::string& path, |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
916 const std::list<std::string>& names) |
4378 | 917 { |
4390 | 918 return find_first_of (path, names, true, true); |
4378 | 919 } |
920 | |
4399 | 921 /* General expansion. Some of this file (the brace-expansion |
4378 | 922 code from bash) is covered by the GPL; this is the only GPL-covered |
923 code in kpathsea. The part of the file that I wrote (the first | |
924 couple of functions) is covered by the LGPL. */ | |
925 | |
926 /* If NAME has a leading ~ or ~user, Unix-style, expand it to the user's | |
927 home directory, and return a new malloced string. If no ~, or no | |
928 <pwd.h>, just return NAME. */ | |
929 | |
4389 | 930 static std::string |
931 kpse_tilde_expand (const std::string& name) | |
4378 | 932 { |
4389 | 933 std::string expansion; |
4391 | 934 |
4378 | 935 /* If no leading tilde, do nothing. */ |
5137 | 936 if (name.empty () || name[0] != '~') |
4391 | 937 { |
938 expansion = name; | |
939 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
940 /* If a bare tilde, return the home directory or '.'. (Very |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
941 unlikely that the directory name will do anyone any good, but |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
942 ... */ |
4391 | 943 } |
944 else if (name.length () == 1) | |
945 { | |
21732
6a1eded90355
use namespace for system env class
John W. Eaton <jwe@octave.org>
parents:
21729
diff
changeset
|
946 expansion = octave::sys::env::get_home_directory (); |
4391 | 947 |
948 if (expansion.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
949 expansion = "."; |
4391 | 950 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
951 /* If '~/', remove any trailing / or replace leading // in $HOME. |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
952 Should really check for doubled intermediate slashes, too. */ |
4378 | 953 } |
4391 | 954 else if (IS_DIR_SEP (name[1])) |
955 { | |
956 unsigned c = 1; | |
21732
6a1eded90355
use namespace for system env class
John W. Eaton <jwe@octave.org>
parents:
21729
diff
changeset
|
957 std::string home = octave::sys::env::get_home_directory (); |
4391 | 958 |
959 if (home.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
960 home = "."; |
4391 | 961 |
962 size_t home_len = home.length (); | |
963 | |
964 /* handle leading // */ | |
965 if (home_len > 1 && IS_DIR_SEP (home[0]) && IS_DIR_SEP (home[1])) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
966 home = home.substr (1); |
4391 | 967 |
968 /* omit / after ~ */ | |
969 if (IS_DIR_SEP (home[home_len - 1])) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
970 c++; |
4391 | 971 |
972 expansion = home + name.substr (c); | |
973 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
974 /* If '~user' or '~user/', look up user in the passwd database (but |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
975 OS/2 doesn't have this concept. */ |
4378 | 976 } |
4391 | 977 else |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
978 #if defined (HAVE_PWD_H) |
4378 | 979 { |
980 unsigned c = 2; | |
4391 | 981 |
982 /* find user name */ | |
983 while (name.length () > c && ! IS_DIR_SEP (name[c])) | |
4378 | 984 c++; |
4391 | 985 |
986 std::string user = name.substr (1, c-1); | |
987 | |
4378 | 988 /* We only need the cast here for (deficient) systems |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
989 which do not declare 'getpwnam' in <pwd.h>. */ |
21729
815b2f500fab
use namespace for system password wrapper class
John W. Eaton <jwe@octave.org>
parents:
21724
diff
changeset
|
990 octave::sys::password p = octave::sys::password::getpwnam (user); |
4378 | 991 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
992 /* If no such user, just use '.'. */ |
4391 | 993 std::string home = p ? p.dir () : std::string ("."); |
994 | |
995 if (home.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
996 home = "."; |
4391 | 997 |
998 /* handle leading // */ | |
999 if (home.length () > 1 && IS_DIR_SEP (home[0]) && IS_DIR_SEP (home[1])) | |
1000 home = home.substr (1); | |
1001 | |
1002 /* If HOME ends in /, omit the / after ~user. */ | |
1003 if (name.length () > c && IS_DIR_SEP (home[home.length () - 1])) | |
1004 c++; | |
1005 | |
1006 expansion = name.length () > c ? home : home + name.substr (c); | |
4378 | 1007 } |
1008 #else /* not HAVE_PWD_H */ | |
4391 | 1009 expansion = name; |
4378 | 1010 #endif /* not HAVE_PWD_H */ |
1011 | |
4389 | 1012 return expansion; |
4378 | 1013 } |
1014 | |
1015 /* Do variable expansion first so ~${USER} works. (Besides, it's what the | |
1016 shells do.) */ | |
1017 | |
4399 | 1018 /* Call kpse_var_expand and kpse_tilde_expand (in that order). Result |
1019 is always in fresh memory, even if no expansions were done. */ | |
1020 | |
1021 static std::string | |
4389 | 1022 kpse_expand (const std::string& s) |
4378 | 1023 { |
4389 | 1024 std::string var_expansion = kpse_var_expand (s); |
1025 return kpse_tilde_expand (var_expansion); | |
4378 | 1026 } |
1027 | |
1028 /* Forward declarations of functions from the original expand.c */ | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1029 static std::list<std::string> brace_expand (const std::string&); |
4378 | 1030 |
1031 /* If $KPSE_DOT is defined in the environment, prepend it to any relative | |
1032 path components. */ | |
1033 | |
4389 | 1034 static std::string |
1035 kpse_expand_kpse_dot (const std::string& path) | |
4378 | 1036 { |
4389 | 1037 std::string ret; |
21732
6a1eded90355
use namespace for system env class
John W. Eaton <jwe@octave.org>
parents:
21729
diff
changeset
|
1038 std::string kpse_dot = octave::sys::env::getenv ("KPSE_DOT"); |
4391 | 1039 |
1040 if (kpse_dot.empty ()) | |
4378 | 1041 return path; |
1042 | |
8021 | 1043 for (kpse_path_iterator pi (path); pi != std::string::npos; pi++) |
4391 | 1044 { |
4394 | 1045 std::string elt = *pi; |
1046 | |
4391 | 1047 /* We assume that the !! magic is only used on absolute components. |
21562
6c2fd62db1f7
maint: Eliminate accidental double spaces in code.
Rik <rik@octave.org>
parents:
21340
diff
changeset
|
1048 Single "." get special treatment, as does "./" or its equivalent. */ |
4391 | 1049 |
4394 | 1050 size_t elt_len = elt.length (); |
1051 | |
1052 if (kpse_absolute_p (elt, false) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1053 || (elt_len > 1 && elt[0] == '!' && elt[1] == '!')) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1054 ret += elt + ENV_SEP_STRING; |
4394 | 1055 else if (elt_len == 1 && elt[0] == '.') |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1056 ret += kpse_dot + ENV_SEP_STRING; |
4394 | 1057 else if (elt_len > 1 && elt[0] == '.' && IS_DIR_SEP (elt[1])) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1058 ret += kpse_dot + elt.substr (1) + ENV_SEP_STRING; |
4391 | 1059 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1060 ret += kpse_dot + DIR_SEP_STRING + elt + ENV_SEP_STRING; |
4378 | 1061 } |
1062 | |
4389 | 1063 int len = ret.length (); |
1064 if (len > 0) | |
4395 | 1065 ret.resize (len-1); |
4389 | 1066 |
4378 | 1067 return ret; |
1068 } | |
1069 | |
1070 /* Do brace expansion on ELT; then do variable and ~ expansion on each | |
1071 element of the result; then do brace expansion again, in case a | |
1072 variable definition contained braces (e.g., $TEXMF). Return a | |
1073 string comprising all of the results separated by ENV_SEP_STRING. */ | |
1074 | |
4389 | 1075 static std::string |
4394 | 1076 kpse_brace_expand_element (const std::string& elt) |
4378 | 1077 { |
4389 | 1078 std::string ret; |
4378 | 1079 |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1080 std::list<std::string> expansions = brace_expand (elt); |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1081 |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1082 for (const auto &expanded_elt : expansions) |
4391 | 1083 { |
1084 /* Do $ and ~ expansion on each element. */ | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1085 std::string x = kpse_expand (expanded_elt); |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1086 |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1087 if (x != elt) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1088 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1089 /* If we did any expansions, do brace expansion again. Since |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1090 recursive variable definitions are not allowed, this recursion |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1091 must terminate. (In practice, it's unlikely there will ever be |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1092 more than one level of recursion.) */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1093 x = kpse_brace_expand_element (x); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1094 } |
4391 | 1095 |
1096 ret += x + ENV_SEP_STRING; | |
4378 | 1097 } |
1098 | |
4389 | 1099 ret.resize (ret.length () - 1); |
4391 | 1100 |
4378 | 1101 return ret; |
1102 } | |
1103 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1104 /* Do brace expansion and call 'kpse_expand' on each element of the |
4399 | 1105 result; return the final expansion (always in fresh memory, even if |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1106 no expansions were done). We don't call 'kpse_expand_default' |
4399 | 1107 because there is a whole sequence of defaults to run through; see |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1108 'kpse_init_format'. */ |
4399 | 1109 |
1110 static std::string | |
4397 | 1111 kpse_brace_expand (const std::string& path) |
4378 | 1112 { |
1113 /* Must do variable expansion first because if we have | |
1114 foo = .:~ | |
1115 TEXINPUTS = $foo | |
1116 we want to end up with TEXINPUTS = .:/home/karl. | |
1117 Since kpse_path_element is not reentrant, we must get all | |
1118 the path elements before we start the loop. */ | |
4389 | 1119 std::string tmp = kpse_var_expand (path); |
4394 | 1120 |
4389 | 1121 std::string ret; |
4378 | 1122 |
8021 | 1123 for (kpse_path_iterator pi (tmp); pi != std::string::npos; pi++) |
4391 | 1124 { |
4394 | 1125 std::string elt = *pi; |
1126 | |
4391 | 1127 /* Do brace expansion first, so tilde expansion happens in {~ka,~kb}. */ |
1128 std::string expansion = kpse_brace_expand_element (elt); | |
1129 ret += expansion + ENV_SEP_STRING; | |
1130 } | |
4378 | 1131 |
4394 | 1132 size_t len = ret.length (); |
4389 | 1133 if (len > 0) |
4395 | 1134 ret.resize (len-1); |
4389 | 1135 |
1136 return kpse_expand_kpse_dot (ret); | |
4378 | 1137 } |
4392 | 1138 |
4378 | 1139 /* Expand all special constructs in a path, and include only the actually |
1140 existing directories in the result. */ | |
4399 | 1141 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1142 /* Do brace expansion and call 'kpse_expand' on each argument of the |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1143 result, then expand any '//' constructs. The final expansion (always |
4399 | 1144 in fresh memory) is a path of all the existing directories that match |
1145 the pattern. */ | |
1146 | |
1147 static std::string | |
4397 | 1148 kpse_path_expand (const std::string& path) |
4378 | 1149 { |
4392 | 1150 std::string ret; |
4378 | 1151 unsigned len; |
1152 | |
1153 len = 0; | |
4391 | 1154 |
4378 | 1155 /* Expand variables and braces first. */ |
4389 | 1156 std::string tmp = kpse_brace_expand (path); |
4392 | 1157 |
4378 | 1158 /* Now expand each of the path elements, printing the results */ |
8021 | 1159 for (kpse_path_iterator pi (tmp); pi != std::string::npos; pi++) |
4391 | 1160 { |
4394 | 1161 std::string elt = *pi; |
1162 | |
4391 | 1163 str_llist_type *dirs; |
1164 | |
1165 /* Skip and ignore magic leading chars. */ | |
4394 | 1166 if (elt.length () > 1 && elt[0] == '!' && elt[1] == '!') |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1167 elt = elt.substr (2); |
4391 | 1168 |
1169 /* Do not touch the device if present */ | |
1170 if (NAME_BEGINS_WITH_DEVICE (elt)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1171 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1172 while (elt.length () > 3 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1173 && IS_DIR_SEP (elt[2]) && IS_DIR_SEP (elt[3])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1174 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1175 elt[2] = elt[1]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1176 elt[1] = elt[0]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1177 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1178 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1179 } |
4391 | 1180 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1181 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1182 /* We never want to search the whole disk. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1183 while (elt.length () > 1 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1184 && IS_DIR_SEP (elt[0]) && IS_DIR_SEP (elt[1])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1185 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1186 } |
4378 | 1187 |
4394 | 1188 /* Search the disk for all dirs in the component specified. |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1189 Be faster to check the database, but this is more reliable. */ |
4394 | 1190 dirs = kpse_element_dirs (elt); |
1191 | |
1192 if (dirs && *dirs) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1193 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1194 str_llist_elt_type *dir; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1195 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1196 for (dir = *dirs; dir; dir = STR_LLIST_NEXT (*dir)) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1197 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1198 const std::string thedir = STR_LLIST (*dir); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1199 unsigned dirlen = thedir.length (); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1200 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1201 ret += thedir; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1202 len += dirlen; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1203 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1204 /* Retain trailing slash if that's the root directory. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1205 if (dirlen == 1 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1206 || (dirlen == 3 && NAME_BEGINS_WITH_DEVICE (thedir) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1207 && IS_DIR_SEP (thedir[2]))) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1208 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1209 ret += ENV_SEP_STRING; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1210 len++; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1211 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1212 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1213 ret[len-1] = ENV_SEP; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1214 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1215 } |
4378 | 1216 } |
4391 | 1217 |
4395 | 1218 if (len > 0) |
1219 ret.resize (len-1); | |
4391 | 1220 |
4378 | 1221 return ret; |
1222 } | |
4392 | 1223 |
21751
b571fc85953f
maint: Use two spaces after period to indicate sentence break.
Rik <rik@octave.org>
parents:
21732
diff
changeset
|
1224 /* braces.c -- code for doing word expansion in curly braces. Taken from |
16768 | 1225 bash 1.14.5. [And subsequently modified for kpatshea.] |
1226 | |
1227 Copyright (C) 1987,1991 Free Software Foundation, Inc. */ | |
4378 | 1228 |
4391 | 1229 #define brace_whitespace(c) (! (c) || (c) == ' ' || (c) == '\t' || (c) == '\n') |
4378 | 1230 |
1231 /* Basic idea: | |
1232 | |
1233 Segregate the text into 3 sections: preamble (stuff before an open brace), | |
1234 postamble (stuff after the matching close brace) and amble (stuff after | |
1235 preamble, and before postamble). Expand amble, and then tack on the | |
1236 expansions to preamble. Expand postamble, and tack on the expansions to | |
4391 | 1237 the result so far. */ |
4378 | 1238 |
4397 | 1239 /* Return a new array of strings which is the result of appending each |
1240 string in ARR2 to each string in ARR1. The resultant array is | |
1241 len (arr1) * len (arr2) long. For convenience, ARR1 (and its contents) | |
1242 are free ()'ed. ARR1 can be NULL, in that case, a new version of ARR2 | |
1243 is returned. */ | |
1244 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1245 static std::list<std::string> |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1246 array_concat (const std::list<std::string>& arr1, |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1247 const std::list<std::string>& arr2) |
4378 | 1248 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1249 std::list<std::string> result; |
4397 | 1250 |
1251 if (arr1.empty ()) | |
1252 result = arr2; | |
1253 else if (arr2.empty ()) | |
1254 result = arr1; | |
1255 else | |
1256 { | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1257 for (const auto &elt_2 : arr2) |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1258 for (const auto &elt_1 : arr1) |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1259 result.push_back (elt_1 + elt_2); |
4397 | 1260 } |
1261 | |
1262 return result; | |
4378 | 1263 } |
1264 | |
4397 | 1265 static int brace_gobbler (const std::string&, int&, int); |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1266 static std::list<std::string> expand_amble (const std::string&); |
4378 | 1267 |
1268 /* Return an array of strings; the brace expansion of TEXT. */ | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1269 static std::list<std::string> |
4397 | 1270 brace_expand (const std::string& text) |
4378 | 1271 { |
1272 /* Find the text of the preamble. */ | |
4397 | 1273 int i = 0; |
1274 int c = brace_gobbler (text, i, '{'); | |
1275 | |
1276 std::string preamble = text.substr (0, i); | |
1277 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1278 std::list<std::string> result (1, preamble); |
4397 | 1279 |
1280 if (c == '{') | |
4378 | 1281 { |
4397 | 1282 /* Find the amble. This is the stuff inside this set of braces. */ |
1283 int start = ++i; | |
1284 c = brace_gobbler (text, i, '}'); | |
1285 | |
1286 /* What if there isn't a matching close brace? */ | |
1287 if (! c) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1288 { |
19410
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1289 (*current_liboctave_warning_with_id_handler) |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1290 ("Octave:pathsearch-syntax", |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1291 "%s: Unmatched {", text.c_str ()); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1292 |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1293 result = std::list<std::string> (1, text); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1294 } |
4397 | 1295 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1296 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1297 std::string amble = text.substr (start, i-start); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1298 result = array_concat (result, expand_amble (amble)); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1299 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1300 std::string postamble = text.substr (i+1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1301 result = array_concat (result, brace_expand (postamble)); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1302 } |
4378 | 1303 } |
1304 | |
4397 | 1305 return result; |
4378 | 1306 } |
1307 | |
4397 | 1308 /* The character which is used to separate arguments. */ |
1309 static int brace_arg_separator = ','; | |
1310 | |
4378 | 1311 /* Expand the text found inside of braces. We simply try to split the |
1312 text at BRACE_ARG_SEPARATORs into separate strings. We then brace | |
1313 expand each slot which needs it, until there are no more slots which | |
1314 need it. */ | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1315 static std::list<std::string> |
4397 | 1316 expand_amble (const std::string& text) |
4378 | 1317 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1318 std::list<std::string> result; |
4397 | 1319 |
1320 size_t text_len = text.length (); | |
1321 size_t start; | |
1322 int i, c; | |
1323 | |
1324 for (start = 0, i = 0, c = 1; c && start < text_len; start = ++i) | |
4378 | 1325 { |
4397 | 1326 int i0 = i; |
1327 int c0 = brace_gobbler (text, i0, brace_arg_separator); | |
1328 int i1 = i; | |
1329 int c1 = brace_gobbler (text, i1, ENV_SEP); | |
4378 | 1330 c = c0 | c1; |
1331 i = (i0 < i1 ? i0 : i1); | |
1332 | |
4397 | 1333 std::string tem = text.substr (start, i-start); |
1334 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1335 std::list<std::string> partial = brace_expand (tem); |
4397 | 1336 |
1337 if (result.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1338 result = partial; |
4378 | 1339 else |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1340 result.splice (result.end (), partial); |
4378 | 1341 } |
4397 | 1342 |
1343 return result; | |
4378 | 1344 } |
1345 | |
21751
b571fc85953f
maint: Use two spaces after period to indicate sentence break.
Rik <rik@octave.org>
parents:
21732
diff
changeset
|
1346 /* Start at INDEX, and skip characters in TEXT. Set INDEX to the |
4378 | 1347 index of the character matching SATISFY. This understands about |
1348 quoting. Return the character that caused us to stop searching; | |
1349 this is either the same as SATISFY, or 0. */ | |
1350 static int | |
4397 | 1351 brace_gobbler (const std::string& text, int& indx, int satisfy) |
4378 | 1352 { |
18084
8e056300994b
Follow coding convention of defining and initializing only 1 variable per line in liboctave.
Rik <rik@octave.org>
parents:
17769
diff
changeset
|
1353 int c = 0; |
8e056300994b
Follow coding convention of defining and initializing only 1 variable per line in liboctave.
Rik <rik@octave.org>
parents:
17769
diff
changeset
|
1354 int level = 0; |
8e056300994b
Follow coding convention of defining and initializing only 1 variable per line in liboctave.
Rik <rik@octave.org>
parents:
17769
diff
changeset
|
1355 int quoted = 0; |
8e056300994b
Follow coding convention of defining and initializing only 1 variable per line in liboctave.
Rik <rik@octave.org>
parents:
17769
diff
changeset
|
1356 int pass_next = 0; |
4397 | 1357 |
1358 size_t text_len = text.length (); | |
1359 | |
1360 size_t i = indx; | |
1361 | |
1362 for (; i < text_len; i++) | |
4378 | 1363 { |
4397 | 1364 c = text[i]; |
1365 | |
4378 | 1366 if (pass_next) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1367 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1368 pass_next = 0; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1369 continue; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1370 } |
4378 | 1371 |
1372 /* A backslash escapes the next character. This allows backslash to | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1373 escape the quote character in a double-quoted string. */ |
4378 | 1374 if (c == '\\' && (quoted == 0 || quoted == '"' || quoted == '`')) |
1375 { | |
1376 pass_next = 1; | |
1377 continue; | |
1378 } | |
1379 | |
1380 if (quoted) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1381 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1382 if (c == quoted) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1383 quoted = 0; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1384 continue; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1385 } |
4378 | 1386 |
1387 if (c == '"' || c == '\'' || c == '`') | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1388 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1389 quoted = c; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1390 continue; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1391 } |
4391 | 1392 |
20955
77f5591878bf
maint: Use '! expr' rather than '!expr' to conform to coding guidelines.
Rik <rik@octave.org>
parents:
20791
diff
changeset
|
1393 if (c == satisfy && ! level && ! quoted) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1394 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1395 /* We ignore an open brace surrounded by whitespace, and also |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1396 an open brace followed immediately by a close brace, that |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1397 was preceded with whitespace. */ |
19864
17d647821d61
maint: More cleanup of C++ code to follow Octave coding conventions.
John W. Eaton <jwe@octave.org>
parents:
19697
diff
changeset
|
1398 if (c == '{' |
17d647821d61
maint: More cleanup of C++ code to follow Octave coding conventions.
John W. Eaton <jwe@octave.org>
parents:
19697
diff
changeset
|
1399 && ((i == 0 || brace_whitespace (text[i-1])) |
17d647821d61
maint: More cleanup of C++ code to follow Octave coding conventions.
John W. Eaton <jwe@octave.org>
parents:
19697
diff
changeset
|
1400 && (i+1 < text_len |
17d647821d61
maint: More cleanup of C++ code to follow Octave coding conventions.
John W. Eaton <jwe@octave.org>
parents:
19697
diff
changeset
|
1401 && (brace_whitespace (text[i+1]) || text[i+1] == '}')))) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1402 continue; |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1403 /* If this is being compiled as part of bash, ignore the '{' |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1404 in a '${ }' construct */ |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1405 if ((c != '{') || i == 0 || (text[i-1] != '$')) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1406 break; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1407 } |
4378 | 1408 |
1409 if (c == '{') | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1410 level++; |
4378 | 1411 else if (c == '}' && level) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1412 level--; |
4378 | 1413 } |
1414 | |
4397 | 1415 indx = i; |
1416 return c; | |
4378 | 1417 } |
1418 | |
1419 /* Return true if FILENAME could be in PATH_ELT, i.e., if the directory | |
1420 part of FILENAME matches PATH_ELT. Have to consider // wildcards, but | |
1421 $ and ~ expansion have already been done. */ | |
4391 | 1422 |
4378 | 1423 static bool |
4390 | 1424 match (const std::string& filename_arg, const std::string& path_elt_arg) |
4378 | 1425 { |
4390 | 1426 const char *filename = filename_arg.c_str (); |
1427 const char *path_elt = path_elt_arg.c_str (); | |
1428 | |
4378 | 1429 const char *original_filename = filename; |
1430 bool matched = false; | |
4391 | 1431 |
1432 for (; *filename && *path_elt; filename++, path_elt++) | |
1433 { | |
4394 | 1434 if (*filename == *path_elt) /* normal character match */ |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1435 ; |
4391 | 1436 |
1437 else if (IS_DIR_SEP (*path_elt) /* at // */ | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1438 && original_filename < filename && IS_DIR_SEP (path_elt[-1])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1439 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1440 while (IS_DIR_SEP (*path_elt)) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1441 path_elt++; /* get past second and any subsequent /'s */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1442 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1443 if (*path_elt == 0) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1444 { |
21751
b571fc85953f
maint: Use two spaces after period to indicate sentence break.
Rik <rik@octave.org>
parents:
21732
diff
changeset
|
1445 /* Trailing //, matches anything. We could make this |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1446 part of the other case, but it seems pointless to do |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1447 the extra work. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1448 matched = true; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1449 break; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1450 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1451 else |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1452 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1453 /* Intermediate //, have to match rest of PATH_ELT. */ |
20955
77f5591878bf
maint: Use '! expr' rather than '!expr' to conform to coding guidelines.
Rik <rik@octave.org>
parents:
20791
diff
changeset
|
1454 for (; ! matched && *filename; filename++) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1455 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1456 /* Try matching at each possible character. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1457 if (IS_DIR_SEP (filename[-1]) && *filename == *path_elt) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1458 matched = match (filename, path_elt); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1459 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1460 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1461 /* Prevent filename++ when *filename='\0'. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1462 break; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1463 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1464 } |
4391 | 1465 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1466 /* normal character nonmatch, quit */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1467 break; |
4378 | 1468 } |
1469 | |
1470 /* If we've reached the end of PATH_ELT, check that we're at the last | |
1471 component of FILENAME, we've matched. */ | |
4391 | 1472 if (! matched && *path_elt == 0) |
1473 { | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1474 /* Probably PATH_ELT ended with 'vf' or some such, and FILENAME |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1475 ends with 'vf/ptmr.vf'. In that case, we'll be at a |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1476 directory separator. On the other hand, if PATH_ELT ended |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1477 with a / (as in 'vf/'), FILENAME being the same 'vf/ptmr.vf', |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1478 we'll be at the 'p'. Upshot: if we're at a dir separator in |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1479 FILENAME, skip it. But if not, that's ok, as long as there |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1480 are no more dir separators. */ |
4391 | 1481 |
1482 if (IS_DIR_SEP (*filename)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1483 filename++; |
4391 | 1484 |
20955
77f5591878bf
maint: Use '! expr' rather than '!expr' to conform to coding guidelines.
Rik <rik@octave.org>
parents:
20791
diff
changeset
|
1485 while (*filename && ! IS_DIR_SEP (*filename)) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1486 filename++; |
4391 | 1487 |
1488 matched = *filename == 0; | |
1489 } | |
1490 | |
4378 | 1491 return matched; |
1492 } | |
1493 | |
4399 | 1494 /* Expand extra colons. */ |
4378 | 1495 |
1496 /* Check for leading colon first, then trailing, then doubled, since | |
1497 that is fastest. Usually it will be leading or trailing. */ | |
1498 | |
4399 | 1499 /* Replace a leading or trailing or doubled : in PATH with DFLT. If |
1500 no extra colons, return PATH. Only one extra colon is replaced. | |
1501 DFLT may not be NULL. */ | |
1502 | |
1503 static std::string | |
4394 | 1504 kpse_expand_default (const std::string& path, const std::string& fallback) |
4378 | 1505 { |
4394 | 1506 std::string expansion; |
1507 | |
1508 size_t path_len = path.length (); | |
1509 | |
1510 if (path_len == 0) | |
1511 expansion = fallback; | |
4378 | 1512 |
1513 /* Solitary or leading :? */ | |
4394 | 1514 else if (IS_ENV_SEP (path[0])) |
4378 | 1515 { |
4394 | 1516 expansion = path_len == 1 ? fallback : fallback + path; |
4378 | 1517 } |
1518 | |
1519 /* Sorry about the assignment in the middle of the expression, but | |
1520 conventions were made to be flouted and all that. I don't see the | |
1521 point of calling strlen twice or complicating the logic just to | |
1522 avoid the assignment (especially now that I've pointed it out at | |
1523 such great length). */ | |
4394 | 1524 else if (IS_ENV_SEP (path[path_len-1])) |
1525 expansion = path + fallback; | |
4378 | 1526 |
1527 /* OK, not leading or trailing. Check for doubled. */ | |
1528 else | |
1529 { | |
1530 /* What we'll return if we find none. */ | |
4394 | 1531 expansion = path; |
1532 | |
1533 for (size_t i = 0; i < path_len; i++) | |
4378 | 1534 { |
4394 | 1535 if (i + 1 < path_len |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1536 && IS_ENV_SEP (path[i]) && IS_ENV_SEP (path[i+1])) |
4394 | 1537 { |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1538 /* We have a doubled colon. */ |
4391 | 1539 |
4378 | 1540 /* Copy stuff up to and including the first colon. */ |
1541 /* Copy in FALLBACK, and then the rest of PATH. */ | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1542 expansion = path.substr (0, i+1) + fallback + path.substr (i+1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1543 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1544 break; |
4378 | 1545 } |
1546 } | |
1547 } | |
4391 | 1548 |
4378 | 1549 return expansion; |
1550 } | |
1551 | |
4399 | 1552 /* Translate a path element to its corresponding director{y,ies}. */ |
4378 | 1553 |
1554 /* To avoid giving prototypes for all the routines and then their real | |
1555 definitions, we give all the subroutines first. The entry point is | |
1556 the last routine in the file. */ | |
4392 | 1557 |
4378 | 1558 /* Make a copy of DIR (unless it's null) and save it in L. Ensure that |
1559 DIR ends with a DIR_SEP for the benefit of later searches. */ | |
1560 | |
1561 static void | |
4390 | 1562 dir_list_add (str_llist_type *l, const std::string& dir) |
4378 | 1563 { |
4390 | 1564 char last_char = dir[dir.length () - 1]; |
4407 | 1565 |
4390 | 1566 std::string saved_dir = dir; |
4407 | 1567 |
1568 if (! (IS_DIR_SEP (last_char) || IS_DEVICE_SEP (last_char))) | |
4390 | 1569 saved_dir += DIR_SEP_STRING; |
4391 | 1570 |
4378 | 1571 str_llist_add (l, saved_dir); |
1572 } | |
1573 | |
4390 | 1574 /* Return true if FN is a directory or a symlink to a directory, |
1575 false if not. */ | |
1576 | |
1577 static bool | |
1578 dir_p (const std::string& fn) | |
1579 { | |
21865 | 1580 octave::sys::file_stat fs (fn); |
1581 | |
1582 return (fs && fs.is_dir ()); | |
4390 | 1583 } |
4391 | 1584 |
4378 | 1585 /* If DIR is a directory, add it to the list L. */ |
1586 | |
1587 static void | |
4390 | 1588 checked_dir_list_add (str_llist_type *l, const std::string& dir) |
4378 | 1589 { |
1590 if (dir_p (dir)) | |
1591 dir_list_add (l, dir); | |
1592 } | |
4392 | 1593 |
4378 | 1594 /* The cache. Typically, several paths have the same element; for |
1595 example, /usr/local/lib/texmf/fonts//. We don't want to compute the | |
1596 expansion of such a thing more than once. Even though we also cache | |
1597 the dir_links call, that's not enough -- without this path element | |
1598 caching as well, the execution time doubles. */ | |
1599 | |
4398 | 1600 struct cache_entry |
4378 | 1601 { |
11501
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
1602 cache_entry (void) : key (), value (0) { } |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
1603 |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
1604 ~cache_entry (void) { } |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
1605 |
4398 | 1606 std::string key; |
4378 | 1607 str_llist_type *value; |
4398 | 1608 }; |
1609 | |
1610 static cache_entry *the_cache = 0; | |
4378 | 1611 static unsigned cache_length = 0; |
1612 | |
1613 /* Associate KEY with VALUE. We implement the cache as a simple linear | |
1614 list, since it's unlikely to ever be more than a dozen or so elements | |
1615 long. We don't bother to check here if PATH has already been saved; | |
1616 we always add it to our list. We copy KEY but not VALUE; not sure | |
1617 that's right, but it seems to be all that's needed. */ | |
1618 | |
1619 static void | |
4398 | 1620 cache (const std::string key, str_llist_type *value) |
4378 | 1621 { |
4398 | 1622 cache_entry *new_cache = new cache_entry [cache_length+1]; |
1623 | |
4399 | 1624 for (unsigned i = 0; i < cache_length; i++) |
4398 | 1625 { |
1626 new_cache[i].key = the_cache[i].key; | |
1627 new_cache[i].value = the_cache[i].value; | |
1628 } | |
1629 | |
1630 delete [] the_cache; | |
1631 | |
1632 the_cache = new_cache; | |
1633 | |
1634 the_cache[cache_length].key = key; | |
1635 the_cache[cache_length].value = value; | |
1636 | |
4378 | 1637 cache_length++; |
1638 } | |
1639 | |
1640 /* To retrieve, just check the list in order. */ | |
1641 | |
1642 static str_llist_type * | |
4398 | 1643 cached (const std::string& key) |
4378 | 1644 { |
1645 unsigned p; | |
4391 | 1646 |
4378 | 1647 for (p = 0; p < cache_length; p++) |
1648 { | |
4398 | 1649 if (key == the_cache[p].key) |
4378 | 1650 return the_cache[p].value; |
1651 } | |
4391 | 1652 |
4398 | 1653 return 0; |
4378 | 1654 } |
4392 | 1655 |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
1656 #if defined (WIN32) |
4398 | 1657 |
4378 | 1658 /* Shared across recursive calls, it acts like a stack. */ |
4398 | 1659 static std::string dirname; |
1660 | |
1661 #else /* WIN32 */ | |
1662 | |
1663 /* Return -1 if FN isn't a directory, else its number of links. | |
1664 Duplicate the call to stat; no need to incur overhead of a function | |
1665 call for that little bit of cleanliness. */ | |
1666 | |
1667 static int | |
1668 dir_links (const std::string& fn) | |
1669 { | |
21865 | 1670 int retval; |
1671 | |
1672 octave::sys::file_stat fs (fn); | |
1673 | |
1674 retval = fs && (fs.is_dir () ? fs.nlink () : -1); | |
4398 | 1675 |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
1676 #if defined (KPSE_DEBUG) |
21865 | 1677 if (KPSE_DEBUG_P (KPSE_DEBUG_STAT)) |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
1678 std::cerr << "kdebug: dir_links (" << fn << ") => " << retval << std::endl; |
4378 | 1679 #endif |
21865 | 1680 |
1681 return retval; | |
4398 | 1682 } |
1683 | |
1684 #endif /* WIN32 */ | |
4378 | 1685 |
21340
9f838471a5da
* kpse.cc: Avoid warning about static function in "header" file.
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
1686 static inline void |
4398 | 1687 do_subdir (str_llist_type *str_list_ptr, const std::string& elt, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1688 unsigned elt_length, const std::string& post) |
4378 | 1689 { |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
1690 #if defined (WIN32) |
4378 | 1691 WIN32_FIND_DATA find_file_data; |
1692 HANDLE hnd; | |
1693 int proceed; | |
1694 #else | |
1695 DIR *dir; | |
1696 struct dirent *e; | |
1697 #endif /* not WIN32 */ | |
4389 | 1698 |
4398 | 1699 std::string name = elt.substr (0, elt_length); |
4389 | 1700 |
4378 | 1701 assert (IS_DIR_SEP (elt[elt_length - 1]) |
1702 || IS_DEVICE_SEP (elt[elt_length - 1])); | |
4391 | 1703 |
4378 | 1704 #if defined (WIN32) |
4398 | 1705 |
1706 dirname = name + "/*.*"; /* "*.*" or "*" -- seems equivalent. */ | |
1707 | |
1708 hnd = FindFirstFile (dirname.c_str (), &find_file_data); | |
4378 | 1709 |
4389 | 1710 if (hnd == INVALID_HANDLE_VALUE) |
4378 | 1711 return; |
1712 | |
1713 /* Include top level before subdirectories, if nothing to match. */ | |
4398 | 1714 if (post.empty ()) |
4390 | 1715 dir_list_add (str_list_ptr, name); |
4398 | 1716 else |
1717 { | |
1718 /* If we do have something to match, see if it exists. For | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1719 example, POST might be 'pk/ljfour', and they might have a |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1720 directory '$TEXMF/fonts/pk/ljfour' that we should find. */ |
4398 | 1721 name += post; |
21864
f3487b21e879
* kpse.cc: Remove obsolete and unused code.
John W. Eaton <jwe@octave.org>
parents:
21863
diff
changeset
|
1722 checked_dir_list_add (str_list_ptr, name); |
4398 | 1723 name.resize (elt_length); |
1724 } | |
1725 | |
4378 | 1726 proceed = 1; |
4398 | 1727 |
4391 | 1728 while (proceed) |
1729 { | |
1730 if (find_file_data.cFileName[0] != '.') | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1731 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1732 /* Construct the potential subdirectory name. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1733 name += find_file_data.cFileName; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1734 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1735 if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1736 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1737 /* It's a directory, so append the separator. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1738 name += DIR_SEP_STRING; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1739 unsigned potential_len = name.length (); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1740 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1741 do_subdir (str_list_ptr, name, potential_len, post); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1742 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1743 name.resize (elt_length); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1744 } |
4398 | 1745 |
4391 | 1746 proceed = FindNextFile (hnd, &find_file_data); |
4378 | 1747 } |
4398 | 1748 |
4391 | 1749 FindClose (hnd); |
4378 | 1750 |
1751 #else /* not WIN32 */ | |
1752 | |
1753 /* If we can't open it, quit. */ | |
10411 | 1754 dir = gnulib::opendir (name.c_str ()); |
4398 | 1755 |
1756 if (! dir) | |
4389 | 1757 return; |
4391 | 1758 |
4378 | 1759 /* Include top level before subdirectories, if nothing to match. */ |
4398 | 1760 if (post.empty ()) |
4390 | 1761 dir_list_add (str_list_ptr, name); |
4378 | 1762 else |
4398 | 1763 { |
1764 /* If we do have something to match, see if it exists. For | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1765 example, POST might be 'pk/ljfour', and they might have a |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1766 directory '$TEXMF/fonts/pk/ljfour' that we should find. */ |
4389 | 1767 name += post; |
21864
f3487b21e879
* kpse.cc: Remove obsolete and unused code.
John W. Eaton <jwe@octave.org>
parents:
21863
diff
changeset
|
1768 checked_dir_list_add (str_list_ptr, name); |
4389 | 1769 name.resize (elt_length); |
4378 | 1770 } |
1771 | |
14155 | 1772 while ((e = gnulib::readdir (dir))) |
4398 | 1773 { |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1774 /* If it begins with a '.', never mind. (This allows "hidden" |
4378 | 1775 directories that the algorithm won't find.) */ |
4398 | 1776 |
4378 | 1777 if (e->d_name[0] != '.') |
1778 { | |
1779 /* Construct the potential subdirectory name. */ | |
4389 | 1780 name += e->d_name; |
4391 | 1781 |
4378 | 1782 /* If we can't stat it, or if it isn't a directory, continue. */ |
21865 | 1783 int links = dir_links (name); |
4378 | 1784 |
1785 if (links >= 0) | |
4391 | 1786 { |
4378 | 1787 /* It's a directory, so append the separator. */ |
4389 | 1788 name += DIR_SEP_STRING; |
1789 unsigned potential_len = name.length (); | |
4391 | 1790 |
4378 | 1791 /* Should we recurse? To see if the subdirectory is a |
1792 leaf, check if it has two links (one for . and one for | |
1793 ..). This means that symbolic links to directories do | |
1794 not affect the leaf-ness. This is arguably wrong, but | |
1795 the only alternative I know of is to stat every entry | |
1796 in the directory, and that is unacceptably slow. | |
4391 | 1797 |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
1798 The #if here makes all this configurable at |
4378 | 1799 compile-time, so that if we're using VMS directories or |
1800 some such, we can still find subdirectories, even if it | |
1801 is much slower. */ | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
1802 #if defined (ST_NLINK_TRICK) |
5622 | 1803 if (links != 2) |
4378 | 1804 #endif /* not ST_NLINK_TRICK */ |
1805 /* All criteria are met; find subdirectories. */ | |
4398 | 1806 do_subdir (str_list_ptr, name, potential_len, post); |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
1807 #if defined (ST_NLINK_TRICK) |
4398 | 1808 else if (post.empty ()) |
4378 | 1809 /* Nothing to match, no recursive subdirectories to |
1810 look for: we're done with this branch. Add it. */ | |
4390 | 1811 dir_list_add (str_list_ptr, name); |
4378 | 1812 #endif |
1813 } | |
1814 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1815 /* Remove the directory entry we just checked from 'name'. */ |
4389 | 1816 name.resize (elt_length); |
4378 | 1817 } |
1818 } | |
4391 | 1819 |
4378 | 1820 xclosedir (dir); |
1821 #endif /* not WIN32 */ | |
1822 } | |
1823 | |
1824 /* Here is the entry point. Returns directory list for ELT. */ | |
1825 | |
4399 | 1826 /* Given a path element ELT, return a pointer to a NULL-terminated list |
1827 of the corresponding (existing) directory or directories, with | |
1828 trailing slashes, or NULL. If ELT is the empty string, check the | |
1829 current working directory. | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11501
diff
changeset
|
1830 |
4399 | 1831 It's up to the caller to expand ELT. This is because this routine is |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1832 most likely only useful to be called from 'kpse_path_search', which |
4399 | 1833 has already assumed expansion has been done. */ |
1834 | |
1835 static str_llist_type * | |
4398 | 1836 kpse_element_dirs (const std::string& elt) |
4378 | 1837 { |
1838 str_llist_type *ret; | |
1839 | |
1840 /* If given nothing, return nothing. */ | |
4398 | 1841 if (elt.empty ()) |
1842 return 0; | |
4378 | 1843 |
1844 /* If we've already cached the answer for ELT, return it. */ | |
1845 ret = cached (elt); | |
1846 if (ret) | |
1847 return ret; | |
1848 | |
1849 /* We're going to have a real directory list to return. */ | |
4390 | 1850 ret = new str_llist_type; |
4398 | 1851 *ret = 0; |
4378 | 1852 |
1853 /* We handle the hard case in a subroutine. */ | |
21864
f3487b21e879
* kpse.cc: Remove obsolete and unused code.
John W. Eaton <jwe@octave.org>
parents:
21863
diff
changeset
|
1854 checked_dir_list_add (ret, elt); |
4378 | 1855 |
1856 /* Remember the directory list we just found, in case future calls are | |
1857 made with the same ELT. */ | |
1858 cache (elt, ret); | |
1859 | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
1860 #if defined (KPSE_DEBUG) |
4378 | 1861 if (KPSE_DEBUG_P (KPSE_DEBUG_EXPAND)) |
1862 { | |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
1863 std::cerr << "kdebug: path element " << elt << " =>"; |
4378 | 1864 if (ret) |
1865 { | |
1866 str_llist_elt_type *e; | |
1867 for (e = *ret; e; e = STR_LLIST_NEXT (*e)) | |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
1868 std::cerr << " " << STR_LLIST (*e); |
4378 | 1869 } |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
1870 std::cerr << std::endl; |
4378 | 1871 } |
1872 #endif /* KPSE_DEBUG */ | |
1873 | |
1874 return ret; | |
1875 } | |
1876 | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
1877 #if ! defined (WIN32) |
4385 | 1878 void |
1879 xclosedir (DIR *d) | |
1880 { | |
10411 | 1881 int ret = gnulib::closedir (d); |
4391 | 1882 |
4385 | 1883 if (ret != 0) |
1884 FATAL ("closedir failed"); | |
1885 } | |
4386 | 1886 #endif |
4385 | 1887 |
4399 | 1888 /* Implementation of a linked list of strings. */ |
4385 | 1889 |
1890 /* Add the new string STR to the end of the list L. */ | |
1891 | |
5085 | 1892 static void |
4390 | 1893 str_llist_add (str_llist_type *l, const std::string& str) |
4385 | 1894 { |
1895 str_llist_elt_type *e; | |
4390 | 1896 str_llist_elt_type *new_elt = new str_llist_elt_type; |
4391 | 1897 |
4385 | 1898 /* The new element will be at the end of the list. */ |
1899 STR_LLIST (*new_elt) = str; | |
1900 STR_LLIST_MOVED (*new_elt) = 0; | |
4398 | 1901 STR_LLIST_NEXT (*new_elt) = 0; |
4391 | 1902 |
4385 | 1903 /* Find the current end of the list. */ |
1904 for (e = *l; e && STR_LLIST_NEXT (*e); e = STR_LLIST_NEXT (*e)) | |
1905 ; | |
4391 | 1906 |
1907 if (! e) | |
4385 | 1908 *l = new_elt; |
1909 else | |
1910 STR_LLIST_NEXT (*e) = new_elt; | |
1911 } | |
4392 | 1912 |
21751
b571fc85953f
maint: Use two spaces after period to indicate sentence break.
Rik <rik@octave.org>
parents:
21732
diff
changeset
|
1913 /* Move an element towards the top. The idea is that when a file is |
4385 | 1914 found in a given directory, later files will likely be in that same |
1915 directory, and looking for the file in all the directories in between | |
1916 is thus a waste. */ | |
1917 | |
5085 | 1918 static void |
4385 | 1919 str_llist_float (str_llist_type *l, str_llist_elt_type *mover) |
1920 { | |
1921 str_llist_elt_type *last_moved, *unmoved; | |
4391 | 1922 |
4385 | 1923 /* If we've already moved this element, never mind. */ |
1924 if (STR_LLIST_MOVED (*mover)) | |
1925 return; | |
4391 | 1926 |
4385 | 1927 /* Find the first unmoved element (to insert before). We're |
1928 guaranteed this will terminate, since MOVER itself is currently | |
1929 unmoved, and it must be in L (by hypothesis). */ | |
4398 | 1930 for (last_moved = 0, unmoved = *l; STR_LLIST_MOVED (*unmoved); |
4385 | 1931 last_moved = unmoved, unmoved = STR_LLIST_NEXT (*unmoved)) |
1932 ; | |
1933 | |
1934 /* If we are the first unmoved element, nothing to relink. */ | |
1935 if (unmoved != mover) | |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1936 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1937 /* Remember 'mover's current successor, so we can relink 'mover's |
4385 | 1938 predecessor to it. */ |
1939 str_llist_elt_type *before_mover; | |
1940 str_llist_elt_type *after_mover = STR_LLIST_NEXT (*mover); | |
4391 | 1941 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1942 /* Find 'mover's predecessor. */ |
4385 | 1943 for (before_mover = unmoved; STR_LLIST_NEXT (*before_mover) != mover; |
1944 before_mover = STR_LLIST_NEXT (*before_mover)) | |
1945 ; | |
4391 | 1946 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1947 /* 'before_mover' now links to 'after_mover'. */ |
4385 | 1948 STR_LLIST_NEXT (*before_mover) = after_mover; |
1949 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1950 /* Insert 'mover' before 'unmoved' and after 'last_moved' (or at |
4385 | 1951 the head of the list). */ |
1952 STR_LLIST_NEXT (*mover) = unmoved; | |
4391 | 1953 if (! last_moved) |
4385 | 1954 *l = mover; |
1955 else | |
1956 STR_LLIST_NEXT (*last_moved) = mover; | |
1957 } | |
1958 | |
1959 /* We've moved it. */ | |
1960 STR_LLIST_MOVED (*mover) = 1; | |
1961 } | |
1962 | |
4399 | 1963 /* Variable expansion. */ |
4385 | 1964 |
1965 /* We have to keep track of variables being expanded, otherwise | |
1966 constructs like TEXINPUTS = $TEXINPUTS result in an infinite loop. | |
1967 (Or indirectly recursive variables, etc.) Our simple solution is to | |
1968 add to a list each time an expansion is started, and check the list | |
1969 before expanding. */ | |
1970 | |
4391 | 1971 static std::map <std::string, bool> expansions; |
4385 | 1972 |
1973 static void | |
4391 | 1974 expanding (const std::string& var, bool xp) |
4385 | 1975 { |
4391 | 1976 expansions[var] = xp; |
4385 | 1977 } |
1978 | |
1979 /* Return whether VAR is currently being expanding. */ | |
1980 | |
4391 | 1981 static bool |
1982 expanding_p (const std::string& var) | |
4385 | 1983 { |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1984 return (expansions.find (var) != expansions.end ()) ? expansions[var] : false; |
4385 | 1985 } |
4392 | 1986 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1987 /* Append the result of value of 'var' to EXPANSION, where 'var' begins |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1988 at START and ends at END. If 'var' is not set, do not complain. |
4385 | 1989 This is a subroutine for the more complicated expansion function. */ |
1990 | |
1991 static void | |
4391 | 1992 expand (std::string &expansion, const std::string& var) |
4385 | 1993 { |
4391 | 1994 if (expanding_p (var)) |
1995 { | |
19410
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1996 (*current_liboctave_warning_with_id_handler) |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1997 ("Octave:pathsearch-syntax", |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1998 "kpathsea: variable '%s' references itself (eventually)", |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1999 var.c_str ()); |
4385 | 2000 } |
4391 | 2001 else |
2002 { | |
2003 /* Check for an environment variable. */ | |
21732
6a1eded90355
use namespace for system env class
John W. Eaton <jwe@octave.org>
parents:
21729
diff
changeset
|
2004 std::string value = octave::sys::env::getenv (var); |
4391 | 2005 |
2006 if (! value.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2007 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2008 expanding (var, true); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2009 std::string tmp = kpse_var_expand (value); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2010 expanding (var, false); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2011 expansion += tmp; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2012 } |
4391 | 2013 } |
4385 | 2014 } |
4392 | 2015 |
4385 | 2016 /* Can't think of when it would be useful to change these (and the |
2017 diagnostic messages assume them), but ... */ | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
2018 #if ! defined (IS_VAR_START) |
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
2019 /* starts all variable references */ |
4385 | 2020 #define IS_VAR_START(c) ((c) == '$') |
2021 #endif | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
2022 #if ! defined (IS_VAR_CHAR) |
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
2023 /* variable name constituent */ |
4385 | 2024 #define IS_VAR_CHAR(c) (isalnum (c) || (c) == '_') |
2025 #endif | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
2026 #if ! defined (IS_VAR_BEGIN_DELIMITER) |
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
2027 /* start delimited variable name (after $) */ |
4385 | 2028 #define IS_VAR_BEGIN_DELIMITER(c) ((c) == '{') |
2029 #endif | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
2030 #if ! defined (IS_VAR_END_DELIMITER) |
4385 | 2031 #define IS_VAR_END_DELIMITER(c) ((c) == '}') |
2032 #endif | |
2033 | |
2034 /* Maybe we should support some or all of the various shell ${...} | |
2035 constructs, especially ${var-value}. */ | |
2036 | |
5085 | 2037 static std::string |
4391 | 2038 kpse_var_expand (const std::string& src) |
4385 | 2039 { |
4389 | 2040 std::string expansion; |
4391 | 2041 |
2042 size_t src_len = src.length (); | |
2043 | |
4385 | 2044 /* Copy everything but variable constructs. */ |
4391 | 2045 for (size_t i = 0; i < src_len; i++) |
2046 { | |
2047 if (IS_VAR_START (src[i])) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2048 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2049 i++; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2050 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
2051 /* Three cases: '$VAR', '${VAR}', '$<anything-else>'. */ |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2052 if (IS_VAR_CHAR (src[i])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2053 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2054 /* $V: collect name constituents, then expand. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2055 size_t var_end = i; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2056 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2057 do |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2058 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2059 var_end++; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2060 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2061 while (IS_VAR_CHAR (src[var_end])); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2062 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2063 var_end--; /* had to go one past */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2064 expand (expansion, src.substr (i, var_end - i + 1)); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2065 i = var_end; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2066 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2067 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2068 else if (IS_VAR_BEGIN_DELIMITER (src[i])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2069 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2070 /* ${: scan ahead for matching delimiter, then expand. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2071 size_t var_end = ++i; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2072 |
20955
77f5591878bf
maint: Use '! expr' rather than '!expr' to conform to coding guidelines.
Rik <rik@octave.org>
parents:
20791
diff
changeset
|
2073 while (var_end < src_len && ! IS_VAR_END_DELIMITER (src[var_end])) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2074 var_end++; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2075 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2076 if (var_end == src_len) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2077 { |
19410
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
2078 (*current_liboctave_warning_with_id_handler) |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
2079 ("Octave:pathsearch-syntax", |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
2080 "%s: No matching } for ${", src.c_str ()); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2081 i = var_end - 1; /* will incr to eos at top of loop */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2082 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2083 else |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2084 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2085 expand (expansion, src.substr (i, var_end - i)); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2086 i = var_end; /* will incr past } at top of loop*/ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2087 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2088 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2089 else |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2090 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2091 /* $<something-else>: error. */ |
19410
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
2092 (*current_liboctave_warning_with_id_handler) |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
2093 ("Octave:pathsearch-syntax", |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
2094 "%s: Unrecognized variable construct '$%c'", |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2095 src.c_str (), src[i]); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2096 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2097 /* Just ignore those chars and keep going. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2098 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2099 } |
4391 | 2100 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2101 expansion += src[i]; |
4391 | 2102 } |
4389 | 2103 |
2104 return expansion; | |
4385 | 2105 } |