Mercurial > octave
annotate liboctave/util/kpse.cc @ 21873:40195d04b17c
still more simplification of pathsearch
* kpse.cc (kpse_element_dir): Rename from kpse_element_dirs. Return
string instead of list of strings. Don't check cache.
(dir_search): Rename from dir_list_search. Search single directory
instead of list.
(match): Delete unused function.
(dir_list_add, checked_dir_list_add): Delete.
(cache_entry): Delete type.
(the_cache, cache_length, dirname;): Delete static variables.
(cache, cached): Delete.
(path_search, path_find_first_of, kpse_path_expand): Update.
* pathsearch.cc (directory_path::all_directories): Update.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sat, 11 Jun 2016 20:07:46 -0400 |
parents | adb0b3ac4b50 |
children | 7508f3a8e234 |
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 |
4389 | 233 static std::string kpse_var_expand (const std::string& src); |
4385 | 234 |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
235 static std::string kpse_element_dir (const std::string& elt); |
4399 | 236 |
237 static std::string kpse_expand (const std::string& s); | |
238 | |
239 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
|
240 const std::string& dflt); |
4399 | 241 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
242 #include <ctime> /* for 'time' */ |
4385 | 243 |
4399 | 244 static bool |
4394 | 245 kpse_is_env_sep (char c) |
246 { | |
247 return IS_ENV_SEP (c); | |
248 } | |
249 | |
4399 | 250 /* A way to step through a path, extracting one directory name at a |
251 time. */ | |
252 | |
253 class kpse_path_iterator | |
254 { | |
255 public: | |
256 | |
257 kpse_path_iterator (const std::string& p) | |
258 : path (p), b (0), e (0), len (path.length ()) { set_end (); } | |
259 | |
260 kpse_path_iterator (const kpse_path_iterator& pi) | |
261 : path (pi.path), b (pi.b), e (pi.e), len (pi.len) { } | |
262 | |
263 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
|
264 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
265 kpse_path_iterator retval (*this); |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
266 next (); |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
267 return retval; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
268 } |
4399 | 269 |
270 std::string operator * (void) { return path.substr (b, e-b); } | |
271 | |
272 bool operator != (const size_t sz) { return b != sz; } | |
273 | |
274 private: | |
275 | |
276 const std::string& path; | |
277 size_t b; | |
278 size_t e; | |
279 size_t len; | |
280 | |
281 void set_end (void) | |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
282 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
283 e = b + 1; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
284 |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
285 if (e == len) |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
286 ; /* 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
|
287 else if (e > len) |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
288 b = e = std::string::npos; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
289 else |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
290 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
291 /* 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
|
292 the path). */ |
20443
610c74748518
maint: Clean up code based on static analysis suggestions.
Rik <rik@octave.org>
parents:
20232
diff
changeset
|
293 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
|
294 e++; |
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 } |
4399 | 297 |
298 void next (void) | |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
299 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
300 b = e + 1; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
301 |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
302 /* Skip any consecutive colons. */ |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
303 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
|
304 b++; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
305 |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
306 if (b >= len) |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
307 b = e = std::string::npos; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
308 else |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
309 set_end (); |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
310 } |
5617 | 311 |
312 // No assignment. | |
313 kpse_path_iterator& operator = (const kpse_path_iterator&); | |
4399 | 314 }; |
315 | |
4391 | 316 /* Truncate any too-long components in NAME, returning the result. It's |
317 too bad this is necessary. See comments in readable.c for why. */ | |
318 | |
4393 | 319 static std::string |
320 kpse_truncate_filename (const std::string& name) | |
4391 | 321 { |
322 unsigned c_len = 0; /* Length of current component. */ | |
323 unsigned ret_len = 0; /* Length of constructed result. */ | |
324 | |
4393 | 325 std::string ret = name; |
326 | |
327 size_t len = name.length (); | |
328 | |
329 for (size_t i = 0; i < len; i++) | |
4391 | 330 { |
4393 | 331 if (IS_DIR_SEP (name[i]) || IS_DEVICE_SEP (name[i])) |
4391 | 332 { |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
333 /* At a directory delimiter, reset component length. */ |
4391 | 334 c_len = 0; |
335 } | |
336 else if (c_len > NAME_MAX) | |
337 { | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
338 /* If past the max for a component, ignore this character. */ |
4391 | 339 continue; |
340 } | |
341 | |
342 /* Copy this character. */ | |
4393 | 343 ret[ret_len++] = name[i]; |
4391 | 344 c_len++; |
345 } | |
346 | |
4393 | 347 ret.resize (ret_len); |
4391 | 348 |
349 return ret; | |
350 } | |
351 | |
352 /* If access can read FN, run stat (assigning to stat buffer ST) and | |
353 check that fn is not a directory. Don't check for just being a | |
354 regular file, as it is potentially useful to read fifo's or some | |
355 kinds of devices. */ | |
356 | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
357 #if defined (WIN32) |
4391 | 358 static inline bool |
21865 | 359 READABLE (const std::string& fn) |
4391 | 360 { |
4393 | 361 const char *t = fn.c_str (); |
362 return (GetFileAttributes (t) != 0xFFFFFFFF | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
363 && ! (GetFileAttributes (t) & FILE_ATTRIBUTE_DIRECTORY)); |
4391 | 364 } |
365 #else | |
366 static inline bool | |
21865 | 367 READABLE (const std::string& fn) |
4391 | 368 { |
21865 | 369 bool retval = false; |
370 | |
4393 | 371 const char *t = fn.c_str (); |
21865 | 372 |
373 if (access (t, R_OK) == 0) | |
374 { | |
375 octave::sys::file_stat fs (fn); | |
376 | |
377 retval = fs && ! fs.is_dir (); | |
378 } | |
379 | |
380 return retval; | |
4391 | 381 } |
382 #endif | |
383 | |
384 /* POSIX invented the brain-damage of not necessarily truncating | |
385 filename components; the system's behavior is defined by the value of | |
386 the symbol _POSIX_NO_TRUNC, but you can't change it dynamically! | |
387 | |
388 Generic const return warning. See extend-fname.c. */ | |
389 | |
4393 | 390 static std::string |
391 kpse_readable_file (const std::string& name) | |
4391 | 392 { |
4393 | 393 std::string ret; |
4391 | 394 |
21865 | 395 if (READABLE (name)) |
4391 | 396 { |
4393 | 397 ret = name; |
4391 | 398 |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
399 #if defined (ENAMETOOLONG) |
4391 | 400 } |
401 else if (errno == ENAMETOOLONG) | |
402 { | |
403 ret = kpse_truncate_filename (name); | |
404 | |
405 /* 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
|
406 so let's call access again. */ |
4391 | 407 |
21865 | 408 if (! READABLE (ret)) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
409 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
410 /* Failed. */ |
21017
93748bcaec17
maint: Replace emtpy 'std::string ()' calls with "".
Rik <rik@octave.org>
parents:
20955
diff
changeset
|
411 ret = ""; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
412 } |
4391 | 413 #endif /* ENAMETOOLONG */ |
414 | |
415 } | |
416 else | |
417 { | |
418 /* Some other error. */ | |
419 if (errno == EACCES) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
420 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
421 /* Maybe warn them if permissions are bad. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
422 perror (name.c_str ()); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
423 } |
4393 | 424 |
21017
93748bcaec17
maint: Replace emtpy 'std::string ()' calls with "".
Rik <rik@octave.org>
parents:
20955
diff
changeset
|
425 ret = ""; |
4391 | 426 } |
427 | |
428 return ret; | |
429 } | |
430 | |
431 static bool | |
432 kpse_absolute_p (const std::string& filename, int relative_ok) | |
433 { | |
21865 | 434 return (octave::sys::env::absolute_pathname (filename) |
435 || (relative_ok | |
436 && octave::sys::env::rooted_relative_pathname (filename))); | |
4391 | 437 } |
438 | |
4378 | 439 /* The very first search is for texmf.cnf, called when someone tries to |
440 initialize the TFM path or whatever. init_path calls kpse_cnf_get | |
441 which calls kpse_all_path_search to find all the texmf.cnf's. We | |
442 need to do various special things in this case, since we obviously | |
443 don't yet have the configuration files when we're searching for the | |
444 configuration files. */ | |
445 static bool first_search = true; | |
446 | |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
447 /* This function is called after every search. */ |
4378 | 448 |
449 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
|
450 log_search (const std::list<std::string>& filenames) |
4378 | 451 { |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
452 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) |
4391 | 453 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
454 for (const auto &filename : filenames) |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
455 std::cerr << time (0) << " " << filename << std::endl; |
4378 | 456 } |
457 } | |
4392 | 458 |
4378 | 459 /* Concatenate each element in DIRS with NAME (assume each ends with a |
460 /, to save time). If SEARCH_ALL is false, return the first readable | |
461 regular file. Else continue to search for more. In any case, if | |
462 none, return a list containing just NULL. | |
463 | |
464 We keep a single buffer for the potential filenames and reallocate | |
465 only when necessary. I'm not sure it's noticeably faster, but it | |
466 does seem cleaner. (We do waste a bit of space in the return | |
467 value, though, since we don't shrink it to the final size returned.) */ | |
468 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
469 static std::list<std::string> |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
470 dir_search (const std::string& dir, const std::string& name, |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
471 bool search_all) |
4378 | 472 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
473 std::list<std::string> ret; |
4378 | 474 |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
475 std::string potential = dir + name; |
4393 | 476 |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
477 std::string tmp = kpse_readable_file (potential); |
4393 | 478 |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
479 if (! tmp.empty ()) |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
480 { |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
481 ret.push_back (potential); |
4391 | 482 |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
483 if (! search_all) |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
484 return ret; |
4378 | 485 } |
4391 | 486 |
4378 | 487 return ret; |
488 } | |
4392 | 489 |
4378 | 490 /* This is called when NAME is absolute or explicitly relative; if it's |
491 readable, return (a list containing) it; otherwise, return NULL. */ | |
492 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
493 static std::list<std::string> |
4393 | 494 absolute_search (const std::string& name) |
4378 | 495 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
496 std::list<std::string> ret_list; |
4393 | 497 std::string found = kpse_readable_file (name); |
4391 | 498 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
499 /* Add 'found' to the return list even if it's null; that tells |
4378 | 500 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
|
501 ret_list.push_back (found); |
4391 | 502 |
4378 | 503 return ret_list; |
504 } | |
4392 | 505 |
4378 | 506 /* This is the hard case -- look for NAME in PATH. If ALL is false, |
507 return the first file found. Otherwise, search all elements of PATH. */ | |
508 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
509 static std::list<std::string> |
4394 | 510 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
|
511 bool /* must_exist */, bool all) |
4378 | 512 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
513 std::list<std::string> ret_list; |
4378 | 514 bool done = false; |
4390 | 515 |
8021 | 516 for (kpse_path_iterator pi (path); ! done && pi != std::string::npos; pi++) |
4390 | 517 { |
4394 | 518 std::string elt = *pi; |
519 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
520 std::list<std::string> found; |
4390 | 521 |
522 /* Do not touch the device if present */ | |
523 if (NAME_BEGINS_WITH_DEVICE (elt)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
524 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
525 while (elt.length () > 3 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
526 && 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
|
527 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
528 elt[2] = elt[1]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
529 elt[1] = elt[0]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
530 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
531 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
532 } |
4390 | 533 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
534 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
535 /* We never want to search the whole disk. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
536 while (elt.length () > 1 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
537 && 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
|
538 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
539 } |
4391 | 540 |
21872 | 541 /* Our caller (search), also tests first_search, and does |
542 the resetting. */ | |
21865 | 543 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
|
544 found = std::list<std::string> (); |
21865 | 545 |
546 /* Search the filesystem. */ | |
547 | |
548 if (found.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
549 { |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
550 std::string dir = kpse_element_dir (elt); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
551 |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
552 if (! dir.empty ()) |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
553 found = dir_search (dir, name, all); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
554 } |
4390 | 555 |
556 /* Did we find anything anywhere? */ | |
557 if (! found.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
558 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
559 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
|
560 ret_list.splice (ret_list.end (), found); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
561 else |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
562 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
563 ret_list.push_back (found.front ()); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
564 done = true; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
565 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
566 } |
4378 | 567 } |
568 | |
569 return ret_list; | |
4390 | 570 } |
4392 | 571 |
4378 | 572 /* Search PATH for ORIGINAL_NAME. If ALL is false, or ORIGINAL_NAME is |
573 absolute_p, check ORIGINAL_NAME itself. Otherwise, look at each | |
574 element of PATH for the first readable ORIGINAL_NAME. | |
4391 | 575 |
4378 | 576 Always return a list; if no files are found, the list will |
577 contain just NULL. If ALL is true, the list will be | |
578 terminated with NULL. */ | |
579 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
580 static std::list<std::string> |
4390 | 581 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
|
582 bool must_exist, bool all) |
4378 | 583 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
584 std::list<std::string> ret_list; |
4378 | 585 bool absolute_p; |
586 | |
587 /* Make a leading ~ count as an absolute filename, and expand $FOO's. */ | |
4390 | 588 std::string name = kpse_expand (original_name); |
4391 | 589 |
4378 | 590 /* If the first name is absolute or explicitly relative, no need to |
591 consider PATH at all. */ | |
592 absolute_p = kpse_absolute_p (name, true); | |
4391 | 593 |
4378 | 594 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
|
595 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
|
596 << ", must_exist=" << must_exist |
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
597 << ", find_all=" << all << ", path=" << path << ")." |
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
598 << std::endl; |
4378 | 599 |
600 /* Find the file(s). */ | |
601 ret_list = absolute_p ? absolute_search (name) | |
602 : path_search (path, name, must_exist, all); | |
4391 | 603 |
4378 | 604 /* The very first search is for texmf.cnf. We can't log that, since |
605 we want to allow setting TEXMFLOG in texmf.cnf. */ | |
4391 | 606 if (first_search) |
607 { | |
608 first_search = false; | |
609 } | |
610 else | |
611 { | |
612 /* 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
|
613 debugging line if we're doing that. */ |
4391 | 614 |
615 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
|
616 std::cerr << "kdebug: search (" << original_name << ") =>"; |
4391 | 617 |
618 log_search (ret_list); | |
619 | |
620 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
|
621 std::cerr << std::endl; |
4391 | 622 } |
4378 | 623 |
4390 | 624 return ret_list; |
4378 | 625 } |
4392 | 626 |
4378 | 627 /* Search PATH for the first NAME. */ |
628 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
629 /* Call 'kpse_expand' on NAME. If the result is an absolute or |
4399 | 630 explicitly relative filename, check whether it is a readable |
631 (regular) file. | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11501
diff
changeset
|
632 |
4399 | 633 Otherwise, look in each of the directories specified in PATH (also do |
21865 | 634 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
|
635 |
21751
b571fc85953f
maint: Use two spaces after period to indicate sentence break.
Rik <rik@octave.org>
parents:
21732
diff
changeset
|
636 The caller must expand PATH. This is because it makes more sense to |
4399 | 637 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
|
638 |
4399 | 639 In any case, return the complete filename if found, otherwise NULL. */ |
640 | |
641 static std::string | |
4390 | 642 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
|
643 bool must_exist) |
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 = 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
|
646 |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
647 return ret_list.empty () ? "" : ret_list.front (); |
4378 | 648 } |
649 | |
650 /* 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
|
651 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
|
652 |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
653 /* Like 'kpse_path_search' with MUST_EXIST true, but return a list of |
4399 | 654 all the filenames (or NULL if none), instead of taking the first. */ |
655 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
656 static std::list<std::string> |
4390 | 657 kpse_all_path_search (const std::string& path, const std::string& name) |
4378 | 658 { |
4390 | 659 return search (path, name, true, true); |
4378 | 660 } |
4392 | 661 |
4378 | 662 /* This is the hard case -- look in each element of PATH for each |
663 element of NAMES. If ALL is false, return the first file found. | |
664 Otherwise, search all elements of PATH. */ | |
665 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
666 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
|
667 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
|
668 const std::list<std::string>& names, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
669 bool /* must_exist */, bool all) |
4378 | 670 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
671 std::list<std::string> ret_list; |
4378 | 672 bool done = false; |
4390 | 673 |
8021 | 674 for (kpse_path_iterator pi (path); ! done && pi != std::string::npos; pi++) |
4378 | 675 { |
4394 | 676 std::string elt = *pi; |
677 | |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
678 std::string dir; |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
679 std::list<std::string> found; |
4378 | 680 |
681 /* Do not touch the device if present */ | |
682 | |
683 if (NAME_BEGINS_WITH_DEVICE (elt)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
684 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
685 while (elt.length () > 3 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
686 && 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
|
687 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
688 elt[2] = elt[1]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
689 elt[1] = elt[0]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
690 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
691 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
692 } |
4378 | 693 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
694 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
695 /* We never want to search the whole disk. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
696 while (elt.length () > 1 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
697 && 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
|
698 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
699 } |
4378 | 700 |
701 /* We have to search one directory at a time. */ | |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
702 dir = kpse_element_dir (elt); |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
703 |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
704 if (! dir.empty ()) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
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 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
|
707 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
708 std::string name = *it; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
709 |
21872 | 710 /* Our caller (find_first_of), also tests first_search, |
711 and does the resetting. */ | |
21865 | 712 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
|
713 found = std::list<std::string> (); |
21865 | 714 |
715 /* Search the filesystem. */ | |
716 | |
717 if (found.empty ()) | |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
718 found = dir_search (dir, name, all); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
719 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
720 /* Did we find anything anywhere? */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
721 if (! found.empty ()) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
722 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
723 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
|
724 ret_list.splice (ret_list.end (), found); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
725 else |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
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 ret_list.push_back (found.front ()); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
728 done = true; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
729 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
730 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
731 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
732 } |
4378 | 733 } |
734 | |
735 return ret_list; | |
4391 | 736 } |
4378 | 737 |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
738 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
|
739 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
|
740 bool must_exist, bool all) |
4378 | 741 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
742 std::list<std::string> ret_list; |
4378 | 743 |
744 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) | |
745 { | |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
746 std::cerr << "kdebug: start find_first_of (("; |
4391 | 747 |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
748 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
|
749 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
750 if (p == names.cbegin ()) |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
751 std::cerr << *p; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
752 else |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
753 std::cerr << ", " << *p; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
754 } |
4391 | 755 |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
756 std::cerr << "), path=" << path << ", must_exist=" |
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
757 << must_exist << "." << std::endl; |
4378 | 758 } |
759 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
760 for (const auto &name : names) |
4409 | 761 { |
762 if (kpse_absolute_p (name, true)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
763 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
764 /* 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
|
765 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
|
766 are done. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
767 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
768 ret_list = absolute_search (name); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
769 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
770 if (! ret_list.empty ()) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
771 return ret_list; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
772 } |
4409 | 773 } |
774 | |
4378 | 775 /* Find the file. */ |
776 ret_list = path_find_first_of (path, names, must_exist, all); | |
777 | |
778 /* The very first search is for texmf.cnf. We can't log that, since | |
779 we want to allow setting TEXMFLOG in texmf.cnf. */ | |
4391 | 780 if (first_search) |
781 { | |
782 first_search = false; | |
783 } | |
784 else | |
785 { | |
786 /* 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
|
787 debugging line if we're doing that. */ |
4391 | 788 |
789 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
790 { |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
791 std::cerr << "kdebug: find_first_of ("; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
792 |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
793 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
|
794 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
795 if (p == names.cbegin ()) |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
796 std:: cerr << *p; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
797 else |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
798 std::cerr << ", " << *p; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
799 } |
10411 | 800 |
21868
e2796ea8feac
* kpse.cc: Use iostream for debug messages.
John W. Eaton <jwe@octave.org>
parents:
21867
diff
changeset
|
801 std::cerr << ") =>"; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
802 } |
4391 | 803 |
804 log_search (ret_list); | |
805 | |
806 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) | |
10411 | 807 gnulib::putc ('\n', stderr); |
4391 | 808 } |
4378 | 809 |
4390 | 810 return ret_list; |
4378 | 811 } |
812 | |
813 /* Search each element of PATH for each element of NAMES. Return the | |
814 first one found. */ | |
815 | |
4399 | 816 /* Search each element of PATH for each element in the list of NAMES. |
817 Return the first one found. */ | |
818 | |
819 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
|
820 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
|
821 const std::list<std::string>& names, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
822 bool must_exist) |
4378 | 823 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
824 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
|
825 = 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
|
826 |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
827 return ret_list.empty () ? "" : ret_list.front (); |
4378 | 828 } |
829 | |
830 /* Search each element of PATH for each element of NAMES and return a | |
831 list containing everything found, in the order found. */ | |
832 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
833 /* Like 'kpse_path_find_first_of' with MUST_EXIST true, but return a |
4399 | 834 list of all the filenames (or NULL if none), instead of taking the |
835 first. */ | |
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 static std::list<std::string> |
4390 | 838 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
|
839 const std::list<std::string>& names) |
4378 | 840 { |
4390 | 841 return find_first_of (path, names, true, true); |
4378 | 842 } |
843 | |
4399 | 844 /* General expansion. Some of this file (the brace-expansion |
4378 | 845 code from bash) is covered by the GPL; this is the only GPL-covered |
846 code in kpathsea. The part of the file that I wrote (the first | |
847 couple of functions) is covered by the LGPL. */ | |
848 | |
849 /* If NAME has a leading ~ or ~user, Unix-style, expand it to the user's | |
850 home directory, and return a new malloced string. If no ~, or no | |
851 <pwd.h>, just return NAME. */ | |
852 | |
4389 | 853 static std::string |
854 kpse_tilde_expand (const std::string& name) | |
4378 | 855 { |
4389 | 856 std::string expansion; |
4391 | 857 |
4378 | 858 /* If no leading tilde, do nothing. */ |
5137 | 859 if (name.empty () || name[0] != '~') |
4391 | 860 { |
861 expansion = name; | |
862 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
863 /* 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
|
864 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
|
865 ... */ |
4391 | 866 } |
867 else if (name.length () == 1) | |
868 { | |
21732
6a1eded90355
use namespace for system env class
John W. Eaton <jwe@octave.org>
parents:
21729
diff
changeset
|
869 expansion = octave::sys::env::get_home_directory (); |
4391 | 870 |
871 if (expansion.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
872 expansion = "."; |
4391 | 873 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
874 /* 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
|
875 Should really check for doubled intermediate slashes, too. */ |
4378 | 876 } |
4391 | 877 else if (IS_DIR_SEP (name[1])) |
878 { | |
879 unsigned c = 1; | |
21732
6a1eded90355
use namespace for system env class
John W. Eaton <jwe@octave.org>
parents:
21729
diff
changeset
|
880 std::string home = octave::sys::env::get_home_directory (); |
4391 | 881 |
882 if (home.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
883 home = "."; |
4391 | 884 |
885 size_t home_len = home.length (); | |
886 | |
887 /* handle leading // */ | |
888 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
|
889 home = home.substr (1); |
4391 | 890 |
891 /* omit / after ~ */ | |
892 if (IS_DIR_SEP (home[home_len - 1])) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
893 c++; |
4391 | 894 |
895 expansion = home + name.substr (c); | |
896 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
897 /* 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
|
898 OS/2 doesn't have this concept. */ |
4378 | 899 } |
4391 | 900 else |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
901 #if defined (HAVE_PWD_H) |
4378 | 902 { |
903 unsigned c = 2; | |
4391 | 904 |
905 /* find user name */ | |
906 while (name.length () > c && ! IS_DIR_SEP (name[c])) | |
4378 | 907 c++; |
4391 | 908 |
909 std::string user = name.substr (1, c-1); | |
910 | |
4378 | 911 /* 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
|
912 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
|
913 octave::sys::password p = octave::sys::password::getpwnam (user); |
4378 | 914 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
915 /* If no such user, just use '.'. */ |
4391 | 916 std::string home = p ? p.dir () : std::string ("."); |
917 | |
918 if (home.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
919 home = "."; |
4391 | 920 |
921 /* handle leading // */ | |
922 if (home.length () > 1 && IS_DIR_SEP (home[0]) && IS_DIR_SEP (home[1])) | |
923 home = home.substr (1); | |
924 | |
925 /* If HOME ends in /, omit the / after ~user. */ | |
926 if (name.length () > c && IS_DIR_SEP (home[home.length () - 1])) | |
927 c++; | |
928 | |
929 expansion = name.length () > c ? home : home + name.substr (c); | |
4378 | 930 } |
931 #else /* not HAVE_PWD_H */ | |
4391 | 932 expansion = name; |
4378 | 933 #endif /* not HAVE_PWD_H */ |
934 | |
4389 | 935 return expansion; |
4378 | 936 } |
937 | |
938 /* Do variable expansion first so ~${USER} works. (Besides, it's what the | |
939 shells do.) */ | |
940 | |
4399 | 941 /* Call kpse_var_expand and kpse_tilde_expand (in that order). Result |
942 is always in fresh memory, even if no expansions were done. */ | |
943 | |
944 static std::string | |
4389 | 945 kpse_expand (const std::string& s) |
4378 | 946 { |
4389 | 947 std::string var_expansion = kpse_var_expand (s); |
948 return kpse_tilde_expand (var_expansion); | |
4378 | 949 } |
950 | |
951 /* 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
|
952 static std::list<std::string> brace_expand (const std::string&); |
4378 | 953 |
954 /* If $KPSE_DOT is defined in the environment, prepend it to any relative | |
955 path components. */ | |
956 | |
4389 | 957 static std::string |
958 kpse_expand_kpse_dot (const std::string& path) | |
4378 | 959 { |
4389 | 960 std::string ret; |
21732
6a1eded90355
use namespace for system env class
John W. Eaton <jwe@octave.org>
parents:
21729
diff
changeset
|
961 std::string kpse_dot = octave::sys::env::getenv ("KPSE_DOT"); |
4391 | 962 |
963 if (kpse_dot.empty ()) | |
4378 | 964 return path; |
965 | |
8021 | 966 for (kpse_path_iterator pi (path); pi != std::string::npos; pi++) |
4391 | 967 { |
4394 | 968 std::string elt = *pi; |
969 | |
21872 | 970 /* Single "." get special treatment, as does "./" or its equivalent. */ |
4391 | 971 |
4394 | 972 size_t elt_len = elt.length (); |
973 | |
21872 | 974 if (kpse_absolute_p (elt, false)) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
975 ret += elt + ENV_SEP_STRING; |
4394 | 976 else if (elt_len == 1 && elt[0] == '.') |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
977 ret += kpse_dot + ENV_SEP_STRING; |
4394 | 978 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
|
979 ret += kpse_dot + elt.substr (1) + ENV_SEP_STRING; |
4391 | 980 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
981 ret += kpse_dot + DIR_SEP_STRING + elt + ENV_SEP_STRING; |
4378 | 982 } |
983 | |
4389 | 984 int len = ret.length (); |
985 if (len > 0) | |
4395 | 986 ret.resize (len-1); |
4389 | 987 |
4378 | 988 return ret; |
989 } | |
990 | |
991 /* Do brace expansion on ELT; then do variable and ~ expansion on each | |
992 element of the result; then do brace expansion again, in case a | |
993 variable definition contained braces (e.g., $TEXMF). Return a | |
994 string comprising all of the results separated by ENV_SEP_STRING. */ | |
995 | |
4389 | 996 static std::string |
4394 | 997 kpse_brace_expand_element (const std::string& elt) |
4378 | 998 { |
4389 | 999 std::string ret; |
4378 | 1000 |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1001 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
|
1002 |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1003 for (const auto &expanded_elt : expansions) |
4391 | 1004 { |
1005 /* 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
|
1006 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
|
1007 |
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1008 if (x != elt) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1009 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1010 /* 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
|
1011 recursive variable definitions are not allowed, this recursion |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1012 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
|
1013 more than one level of recursion.) */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1014 x = kpse_brace_expand_element (x); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1015 } |
4391 | 1016 |
1017 ret += x + ENV_SEP_STRING; | |
4378 | 1018 } |
1019 | |
4389 | 1020 ret.resize (ret.length () - 1); |
4391 | 1021 |
4378 | 1022 return ret; |
1023 } | |
1024 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1025 /* Do brace expansion and call 'kpse_expand' on each element of the |
4399 | 1026 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
|
1027 no expansions were done). We don't call 'kpse_expand_default' |
4399 | 1028 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
|
1029 'kpse_init_format'. */ |
4399 | 1030 |
1031 static std::string | |
4397 | 1032 kpse_brace_expand (const std::string& path) |
4378 | 1033 { |
1034 /* Must do variable expansion first because if we have | |
1035 foo = .:~ | |
1036 TEXINPUTS = $foo | |
1037 we want to end up with TEXINPUTS = .:/home/karl. | |
1038 Since kpse_path_element is not reentrant, we must get all | |
1039 the path elements before we start the loop. */ | |
4389 | 1040 std::string tmp = kpse_var_expand (path); |
4394 | 1041 |
4389 | 1042 std::string ret; |
4378 | 1043 |
8021 | 1044 for (kpse_path_iterator pi (tmp); pi != std::string::npos; pi++) |
4391 | 1045 { |
4394 | 1046 std::string elt = *pi; |
1047 | |
4391 | 1048 /* Do brace expansion first, so tilde expansion happens in {~ka,~kb}. */ |
1049 std::string expansion = kpse_brace_expand_element (elt); | |
1050 ret += expansion + ENV_SEP_STRING; | |
1051 } | |
4378 | 1052 |
4394 | 1053 size_t len = ret.length (); |
4389 | 1054 if (len > 0) |
4395 | 1055 ret.resize (len-1); |
4389 | 1056 |
1057 return kpse_expand_kpse_dot (ret); | |
4378 | 1058 } |
4392 | 1059 |
4378 | 1060 /* Expand all special constructs in a path, and include only the actually |
1061 existing directories in the result. */ | |
4399 | 1062 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1063 /* Do brace expansion and call 'kpse_expand' on each argument of the |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1064 result. The final expansion (always in fresh memory) is a path of |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1065 all the existing directories that match the pattern. */ |
4399 | 1066 |
1067 static std::string | |
4397 | 1068 kpse_path_expand (const std::string& path) |
4378 | 1069 { |
4392 | 1070 std::string ret; |
4378 | 1071 unsigned len; |
1072 | |
1073 len = 0; | |
4391 | 1074 |
4378 | 1075 /* Expand variables and braces first. */ |
4389 | 1076 std::string tmp = kpse_brace_expand (path); |
4392 | 1077 |
4378 | 1078 /* Now expand each of the path elements, printing the results */ |
8021 | 1079 for (kpse_path_iterator pi (tmp); pi != std::string::npos; pi++) |
4391 | 1080 { |
4394 | 1081 std::string elt = *pi; |
1082 | |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1083 std::string dir; |
4391 | 1084 |
1085 /* Do not touch the device if present */ | |
1086 if (NAME_BEGINS_WITH_DEVICE (elt)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1087 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1088 while (elt.length () > 3 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1089 && 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
|
1090 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1091 elt[2] = elt[1]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1092 elt[1] = elt[0]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1093 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1094 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1095 } |
4391 | 1096 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1097 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1098 /* We never want to search the whole disk. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1099 while (elt.length () > 1 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1100 && 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
|
1101 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1102 } |
4378 | 1103 |
4394 | 1104 /* 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
|
1105 Be faster to check the database, but this is more reliable. */ |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1106 dir = kpse_element_dir (elt); |
4394 | 1107 |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1108 size_t dirlen = dir.length (); |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1109 |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1110 if (dirlen > 0) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1111 { |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1112 ret += dir; |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1113 len += dirlen; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1114 |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1115 /* Retain trailing slash if that's the root directory. */ |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1116 if (dirlen == 1 |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1117 || (dirlen == 3 && NAME_BEGINS_WITH_DEVICE (dir) |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1118 && IS_DIR_SEP (dir[2]))) |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1119 { |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1120 ret += ENV_SEP_STRING; |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1121 len++; |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1122 } |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1123 |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1124 ret[len-1] = ENV_SEP; |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1125 } |
4378 | 1126 } |
4391 | 1127 |
4395 | 1128 if (len > 0) |
1129 ret.resize (len-1); | |
4391 | 1130 |
4378 | 1131 return ret; |
1132 } | |
4392 | 1133 |
21751
b571fc85953f
maint: Use two spaces after period to indicate sentence break.
Rik <rik@octave.org>
parents:
21732
diff
changeset
|
1134 /* braces.c -- code for doing word expansion in curly braces. Taken from |
16768 | 1135 bash 1.14.5. [And subsequently modified for kpatshea.] |
1136 | |
1137 Copyright (C) 1987,1991 Free Software Foundation, Inc. */ | |
4378 | 1138 |
4391 | 1139 #define brace_whitespace(c) (! (c) || (c) == ' ' || (c) == '\t' || (c) == '\n') |
4378 | 1140 |
1141 /* Basic idea: | |
1142 | |
1143 Segregate the text into 3 sections: preamble (stuff before an open brace), | |
1144 postamble (stuff after the matching close brace) and amble (stuff after | |
1145 preamble, and before postamble). Expand amble, and then tack on the | |
1146 expansions to preamble. Expand postamble, and tack on the expansions to | |
4391 | 1147 the result so far. */ |
4378 | 1148 |
4397 | 1149 /* Return a new array of strings which is the result of appending each |
1150 string in ARR2 to each string in ARR1. The resultant array is | |
1151 len (arr1) * len (arr2) long. For convenience, ARR1 (and its contents) | |
1152 are free ()'ed. ARR1 can be NULL, in that case, a new version of ARR2 | |
1153 is returned. */ | |
1154 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1155 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
|
1156 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
|
1157 const std::list<std::string>& arr2) |
4378 | 1158 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1159 std::list<std::string> result; |
4397 | 1160 |
1161 if (arr1.empty ()) | |
1162 result = arr2; | |
1163 else if (arr2.empty ()) | |
1164 result = arr1; | |
1165 else | |
1166 { | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1167 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
|
1168 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
|
1169 result.push_back (elt_1 + elt_2); |
4397 | 1170 } |
1171 | |
1172 return result; | |
4378 | 1173 } |
1174 | |
4397 | 1175 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
|
1176 static std::list<std::string> expand_amble (const std::string&); |
4378 | 1177 |
1178 /* 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
|
1179 static std::list<std::string> |
4397 | 1180 brace_expand (const std::string& text) |
4378 | 1181 { |
1182 /* Find the text of the preamble. */ | |
4397 | 1183 int i = 0; |
1184 int c = brace_gobbler (text, i, '{'); | |
1185 | |
1186 std::string preamble = text.substr (0, i); | |
1187 | |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1188 std::list<std::string> result (1, preamble); |
4397 | 1189 |
1190 if (c == '{') | |
4378 | 1191 { |
4397 | 1192 /* Find the amble. This is the stuff inside this set of braces. */ |
1193 int start = ++i; | |
1194 c = brace_gobbler (text, i, '}'); | |
1195 | |
1196 /* What if there isn't a matching close brace? */ | |
1197 if (! c) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1198 { |
19410
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1199 (*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
|
1200 ("Octave:pathsearch-syntax", |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1201 "%s: Unmatched {", text.c_str ()); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1202 |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1203 result = std::list<std::string> (1, text); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1204 } |
4397 | 1205 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1206 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1207 std::string amble = text.substr (start, i-start); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1208 result = array_concat (result, expand_amble (amble)); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1209 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1210 std::string postamble = text.substr (i+1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1211 result = array_concat (result, brace_expand (postamble)); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1212 } |
4378 | 1213 } |
1214 | |
4397 | 1215 return result; |
4378 | 1216 } |
1217 | |
4397 | 1218 /* The character which is used to separate arguments. */ |
1219 static int brace_arg_separator = ','; | |
1220 | |
4378 | 1221 /* Expand the text found inside of braces. We simply try to split the |
1222 text at BRACE_ARG_SEPARATORs into separate strings. We then brace | |
1223 expand each slot which needs it, until there are no more slots which | |
1224 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
|
1225 static std::list<std::string> |
4397 | 1226 expand_amble (const std::string& text) |
4378 | 1227 { |
21867
0cdfd6d230e6
use std::list<std::string> instead of string_vector in pathsearch functions
John W. Eaton <jwe@octave.org>
parents:
21865
diff
changeset
|
1228 std::list<std::string> result; |
4397 | 1229 |
1230 size_t text_len = text.length (); | |
1231 size_t start; | |
1232 int i, c; | |
1233 | |
1234 for (start = 0, i = 0, c = 1; c && start < text_len; start = ++i) | |
4378 | 1235 { |
4397 | 1236 int i0 = i; |
1237 int c0 = brace_gobbler (text, i0, brace_arg_separator); | |
1238 int i1 = i; | |
1239 int c1 = brace_gobbler (text, i1, ENV_SEP); | |
4378 | 1240 c = c0 | c1; |
1241 i = (i0 < i1 ? i0 : i1); | |
1242 | |
4397 | 1243 std::string tem = text.substr (start, i-start); |
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 std::list<std::string> partial = brace_expand (tem); |
4397 | 1246 |
1247 if (result.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1248 result = partial; |
4378 | 1249 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
|
1250 result.splice (result.end (), partial); |
4378 | 1251 } |
4397 | 1252 |
1253 return result; | |
4378 | 1254 } |
1255 | |
21751
b571fc85953f
maint: Use two spaces after period to indicate sentence break.
Rik <rik@octave.org>
parents:
21732
diff
changeset
|
1256 /* Start at INDEX, and skip characters in TEXT. Set INDEX to the |
4378 | 1257 index of the character matching SATISFY. This understands about |
1258 quoting. Return the character that caused us to stop searching; | |
1259 this is either the same as SATISFY, or 0. */ | |
1260 static int | |
4397 | 1261 brace_gobbler (const std::string& text, int& indx, int satisfy) |
4378 | 1262 { |
18084
8e056300994b
Follow coding convention of defining and initializing only 1 variable per line in liboctave.
Rik <rik@octave.org>
parents:
17769
diff
changeset
|
1263 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
|
1264 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
|
1265 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
|
1266 int pass_next = 0; |
4397 | 1267 |
1268 size_t text_len = text.length (); | |
1269 | |
1270 size_t i = indx; | |
1271 | |
1272 for (; i < text_len; i++) | |
4378 | 1273 { |
4397 | 1274 c = text[i]; |
1275 | |
4378 | 1276 if (pass_next) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1277 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1278 pass_next = 0; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1279 continue; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1280 } |
4378 | 1281 |
1282 /* 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
|
1283 escape the quote character in a double-quoted string. */ |
4378 | 1284 if (c == '\\' && (quoted == 0 || quoted == '"' || quoted == '`')) |
1285 { | |
1286 pass_next = 1; | |
1287 continue; | |
1288 } | |
1289 | |
1290 if (quoted) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1291 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1292 if (c == quoted) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1293 quoted = 0; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1294 continue; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1295 } |
4378 | 1296 |
1297 if (c == '"' || c == '\'' || c == '`') | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1298 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1299 quoted = c; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1300 continue; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1301 } |
4391 | 1302 |
20955
77f5591878bf
maint: Use '! expr' rather than '!expr' to conform to coding guidelines.
Rik <rik@octave.org>
parents:
20791
diff
changeset
|
1303 if (c == satisfy && ! level && ! quoted) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1304 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1305 /* 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
|
1306 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
|
1307 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
|
1308 if (c == '{' |
17d647821d61
maint: More cleanup of C++ code to follow Octave coding conventions.
John W. Eaton <jwe@octave.org>
parents:
19697
diff
changeset
|
1309 && ((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
|
1310 && (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
|
1311 && (brace_whitespace (text[i+1]) || text[i+1] == '}')))) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1312 continue; |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1313 /* 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
|
1314 in a '${ }' construct */ |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1315 if ((c != '{') || i == 0 || (text[i-1] != '$')) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1316 break; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1317 } |
4378 | 1318 |
1319 if (c == '{') | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1320 level++; |
4378 | 1321 else if (c == '}' && level) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1322 level--; |
4378 | 1323 } |
1324 | |
4397 | 1325 indx = i; |
1326 return c; | |
4378 | 1327 } |
1328 | |
4399 | 1329 /* Expand extra colons. */ |
4378 | 1330 |
1331 /* Check for leading colon first, then trailing, then doubled, since | |
1332 that is fastest. Usually it will be leading or trailing. */ | |
1333 | |
4399 | 1334 /* Replace a leading or trailing or doubled : in PATH with DFLT. If |
1335 no extra colons, return PATH. Only one extra colon is replaced. | |
1336 DFLT may not be NULL. */ | |
1337 | |
1338 static std::string | |
4394 | 1339 kpse_expand_default (const std::string& path, const std::string& fallback) |
4378 | 1340 { |
4394 | 1341 std::string expansion; |
1342 | |
1343 size_t path_len = path.length (); | |
1344 | |
1345 if (path_len == 0) | |
1346 expansion = fallback; | |
4378 | 1347 |
1348 /* Solitary or leading :? */ | |
4394 | 1349 else if (IS_ENV_SEP (path[0])) |
4378 | 1350 { |
4394 | 1351 expansion = path_len == 1 ? fallback : fallback + path; |
4378 | 1352 } |
1353 | |
1354 /* Sorry about the assignment in the middle of the expression, but | |
1355 conventions were made to be flouted and all that. I don't see the | |
1356 point of calling strlen twice or complicating the logic just to | |
1357 avoid the assignment (especially now that I've pointed it out at | |
1358 such great length). */ | |
4394 | 1359 else if (IS_ENV_SEP (path[path_len-1])) |
1360 expansion = path + fallback; | |
4378 | 1361 |
1362 /* OK, not leading or trailing. Check for doubled. */ | |
1363 else | |
1364 { | |
1365 /* What we'll return if we find none. */ | |
4394 | 1366 expansion = path; |
1367 | |
1368 for (size_t i = 0; i < path_len; i++) | |
4378 | 1369 { |
4394 | 1370 if (i + 1 < path_len |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1371 && IS_ENV_SEP (path[i]) && IS_ENV_SEP (path[i+1])) |
4394 | 1372 { |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1373 /* We have a doubled colon. */ |
4391 | 1374 |
4378 | 1375 /* Copy stuff up to and including the first colon. */ |
1376 /* 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
|
1377 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
|
1378 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1379 break; |
4378 | 1380 } |
1381 } | |
1382 } | |
4391 | 1383 |
4378 | 1384 return expansion; |
1385 } | |
1386 | |
4399 | 1387 /* Translate a path element to its corresponding director{y,ies}. */ |
4378 | 1388 |
1389 /* To avoid giving prototypes for all the routines and then their real | |
1390 definitions, we give all the subroutines first. The entry point is | |
1391 the last routine in the file. */ | |
4392 | 1392 |
4390 | 1393 /* Return true if FN is a directory or a symlink to a directory, |
1394 false if not. */ | |
1395 | |
1396 static bool | |
1397 dir_p (const std::string& fn) | |
1398 { | |
21865 | 1399 octave::sys::file_stat fs (fn); |
1400 | |
1401 return (fs && fs.is_dir ()); | |
4390 | 1402 } |
4391 | 1403 |
4378 | 1404 /* Here is the entry point. Returns directory list for ELT. */ |
1405 | |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1406 /* Given a path element ELT, return a the element with a trailing slash |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1407 or an empty string if the element is not a directory. |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11501
diff
changeset
|
1408 |
4399 | 1409 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
|
1410 most likely only useful to be called from 'kpse_path_search', which |
4399 | 1411 has already assumed expansion has been done. */ |
1412 | |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1413 static std::string |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1414 kpse_element_dir (const std::string& elt) |
4378 | 1415 { |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1416 std::string ret; |
4378 | 1417 |
1418 /* If given nothing, return nothing. */ | |
4398 | 1419 if (elt.empty ()) |
21871
cab605836305
use std::list instead of custom list type in pathsearch code
John W. Eaton <jwe@octave.org>
parents:
21870
diff
changeset
|
1420 return ret; |
4378 | 1421 |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1422 if (dir_p (elt)) |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1423 { |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1424 ret = elt; |
4378 | 1425 |
21873
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1426 char last_char = ret[ret.length () - 1]; |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1427 |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1428 if (! (IS_DIR_SEP (last_char) || IS_DEVICE_SEP (last_char))) |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1429 ret += DIR_SEP_STRING; |
40195d04b17c
still more simplification of pathsearch
John W. Eaton <jwe@octave.org>
parents:
21872
diff
changeset
|
1430 |
4378 | 1431 } |
1432 | |
1433 return ret; | |
1434 } | |
1435 | |
4399 | 1436 /* Variable expansion. */ |
4385 | 1437 |
1438 /* We have to keep track of variables being expanded, otherwise | |
1439 constructs like TEXINPUTS = $TEXINPUTS result in an infinite loop. | |
1440 (Or indirectly recursive variables, etc.) Our simple solution is to | |
1441 add to a list each time an expansion is started, and check the list | |
1442 before expanding. */ | |
1443 | |
4391 | 1444 static std::map <std::string, bool> expansions; |
4385 | 1445 |
1446 static void | |
4391 | 1447 expanding (const std::string& var, bool xp) |
4385 | 1448 { |
4391 | 1449 expansions[var] = xp; |
4385 | 1450 } |
1451 | |
1452 /* Return whether VAR is currently being expanding. */ | |
1453 | |
4391 | 1454 static bool |
1455 expanding_p (const std::string& var) | |
4385 | 1456 { |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1457 return (expansions.find (var) != expansions.end ()) ? expansions[var] : false; |
4385 | 1458 } |
4392 | 1459 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1460 /* 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
|
1461 at START and ends at END. If 'var' is not set, do not complain. |
4385 | 1462 This is a subroutine for the more complicated expansion function. */ |
1463 | |
1464 static void | |
4391 | 1465 expand (std::string &expansion, const std::string& var) |
4385 | 1466 { |
4391 | 1467 if (expanding_p (var)) |
1468 { | |
19410
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1469 (*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
|
1470 ("Octave:pathsearch-syntax", |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1471 "kpathsea: variable '%s' references itself (eventually)", |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1472 var.c_str ()); |
4385 | 1473 } |
4391 | 1474 else |
1475 { | |
1476 /* Check for an environment variable. */ | |
21732
6a1eded90355
use namespace for system env class
John W. Eaton <jwe@octave.org>
parents:
21729
diff
changeset
|
1477 std::string value = octave::sys::env::getenv (var); |
4391 | 1478 |
1479 if (! value.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1480 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1481 expanding (var, true); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1482 std::string tmp = kpse_var_expand (value); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1483 expanding (var, false); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1484 expansion += tmp; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1485 } |
4391 | 1486 } |
4385 | 1487 } |
4392 | 1488 |
4385 | 1489 /* Can't think of when it would be useful to change these (and the |
1490 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
|
1491 #if ! defined (IS_VAR_START) |
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
1492 /* starts all variable references */ |
4385 | 1493 #define IS_VAR_START(c) ((c) == '$') |
1494 #endif | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
1495 #if ! defined (IS_VAR_CHAR) |
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
1496 /* variable name constituent */ |
4385 | 1497 #define IS_VAR_CHAR(c) (isalnum (c) || (c) == '_') |
1498 #endif | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
1499 #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
|
1500 /* start delimited variable name (after $) */ |
4385 | 1501 #define IS_VAR_BEGIN_DELIMITER(c) ((c) == '{') |
1502 #endif | |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21690
diff
changeset
|
1503 #if ! defined (IS_VAR_END_DELIMITER) |
4385 | 1504 #define IS_VAR_END_DELIMITER(c) ((c) == '}') |
1505 #endif | |
1506 | |
1507 /* Maybe we should support some or all of the various shell ${...} | |
1508 constructs, especially ${var-value}. */ | |
1509 | |
5085 | 1510 static std::string |
4391 | 1511 kpse_var_expand (const std::string& src) |
4385 | 1512 { |
4389 | 1513 std::string expansion; |
4391 | 1514 |
1515 size_t src_len = src.length (); | |
1516 | |
4385 | 1517 /* Copy everything but variable constructs. */ |
4391 | 1518 for (size_t i = 0; i < src_len; i++) |
1519 { | |
1520 if (IS_VAR_START (src[i])) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1521 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1522 i++; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1523 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1524 /* Three cases: '$VAR', '${VAR}', '$<anything-else>'. */ |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1525 if (IS_VAR_CHAR (src[i])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1526 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1527 /* $V: collect name constituents, then expand. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1528 size_t var_end = i; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1529 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1530 do |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1531 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1532 var_end++; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1533 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1534 while (IS_VAR_CHAR (src[var_end])); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1535 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1536 var_end--; /* had to go one past */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1537 expand (expansion, src.substr (i, var_end - i + 1)); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1538 i = var_end; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1539 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1540 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1541 else if (IS_VAR_BEGIN_DELIMITER (src[i])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1542 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1543 /* ${: scan ahead for matching delimiter, then expand. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1544 size_t var_end = ++i; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1545 |
20955
77f5591878bf
maint: Use '! expr' rather than '!expr' to conform to coding guidelines.
Rik <rik@octave.org>
parents:
20791
diff
changeset
|
1546 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
|
1547 var_end++; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1548 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1549 if (var_end == src_len) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1550 { |
19410
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1551 (*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
|
1552 ("Octave:pathsearch-syntax", |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1553 "%s: No matching } for ${", src.c_str ()); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1554 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
|
1555 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1556 else |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1557 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1558 expand (expansion, src.substr (i, var_end - i)); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1559 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
|
1560 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1561 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1562 else |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1563 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1564 /* $<something-else>: error. */ |
19410
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1565 (*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
|
1566 ("Octave:pathsearch-syntax", |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1567 "%s: Unrecognized variable construct '$%c'", |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1568 src.c_str (), src[i]); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1569 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1570 /* Just ignore those chars and keep going. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1571 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1572 } |
4391 | 1573 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1574 expansion += src[i]; |
4391 | 1575 } |
4389 | 1576 |
1577 return expansion; | |
4385 | 1578 } |