Mercurial > hg > octave-nkf
view liboctave/oct-env.cc @ 6773:b6e2ab6a8421
[project @ 2007-07-10 12:41:35 by dbateman]
author | dbateman |
---|---|
date | Tue, 10 Jul 2007 12:41:35 +0000 |
parents | e96d66e0d634 |
children | 5e3350bdd91d |
line wrap: on
line source
/* Copyright (C) 1996, 1997 John W. Eaton This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* The functions listed below were adapted from a similar functions from GNU Bash, the Bourne Again SHell, copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc. octave_env::do_absolute_pathname octave_env::do_base_pathname octave_env::do_chdir octave_env::do_getcwd octave_env::do_make_absolute octave_env::do_polite_directory_format octave_env::pathname_backup */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <cctype> #include <cstdlib> #include <string> #ifdef HAVE_UNISTD_H #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif #include <unistd.h> #endif #include "file-ops.h" #include "lo-error.h" #include "lo-sysdep.h" #include "lo-utils.h" #include "oct-env.h" #include "oct-passwd.h" #include "oct-syscalls.h" octave_env::octave_env (void) : follow_symbolic_links (true), verbatim_pwd (true), current_directory (), program_name (), program_invocation_name (), user_name (), host_name () { // Get a real value for the current directory. do_getcwd (); // Etc. do_get_user_name (); do_get_host_name (); } octave_env *octave_env::instance = 0; bool octave_env::instance_ok (void) { bool retval = true; if (! instance) instance = new octave_env (); if (! instance) { (*current_liboctave_error_handler) ("unable to create current working directoy object!"); retval = false; } return retval; } std::string octave_env::polite_directory_format (const std::string& name) { return (instance_ok ()) ? instance->do_polite_directory_format (name) : std::string (); } bool octave_env::absolute_pathname (const std::string& s) { return (instance_ok ()) ? instance->do_absolute_pathname (s) : false; } std::string octave_env::base_pathname (const std::string& s) { return (instance_ok ()) ? instance->do_base_pathname (s) : std::string (); } std::string octave_env::make_absolute (const std::string& s, const std::string& dot_path) { return (instance_ok ()) ? instance->do_make_absolute (s, dot_path) : std::string (); } std::string octave_env::getcwd () { return (instance_ok ()) ? instance->do_getcwd () : std::string (); } std::string octave_env::get_home_directory () { return (instance_ok ()) ? instance->do_get_home_directory () : std::string (); } std::string octave_env::get_program_name (void) { return (instance_ok ()) ? instance->program_name : std::string (); } std::string octave_env::get_program_invocation_name (void) { return (instance_ok ()) ? instance->program_invocation_name : std::string (); } void octave_env::set_program_name (const std::string& s) { if (instance_ok ()) instance->do_set_program_name (s); } std::string octave_env::get_user_name (void) { return (instance_ok ()) ? instance->do_get_user_name () : std::string (); } std::string octave_env::get_host_name (void) { return (instance_ok ()) ? instance->do_get_host_name () : std::string (); } // FIXME -- this leaves no way to distinguish between a // variable that is not set and one that is set to the empty string. // Is this a problem? std::string octave_env::getenv (const std::string& name) { return (instance_ok ()) ? instance->do_getenv (name) : std::string (); } void octave_env::putenv (const std::string& name, const std::string& value) { octave_putenv (name, value); } bool octave_env::have_x11_display (void) { std::string display = getenv ("DISPLAY"); return ! display.empty (); } bool octave_env::chdir (const std::string& newdir) { return (instance_ok ()) ? instance->do_chdir (newdir) : false; } void octave_env::do_set_program_name (const std::string& s) const { program_invocation_name = s; size_t pos = program_invocation_name.find_last_of (file_ops::dir_sep_chars); program_name = (pos == NPOS) ? program_invocation_name : program_invocation_name.substr (pos+1); } // Return a pretty pathname. If the first part of the pathname is the // same as $HOME, then replace that with `~'. std::string octave_env::do_polite_directory_format (const std::string& name) const { std::string retval; std::string home_dir = do_get_home_directory (); size_t len = home_dir.length (); if (len > 1 && home_dir == name.substr (0, len) && (name.length () == len || file_ops::is_dir_sep (name[len]))) { retval = "~"; retval.append (name.substr (len)); } else retval = name; return retval; } bool octave_env::do_absolute_pathname (const std::string& s) const { size_t len = s.length (); if (len == 0) return false; if (file_ops::is_dir_sep (s[0])) return true; #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) if ((len == 2 && isalpha (s[0]) && s[1] == ':') || (len > 2 && isalpha (s[0]) && s[1] == ':' && file_ops::is_dir_sep (s[2]))) return true; #endif return false; } // Return the `basename' of the pathname in STRING (the stuff after // the last directory separator). If STRING is not a full pathname, // simply return it. std::string octave_env::do_base_pathname (const std::string& s) const { if (! do_absolute_pathname (s)) return s; size_t pos = s.find_last_of (file_ops::dir_sep_chars); if (pos == NPOS) return s; else return s.substr (pos+1); } // Turn STRING (a pathname) into an absolute pathname, assuming that // DOT_PATH contains the symbolic location of the current directory. std::string octave_env::do_make_absolute (const std::string& s, const std::string& dot_path) const { #if defined (__EMX__) if (s.length () > 1 && s[1] == ':') return s; #endif if (dot_path.empty () || s.empty () || do_absolute_pathname (s)) return s; std::string current_dir = dot_path; if (current_dir.empty ()) current_dir = do_getcwd (); size_t pos = current_dir.length () - 1; if (! file_ops::is_dir_sep (current_dir[pos])) current_dir.append (file_ops::dir_sep_str); // FIXME -- this is probably not correct for all systems. size_t i = 0; size_t slen = s.length (); while (i < slen) { if (s[i] == '.') { if (i + 1 == slen) return current_dir; if (file_ops::is_dir_sep (s[i+1])) { i += 2; continue; } if (s[i+1] == '.' && (i + 2 == slen || file_ops::is_dir_sep (s[i+2]))) { i += 2; if (i != slen) i++; pathname_backup (current_dir, 1); continue; } } size_t tmp = s.find_first_of (file_ops::dir_sep_chars, i); if (tmp == NPOS) { current_dir.append (s, i, tmp-i); break; } else { current_dir.append (s, i, tmp-i+1); i = tmp + 1; } } return current_dir; } // Return a string which is the current working directory. std::string octave_env::do_getcwd () const { if (! follow_symbolic_links) current_directory = ""; if (verbatim_pwd || current_directory.empty ()) current_directory = ::octave_getcwd (); return current_directory; } // This value is not cached because it can change while Octave is // running. std::string octave_env::do_get_home_directory (void) const { std::string hd = do_getenv ("HOME"); #if defined (__MINGW32__) || defined (_MSC_VER) // Maybe we are started directly from cmd.exe. if (hd.empty ()) { std::string drv = do_getenv ("HOMEDRIVE"); if (drv.empty ()) hd = do_getenv ("HOMEPATH"); else hd = drv + do_getenv ("HOMEPATH"); } #endif if (hd.empty ()) { octave_passwd pw = octave_passwd::getpwuid (octave_syscalls::getuid ()); hd = pw ? pw.dir () : std::string (file_ops::dir_sep_str); } return hd; } std::string octave_env::do_get_user_name (void) const { if (user_name.empty ()) { octave_passwd pw = octave_passwd::getpwuid (octave_syscalls::getuid ()); user_name = pw ? pw.name () : std::string ("unknown"); } return user_name; } std::string octave_env::do_get_host_name (void) const { if (host_name.empty ()) { char hostname[256]; int status = octave_gethostname (hostname, 255); host_name = (status < 0) ? "unknown" : hostname; } return host_name; } std::string octave_env::do_getenv (const std::string& name) const { char *value = ::getenv (name.c_str ()); return value ? value : ""; } // Do the work of changing to the directory NEWDIR. Handle symbolic // link following, etc. bool octave_env::do_chdir (const std::string& newdir) { bool retval = false; std::string tmp; if (follow_symbolic_links) { if (current_directory.empty ()) do_getcwd (); if (current_directory.empty ()) tmp = newdir; else tmp = do_make_absolute (newdir, current_directory); // Get rid of trailing directory separator. size_t len = tmp.length (); if (len > 1) { if (file_ops::is_dir_sep (tmp[--len])) tmp.resize (len); } if (! ::octave_chdir (tmp)) { current_directory = tmp; retval = true; } } else retval = (! ::octave_chdir (newdir)); return retval; } // Remove the last N directories from PATH. void octave_env::pathname_backup (std::string& path, int n) const { if (path.empty ()) return; size_t i = path.length () - 1; while (n--) { while (file_ops::is_dir_sep (path[i]) && i > 0) i--; while (! file_ops::is_dir_sep (path[i]) && i > 0) i--; i++; } path.resize (i); } void octave_env::error (int err_num) const { (*current_liboctave_error_handler) ("%s", strerror (err_num)); } void octave_env::error (const std::string& s) const { (*current_liboctave_error_handler) ("%s", s.c_str ()); } /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */