Mercurial > octave-nkf
annotate liboctave/util/kpse.cc @ 20651:e54ecb33727e
lo-array-gripes.cc: Remove FIXME's related to buffer size.
* lo-array-gripes.cc: Remove FIXME's related to buffer size. Shorten sprintf
buffers from 100 to 64 characters (still well more than 19 required).
Use 'const' decorator on constant value for clarity. Remove extra space
between variable and array bracket.
author | Rik <rik@octave.org> |
---|---|
date | Mon, 12 Oct 2015 21:13:47 -0700 |
parents | 610c74748518 |
children |
rev | line source |
---|---|
4399 | 1 // This file is not compiled to a separate object file. It is |
2 // included in pathsearch.cc. | |
3 | |
4 /* Look up a filename in a path. | |
4378 | 5 |
19731
4197fc428c7d
maint: Update copyright notices for 2015.
John W. Eaton <jwe@octave.org>
parents:
19444
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 |
29 #if defined (HAVE_CONFIG_H) | |
30 #include <config.h> | |
31 #endif | |
32 | |
4390 | 33 #include <map> |
4389 | 34 #include <string> |
35 | |
4399 | 36 /* System defines are for non-Unix systems only. (Testing for all Unix |
37 variations should be done in configure.) Presently the defines used | |
38 are: DOS OS2 WIN32. I do not use any of these systems | |
39 myself; if you do, I'd be grateful for any changes. --kb@mail.tug.org */ | |
40 | |
41 /* 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
|
42 #if defined (DOS) || defined (OS2) || defined (WIN32) || defined (__MSDOS__) |
4399 | 43 #define DOSISH |
44 #endif | |
45 | |
46 #if defined (DOSISH) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
47 #define MONOCASE_FILENAMES /* case-insensitive filename comparisons */ |
4399 | 48 #endif |
49 | |
50 extern "C" { | |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14155
diff
changeset
|
51 #if defined (__MINGW32__) |
4399 | 52 #include <windows.h> |
53 #include <fcntl.h> | |
54 #include <dirent.h> | |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14155
diff
changeset
|
55 #elif defined (WIN32) |
13718
a31c926fb0d5
Do not define __STDC__ under MSVC.
Michael Goffioul <michael.goffioul@gmail.com>
parents:
12912
diff
changeset
|
56 #ifndef _MSC_VER |
4399 | 57 #define __STDC__ 1 |
58 #include "win32lib.h" | |
6106 | 59 #endif |
4399 | 60 #endif /* not WIN32 */ |
61 | |
62 #ifdef __DJGPP__ | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
63 #include <fcntl.h> /* for long filenames' stuff */ |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
64 #include <dir.h> /* for 'getdisk' */ |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
65 #include <io.h> /* for 'setmode' */ |
4399 | 66 #endif |
67 } | |
68 | |
69 /* Some drivers have partially integrated kpathsea changes. */ | |
70 #ifndef KPATHSEA | |
71 #define KPATHSEA 32 | |
72 #endif | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11501
diff
changeset
|
73 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
74 /* System dependencies that are figured out by 'configure'. If we are |
4399 | 75 compiling standalone, we get our c-auto.h. Otherwise, the package |
76 containing us must provide this (unless it can somehow generate ours | |
77 from c-auto.in). We use <...> instead of "..." so that the current | |
78 cpp directory (i.e., kpathsea/) won't be searched. */ | |
79 | |
80 /* If you want to find subdirectories in a directory with non-Unix | |
81 semantics (specifically, if a directory with no subdirectories does | |
5622 | 82 not have exactly two links), define this. */ |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14155
diff
changeset
|
83 #if defined (__DJGPP__) || ! defined (DOSISH) |
4399 | 84 /* Surprise! DJGPP returns st_nlink exactly like on Unix. */ |
85 #define ST_NLINK_TRICK | |
86 #endif /* either not DOSISH or __DJGPP__ */ | |
87 | |
88 #ifdef OS2 | |
89 #define access ln_access | |
90 #define fopen ln_fopen | |
91 #define rename ln_rename | |
92 #define stat ln_stat | |
93 #endif /* OS2 */ | |
94 | |
11236 | 95 /* Define the characters which separate components of |
96 filenames and environment variable paths. */ | |
97 | |
98 /* What separates filename components? */ | |
99 #ifndef DIR_SEP | |
100 #ifdef DOSISH | |
101 /* Either \'s or 's work. Wayne Sullivan's web2pc prefers /, so we'll | |
102 go with that. */ | |
103 #define DIR_SEP '/' | |
104 #define DIR_SEP_STRING "/" | |
105 #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
|
106 #define NAME_BEGINS_WITH_DEVICE(name) ((name.length ()>0) && IS_DEVICE_SEP((name)[1])) |
11236 | 107 /* On DOS, it's good to allow both \ and / between directories. */ |
108 #define IS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\') | |
109 #else | |
110 #define DIR_SEP '/' | |
111 #define DIR_SEP_STRING "/" | |
112 #endif /* not DOSISH */ | |
113 #endif /* not DIR_SEP */ | |
114 | |
115 #ifndef IS_DIR_SEP | |
116 #define IS_DIR_SEP(ch) ((ch) == DIR_SEP) | |
117 #endif | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
118 #ifndef IS_DEVICE_SEP /* No 'devices' on, e.g., Unix. */ |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11501
diff
changeset
|
119 #define IS_DEVICE_SEP(ch) 0 |
11236 | 120 #endif |
121 #ifndef NAME_BEGINS_WITH_DEVICE | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11501
diff
changeset
|
122 #define NAME_BEGINS_WITH_DEVICE(name) 0 |
11236 | 123 #endif |
4378 | 124 |
4396 | 125 #include "lo-error.h" |
4391 | 126 #include "oct-env.h" |
127 #include "oct-passwd.h" | |
4399 | 128 #include "str-vec.h" |
4385 | 129 |
130 /* Header files that essentially all of our sources need, and | |
131 that all implementations have. We include these first, to help with | |
132 NULL being defined multiple times. */ | |
133 #include <cstdio> | |
134 #include <cstdarg> | |
135 #include <cstdlib> | |
136 #include <cerrno> | |
137 #include <cassert> | |
138 | |
139 #include <sys/types.h> | |
140 #include <unistd.h> | |
141 | |
142 #include "sysdir.h" | |
143 #include "statdefs.h" | |
144 | |
145 /* define NAME_MAX, the maximum length of a single | |
146 component in a filename. No such limit may exist, or may vary | |
147 depending on the filesystem. */ | |
148 | |
149 /* Most likely the system will truncate filenames if it is not POSIX, | |
150 and so we can use the BSD value here. */ | |
151 #ifndef _POSIX_NAME_MAX | |
152 #define _POSIX_NAME_MAX 255 | |
153 #endif | |
154 | |
155 #ifndef NAME_MAX | |
156 #define NAME_MAX _POSIX_NAME_MAX | |
157 #endif | |
158 | |
159 #include <cctype> | |
160 | |
161 /* What separates elements in environment variable path lists? */ | |
162 #ifndef ENV_SEP | |
5451 | 163 #if defined (SEPCHAR) && defined (SEPCHAR_STR) |
164 #define ENV_SEP SEPCHAR | |
165 #define ENV_SEP_STRING SEPCHAR_STR | |
166 #elif defined (DOSISH) | |
4385 | 167 #define ENV_SEP ';' |
168 #define ENV_SEP_STRING ";" | |
169 #else | |
170 #define ENV_SEP ':' | |
171 #define ENV_SEP_STRING ":" | |
172 #endif /* not DOS */ | |
173 #endif /* not ENV_SEP */ | |
174 | |
175 #ifndef IS_ENV_SEP | |
176 #define IS_ENV_SEP(ch) ((ch) == ENV_SEP) | |
177 #endif | |
178 | |
4399 | 179 /* define PATH_MAX, the maximum length of a filename. Since no such |
180 limit may exist, it's preferable to dynamically grow filenames as | |
181 needed. */ | |
4385 | 182 |
183 /* Cheat and define this as a manifest constant no matter what, instead | |
184 of using pathconf. I forget why we want to do this. */ | |
185 | |
186 #ifndef _POSIX_PATH_MAX | |
187 #define _POSIX_PATH_MAX 255 | |
188 #endif | |
189 | |
190 #ifndef PATH_MAX | |
191 #ifdef MAXPATHLEN | |
192 #define PATH_MAX MAXPATHLEN | |
193 #else | |
194 #define PATH_MAX _POSIX_PATH_MAX | |
195 #endif | |
196 #endif /* not PATH_MAX */ | |
197 | |
198 /* If NO_DEBUG is defined (not recommended), skip all this. */ | |
199 #ifndef NO_DEBUG | |
200 | |
201 /* OK, we'll have tracing support. */ | |
202 #define KPSE_DEBUG | |
203 | |
204 /* Test if a bit is on. */ | |
205 #define KPSE_DEBUG_P(bit) (kpathsea_debug & (1 << (bit))) | |
206 | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
207 #define KPSE_DEBUG_STAT 0 /* stat calls */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
208 #define KPSE_DEBUG_HASH 1 /* hash lookups */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
209 #define KPSE_DEBUG_FOPEN 2 /* fopen/fclose calls */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
210 #define KPSE_DEBUG_PATHS 3 /* search path initializations */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
211 #define KPSE_DEBUG_EXPAND 4 /* path element expansion */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
212 #define KPSE_DEBUG_SEARCH 5 /* searches */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
213 #define KPSE_DEBUG_VARS 6 /* variable values */ |
4385 | 214 #define KPSE_LAST_DEBUG KPSE_DEBUG_VARS |
215 | |
216 /* A printf for the debugging. */ | |
10411 | 217 #define DEBUGF_START() do { gnulib::fputs ("kdebug:", stderr) |
12912
e116dd862879
use gnulib:: qualifiers for more stdio functions
John W. Eaton <jwe@octave.org>
parents:
11586
diff
changeset
|
218 #define DEBUGF_END() gnulib::fflush (stderr); } while (0) |
4385 | 219 |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
220 #define DEBUGF(str) \ |
10411 | 221 DEBUGF_START (); gnulib::fputs (str, stderr); DEBUGF_END () |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
222 #define DEBUGF1(str, e1) \ |
10411 | 223 DEBUGF_START (); gnulib::fprintf (stderr, str, e1); DEBUGF_END () |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
224 #define DEBUGF2(str, e1, e2) \ |
10411 | 225 DEBUGF_START (); gnulib::fprintf (stderr, str, e1, e2); DEBUGF_END () |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
226 #define DEBUGF3(str, e1, e2, e3) \ |
10411 | 227 DEBUGF_START (); gnulib::fprintf (stderr, str, e1, e2, e3); DEBUGF_END () |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
228 #define DEBUGF4(str, e1, e2, e3, e4) \ |
10411 | 229 DEBUGF_START (); gnulib::fprintf (stderr, str, e1, e2, e3, e4); DEBUGF_END () |
4385 | 230 |
231 #endif /* not NO_DEBUG */ | |
232 | |
4399 | 233 #ifdef KPSE_DEBUG |
234 static unsigned int kpathsea_debug = 0; | |
235 #endif | |
236 | |
4385 | 237 #if defined (WIN32) && !defined (__MINGW32__) |
238 | |
239 /* System description file for Windows NT. */ | |
240 | |
241 /* | |
242 * Define symbols to identify the version of Unix this is. | |
243 * Define all the symbols that apply correctly. | |
244 */ | |
245 | |
246 #ifndef DOSISH | |
247 #define DOSISH | |
248 #endif | |
249 | |
250 #ifndef MAXPATHLEN | |
251 #define MAXPATHLEN _MAX_PATH | |
4378 | 252 #endif |
253 | |
4385 | 254 /* These have to be defined because our compilers treat __STDC__ as being |
255 defined (most of them anyway). */ | |
256 | |
257 #define access _access | |
258 #define stat _stat | |
259 #define strdup _strdup | |
260 | |
261 #define S_IFMT _S_IFMT | |
262 #define S_IFDIR _S_IFDIR | |
263 | |
264 /* Define this so that winsock.h definitions don't get included when | |
265 windows.h is... For this to have proper effect, config.h must | |
4391 | 266 always be included before windows.h. */ |
4385 | 267 #define _WINSOCKAPI_ 1 |
268 | |
269 #include <windows.h> | |
270 | |
271 /* For proper declaration of environ. */ | |
272 #include <io.h> | |
273 #include <fcntl.h> | |
274 #include <process.h> | |
275 | |
276 /* ============================================================ */ | |
277 | |
278 #endif /* WIN32 */ | |
279 | |
280 /* Define common sorts of messages. */ | |
281 | |
282 /* 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
|
283 with status 'errno', because that might be 256, which would mean |
4385 | 284 success (exit statuses are truncated to eight bits). */ |
4396 | 285 #define FATAL_PERROR(str) \ |
286 do \ | |
287 { \ | |
10411 | 288 gnulib::fputs ("pathsearch: ", stderr); \ |
4396 | 289 perror (str); exit (EXIT_FAILURE); \ |
290 } \ | |
291 while (0) | |
292 | |
293 #define FATAL(str) \ | |
294 do \ | |
295 { \ | |
10411 | 296 gnulib::fputs ("pathsearch: fatal: ", stderr); \ |
297 gnulib::fputs (str, stderr); \ | |
298 gnulib::fputs (".\n", stderr); \ | |
4396 | 299 exit (1); \ |
300 } \ | |
301 while (0) | |
4385 | 302 |
4386 | 303 #ifndef WIN32 |
4385 | 304 static void xclosedir (DIR *d); |
4386 | 305 #endif |
4385 | 306 |
4399 | 307 /* It's a little bizarre to be using the same type for the list and the |
308 elements of the list, but no reason not to in this case, I think -- | |
309 we never need a NULL string in the middle of the list, and an extra | |
310 NULL/NULL element always at the end is inconsequential. */ | |
311 | |
312 struct str_llist_elt | |
313 { | |
11501
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
314 str_llist_elt (void) : str (), moved (0), next (0) { } |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
315 |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
316 ~str_llist_elt (void) { } |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
317 |
4399 | 318 std::string str; |
319 int moved; | |
320 struct str_llist_elt *next; | |
321 }; | |
322 | |
323 typedef str_llist_elt str_llist_elt_type; | |
324 typedef str_llist_elt *str_llist_type; | |
325 | |
326 #define STR_LLIST(sl) ((sl).str) | |
327 #define STR_LLIST_MOVED(sl) ((sl).moved) | |
328 #define STR_LLIST_NEXT(sl) ((sl).next) | |
329 | |
4390 | 330 static void str_llist_add (str_llist_type *l, const std::string& str); |
4385 | 331 |
332 static void str_llist_float (str_llist_type *l, str_llist_elt_type *mover); | |
333 | |
4389 | 334 static std::string kpse_var_expand (const std::string& src); |
4385 | 335 |
4399 | 336 static str_llist_type *kpse_element_dirs (const std::string& elt); |
337 | |
338 static std::string kpse_expand (const std::string& s); | |
339 | |
340 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
|
341 const std::string& dflt); |
4399 | 342 |
343 static string_vector kpse_db_search (const std::string& name, | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
344 const std::string& path_elt, bool all); |
4399 | 345 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
346 #include <ctime> /* for 'time' */ |
4385 | 347 |
4399 | 348 static bool |
4394 | 349 kpse_is_env_sep (char c) |
350 { | |
351 return IS_ENV_SEP (c); | |
352 } | |
353 | |
4392 | 354 /* These routines just check the return status from standard library |
355 routines and abort if an error happens. */ | |
356 | |
357 static FILE * | |
4393 | 358 xfopen (const std::string& filename, const char *mode) |
4392 | 359 { |
360 FILE *f; | |
361 | |
4393 | 362 assert (! filename.empty () && mode); |
363 | |
14153 | 364 f = gnulib::fopen (filename.c_str (), mode); |
4393 | 365 |
366 if (! f) | |
367 FATAL_PERROR (filename.c_str ()); | |
4392 | 368 |
14153 | 369 if (KPSE_DEBUG_P (KPSE_DEBUG_FOPEN)) |
370 DEBUGF3 ("fopen (%s, %s) => 0x%lx\n", filename.c_str (), mode, | |
16314
0723ea02dcdb
use intptr_t instead of long
John W. Eaton <jwe@octave.org>
parents:
15467
diff
changeset
|
371 reinterpret_cast<intptr_t> (f)); |
14153 | 372 |
4392 | 373 return f; |
374 } | |
375 | |
376 /* A single (key,value) pair. */ | |
377 | |
378 struct hash_element_type | |
379 { | |
380 std::string key; | |
381 std::string value; | |
382 struct hash_element_type *next; | |
383 }; | |
384 | |
385 /* The usual arrangement of buckets initialized to null. */ | |
386 | |
387 struct hash_table_type | |
388 { | |
389 hash_element_type **buckets; | |
390 unsigned size; | |
391 }; | |
392 | |
393 static unsigned | |
5764 | 394 kpse_hash (hash_table_type table, const std::string& key) |
4392 | 395 { |
396 unsigned n = 0; | |
397 | |
398 /* Our keys aren't often anagrams of each other, so no point in | |
399 weighting the characters. */ | |
400 size_t len = key.length (); | |
401 for (size_t i = 0; i < len; i++) | |
4394 | 402 n = (n + n + key[i]) % table.size; |
4392 | 403 |
404 return n; | |
405 } | |
406 | |
407 /* Look up STR in MAP. Return a (dynamically-allocated) list of the | |
408 corresponding strings or NULL if no match. */ | |
409 | |
410 static string_vector | |
411 hash_lookup (hash_table_type table, const std::string& key) | |
412 { | |
413 hash_element_type *p; | |
414 string_vector ret; | |
5764 | 415 unsigned n = kpse_hash (table, key); |
4392 | 416 |
417 /* Look at everything in this bucket. */ | |
4398 | 418 for (p = table.buckets[n]; p; p = p->next) |
4394 | 419 if (key == p->key) |
4392 | 420 ret.append (p->value); |
421 | |
422 #ifdef KPSE_DEBUG | |
423 if (KPSE_DEBUG_P (KPSE_DEBUG_HASH)) | |
424 { | |
425 DEBUGF1 ("hash_lookup (%s) =>", key.c_str ()); | |
426 if (ret.empty ()) | |
10411 | 427 gnulib::fputs (" (nil)\n", stderr); |
4392 | 428 else |
429 { | |
20267
a9574e3c6e9e
Deprecate Array::length() and Sparse::length() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
20052
diff
changeset
|
430 int len = ret.numel (); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
431 for (int i = 0; i < len; i++) |
4392 | 432 { |
10411 | 433 gnulib::putc (' ', stderr); |
434 gnulib::fputs (ret[i].c_str (), stderr); | |
4392 | 435 } |
10411 | 436 gnulib::putc ('\n', stderr); |
4392 | 437 } |
12912
e116dd862879
use gnulib:: qualifiers for more stdio functions
John W. Eaton <jwe@octave.org>
parents:
11586
diff
changeset
|
438 gnulib::fflush (stderr); |
4392 | 439 } |
440 #endif | |
441 | |
442 return ret; | |
443 } | |
444 | |
4399 | 445 /* A way to step through a path, extracting one directory name at a |
446 time. */ | |
447 | |
448 class kpse_path_iterator | |
449 { | |
450 public: | |
451 | |
452 kpse_path_iterator (const std::string& p) | |
453 : path (p), b (0), e (0), len (path.length ()) { set_end (); } | |
454 | |
455 kpse_path_iterator (const kpse_path_iterator& pi) | |
456 : path (pi.path), b (pi.b), e (pi.e), len (pi.len) { } | |
457 | |
458 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
|
459 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
460 kpse_path_iterator retval (*this); |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
461 next (); |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
462 return retval; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
463 } |
4399 | 464 |
465 std::string operator * (void) { return path.substr (b, e-b); } | |
466 | |
467 bool operator != (const size_t sz) { return b != sz; } | |
468 | |
469 private: | |
470 | |
471 const std::string& path; | |
472 size_t b; | |
473 size_t e; | |
474 size_t len; | |
475 | |
476 void set_end (void) | |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
477 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
478 e = b + 1; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
479 |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
480 if (e == len) |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
481 ; /* 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
|
482 else if (e > len) |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
483 b = e = std::string::npos; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
484 else |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
485 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
486 /* 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
|
487 the path). */ |
20478
610c74748518
maint: Clean up code based on static analysis suggestions.
Rik <rik@octave.org>
parents:
20267
diff
changeset
|
488 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
|
489 e++; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
490 } |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
491 } |
4399 | 492 |
493 void next (void) | |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
494 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
495 b = e + 1; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
496 |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
497 /* Skip any consecutive colons. */ |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
498 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
|
499 b++; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
500 |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
501 if (b >= len) |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
502 b = e = std::string::npos; |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
503 else |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
504 set_end (); |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
505 } |
5617 | 506 |
507 // No assignment. | |
508 kpse_path_iterator& operator = (const kpse_path_iterator&); | |
4399 | 509 }; |
510 | |
4391 | 511 /* Here's the simple one, when a program just wants a value. */ |
512 | |
513 static std::string | |
514 kpse_var_value (const std::string& var) | |
515 { | |
516 std::string ret; | |
517 | |
518 std::string tmp = octave_env::getenv (var); | |
519 | |
520 if (! tmp.empty ()) | |
521 ret = kpse_var_expand (tmp); | |
522 | |
523 #ifdef KPSE_DEBUG | |
524 if (KPSE_DEBUG_P (KPSE_DEBUG_VARS)) | |
525 DEBUGF2 ("variable: %s = %s\n", var.c_str (), | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
526 tmp.empty () ? "(nil)" : tmp.c_str ()); |
4391 | 527 #endif |
528 | |
529 return ret; | |
530 } | |
531 | |
532 /* Truncate any too-long components in NAME, returning the result. It's | |
533 too bad this is necessary. See comments in readable.c for why. */ | |
534 | |
4393 | 535 static std::string |
536 kpse_truncate_filename (const std::string& name) | |
4391 | 537 { |
538 unsigned c_len = 0; /* Length of current component. */ | |
539 unsigned ret_len = 0; /* Length of constructed result. */ | |
540 | |
4393 | 541 std::string ret = name; |
542 | |
543 size_t len = name.length (); | |
544 | |
545 for (size_t i = 0; i < len; i++) | |
4391 | 546 { |
4393 | 547 if (IS_DIR_SEP (name[i]) || IS_DEVICE_SEP (name[i])) |
4391 | 548 { |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
549 /* At a directory delimiter, reset component length. */ |
4391 | 550 c_len = 0; |
551 } | |
552 else if (c_len > NAME_MAX) | |
553 { | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
554 /* If past the max for a component, ignore this character. */ |
4391 | 555 continue; |
556 } | |
557 | |
558 /* Copy this character. */ | |
4393 | 559 ret[ret_len++] = name[i]; |
4391 | 560 c_len++; |
561 } | |
562 | |
4393 | 563 ret.resize (ret_len); |
4391 | 564 |
565 return ret; | |
566 } | |
567 | |
568 /* If access can read FN, run stat (assigning to stat buffer ST) and | |
569 check that fn is not a directory. Don't check for just being a | |
570 regular file, as it is potentially useful to read fifo's or some | |
571 kinds of devices. */ | |
572 | |
573 #ifdef WIN32 | |
574 static inline bool | |
4393 | 575 READABLE (const std::string& fn, struct stat&) |
4391 | 576 { |
4393 | 577 const char *t = fn.c_str (); |
578 return (GetFileAttributes (t) != 0xFFFFFFFF | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
579 && ! (GetFileAttributes (t) & FILE_ATTRIBUTE_DIRECTORY)); |
4391 | 580 } |
581 #else | |
582 static inline bool | |
4393 | 583 READABLE (const std::string& fn, struct stat& st) |
4391 | 584 { |
4393 | 585 const char *t = fn.c_str (); |
586 return (access (t, R_OK) == 0 | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
587 && stat (t, &(st)) == 0 && ! S_ISDIR (st.st_mode)); |
4391 | 588 } |
589 #endif | |
590 | |
591 /* POSIX invented the brain-damage of not necessarily truncating | |
592 filename components; the system's behavior is defined by the value of | |
593 the symbol _POSIX_NO_TRUNC, but you can't change it dynamically! | |
594 | |
595 Generic const return warning. See extend-fname.c. */ | |
596 | |
4393 | 597 static std::string |
598 kpse_readable_file (const std::string& name) | |
4391 | 599 { |
600 struct stat st; | |
4393 | 601 std::string ret; |
4391 | 602 |
603 if (READABLE (name, st)) | |
604 { | |
4393 | 605 ret = name; |
4391 | 606 |
607 #ifdef ENAMETOOLONG | |
608 } | |
609 else if (errno == ENAMETOOLONG) | |
610 { | |
611 ret = kpse_truncate_filename (name); | |
612 | |
613 /* 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
|
614 so let's call access again. */ |
4391 | 615 |
616 if (! READABLE (ret, st)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
617 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
618 /* Failed. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
619 ret = std::string (); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
620 } |
4391 | 621 #endif /* ENAMETOOLONG */ |
622 | |
623 } | |
624 else | |
625 { | |
626 /* Some other error. */ | |
627 if (errno == EACCES) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
628 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
629 /* Maybe warn them if permissions are bad. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
630 perror (name.c_str ()); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
631 } |
4393 | 632 |
633 ret = std::string (); | |
4391 | 634 } |
635 | |
636 return ret; | |
637 } | |
638 | |
639 /* Sorry this is such a system-dependent mess, but I can't see any way | |
640 to usefully generalize. */ | |
641 | |
642 static bool | |
643 kpse_absolute_p (const std::string& filename, int relative_ok) | |
644 { | |
645 size_t len = filename.length (); | |
646 | |
4409 | 647 int absolute = (len > 0 && IS_DIR_SEP (filename[0])) |
4391 | 648 #ifdef DOSISH |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
649 /* Novell allows non-alphanumeric drive letters. */ |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
650 || (len > 0 && IS_DEVICE_SEP (filename[1])) |
4391 | 651 #endif /* DOSISH */ |
652 #ifdef WIN32 | |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
653 /* UNC names */ |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
654 || (len > 1 && filename[0] == '\\' && filename[1] == '\\') |
4391 | 655 #endif |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
656 ; |
4409 | 657 |
4391 | 658 int explicit_relative |
659 = relative_ok | |
660 && (len > 1 | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
661 && filename[0] == '.' |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
662 && (IS_DIR_SEP (filename[1]) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
663 || (len > 2 && filename[1] == '.' && IS_DIR_SEP (filename[2])))); |
4391 | 664 |
665 return absolute || explicit_relative; | |
666 } | |
667 | |
4378 | 668 /* The very first search is for texmf.cnf, called when someone tries to |
669 initialize the TFM path or whatever. init_path calls kpse_cnf_get | |
670 which calls kpse_all_path_search to find all the texmf.cnf's. We | |
671 need to do various special things in this case, since we obviously | |
672 don't yet have the configuration files when we're searching for the | |
673 configuration files. */ | |
674 static bool first_search = true; | |
675 | |
676 /* This function is called after every search (except the first, since | |
677 we definitely want to allow enabling the logging in texmf.cnf) to | |
678 record the filename(s) found in $TEXMFLOG. */ | |
679 | |
680 static void | |
4391 | 681 log_search (const string_vector& filenames) |
4378 | 682 { |
4398 | 683 static FILE *log_file = 0; |
4378 | 684 static bool first_time = true; /* Need to open the log file? */ |
4391 | 685 |
686 if (first_time) | |
687 { | |
688 first_time = false; | |
689 | |
690 /* Get name from either envvar or config file. */ | |
691 std::string log_name = kpse_var_value ("TEXMFLOG"); | |
692 | |
693 if (! log_name.empty ()) | |
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 log_file = xfopen (log_name.c_str (), "a"); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
696 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
697 if (! log_file) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
698 perror (log_name.c_str ()); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
699 } |
4378 | 700 } |
4391 | 701 |
702 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH) || log_file) | |
703 { | |
704 /* FILENAMES should never be null, but safety doesn't hurt. */ | |
20267
a9574e3c6e9e
Deprecate Array::length() and Sparse::length() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
20052
diff
changeset
|
705 for (int e = 0; e < filenames.numel () && ! filenames[e].empty (); e++) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
706 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
707 std::string filename = filenames[e]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
708 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
709 /* Only record absolute filenames, for privacy. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
710 if (log_file && kpse_absolute_p (filename.c_str (), false)) |
10411 | 711 gnulib::fprintf (log_file, "%lu %s\n", |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
712 static_cast<unsigned long> (time (0)), |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
713 filename.c_str ()); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
714 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
715 /* And show them online, if debugging. We've already started |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
716 the debugging line in 'search', where this is called, so |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
717 just print the filename here, don't use DEBUGF. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
718 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) |
10411 | 719 gnulib::fputs (filename.c_str (), stderr); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
720 } |
4378 | 721 } |
722 } | |
4392 | 723 |
4378 | 724 /* Concatenate each element in DIRS with NAME (assume each ends with a |
725 /, to save time). If SEARCH_ALL is false, return the first readable | |
726 regular file. Else continue to search for more. In any case, if | |
727 none, return a list containing just NULL. | |
728 | |
729 We keep a single buffer for the potential filenames and reallocate | |
730 only when necessary. I'm not sure it's noticeably faster, but it | |
731 does seem cleaner. (We do waste a bit of space in the return | |
732 value, though, since we don't shrink it to the final size returned.) */ | |
733 | |
4390 | 734 static string_vector |
735 dir_list_search (str_llist_type *dirs, const std::string& name, | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
736 bool search_all) |
4378 | 737 { |
738 str_llist_elt_type *elt; | |
4390 | 739 string_vector ret; |
4378 | 740 |
741 for (elt = *dirs; elt; elt = STR_LLIST_NEXT (*elt)) | |
742 { | |
4390 | 743 const std::string dir = STR_LLIST (*elt); |
4393 | 744 |
745 std::string potential = dir + name; | |
746 | |
747 std::string tmp = kpse_readable_file (potential); | |
748 | |
749 if (! tmp.empty ()) | |
4378 | 750 { |
4393 | 751 ret.append (potential); |
4391 | 752 |
4378 | 753 /* Move this element towards the top of the list. */ |
754 str_llist_float (dirs, elt); | |
4391 | 755 |
756 if (! search_all) | |
4378 | 757 return ret; |
758 } | |
759 } | |
4391 | 760 |
4378 | 761 return ret; |
762 } | |
4392 | 763 |
4378 | 764 /* This is called when NAME is absolute or explicitly relative; if it's |
765 readable, return (a list containing) it; otherwise, return NULL. */ | |
766 | |
4390 | 767 static string_vector |
4393 | 768 absolute_search (const std::string& name) |
4378 | 769 { |
4390 | 770 string_vector ret_list; |
4393 | 771 std::string found = kpse_readable_file (name); |
4391 | 772 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
773 /* Add 'found' to the return list even if it's null; that tells |
4378 | 774 the caller we didn't find anything. */ |
4394 | 775 ret_list.append (found); |
4391 | 776 |
4378 | 777 return ret_list; |
778 } | |
4392 | 779 |
4378 | 780 /* This is the hard case -- look for NAME in PATH. If ALL is false, |
781 return the first file found. Otherwise, search all elements of PATH. */ | |
782 | |
4390 | 783 static string_vector |
4394 | 784 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
|
785 bool /* must_exist */, bool all) |
4378 | 786 { |
4390 | 787 string_vector ret_list; |
4378 | 788 bool done = false; |
4390 | 789 |
8021 | 790 for (kpse_path_iterator pi (path); ! done && pi != std::string::npos; pi++) |
4390 | 791 { |
4394 | 792 std::string elt = *pi; |
793 | |
4390 | 794 string_vector found; |
795 bool allow_disk_search = true; | |
796 | |
4394 | 797 if (elt.length () > 1 && elt[0] == '!' && elt[1] == '!') |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
798 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
799 /* Those magic leading chars in a path element means don't |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
800 search the disk for this elt. And move past the magic to |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
801 get to the name. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
802 allow_disk_search = false; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
803 elt = elt.substr (2); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
804 } |
4390 | 805 |
806 /* Do not touch the device if present */ | |
807 if (NAME_BEGINS_WITH_DEVICE (elt)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
808 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
809 while (elt.length () > 3 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
810 && 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
|
811 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
812 elt[2] = elt[1]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
813 elt[1] = elt[0]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
814 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
815 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
816 } |
4390 | 817 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
818 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
819 /* We never want to search the whole disk. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
820 while (elt.length () > 1 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
821 && 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
|
822 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
823 } |
4391 | 824 |
4390 | 825 /* Try ls-R, unless we're searching for texmf.cnf. Our caller |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
826 (search), also tests first_search, and does the resetting. */ |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
827 found = first_search ? string_vector () : kpse_db_search (name, elt, all); |
4390 | 828 |
829 /* Search the filesystem if (1) the path spec allows it, and either | |
4378 | 830 (2a) we are searching for texmf.cnf ; or |
4391 | 831 (2b) no db exists; or |
4378 | 832 (2c) no db's are relevant to this elt; or |
833 (3) MUST_EXIST && NAME was not in the db. | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
834 In (2*), 'found' will be NULL. |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
835 In (3), 'found' will be an empty list. */ |
4390 | 836 |
837 if (allow_disk_search && found.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
838 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
839 str_llist_type *dirs = kpse_element_dirs (elt); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
840 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
841 if (dirs && *dirs) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
842 found = dir_list_search (dirs, name, all); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
843 } |
4390 | 844 |
845 /* Did we find anything anywhere? */ | |
846 if (! found.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
847 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
848 if (all) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
849 ret_list.append (found); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
850 else |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
851 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
852 ret_list.append (found[0]); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
853 done = true; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
854 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
855 } |
4378 | 856 } |
857 | |
858 return ret_list; | |
4390 | 859 } |
4392 | 860 |
4378 | 861 /* Search PATH for ORIGINAL_NAME. If ALL is false, or ORIGINAL_NAME is |
862 absolute_p, check ORIGINAL_NAME itself. Otherwise, look at each | |
863 element of PATH for the first readable ORIGINAL_NAME. | |
4391 | 864 |
4378 | 865 Always return a list; if no files are found, the list will |
866 contain just NULL. If ALL is true, the list will be | |
867 terminated with NULL. */ | |
868 | |
4390 | 869 static string_vector |
870 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
|
871 bool must_exist, bool all) |
4378 | 872 { |
4390 | 873 string_vector ret_list; |
4378 | 874 bool absolute_p; |
875 | |
876 /* Make a leading ~ count as an absolute filename, and expand $FOO's. */ | |
4390 | 877 std::string name = kpse_expand (original_name); |
4391 | 878 |
4378 | 879 /* If the first name is absolute or explicitly relative, no need to |
880 consider PATH at all. */ | |
881 absolute_p = kpse_absolute_p (name, true); | |
4391 | 882 |
4378 | 883 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) |
4391 | 884 DEBUGF4 ("start search (file=%s, must_exist=%d, find_all=%d, path=%s).\n", |
4390 | 885 name.c_str (), must_exist, all, path.c_str ()); |
4378 | 886 |
887 /* Find the file(s). */ | |
888 ret_list = absolute_p ? absolute_search (name) | |
889 : path_search (path, name, must_exist, all); | |
4391 | 890 |
4378 | 891 /* The very first search is for texmf.cnf. We can't log that, since |
892 we want to allow setting TEXMFLOG in texmf.cnf. */ | |
4391 | 893 if (first_search) |
894 { | |
895 first_search = false; | |
896 } | |
897 else | |
898 { | |
899 /* 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
|
900 debugging line if we're doing that. */ |
4391 | 901 |
902 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
903 DEBUGF1 ("search (%s) =>", original_name.c_str ()); |
4391 | 904 |
905 log_search (ret_list); | |
906 | |
907 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) | |
10411 | 908 gnulib::putc ('\n', stderr); |
4391 | 909 } |
4378 | 910 |
4390 | 911 return ret_list; |
4378 | 912 } |
4392 | 913 |
4378 | 914 /* Search PATH for the first NAME. */ |
915 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
916 /* Call 'kpse_expand' on NAME. If the result is an absolute or |
4399 | 917 explicitly relative filename, check whether it is a readable |
918 (regular) file. | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11501
diff
changeset
|
919 |
4399 | 920 Otherwise, look in each of the directories specified in PATH (also do |
921 tilde and variable expansion on elements in PATH), using a prebuilt | |
922 db (see db.h) if it's relevant for a given path element. | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11501
diff
changeset
|
923 |
4399 | 924 If the prebuilt db doesn't exist, or if MUST_EXIST is true and NAME |
925 isn't found in the prebuilt db, look on the filesystem. (I.e., if | |
926 MUST_EXIST is false, and NAME isn't found in the db, do *not* look on | |
927 the filesystem.) | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11501
diff
changeset
|
928 |
4399 | 929 The caller must expand PATH. This is because it makes more sense to |
930 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
|
931 |
4399 | 932 In any case, return the complete filename if found, otherwise NULL. */ |
933 | |
934 static std::string | |
4390 | 935 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
|
936 bool must_exist) |
4378 | 937 { |
4390 | 938 string_vector ret_list = search (path, name, must_exist, false); |
939 | |
940 return ret_list.empty () ? std::string () : ret_list[0]; | |
4378 | 941 } |
942 | |
943 /* 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
|
944 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
|
945 |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
946 /* Like 'kpse_path_search' with MUST_EXIST true, but return a list of |
4399 | 947 all the filenames (or NULL if none), instead of taking the first. */ |
948 | |
949 static string_vector | |
4390 | 950 kpse_all_path_search (const std::string& path, const std::string& name) |
4378 | 951 { |
4390 | 952 return search (path, name, true, true); |
4378 | 953 } |
4392 | 954 |
4378 | 955 /* This is the hard case -- look in each element of PATH for each |
956 element of NAMES. If ALL is false, return the first file found. | |
957 Otherwise, search all elements of PATH. */ | |
958 | |
4390 | 959 static string_vector |
4394 | 960 path_find_first_of (const std::string& path, const string_vector& names, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
961 bool /* must_exist */, bool all) |
4378 | 962 { |
4390 | 963 string_vector ret_list; |
4378 | 964 bool done = false; |
4390 | 965 |
8021 | 966 for (kpse_path_iterator pi (path); ! done && pi != std::string::npos; pi++) |
4378 | 967 { |
4394 | 968 std::string elt = *pi; |
969 | |
4378 | 970 str_llist_type *dirs; |
971 str_llist_elt_type *dirs_elt; | |
4390 | 972 string_vector found; |
4378 | 973 bool allow_disk_search = true; |
974 | |
4394 | 975 if (elt.length () > 1 && elt[0] == '!' && elt[1] == '!') |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
976 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
977 /* Those magic leading chars in a path element means don't |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
978 search the disk for this elt. And move past the magic to |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
979 get to the name. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
980 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
981 allow_disk_search = false; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
982 elt = elt.substr (2); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
983 } |
4378 | 984 |
985 /* Do not touch the device if present */ | |
986 | |
987 if (NAME_BEGINS_WITH_DEVICE (elt)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
988 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
989 while (elt.length () > 3 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
990 && 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
|
991 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
992 elt[2] = elt[1]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
993 elt[1] = elt[0]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
994 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
995 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
996 } |
4378 | 997 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
998 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
999 /* We never want to search the whole disk. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1000 while (elt.length () > 1 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1001 && 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
|
1002 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1003 } |
4378 | 1004 |
1005 /* We have to search one directory at a time. */ | |
1006 dirs = kpse_element_dirs (elt); | |
1007 for (dirs_elt = *dirs; dirs_elt; dirs_elt = STR_LLIST_NEXT (*dirs_elt)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1008 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1009 const std::string dir = STR_LLIST (*dirs_elt); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1010 |
20267
a9574e3c6e9e
Deprecate Array::length() and Sparse::length() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
20052
diff
changeset
|
1011 int len = names.numel (); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1012 for (int i = 0; i < len && !done; i++) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1013 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1014 std::string name = names[i]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1015 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1016 /* Try ls-R, unless we're searching for texmf.cnf. Our caller |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1017 (find_first_of), also tests first_search, and does the |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1018 resetting. */ |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1019 found = first_search ? string_vector () |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1020 : kpse_db_search (name, dir.c_str (), all); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1021 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1022 /* Search the filesystem if (1) the path spec allows it, |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1023 and either |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1024 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1025 (2a) we are searching for texmf.cnf ; or |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1026 (2b) no db exists; or |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1027 (2c) no db's are relevant to this elt; or |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1028 (3) MUST_EXIST && NAME was not in the db. |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1029 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1030 In (2*), 'found' will be NULL. |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1031 In (3), 'found' will be an empty list. */ |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1032 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1033 if (allow_disk_search && found.empty ()) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1034 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1035 static str_llist_type *tmp = 0; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1036 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1037 if (! tmp) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1038 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1039 tmp = new str_llist_type; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1040 *tmp = 0; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1041 str_llist_add (tmp, ""); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1042 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1043 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1044 STR_LLIST (*(*tmp)) = dir; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1045 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1046 found = dir_list_search (tmp, name, all); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1047 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1048 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1049 /* Did we find anything anywhere? */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1050 if (! found.empty ()) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1051 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1052 if (all) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1053 ret_list.append (found); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1054 else |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1055 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1056 ret_list.append (found[0]); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1057 done = true; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1058 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1059 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1060 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1061 } |
4378 | 1062 } |
1063 | |
1064 return ret_list; | |
4391 | 1065 } |
4378 | 1066 |
4390 | 1067 static string_vector |
1068 find_first_of (const std::string& path, const string_vector& names, | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1069 bool must_exist, bool all) |
4378 | 1070 { |
4390 | 1071 string_vector ret_list; |
4378 | 1072 |
1073 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) | |
1074 { | |
10411 | 1075 gnulib::fputs ("start find_first_of ((", stderr); |
4391 | 1076 |
20267
a9574e3c6e9e
Deprecate Array::length() and Sparse::length() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
20052
diff
changeset
|
1077 int len = names.numel (); |
4391 | 1078 |
4390 | 1079 for (int i = 0; i < len; i++) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1080 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1081 if (i == 0) |
10411 | 1082 gnulib::fputs (names[i].c_str (), stderr); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1083 else |
10411 | 1084 gnulib::fprintf (stderr, ", %s", names[i].c_str ()); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1085 } |
4391 | 1086 |
10411 | 1087 gnulib::fprintf (stderr, "), path=%s, must_exist=%d).\n", |
1088 path.c_str (), must_exist); | |
4378 | 1089 } |
1090 | |
20267
a9574e3c6e9e
Deprecate Array::length() and Sparse::length() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
20052
diff
changeset
|
1091 for (int i = 0; i < names.numel (); i++) |
4409 | 1092 { |
1093 std::string name = names[i]; | |
1094 | |
1095 if (kpse_absolute_p (name, true)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1096 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1097 /* 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
|
1098 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
|
1099 are done. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1100 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1101 ret_list = absolute_search (name); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1102 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1103 if (! ret_list.empty ()) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1104 return ret_list; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1105 } |
4409 | 1106 } |
1107 | |
4378 | 1108 /* Find the file. */ |
1109 ret_list = path_find_first_of (path, names, must_exist, all); | |
1110 | |
1111 /* The very first search is for texmf.cnf. We can't log that, since | |
1112 we want to allow setting TEXMFLOG in texmf.cnf. */ | |
4391 | 1113 if (first_search) |
1114 { | |
1115 first_search = false; | |
1116 } | |
1117 else | |
1118 { | |
1119 /* 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
|
1120 debugging line if we're doing that. */ |
4391 | 1121 |
1122 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1123 { |
10411 | 1124 gnulib::fputs ("find_first_of (", stderr); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1125 |
20267
a9574e3c6e9e
Deprecate Array::length() and Sparse::length() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
20052
diff
changeset
|
1126 int len = names.numel (); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1127 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1128 for (int i = 0; i < len; i++) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1129 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1130 if (i == 0) |
10411 | 1131 gnulib::fputs (names[i].c_str (), stderr); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1132 else |
10411 | 1133 gnulib::fprintf (stderr, ", %s", names[i].c_str ()); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1134 } |
10411 | 1135 |
1136 gnulib::fputs (") =>", stderr); | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1137 } |
4391 | 1138 |
1139 log_search (ret_list); | |
1140 | |
1141 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) | |
10411 | 1142 gnulib::putc ('\n', stderr); |
4391 | 1143 } |
4378 | 1144 |
4390 | 1145 return ret_list; |
4378 | 1146 } |
1147 | |
1148 /* Search each element of PATH for each element of NAMES. Return the | |
1149 first one found. */ | |
1150 | |
4399 | 1151 /* Search each element of PATH for each element in the list of NAMES. |
1152 Return the first one found. */ | |
1153 | |
1154 static std::string | |
4390 | 1155 kpse_path_find_first_of (const std::string& path, const string_vector& names, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1156 bool must_exist) |
4378 | 1157 { |
4390 | 1158 string_vector ret_list = find_first_of (path, names, must_exist, false); |
1159 | |
1160 return ret_list.empty () ? std::string () : ret_list[0]; | |
4378 | 1161 } |
1162 | |
1163 /* Search each element of PATH for each element of NAMES and return a | |
1164 list containing everything found, in the order found. */ | |
1165 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1166 /* Like 'kpse_path_find_first_of' with MUST_EXIST true, but return a |
4399 | 1167 list of all the filenames (or NULL if none), instead of taking the |
1168 first. */ | |
1169 | |
1170 static string_vector | |
4390 | 1171 kpse_all_path_find_first_of (const std::string& path, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1172 const string_vector& names) |
4378 | 1173 { |
4390 | 1174 return find_first_of (path, names, true, true); |
4378 | 1175 } |
1176 | |
4399 | 1177 /* General expansion. Some of this file (the brace-expansion |
4378 | 1178 code from bash) is covered by the GPL; this is the only GPL-covered |
1179 code in kpathsea. The part of the file that I wrote (the first | |
1180 couple of functions) is covered by the LGPL. */ | |
1181 | |
1182 /* If NAME has a leading ~ or ~user, Unix-style, expand it to the user's | |
1183 home directory, and return a new malloced string. If no ~, or no | |
1184 <pwd.h>, just return NAME. */ | |
1185 | |
4389 | 1186 static std::string |
1187 kpse_tilde_expand (const std::string& name) | |
4378 | 1188 { |
4389 | 1189 std::string expansion; |
4391 | 1190 |
4378 | 1191 /* If no leading tilde, do nothing. */ |
5137 | 1192 if (name.empty () || name[0] != '~') |
4391 | 1193 { |
1194 expansion = name; | |
1195 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1196 /* 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
|
1197 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
|
1198 ... */ |
4391 | 1199 } |
1200 else if (name.length () == 1) | |
1201 { | |
20052
4b7b7ac7af2c
use get_home_directory instead of getenv ("HOME") (bug #44694)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
1202 expansion = octave_env::get_home_directory (); |
4391 | 1203 |
1204 if (expansion.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1205 expansion = "."; |
4391 | 1206 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1207 /* 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
|
1208 Should really check for doubled intermediate slashes, too. */ |
4378 | 1209 } |
4391 | 1210 else if (IS_DIR_SEP (name[1])) |
1211 { | |
1212 unsigned c = 1; | |
20052
4b7b7ac7af2c
use get_home_directory instead of getenv ("HOME") (bug #44694)
John W. Eaton <jwe@octave.org>
parents:
19898
diff
changeset
|
1213 std::string home = octave_env::get_home_directory (); |
4391 | 1214 |
1215 if (home.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1216 home = "."; |
4391 | 1217 |
1218 size_t home_len = home.length (); | |
1219 | |
1220 /* handle leading // */ | |
1221 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
|
1222 home = home.substr (1); |
4391 | 1223 |
1224 /* omit / after ~ */ | |
1225 if (IS_DIR_SEP (home[home_len - 1])) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1226 c++; |
4391 | 1227 |
1228 expansion = home + name.substr (c); | |
1229 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1230 /* 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
|
1231 OS/2 doesn't have this concept. */ |
4378 | 1232 } |
4391 | 1233 else |
4378 | 1234 #ifdef HAVE_PWD_H |
1235 { | |
1236 unsigned c = 2; | |
4391 | 1237 |
1238 /* find user name */ | |
1239 while (name.length () > c && ! IS_DIR_SEP (name[c])) | |
4378 | 1240 c++; |
4391 | 1241 |
1242 std::string user = name.substr (1, c-1); | |
1243 | |
4378 | 1244 /* 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
|
1245 which do not declare 'getpwnam' in <pwd.h>. */ |
4391 | 1246 octave_passwd p = octave_passwd::getpwnam (user); |
4378 | 1247 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1248 /* If no such user, just use '.'. */ |
4391 | 1249 std::string home = p ? p.dir () : std::string ("."); |
1250 | |
1251 if (home.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1252 home = "."; |
4391 | 1253 |
1254 /* handle leading // */ | |
1255 if (home.length () > 1 && IS_DIR_SEP (home[0]) && IS_DIR_SEP (home[1])) | |
1256 home = home.substr (1); | |
1257 | |
1258 /* If HOME ends in /, omit the / after ~user. */ | |
1259 if (name.length () > c && IS_DIR_SEP (home[home.length () - 1])) | |
1260 c++; | |
1261 | |
1262 expansion = name.length () > c ? home : home + name.substr (c); | |
4378 | 1263 } |
1264 #else /* not HAVE_PWD_H */ | |
4391 | 1265 expansion = name; |
4378 | 1266 #endif /* not HAVE_PWD_H */ |
1267 | |
4389 | 1268 return expansion; |
4378 | 1269 } |
1270 | |
1271 /* Do variable expansion first so ~${USER} works. (Besides, it's what the | |
1272 shells do.) */ | |
1273 | |
4399 | 1274 /* Call kpse_var_expand and kpse_tilde_expand (in that order). Result |
1275 is always in fresh memory, even if no expansions were done. */ | |
1276 | |
1277 static std::string | |
4389 | 1278 kpse_expand (const std::string& s) |
4378 | 1279 { |
4389 | 1280 std::string var_expansion = kpse_var_expand (s); |
1281 return kpse_tilde_expand (var_expansion); | |
4378 | 1282 } |
1283 | |
1284 /* Forward declarations of functions from the original expand.c */ | |
4397 | 1285 static string_vector brace_expand (const std::string&); |
4378 | 1286 |
1287 /* If $KPSE_DOT is defined in the environment, prepend it to any relative | |
1288 path components. */ | |
1289 | |
4389 | 1290 static std::string |
1291 kpse_expand_kpse_dot (const std::string& path) | |
4378 | 1292 { |
4389 | 1293 std::string ret; |
4391 | 1294 std::string kpse_dot = octave_env::getenv ("KPSE_DOT"); |
1295 | |
1296 if (kpse_dot.empty ()) | |
4378 | 1297 return path; |
1298 | |
8021 | 1299 for (kpse_path_iterator pi (path); pi != std::string::npos; pi++) |
4391 | 1300 { |
4394 | 1301 std::string elt = *pi; |
1302 | |
4391 | 1303 /* We assume that the !! magic is only used on absolute components. |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1304 Single "." get special treatment, as does "./" or its equivalent. */ |
4391 | 1305 |
4394 | 1306 size_t elt_len = elt.length (); |
1307 | |
1308 if (kpse_absolute_p (elt, false) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1309 || (elt_len > 1 && elt[0] == '!' && elt[1] == '!')) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1310 ret += elt + ENV_SEP_STRING; |
4394 | 1311 else if (elt_len == 1 && elt[0] == '.') |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1312 ret += kpse_dot + ENV_SEP_STRING; |
4394 | 1313 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
|
1314 ret += kpse_dot + elt.substr (1) + ENV_SEP_STRING; |
4391 | 1315 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1316 ret += kpse_dot + DIR_SEP_STRING + elt + ENV_SEP_STRING; |
4378 | 1317 } |
1318 | |
4389 | 1319 int len = ret.length (); |
1320 if (len > 0) | |
4395 | 1321 ret.resize (len-1); |
4389 | 1322 |
4378 | 1323 return ret; |
1324 } | |
1325 | |
1326 /* Do brace expansion on ELT; then do variable and ~ expansion on each | |
1327 element of the result; then do brace expansion again, in case a | |
1328 variable definition contained braces (e.g., $TEXMF). Return a | |
1329 string comprising all of the results separated by ENV_SEP_STRING. */ | |
1330 | |
4389 | 1331 static std::string |
4394 | 1332 kpse_brace_expand_element (const std::string& elt) |
4378 | 1333 { |
4389 | 1334 std::string ret; |
4378 | 1335 |
4397 | 1336 string_vector expansions = brace_expand (elt); |
1337 | |
20267
a9574e3c6e9e
Deprecate Array::length() and Sparse::length() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
20052
diff
changeset
|
1338 for (int i = 0; i < expansions.numel (); i++) |
4391 | 1339 { |
1340 /* Do $ and ~ expansion on each element. */ | |
1341 std::string x = kpse_expand (expansions[i]); | |
1342 | |
1343 if (x != expansions[i]) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1344 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1345 /* 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
|
1346 recursive variable definitions are not allowed, this recursion |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1347 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
|
1348 more than one level of recursion.) */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1349 x = kpse_brace_expand_element (x); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1350 } |
4391 | 1351 |
1352 ret += x + ENV_SEP_STRING; | |
4378 | 1353 } |
1354 | |
4389 | 1355 ret.resize (ret.length () - 1); |
4391 | 1356 |
4378 | 1357 return ret; |
1358 } | |
1359 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1360 /* Do brace expansion and call 'kpse_expand' on each element of the |
4399 | 1361 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
|
1362 no expansions were done). We don't call 'kpse_expand_default' |
4399 | 1363 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
|
1364 'kpse_init_format'. */ |
4399 | 1365 |
1366 static std::string | |
4397 | 1367 kpse_brace_expand (const std::string& path) |
4378 | 1368 { |
1369 /* Must do variable expansion first because if we have | |
1370 foo = .:~ | |
1371 TEXINPUTS = $foo | |
1372 we want to end up with TEXINPUTS = .:/home/karl. | |
1373 Since kpse_path_element is not reentrant, we must get all | |
1374 the path elements before we start the loop. */ | |
4389 | 1375 std::string tmp = kpse_var_expand (path); |
4394 | 1376 |
4389 | 1377 std::string ret; |
4378 | 1378 |
8021 | 1379 for (kpse_path_iterator pi (tmp); pi != std::string::npos; pi++) |
4391 | 1380 { |
4394 | 1381 std::string elt = *pi; |
1382 | |
4391 | 1383 /* Do brace expansion first, so tilde expansion happens in {~ka,~kb}. */ |
1384 std::string expansion = kpse_brace_expand_element (elt); | |
1385 ret += expansion + ENV_SEP_STRING; | |
1386 } | |
4378 | 1387 |
4394 | 1388 size_t len = ret.length (); |
4389 | 1389 if (len > 0) |
4395 | 1390 ret.resize (len-1); |
4389 | 1391 |
1392 return kpse_expand_kpse_dot (ret); | |
4378 | 1393 } |
4392 | 1394 |
4378 | 1395 /* Expand all special constructs in a path, and include only the actually |
1396 existing directories in the result. */ | |
4399 | 1397 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1398 /* Do brace expansion and call 'kpse_expand' on each argument of the |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1399 result, then expand any '//' constructs. The final expansion (always |
4399 | 1400 in fresh memory) is a path of all the existing directories that match |
1401 the pattern. */ | |
1402 | |
1403 static std::string | |
4397 | 1404 kpse_path_expand (const std::string& path) |
4378 | 1405 { |
4392 | 1406 std::string ret; |
4378 | 1407 unsigned len; |
1408 | |
1409 len = 0; | |
4391 | 1410 |
4378 | 1411 /* Expand variables and braces first. */ |
4389 | 1412 std::string tmp = kpse_brace_expand (path); |
4392 | 1413 |
4378 | 1414 /* Now expand each of the path elements, printing the results */ |
8021 | 1415 for (kpse_path_iterator pi (tmp); pi != std::string::npos; pi++) |
4391 | 1416 { |
4394 | 1417 std::string elt = *pi; |
1418 | |
4391 | 1419 str_llist_type *dirs; |
1420 | |
1421 /* Skip and ignore magic leading chars. */ | |
4394 | 1422 if (elt.length () > 1 && elt[0] == '!' && elt[1] == '!') |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1423 elt = elt.substr (2); |
4391 | 1424 |
1425 /* Do not touch the device if present */ | |
1426 if (NAME_BEGINS_WITH_DEVICE (elt)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1427 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1428 while (elt.length () > 3 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1429 && 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
|
1430 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1431 elt[2] = elt[1]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1432 elt[1] = elt[0]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1433 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1434 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1435 } |
4391 | 1436 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1437 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1438 /* We never want to search the whole disk. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1439 while (elt.length () > 1 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1440 && 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
|
1441 elt = elt.substr (1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1442 } |
4378 | 1443 |
4394 | 1444 /* 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
|
1445 Be faster to check the database, but this is more reliable. */ |
4394 | 1446 dirs = kpse_element_dirs (elt); |
1447 | |
1448 if (dirs && *dirs) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1449 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1450 str_llist_elt_type *dir; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1451 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1452 for (dir = *dirs; dir; dir = STR_LLIST_NEXT (*dir)) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1453 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1454 const std::string thedir = STR_LLIST (*dir); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1455 unsigned dirlen = thedir.length (); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1456 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1457 ret += thedir; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1458 len += dirlen; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1459 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1460 /* Retain trailing slash if that's the root directory. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1461 if (dirlen == 1 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1462 || (dirlen == 3 && NAME_BEGINS_WITH_DEVICE (thedir) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1463 && IS_DIR_SEP (thedir[2]))) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1464 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1465 ret += ENV_SEP_STRING; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1466 len++; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1467 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1468 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1469 ret[len-1] = ENV_SEP; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1470 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1471 } |
4378 | 1472 } |
4391 | 1473 |
4395 | 1474 if (len > 0) |
1475 ret.resize (len-1); | |
4391 | 1476 |
4378 | 1477 return ret; |
1478 } | |
4392 | 1479 |
4378 | 1480 /* braces.c -- code for doing word expansion in curly braces. Taken from |
16768 | 1481 bash 1.14.5. [And subsequently modified for kpatshea.] |
1482 | |
1483 Copyright (C) 1987,1991 Free Software Foundation, Inc. */ | |
4378 | 1484 |
4391 | 1485 #define brace_whitespace(c) (! (c) || (c) == ' ' || (c) == '\t' || (c) == '\n') |
4378 | 1486 |
1487 /* Basic idea: | |
1488 | |
1489 Segregate the text into 3 sections: preamble (stuff before an open brace), | |
1490 postamble (stuff after the matching close brace) and amble (stuff after | |
1491 preamble, and before postamble). Expand amble, and then tack on the | |
1492 expansions to preamble. Expand postamble, and tack on the expansions to | |
4391 | 1493 the result so far. */ |
4378 | 1494 |
4397 | 1495 /* Return a new array of strings which is the result of appending each |
1496 string in ARR2 to each string in ARR1. The resultant array is | |
1497 len (arr1) * len (arr2) long. For convenience, ARR1 (and its contents) | |
1498 are free ()'ed. ARR1 can be NULL, in that case, a new version of ARR2 | |
1499 is returned. */ | |
1500 | |
1501 static string_vector | |
1502 array_concat (const string_vector& arr1, const string_vector& arr2) | |
4378 | 1503 { |
4397 | 1504 string_vector result; |
1505 | |
1506 if (arr1.empty ()) | |
1507 result = arr2; | |
1508 else if (arr2.empty ()) | |
1509 result = arr1; | |
1510 else | |
1511 { | |
20267
a9574e3c6e9e
Deprecate Array::length() and Sparse::length() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
20052
diff
changeset
|
1512 int len1 = arr1.numel (); |
a9574e3c6e9e
Deprecate Array::length() and Sparse::length() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
20052
diff
changeset
|
1513 int len2 = arr2.numel (); |
4397 | 1514 |
1515 result = string_vector (len1 * len2); | |
1516 | |
1517 int k = 0; | |
1518 for (int i = 0; i < len2; i++) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1519 for (int j = 0; j < len1; j++) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1520 result[k++] = arr1[j] + arr2[i]; |
4397 | 1521 } |
1522 | |
1523 return result; | |
4378 | 1524 } |
1525 | |
4397 | 1526 static int brace_gobbler (const std::string&, int&, int); |
1527 static string_vector expand_amble (const std::string&); | |
4378 | 1528 |
1529 /* Return an array of strings; the brace expansion of TEXT. */ | |
4397 | 1530 static string_vector |
1531 brace_expand (const std::string& text) | |
4378 | 1532 { |
1533 /* Find the text of the preamble. */ | |
4397 | 1534 int i = 0; |
1535 int c = brace_gobbler (text, i, '{'); | |
1536 | |
1537 std::string preamble = text.substr (0, i); | |
1538 | |
1539 string_vector result = string_vector (preamble); | |
1540 | |
1541 if (c == '{') | |
4378 | 1542 { |
4397 | 1543 /* Find the amble. This is the stuff inside this set of braces. */ |
1544 int start = ++i; | |
1545 c = brace_gobbler (text, i, '}'); | |
1546 | |
1547 /* What if there isn't a matching close brace? */ | |
1548 if (! c) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1549 { |
19444
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1550 (*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
|
1551 ("Octave:pathsearch-syntax", |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
1552 "%s: Unmatched {", text.c_str ()); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1553 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1554 result = string_vector (text); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1555 } |
4397 | 1556 else |
10314
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 std::string amble = text.substr (start, i-start); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1559 result = array_concat (result, expand_amble (amble)); |
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 std::string postamble = text.substr (i+1); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1562 result = array_concat (result, brace_expand (postamble)); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1563 } |
4378 | 1564 } |
1565 | |
4397 | 1566 return result; |
4378 | 1567 } |
1568 | |
4397 | 1569 /* The character which is used to separate arguments. */ |
1570 static int brace_arg_separator = ','; | |
1571 | |
4378 | 1572 /* Expand the text found inside of braces. We simply try to split the |
1573 text at BRACE_ARG_SEPARATORs into separate strings. We then brace | |
1574 expand each slot which needs it, until there are no more slots which | |
1575 need it. */ | |
4397 | 1576 static string_vector |
1577 expand_amble (const std::string& text) | |
4378 | 1578 { |
4397 | 1579 string_vector result; |
1580 | |
1581 size_t text_len = text.length (); | |
1582 size_t start; | |
1583 int i, c; | |
1584 | |
1585 for (start = 0, i = 0, c = 1; c && start < text_len; start = ++i) | |
4378 | 1586 { |
4397 | 1587 int i0 = i; |
1588 int c0 = brace_gobbler (text, i0, brace_arg_separator); | |
1589 int i1 = i; | |
1590 int c1 = brace_gobbler (text, i1, ENV_SEP); | |
4378 | 1591 c = c0 | c1; |
1592 i = (i0 < i1 ? i0 : i1); | |
1593 | |
4397 | 1594 std::string tem = text.substr (start, i-start); |
1595 | |
1596 string_vector partial = brace_expand (tem); | |
1597 | |
1598 if (result.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1599 result = partial; |
4378 | 1600 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1601 result.append (partial); |
4378 | 1602 } |
4397 | 1603 |
1604 return result; | |
4378 | 1605 } |
1606 | |
1607 /* Start at INDEX, and skip characters in TEXT. Set INDEX to the | |
1608 index of the character matching SATISFY. This understands about | |
1609 quoting. Return the character that caused us to stop searching; | |
1610 this is either the same as SATISFY, or 0. */ | |
1611 static int | |
4397 | 1612 brace_gobbler (const std::string& text, int& indx, int satisfy) |
4378 | 1613 { |
18084
8e056300994b
Follow coding convention of defining and initializing only 1 variable per line in liboctave.
Rik <rik@octave.org>
parents:
17769
diff
changeset
|
1614 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
|
1615 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
|
1616 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
|
1617 int pass_next = 0; |
4397 | 1618 |
1619 size_t text_len = text.length (); | |
1620 | |
1621 size_t i = indx; | |
1622 | |
1623 for (; i < text_len; i++) | |
4378 | 1624 { |
4397 | 1625 c = text[i]; |
1626 | |
4378 | 1627 if (pass_next) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1628 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1629 pass_next = 0; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1630 continue; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1631 } |
4378 | 1632 |
1633 /* 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
|
1634 escape the quote character in a double-quoted string. */ |
4378 | 1635 if (c == '\\' && (quoted == 0 || quoted == '"' || quoted == '`')) |
1636 { | |
1637 pass_next = 1; | |
1638 continue; | |
1639 } | |
1640 | |
1641 if (quoted) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1642 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1643 if (c == quoted) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1644 quoted = 0; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1645 continue; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1646 } |
4378 | 1647 |
1648 if (c == '"' || c == '\'' || c == '`') | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1649 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1650 quoted = c; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1651 continue; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1652 } |
4391 | 1653 |
4378 | 1654 if (c == satisfy && !level && !quoted) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1655 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1656 /* 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
|
1657 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
|
1658 was preceded with whitespace. */ |
19898
17d647821d61
maint: More cleanup of C++ code to follow Octave coding conventions.
John W. Eaton <jwe@octave.org>
parents:
19731
diff
changeset
|
1659 if (c == '{' |
17d647821d61
maint: More cleanup of C++ code to follow Octave coding conventions.
John W. Eaton <jwe@octave.org>
parents:
19731
diff
changeset
|
1660 && ((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:
19731
diff
changeset
|
1661 && (i+1 < text_len |
17d647821d61
maint: More cleanup of C++ code to follow Octave coding conventions.
John W. Eaton <jwe@octave.org>
parents:
19731
diff
changeset
|
1662 && (brace_whitespace (text[i+1]) || text[i+1] == '}')))) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1663 continue; |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1664 /* 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
|
1665 in a '${ }' construct */ |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1666 if ((c != '{') || i == 0 || (text[i-1] != '$')) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1667 break; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1668 } |
4378 | 1669 |
1670 if (c == '{') | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1671 level++; |
4378 | 1672 else if (c == '}' && level) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1673 level--; |
4378 | 1674 } |
1675 | |
4397 | 1676 indx = i; |
1677 return c; | |
4378 | 1678 } |
1679 | |
1680 /* For each file format, we record the following information. The main | |
1681 thing that is not part of this structure is the environment variable | |
1682 lists. They are used directly in tex-file.c. We could incorporate | |
1683 them here, but it would complicate the code a bit. We could also do | |
1684 it via variable expansion, but not now, maybe not ever: | |
1685 ${PKFONTS-${TEXFONTS-/usr/local/lib/texmf/fonts//}}. */ | |
1686 | |
4399 | 1687 struct kpse_format_info_type |
4378 | 1688 { |
11501
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
1689 kpse_format_info_type (void) |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
1690 : type (), path (), raw_path (), path_source (), override_path (), |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
1691 client_path (), cnf_path (), default_path (), suffix () |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
1692 { } |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
1693 |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
1694 ~kpse_format_info_type (void) { } |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
1695 |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1696 std::string type; /* Human-readable description. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1697 std::string path; /* The search path to use. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1698 std::string raw_path; /* Pre-$~ (but post-default) expansion. */ |
4390 | 1699 std::string path_source; /* Where the path started from. */ |
1700 std::string override_path; /* From client environment variable. */ | |
1701 std::string client_path; /* E.g., from dvips's config.ps. */ | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1702 std::string cnf_path; /* From texmf.cnf. */ |
4390 | 1703 std::string default_path; /* If all else fails. */ |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1704 string_vector suffix; /* For kpse_find_file to check for/append. */ |
4399 | 1705 }; |
4378 | 1706 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1707 /* The sole variable of that type, indexed by 'kpse_file_format_type'. |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1708 Initialized by calls to 'kpse_find_file' for 'kpse_init_format'. */ |
4378 | 1709 static kpse_format_info_type kpse_format_info; |
1710 | |
1711 /* And EXPAND_DEFAULT calls kpse_expand_default on try_path and the | |
1712 present info->path. */ | |
4396 | 1713 #define EXPAND_DEFAULT(try_path, source_string) \ |
1714 do \ | |
1715 { \ | |
1716 if (! try_path.empty ()) \ | |
1717 { \ | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1718 info.raw_path = try_path; \ |
4396 | 1719 info.path = kpse_expand_default (try_path, info.path); \ |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1720 info.path_source = source_string; \ |
4396 | 1721 } \ |
1722 } \ | |
1723 while (0) | |
4378 | 1724 |
1725 static hash_table_type db; /* The hash table for all the ls-R's. */ | |
4928 | 1726 |
4378 | 1727 static hash_table_type alias_db; |
1728 | |
4390 | 1729 static string_vector db_dir_list; |
4392 | 1730 |
4378 | 1731 /* Return true if FILENAME could be in PATH_ELT, i.e., if the directory |
1732 part of FILENAME matches PATH_ELT. Have to consider // wildcards, but | |
1733 $ and ~ expansion have already been done. */ | |
4391 | 1734 |
4378 | 1735 static bool |
4390 | 1736 match (const std::string& filename_arg, const std::string& path_elt_arg) |
4378 | 1737 { |
4390 | 1738 const char *filename = filename_arg.c_str (); |
1739 const char *path_elt = path_elt_arg.c_str (); | |
1740 | |
4378 | 1741 const char *original_filename = filename; |
1742 bool matched = false; | |
4391 | 1743 |
1744 for (; *filename && *path_elt; filename++, path_elt++) | |
1745 { | |
4394 | 1746 if (*filename == *path_elt) /* normal character match */ |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1747 ; |
4391 | 1748 |
1749 else if (IS_DIR_SEP (*path_elt) /* at // */ | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1750 && original_filename < filename && IS_DIR_SEP (path_elt[-1])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1751 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1752 while (IS_DIR_SEP (*path_elt)) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1753 path_elt++; /* get past second and any subsequent /'s */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1754 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1755 if (*path_elt == 0) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1756 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1757 /* Trailing //, matches anything. We could make this |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1758 part of the other case, but it seems pointless to do |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1759 the extra work. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1760 matched = true; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1761 break; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1762 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1763 else |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1764 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1765 /* Intermediate //, have to match rest of PATH_ELT. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1766 for (; !matched && *filename; filename++) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1767 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1768 /* Try matching at each possible character. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1769 if (IS_DIR_SEP (filename[-1]) && *filename == *path_elt) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1770 matched = match (filename, path_elt); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1771 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1772 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1773 /* Prevent filename++ when *filename='\0'. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1774 break; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1775 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1776 } |
4391 | 1777 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1778 /* normal character nonmatch, quit */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1779 break; |
4378 | 1780 } |
1781 | |
1782 /* If we've reached the end of PATH_ELT, check that we're at the last | |
1783 component of FILENAME, we've matched. */ | |
4391 | 1784 if (! matched && *path_elt == 0) |
1785 { | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1786 /* Probably PATH_ELT ended with 'vf' or some such, and FILENAME |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1787 ends with 'vf/ptmr.vf'. In that case, we'll be at a |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1788 directory separator. On the other hand, if PATH_ELT ended |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1789 with a / (as in 'vf/'), FILENAME being the same 'vf/ptmr.vf', |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1790 we'll be at the 'p'. Upshot: if we're at a dir separator in |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1791 FILENAME, skip it. But if not, that's ok, as long as there |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1792 are no more dir separators. */ |
4391 | 1793 |
1794 if (IS_DIR_SEP (*filename)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1795 filename++; |
4391 | 1796 |
1797 while (*filename && !IS_DIR_SEP (*filename)) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1798 filename++; |
4391 | 1799 |
1800 matched = *filename == 0; | |
1801 } | |
1802 | |
4378 | 1803 return matched; |
1804 } | |
1805 | |
1806 /* If DB_DIR is a prefix of PATH_ELT, return true; otherwise false. | |
1807 That is, the question is whether to try the db for a file looked up | |
1808 in PATH_ELT. If PATH_ELT == ".", for example, the answer is no. If | |
1809 PATH_ELT == "/usr/local/lib/texmf/fonts//tfm", the answer is yes. | |
4391 | 1810 |
4378 | 1811 In practice, ls-R is only needed for lengthy subdirectory |
1812 comparisons, but there's no gain to checking PATH_ELT to see if it is | |
1813 a subdir match, since the only way to do that is to do a string | |
1814 search in it, which is all we do anyway. */ | |
4391 | 1815 |
4378 | 1816 static bool |
4390 | 1817 elt_in_db (const std::string& db_dir, const std::string& path_elt) |
4378 | 1818 { |
1819 bool found = false; | |
1820 | |
4390 | 1821 size_t db_dir_len = db_dir.length (); |
1822 size_t path_elt_len = path_elt.length (); | |
1823 | |
1824 size_t i = 0; | |
1825 | |
4394 | 1826 while (! found && db_dir[i] == path_elt[i]) |
4391 | 1827 { |
1828 i++; | |
1829 /* If we've matched the entire db directory, it's good. */ | |
1830 if (i == db_dir_len) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1831 found = true; |
4391 | 1832 |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1833 /* If we've reached the end of PATH_ELT, but not the end of the db |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1834 directory, it's no good. */ |
4391 | 1835 else if (i == path_elt_len) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1836 break; |
4391 | 1837 } |
4378 | 1838 |
1839 return found; | |
1840 } | |
4392 | 1841 |
4378 | 1842 /* Avoid doing anything if this PATH_ELT is irrelevant to the databases. */ |
1843 | |
4399 | 1844 /* Return list of matches for NAME in the ls-R file matching PATH_ELT. If |
1845 ALL is set, return (null-terminated list) of all matches, else just | |
1846 the first. If no matches, return a pointer to an empty list. If no | |
1847 databases can be read, or PATH_ELT is not in any of the databases, | |
1848 return NULL. */ | |
1849 | |
1850 static string_vector | |
4390 | 1851 kpse_db_search (const std::string& name_arg, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1852 const std::string& orig_path_elt, bool all) |
4378 | 1853 { |
1854 bool done; | |
4390 | 1855 string_vector ret; |
1856 string_vector aliases; | |
4378 | 1857 bool relevant = false; |
4390 | 1858 |
4394 | 1859 std::string name = name_arg; |
4391 | 1860 |
4378 | 1861 /* If we failed to build the database (or if this is the recursive |
1862 call to build the db path), quit. */ | |
4398 | 1863 if (! db.buckets) |
4390 | 1864 return ret; |
4391 | 1865 |
4378 | 1866 /* When tex-glyph.c calls us looking for, e.g., dpi600/cmr10.pk, we |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1867 won't find it unless we change NAME to just 'cmr10.pk' and append |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1868 '/dpi600' to PATH_ELT. We are justified in using a literal '/' |
4378 | 1869 here, since that's what tex-glyph.c unconditionally uses in |
1870 DPI_BITMAP_SPEC. But don't do anything if the / begins NAME; that | |
1871 should never happen. */ | |
4394 | 1872 std::string path_elt; |
1873 size_t last_slash = name.rfind ('/'); | |
8021 | 1874 if (last_slash != std::string::npos && last_slash != 0) |
4390 | 1875 { |
4394 | 1876 std::string dir_part = name.substr (0, last_slash); |
1877 name = name.substr (last_slash + 1); | |
4390 | 1878 } |
1879 else | |
4394 | 1880 path_elt = orig_path_elt; |
4378 | 1881 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1882 /* Don't bother doing any lookups if this 'path_elt' isn't covered by |
4378 | 1883 any of database directories. We do this not so much because the |
1884 extra couple of hash lookups matter -- they don't -- but rather | |
1885 because we want to return NULL in this case, so path_search can | |
1886 know to do a disk search. */ | |
20267
a9574e3c6e9e
Deprecate Array::length() and Sparse::length() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
20052
diff
changeset
|
1887 for (int e = 0; ! relevant && e < db_dir_list.numel (); e++) |
4390 | 1888 relevant = elt_in_db (db_dir_list[e], path_elt); |
1889 | |
4391 | 1890 if (! relevant) |
4390 | 1891 return ret; |
4378 | 1892 |
1893 /* If we have aliases for this name, use them. */ | |
1894 if (alias_db.buckets) | |
1895 aliases = hash_lookup (alias_db, name); | |
1896 | |
4390 | 1897 /* Push aliases up by one and insert the original name at the front. */ |
20267
a9574e3c6e9e
Deprecate Array::length() and Sparse::length() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
20052
diff
changeset
|
1898 int len = aliases.numel (); |
4390 | 1899 aliases.resize (len+1); |
1900 for (int i = len; i > 0; i--) | |
1901 aliases[i] = aliases[i - 1]; | |
1902 aliases[0] = name; | |
4378 | 1903 |
1904 done = false; | |
20267
a9574e3c6e9e
Deprecate Array::length() and Sparse::length() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
20052
diff
changeset
|
1905 len = aliases.numel (); |
4390 | 1906 for (int i = 0; i < len && !done; i++) |
1907 { | |
1908 std::string atry = aliases[i]; | |
1909 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1910 /* We have an ls-R db. Look up 'atry'. */ |
4390 | 1911 string_vector db_dirs = hash_lookup (db, atry); |
1912 | |
1913 /* For each filename found, see if it matches the path element. For | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1914 example, if we have .../cx/cmr10.300pk and .../ricoh/cmr10.300pk, |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1915 and the path looks like .../cx, we don't want the ricoh file. */ |
4390 | 1916 |
20267
a9574e3c6e9e
Deprecate Array::length() and Sparse::length() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
20052
diff
changeset
|
1917 int db_dirs_len = db_dirs.numel (); |
4390 | 1918 for (int j = 0; j < db_dirs_len && !done; j++) |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1919 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1920 std::string db_file = db_dirs[j] + atry; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1921 bool matched = match (db_file, path_elt); |
4378 | 1922 |
1923 #ifdef KPSE_DEBUG | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1924 if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1925 DEBUGF3 ("db:match (%s,%s) = %d\n", |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1926 db_file.c_str (), path_elt.c_str (), matched); |
4378 | 1927 #endif |
1928 | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1929 /* We got a hit in the database. Now see if the file actually |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1930 exists, possibly under an alias. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1931 if (matched) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1932 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1933 std::string found; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1934 std::string tmp = kpse_readable_file (db_file); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1935 if (! tmp.empty ()) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1936 found = db_file; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1937 else |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1938 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1939 /* The hit in the DB doesn't exist in disk. Now try |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1940 all its aliases. For example, suppose we have a |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1941 hierarchy on CD, thus 'mf.bas', but ls-R contains |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
1942 'mf.base'. Find it anyway. Could probably work |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1943 around this with aliases, but this is pretty easy |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1944 and shouldn't hurt. The upshot is that if one of |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1945 the aliases actually exists, we use that. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1946 |
20267
a9574e3c6e9e
Deprecate Array::length() and Sparse::length() in favour of ::numel().
Carnë Draug <carandraug@octave.org>
parents:
20052
diff
changeset
|
1947 int aliases_len = aliases.numel (); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1948 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1949 for (int k = 1; k < aliases_len && found.empty (); k++) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1950 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1951 std::string aatry = db_dirs[j] + aliases[k]; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1952 tmp = kpse_readable_file (aatry); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1953 if (! tmp.empty ()) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1954 found = aatry; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1955 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1956 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1957 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1958 /* If we have a real file, add it to the list, maybe done. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1959 if (! found.empty ()) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1960 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1961 ret.append (found); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1962 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1963 if (! (all || found.empty ())) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1964 done = true; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1965 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1966 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
1967 } |
4378 | 1968 } |
4391 | 1969 |
4378 | 1970 return ret; |
1971 } | |
1972 | |
4399 | 1973 /* Expand extra colons. */ |
4378 | 1974 |
1975 /* Check for leading colon first, then trailing, then doubled, since | |
1976 that is fastest. Usually it will be leading or trailing. */ | |
1977 | |
4399 | 1978 /* Replace a leading or trailing or doubled : in PATH with DFLT. If |
1979 no extra colons, return PATH. Only one extra colon is replaced. | |
1980 DFLT may not be NULL. */ | |
1981 | |
1982 static std::string | |
4394 | 1983 kpse_expand_default (const std::string& path, const std::string& fallback) |
4378 | 1984 { |
4394 | 1985 std::string expansion; |
1986 | |
1987 size_t path_len = path.length (); | |
1988 | |
1989 if (path_len == 0) | |
1990 expansion = fallback; | |
4378 | 1991 |
1992 /* Solitary or leading :? */ | |
4394 | 1993 else if (IS_ENV_SEP (path[0])) |
4378 | 1994 { |
4394 | 1995 expansion = path_len == 1 ? fallback : fallback + path; |
4378 | 1996 } |
1997 | |
1998 /* Sorry about the assignment in the middle of the expression, but | |
1999 conventions were made to be flouted and all that. I don't see the | |
2000 point of calling strlen twice or complicating the logic just to | |
2001 avoid the assignment (especially now that I've pointed it out at | |
2002 such great length). */ | |
4394 | 2003 else if (IS_ENV_SEP (path[path_len-1])) |
2004 expansion = path + fallback; | |
4378 | 2005 |
2006 /* OK, not leading or trailing. Check for doubled. */ | |
2007 else | |
2008 { | |
2009 /* What we'll return if we find none. */ | |
4394 | 2010 expansion = path; |
2011 | |
2012 for (size_t i = 0; i < path_len; i++) | |
4378 | 2013 { |
4394 | 2014 if (i + 1 < path_len |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2015 && IS_ENV_SEP (path[i]) && IS_ENV_SEP (path[i+1])) |
4394 | 2016 { |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2017 /* We have a doubled colon. */ |
4391 | 2018 |
4378 | 2019 /* Copy stuff up to and including the first colon. */ |
2020 /* 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
|
2021 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
|
2022 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2023 break; |
4378 | 2024 } |
2025 } | |
2026 } | |
4391 | 2027 |
4378 | 2028 return expansion; |
2029 } | |
2030 | |
4399 | 2031 /* Translate a path element to its corresponding director{y,ies}. */ |
4378 | 2032 |
2033 /* To avoid giving prototypes for all the routines and then their real | |
2034 definitions, we give all the subroutines first. The entry point is | |
2035 the last routine in the file. */ | |
4392 | 2036 |
4378 | 2037 /* Make a copy of DIR (unless it's null) and save it in L. Ensure that |
2038 DIR ends with a DIR_SEP for the benefit of later searches. */ | |
2039 | |
2040 static void | |
4390 | 2041 dir_list_add (str_llist_type *l, const std::string& dir) |
4378 | 2042 { |
4390 | 2043 char last_char = dir[dir.length () - 1]; |
4407 | 2044 |
4390 | 2045 std::string saved_dir = dir; |
4407 | 2046 |
2047 if (! (IS_DIR_SEP (last_char) || IS_DEVICE_SEP (last_char))) | |
4390 | 2048 saved_dir += DIR_SEP_STRING; |
4391 | 2049 |
4378 | 2050 str_llist_add (l, saved_dir); |
2051 } | |
2052 | |
4390 | 2053 /* Return true if FN is a directory or a symlink to a directory, |
2054 false if not. */ | |
2055 | |
2056 static bool | |
2057 dir_p (const std::string& fn) | |
2058 { | |
2059 #ifdef WIN32 | |
4391 | 2060 unsigned int fa = GetFileAttributes (fn.c_str ()); |
4390 | 2061 return (fa != 0xFFFFFFFF && (fa & FILE_ATTRIBUTE_DIRECTORY)); |
2062 #else | |
2063 struct stat stats; | |
2064 return stat (fn.c_str (), &stats) == 0 && S_ISDIR (stats.st_mode); | |
2065 #endif | |
2066 } | |
4391 | 2067 |
4378 | 2068 /* If DIR is a directory, add it to the list L. */ |
2069 | |
2070 static void | |
4390 | 2071 checked_dir_list_add (str_llist_type *l, const std::string& dir) |
4378 | 2072 { |
2073 if (dir_p (dir)) | |
2074 dir_list_add (l, dir); | |
2075 } | |
4392 | 2076 |
4378 | 2077 /* The cache. Typically, several paths have the same element; for |
2078 example, /usr/local/lib/texmf/fonts//. We don't want to compute the | |
2079 expansion of such a thing more than once. Even though we also cache | |
2080 the dir_links call, that's not enough -- without this path element | |
2081 caching as well, the execution time doubles. */ | |
2082 | |
4398 | 2083 struct cache_entry |
4378 | 2084 { |
11501
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
2085 cache_entry (void) : key (), value (0) { } |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
2086 |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
2087 ~cache_entry (void) { } |
331fcc41ca23
data member initialization fixes
John W. Eaton <jwe@octave.org>
parents:
11236
diff
changeset
|
2088 |
4398 | 2089 std::string key; |
4378 | 2090 str_llist_type *value; |
4398 | 2091 }; |
2092 | |
2093 static cache_entry *the_cache = 0; | |
4378 | 2094 static unsigned cache_length = 0; |
2095 | |
2096 /* Associate KEY with VALUE. We implement the cache as a simple linear | |
2097 list, since it's unlikely to ever be more than a dozen or so elements | |
2098 long. We don't bother to check here if PATH has already been saved; | |
2099 we always add it to our list. We copy KEY but not VALUE; not sure | |
2100 that's right, but it seems to be all that's needed. */ | |
2101 | |
2102 static void | |
4398 | 2103 cache (const std::string key, str_llist_type *value) |
4378 | 2104 { |
4398 | 2105 cache_entry *new_cache = new cache_entry [cache_length+1]; |
2106 | |
4399 | 2107 for (unsigned i = 0; i < cache_length; i++) |
4398 | 2108 { |
2109 new_cache[i].key = the_cache[i].key; | |
2110 new_cache[i].value = the_cache[i].value; | |
2111 } | |
2112 | |
2113 delete [] the_cache; | |
2114 | |
2115 the_cache = new_cache; | |
2116 | |
2117 the_cache[cache_length].key = key; | |
2118 the_cache[cache_length].value = value; | |
2119 | |
4378 | 2120 cache_length++; |
2121 } | |
2122 | |
2123 /* To retrieve, just check the list in order. */ | |
2124 | |
2125 static str_llist_type * | |
4398 | 2126 cached (const std::string& key) |
4378 | 2127 { |
2128 unsigned p; | |
4391 | 2129 |
4378 | 2130 for (p = 0; p < cache_length; p++) |
2131 { | |
4398 | 2132 if (key == the_cache[p].key) |
4378 | 2133 return the_cache[p].value; |
2134 } | |
4391 | 2135 |
4398 | 2136 return 0; |
4378 | 2137 } |
4392 | 2138 |
4378 | 2139 /* Handle the magic path constructs. */ |
2140 | |
2141 /* Declare recursively called routine. */ | |
4398 | 2142 static void expand_elt (str_llist_type *, const std::string&, unsigned); |
4378 | 2143 |
2144 /* POST is a pointer into the original element (which may no longer be | |
2145 ELT) to just after the doubled DIR_SEP, perhaps to the null. Append | |
2146 subdirectories of ELT (up to ELT_LENGTH, which must be a /) to | |
2147 STR_LIST_PTR. */ | |
2148 | |
2149 #ifdef WIN32 | |
4398 | 2150 |
4378 | 2151 /* Shared across recursive calls, it acts like a stack. */ |
4398 | 2152 static std::string dirname; |
2153 | |
2154 #else /* WIN32 */ | |
2155 | |
2156 /* Return -1 if FN isn't a directory, else its number of links. | |
2157 Duplicate the call to stat; no need to incur overhead of a function | |
2158 call for that little bit of cleanliness. */ | |
2159 | |
2160 static int | |
2161 dir_links (const std::string& fn) | |
2162 { | |
2163 std::map<std::string, long> link_table; | |
2164 | |
2165 long ret; | |
2166 | |
2167 if (link_table.find (fn) != link_table.end ()) | |
2168 ret = link_table[fn]; | |
2169 else | |
2170 { | |
2171 struct stat stats; | |
2172 | |
2173 ret = stat (fn.c_str (), &stats) == 0 && S_ISDIR (stats.st_mode) | |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
2174 ? stats.st_nlink : static_cast<unsigned> (-1); |
4398 | 2175 |
2176 link_table[fn] = ret; | |
2177 | |
2178 #ifdef KPSE_DEBUG | |
2179 if (KPSE_DEBUG_P (KPSE_DEBUG_STAT)) | |
2180 DEBUGF2 ("dir_links (%s) => %ld\n", fn.c_str (), ret); | |
4378 | 2181 #endif |
4398 | 2182 } |
2183 | |
2184 return ret; | |
2185 } | |
2186 | |
2187 #endif /* WIN32 */ | |
4378 | 2188 |
2189 static void | |
4398 | 2190 do_subdir (str_llist_type *str_list_ptr, const std::string& elt, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2191 unsigned elt_length, const std::string& post) |
4378 | 2192 { |
2193 #ifdef WIN32 | |
2194 WIN32_FIND_DATA find_file_data; | |
2195 HANDLE hnd; | |
2196 int proceed; | |
2197 #else | |
2198 DIR *dir; | |
2199 struct dirent *e; | |
2200 #endif /* not WIN32 */ | |
4389 | 2201 |
4398 | 2202 std::string name = elt.substr (0, elt_length); |
4389 | 2203 |
4378 | 2204 assert (IS_DIR_SEP (elt[elt_length - 1]) |
2205 || IS_DEVICE_SEP (elt[elt_length - 1])); | |
4391 | 2206 |
4378 | 2207 #if defined (WIN32) |
4398 | 2208 |
2209 dirname = name + "/*.*"; /* "*.*" or "*" -- seems equivalent. */ | |
2210 | |
2211 hnd = FindFirstFile (dirname.c_str (), &find_file_data); | |
4378 | 2212 |
4389 | 2213 if (hnd == INVALID_HANDLE_VALUE) |
4378 | 2214 return; |
2215 | |
2216 /* Include top level before subdirectories, if nothing to match. */ | |
4398 | 2217 if (post.empty ()) |
4390 | 2218 dir_list_add (str_list_ptr, name); |
4398 | 2219 else |
2220 { | |
2221 /* If we do have something to match, see if it exists. For | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
2222 example, POST might be 'pk/ljfour', and they might have a |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
2223 directory '$TEXMF/fonts/pk/ljfour' that we should find. */ |
4398 | 2224 name += post; |
2225 expand_elt (str_list_ptr, name, elt_length); | |
2226 name.resize (elt_length); | |
2227 } | |
2228 | |
4378 | 2229 proceed = 1; |
4398 | 2230 |
4391 | 2231 while (proceed) |
2232 { | |
2233 if (find_file_data.cFileName[0] != '.') | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2234 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2235 /* Construct the potential subdirectory name. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2236 name += find_file_data.cFileName; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2237 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2238 if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2239 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2240 /* It's a directory, so append the separator. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2241 name += DIR_SEP_STRING; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2242 unsigned potential_len = name.length (); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2243 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2244 do_subdir (str_list_ptr, name, potential_len, post); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2245 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2246 name.resize (elt_length); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2247 } |
4398 | 2248 |
4391 | 2249 proceed = FindNextFile (hnd, &find_file_data); |
4378 | 2250 } |
4398 | 2251 |
4391 | 2252 FindClose (hnd); |
4378 | 2253 |
2254 #else /* not WIN32 */ | |
2255 | |
2256 /* If we can't open it, quit. */ | |
10411 | 2257 dir = gnulib::opendir (name.c_str ()); |
4398 | 2258 |
2259 if (! dir) | |
4389 | 2260 return; |
4391 | 2261 |
4378 | 2262 /* Include top level before subdirectories, if nothing to match. */ |
4398 | 2263 if (post.empty ()) |
4390 | 2264 dir_list_add (str_list_ptr, name); |
4378 | 2265 else |
4398 | 2266 { |
2267 /* If we do have something to match, see if it exists. For | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
2268 example, POST might be 'pk/ljfour', and they might have a |
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
2269 directory '$TEXMF/fonts/pk/ljfour' that we should find. */ |
4389 | 2270 name += post; |
4398 | 2271 expand_elt (str_list_ptr, name, elt_length); |
4389 | 2272 name.resize (elt_length); |
4378 | 2273 } |
2274 | |
14155 | 2275 while ((e = gnulib::readdir (dir))) |
4398 | 2276 { |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
2277 /* If it begins with a '.', never mind. (This allows "hidden" |
4378 | 2278 directories that the algorithm won't find.) */ |
4398 | 2279 |
4378 | 2280 if (e->d_name[0] != '.') |
2281 { | |
2282 int links; | |
4391 | 2283 |
4378 | 2284 /* Construct the potential subdirectory name. */ |
4389 | 2285 name += e->d_name; |
4391 | 2286 |
4378 | 2287 /* If we can't stat it, or if it isn't a directory, continue. */ |
4398 | 2288 links = dir_links (name); |
4378 | 2289 |
2290 if (links >= 0) | |
4391 | 2291 { |
4378 | 2292 /* It's a directory, so append the separator. */ |
4389 | 2293 name += DIR_SEP_STRING; |
2294 unsigned potential_len = name.length (); | |
4391 | 2295 |
4378 | 2296 /* Should we recurse? To see if the subdirectory is a |
2297 leaf, check if it has two links (one for . and one for | |
2298 ..). This means that symbolic links to directories do | |
2299 not affect the leaf-ness. This is arguably wrong, but | |
2300 the only alternative I know of is to stat every entry | |
2301 in the directory, and that is unacceptably slow. | |
4391 | 2302 |
4378 | 2303 The #ifdef here makes all this configurable at |
2304 compile-time, so that if we're using VMS directories or | |
2305 some such, we can still find subdirectories, even if it | |
2306 is much slower. */ | |
2307 #ifdef ST_NLINK_TRICK | |
5622 | 2308 if (links != 2) |
4378 | 2309 #endif /* not ST_NLINK_TRICK */ |
2310 /* All criteria are met; find subdirectories. */ | |
4398 | 2311 do_subdir (str_list_ptr, name, potential_len, post); |
4378 | 2312 #ifdef ST_NLINK_TRICK |
4398 | 2313 else if (post.empty ()) |
4378 | 2314 /* Nothing to match, no recursive subdirectories to |
2315 look for: we're done with this branch. Add it. */ | |
4390 | 2316 dir_list_add (str_list_ptr, name); |
4378 | 2317 #endif |
2318 } | |
2319 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
2320 /* Remove the directory entry we just checked from 'name'. */ |
4389 | 2321 name.resize (elt_length); |
4378 | 2322 } |
2323 } | |
4391 | 2324 |
4378 | 2325 xclosedir (dir); |
2326 #endif /* not WIN32 */ | |
2327 } | |
2328 | |
2329 /* Assume ELT is non-empty and non-NULL. Return list of corresponding | |
2330 directories (with no terminating NULL entry) in STR_LIST_PTR. Start | |
2331 looking for magic constructs at START. */ | |
2332 | |
2333 static void | |
4398 | 2334 expand_elt (str_llist_type *str_list_ptr, const std::string& elt, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2335 unsigned /* start */) |
4378 | 2336 { |
6306 | 2337 #if 0 |
2338 // We don't want magic constructs. | |
2339 | |
4398 | 2340 size_t elt_len = elt.length (); |
2341 | |
2342 size_t dir = start; | |
2343 | |
2344 | |
2345 while (dir < elt_len) | |
4378 | 2346 { |
4398 | 2347 if (IS_DIR_SEP (elt[dir])) |
4378 | 2348 { |
2349 /* If two or more consecutive /'s, find subdirectories. */ | |
4398 | 2350 if (++dir < elt_len && IS_DIR_SEP (elt[dir])) |
4378 | 2351 { |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2352 size_t i = dir; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2353 while (i < elt_len && IS_DIR_SEP (elt[i])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2354 i++; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2355 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2356 std::string post = elt.substr (i); |
4398 | 2357 |
2358 do_subdir (str_list_ptr, elt, dir, post); | |
2359 | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2360 return; |
4378 | 2361 } |
2362 | |
2363 /* No special stuff at this slash. Keep going. */ | |
2364 } | |
4398 | 2365 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2366 dir++; |
4378 | 2367 } |
6306 | 2368 #endif |
4391 | 2369 |
4378 | 2370 /* When we reach the end of ELT, it will be a normal filename. */ |
2371 checked_dir_list_add (str_list_ptr, elt); | |
2372 } | |
4392 | 2373 |
4378 | 2374 /* Here is the entry point. Returns directory list for ELT. */ |
2375 | |
4399 | 2376 /* Given a path element ELT, return a pointer to a NULL-terminated list |
2377 of the corresponding (existing) directory or directories, with | |
2378 trailing slashes, or NULL. If ELT is the empty string, check the | |
2379 current working directory. | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11501
diff
changeset
|
2380 |
4399 | 2381 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
|
2382 most likely only useful to be called from 'kpse_path_search', which |
4399 | 2383 has already assumed expansion has been done. */ |
2384 | |
2385 static str_llist_type * | |
4398 | 2386 kpse_element_dirs (const std::string& elt) |
4378 | 2387 { |
2388 str_llist_type *ret; | |
2389 | |
2390 /* If given nothing, return nothing. */ | |
4398 | 2391 if (elt.empty ()) |
2392 return 0; | |
4378 | 2393 |
2394 /* If we've already cached the answer for ELT, return it. */ | |
2395 ret = cached (elt); | |
2396 if (ret) | |
2397 return ret; | |
2398 | |
2399 /* We're going to have a real directory list to return. */ | |
4390 | 2400 ret = new str_llist_type; |
4398 | 2401 *ret = 0; |
4378 | 2402 |
2403 /* We handle the hard case in a subroutine. */ | |
2404 expand_elt (ret, elt, 0); | |
2405 | |
2406 /* Remember the directory list we just found, in case future calls are | |
2407 made with the same ELT. */ | |
2408 cache (elt, ret); | |
2409 | |
2410 #ifdef KPSE_DEBUG | |
2411 if (KPSE_DEBUG_P (KPSE_DEBUG_EXPAND)) | |
2412 { | |
4398 | 2413 DEBUGF1 ("path element %s =>", elt.c_str ()); |
4378 | 2414 if (ret) |
2415 { | |
2416 str_llist_elt_type *e; | |
2417 for (e = *ret; e; e = STR_LLIST_NEXT (*e)) | |
10411 | 2418 gnulib::fprintf (stderr, " %s", (STR_LLIST (*e)).c_str ()); |
4378 | 2419 } |
10411 | 2420 gnulib::putc ('\n', stderr); |
12912
e116dd862879
use gnulib:: qualifiers for more stdio functions
John W. Eaton <jwe@octave.org>
parents:
11586
diff
changeset
|
2421 gnulib::fflush (stderr); |
4378 | 2422 } |
2423 #endif /* KPSE_DEBUG */ | |
2424 | |
2425 return ret; | |
2426 } | |
2427 | |
4386 | 2428 #ifndef WIN32 |
4385 | 2429 void |
2430 xclosedir (DIR *d) | |
2431 { | |
10411 | 2432 int ret = gnulib::closedir (d); |
4391 | 2433 |
4385 | 2434 if (ret != 0) |
2435 FATAL ("closedir failed"); | |
2436 } | |
4386 | 2437 #endif |
4385 | 2438 |
4399 | 2439 /* Implementation of a linked list of strings. */ |
4385 | 2440 |
2441 /* Add the new string STR to the end of the list L. */ | |
2442 | |
5085 | 2443 static void |
4390 | 2444 str_llist_add (str_llist_type *l, const std::string& str) |
4385 | 2445 { |
2446 str_llist_elt_type *e; | |
4390 | 2447 str_llist_elt_type *new_elt = new str_llist_elt_type; |
4391 | 2448 |
4385 | 2449 /* The new element will be at the end of the list. */ |
2450 STR_LLIST (*new_elt) = str; | |
2451 STR_LLIST_MOVED (*new_elt) = 0; | |
4398 | 2452 STR_LLIST_NEXT (*new_elt) = 0; |
4391 | 2453 |
4385 | 2454 /* Find the current end of the list. */ |
2455 for (e = *l; e && STR_LLIST_NEXT (*e); e = STR_LLIST_NEXT (*e)) | |
2456 ; | |
4391 | 2457 |
2458 if (! e) | |
4385 | 2459 *l = new_elt; |
2460 else | |
2461 STR_LLIST_NEXT (*e) = new_elt; | |
2462 } | |
4392 | 2463 |
4385 | 2464 /* Move an element towards the top. The idea is that when a file is |
2465 found in a given directory, later files will likely be in that same | |
2466 directory, and looking for the file in all the directories in between | |
2467 is thus a waste. */ | |
2468 | |
5085 | 2469 static void |
4385 | 2470 str_llist_float (str_llist_type *l, str_llist_elt_type *mover) |
2471 { | |
2472 str_llist_elt_type *last_moved, *unmoved; | |
4391 | 2473 |
4385 | 2474 /* If we've already moved this element, never mind. */ |
2475 if (STR_LLIST_MOVED (*mover)) | |
2476 return; | |
4391 | 2477 |
4385 | 2478 /* Find the first unmoved element (to insert before). We're |
2479 guaranteed this will terminate, since MOVER itself is currently | |
2480 unmoved, and it must be in L (by hypothesis). */ | |
4398 | 2481 for (last_moved = 0, unmoved = *l; STR_LLIST_MOVED (*unmoved); |
4385 | 2482 last_moved = unmoved, unmoved = STR_LLIST_NEXT (*unmoved)) |
2483 ; | |
2484 | |
2485 /* If we are the first unmoved element, nothing to relink. */ | |
2486 if (unmoved != mover) | |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
2487 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
2488 /* Remember 'mover's current successor, so we can relink 'mover's |
4385 | 2489 predecessor to it. */ |
2490 str_llist_elt_type *before_mover; | |
2491 str_llist_elt_type *after_mover = STR_LLIST_NEXT (*mover); | |
4391 | 2492 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
2493 /* Find 'mover's predecessor. */ |
4385 | 2494 for (before_mover = unmoved; STR_LLIST_NEXT (*before_mover) != mover; |
2495 before_mover = STR_LLIST_NEXT (*before_mover)) | |
2496 ; | |
4391 | 2497 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
2498 /* 'before_mover' now links to 'after_mover'. */ |
4385 | 2499 STR_LLIST_NEXT (*before_mover) = after_mover; |
2500 | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
2501 /* Insert 'mover' before 'unmoved' and after 'last_moved' (or at |
4385 | 2502 the head of the list). */ |
2503 STR_LLIST_NEXT (*mover) = unmoved; | |
4391 | 2504 if (! last_moved) |
4385 | 2505 *l = mover; |
2506 else | |
2507 STR_LLIST_NEXT (*last_moved) = mover; | |
2508 } | |
2509 | |
2510 /* We've moved it. */ | |
2511 STR_LLIST_MOVED (*mover) = 1; | |
2512 } | |
2513 | |
4399 | 2514 /* Variable expansion. */ |
4385 | 2515 |
2516 /* We have to keep track of variables being expanded, otherwise | |
2517 constructs like TEXINPUTS = $TEXINPUTS result in an infinite loop. | |
2518 (Or indirectly recursive variables, etc.) Our simple solution is to | |
2519 add to a list each time an expansion is started, and check the list | |
2520 before expanding. */ | |
2521 | |
4391 | 2522 static std::map <std::string, bool> expansions; |
4385 | 2523 |
2524 static void | |
4391 | 2525 expanding (const std::string& var, bool xp) |
4385 | 2526 { |
4391 | 2527 expansions[var] = xp; |
4385 | 2528 } |
2529 | |
2530 /* Return whether VAR is currently being expanding. */ | |
2531 | |
4391 | 2532 static bool |
2533 expanding_p (const std::string& var) | |
4385 | 2534 { |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
2535 return (expansions.find (var) != expansions.end ()) ? expansions[var] : false; |
4385 | 2536 } |
4392 | 2537 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
2538 /* 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
|
2539 at START and ends at END. If 'var' is not set, do not complain. |
4385 | 2540 This is a subroutine for the more complicated expansion function. */ |
2541 | |
2542 static void | |
4391 | 2543 expand (std::string &expansion, const std::string& var) |
4385 | 2544 { |
4391 | 2545 if (expanding_p (var)) |
2546 { | |
19444
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
2547 (*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
|
2548 ("Octave:pathsearch-syntax", |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
2549 "kpathsea: variable '%s' references itself (eventually)", |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2550 var.c_str ()); |
4385 | 2551 } |
4391 | 2552 else |
2553 { | |
2554 /* Check for an environment variable. */ | |
2555 std::string value = octave_env::getenv (var); | |
2556 | |
2557 if (! value.empty ()) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2558 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2559 expanding (var, true); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2560 std::string tmp = kpse_var_expand (value); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2561 expanding (var, false); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2562 expansion += tmp; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2563 } |
4391 | 2564 } |
4385 | 2565 } |
4392 | 2566 |
4385 | 2567 /* Can't think of when it would be useful to change these (and the |
2568 diagnostic messages assume them), but ... */ | |
2569 #ifndef IS_VAR_START /* starts all variable references */ | |
2570 #define IS_VAR_START(c) ((c) == '$') | |
2571 #endif | |
2572 #ifndef IS_VAR_CHAR /* variable name constituent */ | |
2573 #define IS_VAR_CHAR(c) (isalnum (c) || (c) == '_') | |
2574 #endif | |
2575 #ifndef IS_VAR_BEGIN_DELIMITER /* start delimited variable name (after $) */ | |
2576 #define IS_VAR_BEGIN_DELIMITER(c) ((c) == '{') | |
2577 #endif | |
2578 #ifndef IS_VAR_END_DELIMITER | |
2579 #define IS_VAR_END_DELIMITER(c) ((c) == '}') | |
2580 #endif | |
2581 | |
2582 /* Maybe we should support some or all of the various shell ${...} | |
2583 constructs, especially ${var-value}. */ | |
2584 | |
5085 | 2585 static std::string |
4391 | 2586 kpse_var_expand (const std::string& src) |
4385 | 2587 { |
4389 | 2588 std::string expansion; |
4391 | 2589 |
2590 size_t src_len = src.length (); | |
2591 | |
4385 | 2592 /* Copy everything but variable constructs. */ |
4391 | 2593 for (size_t i = 0; i < src_len; i++) |
2594 { | |
2595 if (IS_VAR_START (src[i])) | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2596 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2597 i++; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2598 |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14155
diff
changeset
|
2599 /* Three cases: '$VAR', '${VAR}', '$<anything-else>'. */ |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2600 if (IS_VAR_CHAR (src[i])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2601 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2602 /* $V: collect name constituents, then expand. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2603 size_t var_end = i; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2604 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2605 do |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2606 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2607 var_end++; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2608 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2609 while (IS_VAR_CHAR (src[var_end])); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2610 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2611 var_end--; /* had to go one past */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2612 expand (expansion, src.substr (i, var_end - i + 1)); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2613 i = var_end; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2614 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2615 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2616 else if (IS_VAR_BEGIN_DELIMITER (src[i])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2617 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2618 /* ${: scan ahead for matching delimiter, then expand. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2619 size_t var_end = ++i; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2620 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2621 while (var_end < src_len && !IS_VAR_END_DELIMITER (src[var_end])) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2622 var_end++; |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2623 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2624 if (var_end == src_len) |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2625 { |
19444
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
2626 (*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
|
2627 ("Octave:pathsearch-syntax", |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
2628 "%s: No matching } for ${", src.c_str ()); |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2629 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
|
2630 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2631 else |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2632 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2633 expand (expansion, src.substr (i, var_end - i)); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2634 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
|
2635 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2636 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2637 else |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2638 { |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2639 /* $<something-else>: error. */ |
19444
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
2640 (*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
|
2641 ("Octave:pathsearch-syntax", |
95c533ed464b
use warning IDs for all warnings in liboctave
John W. Eaton <jwe@octave.org>
parents:
18084
diff
changeset
|
2642 "%s: Unrecognized variable construct '$%c'", |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2643 src.c_str (), src[i]); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2644 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2645 /* Just ignore those chars and keep going. */ |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2646 } |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2647 } |
4391 | 2648 else |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10182
diff
changeset
|
2649 expansion += src[i]; |
4391 | 2650 } |
4389 | 2651 |
2652 return expansion; | |
4385 | 2653 } |