メインページ   クラス階層   構成   ファイル一覧   構成メンバ   ファイルメンバ  

oct-env.cc

解説を見る。
00001 /*
00002 
00003 Copyright (C) 1996, 1997 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 2, or (at your option) any
00010 later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, write to the Free
00019 Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020 
00021 */
00022 
00023 /*
00024 
00025 The functions listed below were adapted from a similar functions
00026 from GNU Bash, the Bourne Again SHell, copyright (C) 1987, 1989, 1991
00027 Free Software Foundation, Inc.
00028 
00029   octave_env::do_absolute_pathname
00030   octave_env::do_base_pathname
00031   octave_env::do_chdir
00032   octave_env::do_getcwd
00033   octave_env::do_make_absolute
00034   octave_env::do_polite_directory_format
00035   octave_env::pathname_backup
00036 
00037 */ 
00038 
00039 #ifdef HAVE_CONFIG_H
00040 #include <config.h>
00041 #endif
00042 
00043 #include <cctype>
00044 #include <cstdlib>
00045 
00046 #include <string>
00047 
00048 #ifdef HAVE_UNISTD_H
00049 #ifdef HAVE_SYS_TYPES_H
00050 #include <sys/types.h>
00051 #endif
00052 #include <unistd.h>
00053 #endif
00054 
00055 #include "file-ops.h"
00056 #include "lo-error.h"
00057 #include "lo-sysdep.h"
00058 #include "lo-utils.h"
00059 #include "oct-env.h"
00060 #include "oct-passwd.h"
00061 #include "oct-syscalls.h"
00062 
00063 octave_env::octave_env (void)
00064   : follow_symbolic_links (true), verbatim_pwd (true),
00065     current_directory (), program_name (), program_invocation_name (),
00066     user_name (), host_name ()
00067 {
00068   // Get a real value for the current directory.
00069   do_getcwd ();
00070 
00071   // Etc.
00072   do_get_user_name ();
00073 
00074   do_get_host_name ();
00075 }
00076 
00077 octave_env *octave_env::instance = 0;
00078 
00079 bool
00080 octave_env::instance_ok (void)
00081 {
00082   bool retval = true;
00083 
00084   if (! instance)
00085     instance = new octave_env ();
00086 
00087   if (! instance)
00088     {
00089       (*current_liboctave_error_handler)
00090         ("unable to create current working directoy object!");
00091 
00092       retval = false;
00093     }
00094 
00095   return retval;
00096 }
00097 
00098 std::string
00099 octave_env::polite_directory_format (const std::string& name)
00100 {
00101   return (instance_ok ())
00102     ? instance->do_polite_directory_format (name) : std::string ();
00103 }
00104 
00105 bool
00106 octave_env::absolute_pathname (const std::string& s)
00107 {
00108   return (instance_ok ())
00109     ? instance->do_absolute_pathname (s) : false;
00110 }
00111 
00112 std::string
00113 octave_env::base_pathname (const std::string& s)
00114 {
00115   return (instance_ok ())
00116     ? instance->do_base_pathname (s) : std::string ();
00117 }
00118 
00119 std::string
00120 octave_env::make_absolute (const std::string& s, const std::string& dot_path)
00121 {
00122   return (instance_ok ())
00123     ? instance->do_make_absolute (s, dot_path) : std::string ();
00124 }
00125 
00126 std::string
00127 octave_env::getcwd ()
00128 {
00129   return (instance_ok ())
00130     ? instance->do_getcwd () : std::string ();
00131 }
00132 
00133 std::string
00134 octave_env::get_home_directory ()
00135 {
00136   return (instance_ok ())
00137     ? instance->do_get_home_directory () : std::string ();
00138 }
00139 
00140 std::string
00141 octave_env::get_program_name (void)
00142 {
00143   return (instance_ok ())
00144     ? instance->program_name : std::string ();
00145 }
00146 
00147 std::string
00148 octave_env::get_program_invocation_name (void)
00149 {
00150   return (instance_ok ())
00151     ? instance->program_invocation_name : std::string ();
00152 }
00153 
00154 void
00155 octave_env::set_program_name (const std::string& s)
00156 {
00157   if (instance_ok ())
00158     instance->do_set_program_name (s);
00159 }
00160 
00161 std::string
00162 octave_env::get_user_name (void)
00163 {
00164   return (instance_ok ())
00165     ? instance->do_get_user_name () : std::string ();
00166 }
00167 
00168 std::string
00169 octave_env::get_host_name (void)
00170 {
00171   return (instance_ok ())
00172     ? instance->do_get_host_name () : std::string ();
00173 }
00174 
00175 // XXX FIXME XXX -- this leaves no way to distinguish between a
00176 // variable that is not set and one that is set to the empty string.
00177 // Is this a problem?
00178 
00179 std::string
00180 octave_env::getenv (const std::string& name)
00181 {
00182   return (instance_ok ())
00183     ? instance->do_getenv (name) : std::string ();
00184 }
00185 
00186 void
00187 octave_env::putenv (const std::string& name, const std::string& value)
00188 {
00189   octave_putenv (name, value);
00190 }
00191 
00192 bool
00193 octave_env::chdir (const std::string& newdir)
00194 {
00195   return (instance_ok ())
00196     ? instance->do_chdir (newdir) : false;
00197 }
00198 
00199 void
00200 octave_env::do_set_program_name (const std::string& s) const
00201 {
00202   program_invocation_name = s;
00203 
00204   size_t pos = program_invocation_name.find_last_of (file_ops::dir_sep_chars);
00205 
00206   program_name = (pos == NPOS)
00207     ? program_invocation_name : program_invocation_name.substr (pos+1);
00208 }
00209 
00210 // Return a pretty pathname.  If the first part of the pathname is the
00211 // same as $HOME, then replace that with `~'.
00212 
00213 std::string
00214 octave_env::do_polite_directory_format (const std::string& name) const
00215 {
00216   std::string retval;
00217 
00218   std::string home_dir = do_get_home_directory ();
00219 
00220   size_t len = home_dir.length ();
00221 
00222   if (len > 1 && home_dir == name.substr (0, len)
00223       && (name.length () == len || file_ops::is_dir_sep (name[len])))
00224     {
00225       retval = "~";
00226       retval.append (name.substr (len));
00227     }
00228   else
00229     retval = name;
00230 
00231   return retval;
00232 }
00233 
00234 bool
00235 octave_env::do_absolute_pathname (const std::string& s) const
00236 {
00237   size_t len = s.length ();
00238 
00239   if (len == 0)
00240     return false;
00241 
00242   if (file_ops::is_dir_sep (s[0]))
00243     return true;
00244 
00245 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM)
00246   if ((len == 2 && isalpha (s[0]) && s[1] == ':')
00247       || (len > 2 && isalpha (s[0]) && s[1] == ':'
00248           && file_ops::is_dir_sep (s[2])))
00249     return true;
00250 #endif
00251 
00252   return false;
00253 }
00254 
00255 // Return the `basename' of the pathname in STRING (the stuff after
00256 // the last directory separator).  If STRING is not a full pathname,
00257 // simply return it.
00258 
00259 std::string
00260 octave_env::do_base_pathname (const std::string& s) const
00261 {
00262   if (! do_absolute_pathname (s))
00263     return s;
00264 
00265   size_t pos = s.find_last_of (file_ops::dir_sep_chars);
00266 
00267   if (pos == NPOS)
00268     return s;
00269   else
00270     return s.substr (pos+1);
00271 }
00272 
00273 // Turn STRING (a pathname) into an absolute pathname, assuming that
00274 // DOT_PATH contains the symbolic location of the current directory.
00275 
00276 std::string
00277 octave_env::do_make_absolute (const std::string& s,
00278                               const std::string& dot_path) const
00279 {
00280 #if defined (__EMX__)
00281   if (s.length () > 1 && s[1] == ':')
00282     return s;
00283 #endif
00284 
00285   if (dot_path.empty () || s.empty () || do_absolute_pathname (s))
00286     return s;
00287 
00288   std::string current_dir = dot_path;
00289 
00290   if (current_dir.empty ())
00291     current_dir = do_getcwd ();
00292 
00293   size_t pos = current_dir.length () - 1;
00294 
00295   if (! file_ops::is_dir_sep (current_dir[pos]))
00296     current_dir.append (file_ops::dir_sep_str);
00297 
00298   // XXX FIXME XXX -- this is probably not correct for all systems.
00299 
00300   size_t i = 0;
00301   size_t slen = s.length ();
00302 
00303   while (i < slen)
00304     {
00305       if (s[i] == '.')
00306         {
00307           if (i + 1 == slen)
00308             return current_dir;
00309 
00310           if (file_ops::is_dir_sep (s[i+1]))
00311             {
00312               i += 2;
00313               continue;
00314             }
00315 
00316           if (s[i+1] == '.'
00317               && (i + 2 == slen || file_ops::is_dir_sep (s[i+2])))
00318             {
00319               i += 2;
00320 
00321               if (i != slen)
00322                 i++;
00323 
00324               pathname_backup (current_dir, 1);
00325 
00326               continue;
00327             }
00328         }
00329 
00330       size_t tmp = s.find_first_of (file_ops::dir_sep_chars, i);
00331 
00332       if (tmp == NPOS)
00333         {
00334           current_dir.append (s, i, tmp-i);
00335           break;
00336         }
00337       else
00338         {
00339           current_dir.append (s, i, tmp-i+1);
00340           i = tmp + 1;
00341         }
00342     }
00343 
00344   return current_dir;
00345 }
00346 
00347 // Return a string which is the current working directory.
00348 
00349 std::string
00350 octave_env::do_getcwd () const
00351 {
00352   if (! follow_symbolic_links)
00353     current_directory = "";
00354 
00355   if (verbatim_pwd || current_directory.empty ())
00356     current_directory = ::octave_getcwd ();
00357 
00358   return current_directory;
00359 }
00360 
00361 // This value is not cached because it can change while Octave is
00362 // running.
00363 
00364 std::string
00365 octave_env::do_get_home_directory (void) const
00366 {
00367   std::string hd = do_getenv ("HOME");
00368 
00369   if (hd.empty ())
00370     {
00371       octave_passwd pw = octave_passwd::getpwuid (octave_syscalls::getuid ());
00372 
00373       hd = pw ? pw.dir () : std::string (file_ops::dir_sep_str);
00374     }
00375 
00376   return hd;
00377 }
00378 
00379 std::string
00380 octave_env::do_get_user_name (void) const
00381 {
00382   // XXX FIXME XXX -- is it possible for this to change while Octave
00383   // is running?
00384 
00385   if (user_name.empty ())
00386     {
00387       octave_passwd pw = octave_passwd::getpwuid (octave_syscalls::getuid ());
00388 
00389       user_name = pw ? pw.name () : std::string ("unknown");
00390     }
00391 
00392   return user_name;
00393 }
00394 
00395 std::string
00396 octave_env::do_get_host_name (void) const
00397 {
00398   // XXX FIXME XXX -- is it possible for this to change while Octave
00399   // is running?
00400 
00401   if (host_name.empty ())
00402     {
00403       char hostname[256];
00404 
00405       int status = octave_gethostname (hostname, 255);
00406 
00407       host_name = (status < 0) ? "unknown" : hostname;
00408     }
00409 
00410   return host_name;
00411 }
00412 
00413 std::string
00414 octave_env::do_getenv (const std::string& name) const
00415 {
00416   char *value = ::getenv (name.c_str ());
00417 
00418   return value ? value : "";
00419 }
00420 
00421 // Do the work of changing to the directory NEWDIR.  Handle symbolic
00422 // link following, etc.
00423 
00424 bool
00425 octave_env::do_chdir (const std::string& newdir)
00426 {
00427   bool retval = false;
00428 
00429   std::string tmp;
00430 
00431   if (follow_symbolic_links)
00432     {
00433       if (current_directory.empty ())
00434         do_getcwd ();
00435 
00436       if (current_directory.empty ())
00437         tmp = newdir;
00438       else
00439         tmp = do_make_absolute (newdir, current_directory);
00440 
00441       // Get rid of trailing directory separator.
00442 
00443       size_t len = tmp.length ();
00444 
00445       if (len > 1)
00446         {
00447           if (file_ops::is_dir_sep (tmp[--len]))
00448             tmp.resize (len);
00449         }
00450 
00451       if (! ::octave_chdir (tmp))
00452         {
00453           current_directory = tmp;
00454           retval = true;
00455         }
00456     }
00457   else
00458     retval = (! ::octave_chdir (newdir));
00459 
00460   return retval;
00461 }
00462 
00463 // Remove the last N directories from PATH.
00464 
00465 void
00466 octave_env::pathname_backup (std::string& path, int n) const
00467 {
00468   if (path.empty ())
00469     return;
00470 
00471   size_t i = path.length () - 1;
00472 
00473   while (n--)
00474     {
00475       while (file_ops::is_dir_sep (path[i]) && i > 0)
00476         i--;
00477 
00478       while (! file_ops::is_dir_sep (path[i]) && i > 0)
00479         i--;
00480 
00481       i++;
00482     }
00483 
00484   path.resize (i);
00485 }
00486 
00487 void
00488 octave_env::error (int err_num) const
00489 {
00490   (*current_liboctave_error_handler) ("%s", strerror (err_num));
00491 }
00492 
00493 void
00494 octave_env::error (const std::string& s) const
00495 {
00496   (*current_liboctave_error_handler) ("%s", s.c_str ());
00497 }
00498 
00499 /*
00500 ;;; Local Variables: ***
00501 ;;; mode: C++ ***
00502 ;;; End: ***
00503 */

Wed Dec 29 11:52:06 2004に生成されました。 doxygen1.2.18
SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送