Mercurial > hg > octave-nkf
view liboctave/oct-env.cc @ 12302:1b71befc2f40 release-3-4-x
oct-parse.yy (class stdio_stream_reader): disallow copying
author | Pascal Dupuis <Pascal.Dupuis@uclouvain.be> |
---|---|
date | Sun, 30 Jan 2011 04:38:10 -0500 |
parents | 12df7854fa7c |
children | 7dd7cccf0757 |
line wrap: on
line source
/* Copyright (C) 1996-2011 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */ /* 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 <cstring> #include <string> #include <sys/types.h> #include <unistd.h> #include "progname.h" #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 (), prog_name (), prog_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 directory 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; } bool octave_env::rooted_relative_pathname (const std::string& s) { return (instance_ok ()) ? instance->do_rooted_relative_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::get_current_directory () { 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->prog_name : std::string (); } std::string octave_env::get_program_invocation_name (void) { return (instance_ok ()) ? instance->prog_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 { // For gnulib. ::set_program_name (s.c_str ()); // Let gnulib strip off things like the "lt-" prefix from libtool. prog_invocation_name = program_name; size_t pos = prog_invocation_name.find_last_of (file_ops::dir_sep_chars ()); // Also keep a shortened version of the program name. prog_name = (pos == std::string::npos) ? prog_invocation_name : prog_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; } bool octave_env::do_rooted_relative_pathname (const std::string& s) const { size_t len = s.length (); if (len == 0) return false; if (len == 1 && s[0] == '.') return true; if (len > 1 && s[0] == '.' && file_ops::is_dir_sep (s[1])) return true; if (len == 2 && s[0] == '.' && s[1] == '.') return true; if (len > 2 && s[0] == '.' && s[1] == '.' && file_ops::is_dir_sep (s[2])) return true; 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) || do_rooted_relative_pathname (s))) return s; size_t pos = s.find_last_of (file_ops::dir_sep_chars ()); if (pos == std::string::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 (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 == std::string::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[1024]; int status = gnulib::gethostname (hostname, 1023); 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", gnulib::strerror (err_num)); } void octave_env::error (const std::string& s) const { (*current_liboctave_error_handler) ("%s", s.c_str ()); }