Mercurial > hg > octave-nkf
annotate liboctave/oct-env.cc @ 8006:b0e7bbe7cd47
oct-env.cc (octave_env::instance_ok): fix type in error message
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Mon, 04 Aug 2008 22:32:47 -0400 |
parents | 7e6002d15d4d |
children | a2ab20ba78f7 |
rev | line source |
---|---|
2926 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2005, 2006, |
4 2007 John W. Eaton | |
2926 | 5 |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
2926 | 12 |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
2926 | 21 |
22 */ | |
23 | |
24 /* | |
25 | |
26 The functions listed below were adapted from a similar functions | |
27 from GNU Bash, the Bourne Again SHell, copyright (C) 1987, 1989, 1991 | |
28 Free Software Foundation, Inc. | |
29 | |
30 octave_env::do_absolute_pathname | |
31 octave_env::do_base_pathname | |
32 octave_env::do_chdir | |
33 octave_env::do_getcwd | |
34 octave_env::do_make_absolute | |
35 octave_env::do_polite_directory_format | |
36 octave_env::pathname_backup | |
37 | |
38 */ | |
39 | |
40 #ifdef HAVE_CONFIG_H | |
41 #include <config.h> | |
42 #endif | |
43 | |
4093 | 44 #include <cctype> |
2926 | 45 #include <cstdlib> |
7048 | 46 #include <cstring> |
4093 | 47 |
3504 | 48 #include <string> |
2926 | 49 |
50 #ifdef HAVE_UNISTD_H | |
51 #ifdef HAVE_SYS_TYPES_H | |
52 #include <sys/types.h> | |
53 #endif | |
54 #include <unistd.h> | |
55 #endif | |
56 | |
4097 | 57 #include "file-ops.h" |
2926 | 58 #include "lo-error.h" |
59 #include "lo-sysdep.h" | |
60 #include "lo-utils.h" | |
61 #include "oct-env.h" | |
2934 | 62 #include "oct-passwd.h" |
2947 | 63 #include "oct-syscalls.h" |
2926 | 64 |
65 octave_env::octave_env (void) | |
66 : follow_symbolic_links (true), verbatim_pwd (true), | |
67 current_directory (), program_name (), program_invocation_name (), | |
68 user_name (), host_name () | |
69 { | |
70 // Get a real value for the current directory. | |
71 do_getcwd (); | |
72 | |
73 // Etc. | |
74 do_get_user_name (); | |
75 | |
76 do_get_host_name (); | |
77 } | |
78 | |
79 octave_env *octave_env::instance = 0; | |
80 | |
81 bool | |
82 octave_env::instance_ok (void) | |
83 { | |
84 bool retval = true; | |
85 | |
86 if (! instance) | |
87 instance = new octave_env (); | |
88 | |
89 if (! instance) | |
90 { | |
91 (*current_liboctave_error_handler) | |
8006
b0e7bbe7cd47
oct-env.cc (octave_env::instance_ok): fix type in error message
John W. Eaton <jwe@octave.org>
parents:
7609
diff
changeset
|
92 ("unable to create current working directory object!"); |
2926 | 93 |
94 retval = false; | |
95 } | |
96 | |
97 return retval; | |
98 } | |
99 | |
3504 | 100 std::string |
101 octave_env::polite_directory_format (const std::string& name) | |
2926 | 102 { |
103 return (instance_ok ()) | |
3504 | 104 ? instance->do_polite_directory_format (name) : std::string (); |
2926 | 105 } |
106 | |
107 bool | |
3504 | 108 octave_env::absolute_pathname (const std::string& s) |
2926 | 109 { |
110 return (instance_ok ()) | |
111 ? instance->do_absolute_pathname (s) : false; | |
112 } | |
113 | |
6838 | 114 bool |
115 octave_env::rooted_relative_pathname (const std::string& s) | |
116 { | |
117 return (instance_ok ()) | |
118 ? instance->do_rooted_relative_pathname (s) : false; | |
119 } | |
120 | |
3504 | 121 std::string |
122 octave_env::base_pathname (const std::string& s) | |
2926 | 123 { |
124 return (instance_ok ()) | |
3504 | 125 ? instance->do_base_pathname (s) : std::string (); |
2926 | 126 } |
127 | |
3504 | 128 std::string |
129 octave_env::make_absolute (const std::string& s, const std::string& dot_path) | |
2926 | 130 { |
131 return (instance_ok ()) | |
3504 | 132 ? instance->do_make_absolute (s, dot_path) : std::string (); |
2926 | 133 } |
134 | |
3504 | 135 std::string |
2926 | 136 octave_env::getcwd () |
137 { | |
138 return (instance_ok ()) | |
3504 | 139 ? instance->do_getcwd () : std::string (); |
2926 | 140 } |
141 | |
3504 | 142 std::string |
2926 | 143 octave_env::get_home_directory () |
144 { | |
145 return (instance_ok ()) | |
3504 | 146 ? instance->do_get_home_directory () : std::string (); |
2926 | 147 } |
148 | |
3504 | 149 std::string |
2926 | 150 octave_env::get_program_name (void) |
151 { | |
152 return (instance_ok ()) | |
3504 | 153 ? instance->program_name : std::string (); |
2926 | 154 } |
155 | |
3504 | 156 std::string |
2926 | 157 octave_env::get_program_invocation_name (void) |
158 { | |
159 return (instance_ok ()) | |
3504 | 160 ? instance->program_invocation_name : std::string (); |
2926 | 161 } |
162 | |
163 void | |
3504 | 164 octave_env::set_program_name (const std::string& s) |
2926 | 165 { |
166 if (instance_ok ()) | |
167 instance->do_set_program_name (s); | |
168 } | |
169 | |
3504 | 170 std::string |
2926 | 171 octave_env::get_user_name (void) |
172 { | |
173 return (instance_ok ()) | |
3504 | 174 ? instance->do_get_user_name () : std::string (); |
2926 | 175 } |
176 | |
3504 | 177 std::string |
2926 | 178 octave_env::get_host_name (void) |
179 { | |
180 return (instance_ok ()) | |
3504 | 181 ? instance->do_get_host_name () : std::string (); |
2926 | 182 } |
183 | |
5775 | 184 // FIXME -- this leaves no way to distinguish between a |
2926 | 185 // variable that is not set and one that is set to the empty string. |
186 // Is this a problem? | |
187 | |
3504 | 188 std::string |
189 octave_env::getenv (const std::string& name) | |
2926 | 190 { |
191 return (instance_ok ()) | |
3504 | 192 ? instance->do_getenv (name) : std::string (); |
2926 | 193 } |
194 | |
195 void | |
3504 | 196 octave_env::putenv (const std::string& name, const std::string& value) |
2926 | 197 { |
198 octave_putenv (name, value); | |
199 } | |
200 | |
201 bool | |
5489 | 202 octave_env::have_x11_display (void) |
203 { | |
204 std::string display = getenv ("DISPLAY"); | |
205 | |
206 return ! display.empty (); | |
207 } | |
208 | |
209 bool | |
3504 | 210 octave_env::chdir (const std::string& newdir) |
2926 | 211 { |
212 return (instance_ok ()) | |
213 ? instance->do_chdir (newdir) : false; | |
214 } | |
215 | |
216 void | |
3504 | 217 octave_env::do_set_program_name (const std::string& s) const |
2926 | 218 { |
219 program_invocation_name = s; | |
220 | |
4101 | 221 size_t pos = program_invocation_name.find_last_of (file_ops::dir_sep_chars); |
2926 | 222 |
223 program_name = (pos == NPOS) | |
224 ? program_invocation_name : program_invocation_name.substr (pos+1); | |
225 } | |
226 | |
227 // Return a pretty pathname. If the first part of the pathname is the | |
228 // same as $HOME, then replace that with `~'. | |
229 | |
3504 | 230 std::string |
231 octave_env::do_polite_directory_format (const std::string& name) const | |
2926 | 232 { |
3504 | 233 std::string retval; |
2926 | 234 |
3504 | 235 std::string home_dir = do_get_home_directory (); |
2926 | 236 |
237 size_t len = home_dir.length (); | |
238 | |
3516 | 239 if (len > 1 && home_dir == name.substr (0, len) |
4097 | 240 && (name.length () == len || file_ops::is_dir_sep (name[len]))) |
2926 | 241 { |
242 retval = "~"; | |
243 retval.append (name.substr (len)); | |
244 } | |
245 else | |
246 retval = name; | |
247 | |
248 return retval; | |
249 } | |
250 | |
251 bool | |
3504 | 252 octave_env::do_absolute_pathname (const std::string& s) const |
2926 | 253 { |
4087 | 254 size_t len = s.length (); |
255 | |
256 if (len == 0) | |
257 return false; | |
2926 | 258 |
4097 | 259 if (file_ops::is_dir_sep (s[0])) |
2926 | 260 return true; |
261 | |
4101 | 262 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) |
4088 | 263 if ((len == 2 && isalpha (s[0]) && s[1] == ':') |
4097 | 264 || (len > 2 && isalpha (s[0]) && s[1] == ':' |
265 && file_ops::is_dir_sep (s[2]))) | |
4087 | 266 return true; |
267 #endif | |
268 | |
2926 | 269 return false; |
270 } | |
271 | |
6838 | 272 bool |
273 octave_env::do_rooted_relative_pathname (const std::string& s) const | |
274 { | |
275 size_t len = s.length (); | |
276 | |
277 if (len == 0) | |
278 return false; | |
279 | |
280 if (len == 1 && s[0] == '.') | |
281 return true; | |
282 | |
283 if (len > 1 && s[0] == '.' && file_ops::is_dir_sep (s[1])) | |
284 return true; | |
285 | |
286 if (len == 2 && s[0] == '.' && s[1] == '.') | |
287 return true; | |
288 | |
289 if (len > 2 && s[0] == '.' && s[1] == '.' && file_ops::is_dir_sep (s[2])) | |
290 return true; | |
291 | |
292 return false; | |
293 } | |
294 | |
2926 | 295 // Return the `basename' of the pathname in STRING (the stuff after |
4097 | 296 // the last directory separator). If STRING is not a full pathname, |
297 // simply return it. | |
2926 | 298 |
3504 | 299 std::string |
300 octave_env::do_base_pathname (const std::string& s) const | |
2926 | 301 { |
7609
7e6002d15d4d
octave_env::do_base_pathname: handle rooted relativel names
John W. Eaton <jwe@octave.org>
parents:
7048
diff
changeset
|
302 if (! (do_absolute_pathname (s) || do_rooted_relative_pathname (s))) |
2926 | 303 return s; |
304 | |
4101 | 305 size_t pos = s.find_last_of (file_ops::dir_sep_chars); |
2926 | 306 |
307 if (pos == NPOS) | |
308 return s; | |
309 else | |
310 return s.substr (pos+1); | |
311 } | |
312 | |
313 // Turn STRING (a pathname) into an absolute pathname, assuming that | |
4097 | 314 // DOT_PATH contains the symbolic location of the current directory. |
2926 | 315 |
3504 | 316 std::string |
317 octave_env::do_make_absolute (const std::string& s, | |
318 const std::string& dot_path) const | |
2926 | 319 { |
320 #if defined (__EMX__) | |
321 if (s.length () > 1 && s[1] == ':') | |
322 return s; | |
323 #endif | |
324 | |
4087 | 325 if (dot_path.empty () || s.empty () || do_absolute_pathname (s)) |
2926 | 326 return s; |
327 | |
4097 | 328 std::string current_dir = dot_path; |
2926 | 329 |
4097 | 330 if (current_dir.empty ()) |
331 current_dir = do_getcwd (); | |
2926 | 332 |
4097 | 333 size_t pos = current_dir.length () - 1; |
2926 | 334 |
4097 | 335 if (! file_ops::is_dir_sep (current_dir[pos])) |
4101 | 336 current_dir.append (file_ops::dir_sep_str); |
4097 | 337 |
5775 | 338 // FIXME -- this is probably not correct for all systems. |
2926 | 339 |
340 size_t i = 0; | |
341 size_t slen = s.length (); | |
342 | |
343 while (i < slen) | |
344 { | |
345 if (s[i] == '.') | |
346 { | |
347 if (i + 1 == slen) | |
4097 | 348 return current_dir; |
2926 | 349 |
4097 | 350 if (file_ops::is_dir_sep (s[i+1])) |
2926 | 351 { |
352 i += 2; | |
353 continue; | |
354 } | |
355 | |
4097 | 356 if (s[i+1] == '.' |
357 && (i + 2 == slen || file_ops::is_dir_sep (s[i+2]))) | |
2926 | 358 { |
359 i += 2; | |
360 | |
361 if (i != slen) | |
362 i++; | |
363 | |
4097 | 364 pathname_backup (current_dir, 1); |
2926 | 365 |
366 continue; | |
367 } | |
368 } | |
369 | |
4101 | 370 size_t tmp = s.find_first_of (file_ops::dir_sep_chars, i); |
2926 | 371 |
372 if (tmp == NPOS) | |
373 { | |
4097 | 374 current_dir.append (s, i, tmp-i); |
2926 | 375 break; |
376 } | |
377 else | |
378 { | |
4097 | 379 current_dir.append (s, i, tmp-i+1); |
2926 | 380 i = tmp + 1; |
381 } | |
382 } | |
383 | |
4097 | 384 return current_dir; |
2926 | 385 } |
386 | |
4097 | 387 // Return a string which is the current working directory. |
2926 | 388 |
3504 | 389 std::string |
4097 | 390 octave_env::do_getcwd () const |
2926 | 391 { |
392 if (! follow_symbolic_links) | |
393 current_directory = ""; | |
394 | |
395 if (verbatim_pwd || current_directory.empty ()) | |
396 current_directory = ::octave_getcwd (); | |
397 | |
398 return current_directory; | |
399 } | |
400 | |
401 // This value is not cached because it can change while Octave is | |
402 // running. | |
403 | |
3504 | 404 std::string |
2926 | 405 octave_env::do_get_home_directory (void) const |
406 { | |
3504 | 407 std::string hd = do_getenv ("HOME"); |
2926 | 408 |
6096 | 409 #if defined (__MINGW32__) || defined (_MSC_VER) |
410 // Maybe we are started directly from cmd.exe. | |
5451 | 411 if (hd.empty ()) |
5454 | 412 { |
413 std::string drv = do_getenv ("HOMEDRIVE"); | |
414 if (drv.empty ()) | |
415 hd = do_getenv ("HOMEPATH"); | |
416 else | |
417 hd = drv + do_getenv ("HOMEPATH"); | |
418 } | |
5451 | 419 #endif |
420 | |
2947 | 421 if (hd.empty ()) |
422 { | |
423 octave_passwd pw = octave_passwd::getpwuid (octave_syscalls::getuid ()); | |
424 | |
4101 | 425 hd = pw ? pw.dir () : std::string (file_ops::dir_sep_str); |
2947 | 426 } |
427 | |
428 return hd; | |
2926 | 429 } |
430 | |
3504 | 431 std::string |
2926 | 432 octave_env::do_get_user_name (void) const |
433 { | |
434 if (user_name.empty ()) | |
435 { | |
2947 | 436 octave_passwd pw = octave_passwd::getpwuid (octave_syscalls::getuid ()); |
2926 | 437 |
3504 | 438 user_name = pw ? pw.name () : std::string ("unknown"); |
2926 | 439 } |
440 | |
441 return user_name; | |
442 } | |
443 | |
3504 | 444 std::string |
2926 | 445 octave_env::do_get_host_name (void) const |
446 { | |
447 if (host_name.empty ()) | |
448 { | |
449 char hostname[256]; | |
450 | |
3803 | 451 int status = octave_gethostname (hostname, 255); |
2926 | 452 |
3185 | 453 host_name = (status < 0) ? "unknown" : hostname; |
2926 | 454 } |
455 | |
456 return host_name; | |
457 } | |
458 | |
3504 | 459 std::string |
460 octave_env::do_getenv (const std::string& name) const | |
2926 | 461 { |
462 char *value = ::getenv (name.c_str ()); | |
463 | |
464 return value ? value : ""; | |
465 } | |
466 | |
467 // Do the work of changing to the directory NEWDIR. Handle symbolic | |
468 // link following, etc. | |
469 | |
470 bool | |
3504 | 471 octave_env::do_chdir (const std::string& newdir) |
2926 | 472 { |
473 bool retval = false; | |
474 | |
3504 | 475 std::string tmp; |
2926 | 476 |
477 if (follow_symbolic_links) | |
478 { | |
479 if (current_directory.empty ()) | |
480 do_getcwd (); | |
481 | |
482 if (current_directory.empty ()) | |
483 tmp = newdir; | |
484 else | |
485 tmp = do_make_absolute (newdir, current_directory); | |
486 | |
4097 | 487 // Get rid of trailing directory separator. |
2926 | 488 |
489 size_t len = tmp.length (); | |
490 | |
491 if (len > 1) | |
492 { | |
4097 | 493 if (file_ops::is_dir_sep (tmp[--len])) |
2926 | 494 tmp.resize (len); |
495 } | |
496 | |
497 if (! ::octave_chdir (tmp)) | |
498 { | |
499 current_directory = tmp; | |
500 retval = true; | |
501 } | |
502 } | |
503 else | |
504 retval = (! ::octave_chdir (newdir)); | |
505 | |
506 return retval; | |
507 } | |
508 | |
509 // Remove the last N directories from PATH. | |
510 | |
511 void | |
3504 | 512 octave_env::pathname_backup (std::string& path, int n) const |
2926 | 513 { |
514 if (path.empty ()) | |
515 return; | |
516 | |
517 size_t i = path.length () - 1; | |
518 | |
519 while (n--) | |
520 { | |
4097 | 521 while (file_ops::is_dir_sep (path[i]) && i > 0) |
2926 | 522 i--; |
523 | |
4097 | 524 while (! file_ops::is_dir_sep (path[i]) && i > 0) |
2926 | 525 i--; |
526 | |
527 i++; | |
528 } | |
529 | |
530 path.resize (i); | |
531 } | |
532 | |
533 void | |
534 octave_env::error (int err_num) const | |
535 { | |
536 (*current_liboctave_error_handler) ("%s", strerror (err_num)); | |
537 } | |
538 | |
539 void | |
3504 | 540 octave_env::error (const std::string& s) const |
2926 | 541 { |
542 (*current_liboctave_error_handler) ("%s", s.c_str ()); | |
543 } | |
544 | |
545 /* | |
546 ;;; Local Variables: *** | |
547 ;;; mode: C++ *** | |
548 ;;; End: *** | |
549 */ |