sysdep.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1993-2012 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 3 of the License, or (at your
00010 option) any 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, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include <cfloat>
00028 #include <cstddef>
00029 #include <cstdio>
00030 #include <cstdlib>
00031 #include <cstring>
00032 
00033 #include <iostream>
00034 #include <string>
00035 
00036 #include <sys/types.h>
00037 #include <unistd.h>
00038 
00039 #if defined (HAVE_TERMIOS_H)
00040 #include <termios.h>
00041 #elif defined (HAVE_TERMIO_H)
00042 #include <termio.h>
00043 #elif defined (HAVE_SGTTY_H)
00044 #include <sgtty.h>
00045 #endif
00046 
00047 #if defined (HAVE_CONIO_H)
00048 #include <conio.h>
00049 #endif
00050 
00051 #if defined (HAVE_SYS_IOCTL_H)
00052 #include <sys/ioctl.h>
00053 #endif
00054 
00055 #if defined (HAVE_FLOATINGPOINT_H)
00056 #include <floatingpoint.h>
00057 #endif
00058 
00059 #if defined (HAVE_IEEEFP_H)
00060 #include <ieeefp.h>
00061 #endif
00062 
00063 #include "cmd-edit.h"
00064 #include "file-ops.h"
00065 #include "lo-mappers.h"
00066 #include "lo-math.h"
00067 #include "mach-info.h"
00068 #include "oct-env.h"
00069 #include "quit.h"
00070 
00071 #include "Cell.h"
00072 #include "defun.h"
00073 #include "error.h"
00074 #include "input.h"
00075 #include "oct-obj.h"
00076 #include "ov.h"
00077 #include "pager.h"
00078 #include "parse.h"
00079 #include "sighandlers.h"
00080 #include "sysdep.h"
00081 #include "toplev.h"
00082 #include "utils.h"
00083 #include "file-stat.h"
00084 
00085 #ifndef STDIN_FILENO
00086 #define STDIN_FILENO 1
00087 #endif
00088 
00089 #if defined (__386BSD__) || defined (__FreeBSD__) || defined (__NetBSD__)
00090 static void
00091 BSD_init (void)
00092 {
00093 #if defined (HAVE_FLOATINGPOINT_H)
00094   // Disable trapping on common exceptions.
00095 #ifndef FP_X_DNML
00096 #define FP_X_DNML 0
00097 #endif
00098   fpsetmask (~(FP_X_OFL|FP_X_INV|FP_X_DZ|FP_X_DNML|FP_X_UFL|FP_X_IMP));
00099 #endif
00100 }
00101 #endif
00102 
00103 #if defined (__WIN32__) && ! defined (_POSIX_VERSION)
00104 
00105 #define WIN32_LEAN_AND_MEAN
00106 #include <tlhelp32.h>
00107 
00108 static void
00109 w32_set_octave_home (void)
00110 {
00111   std::string bin_dir;
00112 
00113   HANDLE h = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE
00114 #ifdef TH32CS_SNAPMODULE32
00115                                        | TH32CS_SNAPMODULE32
00116 #endif
00117                                        , 0);
00118 
00119   if (h != INVALID_HANDLE_VALUE)
00120     {
00121       MODULEENTRY32 mod_info;
00122 
00123       ZeroMemory (&mod_info, sizeof (mod_info));
00124       mod_info.dwSize = sizeof (mod_info);
00125 
00126       if (Module32First (h, &mod_info))
00127   {
00128     do
00129       {
00130         std::string mod_name (mod_info.szModule);
00131 
00132         if (mod_name.find ("octinterp") != std::string::npos)
00133     {
00134       bin_dir = mod_info.szExePath;
00135       if (bin_dir[bin_dir.length () - 1] != '\\')
00136         bin_dir.append (1, '\\');
00137       break;
00138     }
00139       }
00140     while (Module32Next (h, &mod_info));
00141   }
00142 
00143       CloseHandle (h);
00144     }
00145 
00146   if (! bin_dir.empty ())
00147     {
00148       size_t pos = bin_dir.rfind ("\\bin\\");
00149 
00150       if (pos != std::string::npos)
00151         octave_env::putenv ("OCTAVE_HOME", bin_dir.substr (0, pos));
00152     }
00153 }
00154 
00155 void
00156 w32_set_quiet_shutdown (void)
00157 {
00158   // Let the user close the console window or shutdown without the
00159   // pesky dialog.
00160   //
00161   // FIXME -- should this be user configurable?
00162   SetProcessShutdownParameters (0x280, SHUTDOWN_NORETRY);
00163 }
00164 
00165 void
00166 MINGW_signal_cleanup (void)
00167 {
00168   w32_set_quiet_shutdown ();
00169 
00170   w32_raise_final ();
00171 }
00172 #endif
00173 
00174 #if defined (__MINGW32__)
00175 static void
00176 MINGW_init (void)
00177 {
00178   w32_set_octave_home ();
00179 
00180   // Init mutex to protect setjmp/longjmp and get main thread context
00181   w32_sigint_init ();
00182 
00183   w32_set_quiet_shutdown ();
00184 }
00185 #endif
00186 
00187 #if defined (_MSC_VER)
00188 static void
00189 MSVC_init (void)
00190 {
00191   w32_set_octave_home ();
00192 
00193   // Init mutex to protect setjmp/longjmp and get main thread context
00194   w32_sigint_init ();
00195 
00196   w32_set_quiet_shutdown ();
00197 }
00198 #endif
00199 
00200 
00201 // Return TRUE if FILE1 and FILE2 refer to the same (physical) file.
00202 
00203 bool
00204 same_file_internal (const std::string& file1, const std::string& file2)
00205 {
00206 #ifdef OCTAVE_USE_WINDOWS_API
00207 
00208   bool retval = false;
00209 
00210   // Windows native code
00211   // Reference: http://msdn2.microsoft.com/en-us/library/aa363788.aspx
00212 
00213   HANDLE hfile1 = CreateFile (file1.c_str (), 0, FILE_SHARE_READ, 0,
00214                               OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
00215 
00216   if (hfile1 != INVALID_HANDLE_VALUE)
00217     {
00218       HANDLE hfile2 = CreateFile (file2.c_str (), 0, FILE_SHARE_READ, 0,
00219                                   OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
00220 
00221       if (hfile2 != INVALID_HANDLE_VALUE)
00222         {
00223           BY_HANDLE_FILE_INFORMATION hfi1;
00224           BY_HANDLE_FILE_INFORMATION hfi2;
00225 
00226           if (GetFileInformationByHandle (hfile1, &hfi1)
00227               && GetFileInformationByHandle (hfile2, &hfi2))
00228 
00229             retval = (hfi1.dwVolumeSerialNumber == hfi2.dwVolumeSerialNumber
00230                       && hfi1.nFileIndexHigh == hfi2.nFileIndexHigh
00231                       && hfi1.nFileIndexLow == hfi2.nFileIndexLow);
00232 
00233           CloseHandle (hfile2);
00234         }
00235 
00236       CloseHandle (hfile1);
00237     }
00238 
00239   return retval;
00240 
00241 #else
00242 
00243   // POSIX Code
00244 
00245   file_stat fs_file1 (file1);
00246   file_stat fs_file2 (file2);
00247 
00248   return (fs_file1 && fs_file2
00249           && fs_file1.ino () == fs_file2.ino ()
00250           && fs_file1.dev () == fs_file2.dev ());
00251 
00252 #endif
00253 }
00254 
00255 void
00256 sysdep_init (void)
00257 {
00258 #if defined (__386BSD__) || defined (__FreeBSD__) || defined(__NetBSD__)
00259   BSD_init ();
00260 #elif defined (__MINGW32__)
00261   MINGW_init ();
00262 #elif defined (_MSC_VER)
00263   MSVC_init ();
00264 #endif
00265 }
00266 
00267 void
00268 sysdep_cleanup (void)
00269 {
00270   MINGW_SIGNAL_CLEANUP ();
00271 }
00272 
00273 // Set terminal in raw mode.  From less-177.
00274 //
00275 // Change terminal to "raw mode", or restore to "normal" mode.
00276 // "Raw mode" means
00277 //      1. An outstanding read will complete on receipt of a single keystroke.
00278 //      2. Input is not echoed.
00279 //      3. On output, \n is mapped to \r\n.
00280 //      4. \t is NOT expanded into spaces.
00281 //      5. Signal-causing characters such as ctrl-C (interrupt),
00282 //         etc. are NOT disabled.
00283 // It doesn't matter whether an input \n is mapped to \r, or vice versa.
00284 
00285 void
00286 raw_mode (bool on, bool wait)
00287 {
00288   static bool curr_on = false;
00289 
00290   int tty_fd = STDIN_FILENO;
00291   if (! gnulib::isatty (tty_fd))
00292     {
00293       if (interactive)
00294         error ("stdin is not a tty!");
00295       return;
00296     }
00297 
00298   if (on == curr_on)
00299     return;
00300 
00301 #if defined (HAVE_TERMIOS_H)
00302   {
00303     struct termios s;
00304     static struct termios save_term;
00305 
00306     if (on)
00307       {
00308         // Get terminal modes.
00309 
00310         tcgetattr (tty_fd, &s);
00311 
00312         // Save modes and set certain variables dependent on modes.
00313 
00314         save_term = s;
00315 //      ospeed = s.c_cflag & CBAUD;
00316 //      erase_char = s.c_cc[VERASE];
00317 //      kill_char = s.c_cc[VKILL];
00318 
00319         // Set the modes to the way we want them.
00320 
00321         s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
00322         s.c_oflag |=  (OPOST|ONLCR);
00323 #if defined (OCRNL)
00324         s.c_oflag &= ~(OCRNL);
00325 #endif
00326 #if defined (ONOCR)
00327         s.c_oflag &= ~(ONOCR);
00328 #endif
00329 #if defined (ONLRET)
00330         s.c_oflag &= ~(ONLRET);
00331 #endif
00332         s.c_cc[VMIN] = wait ? 1 : 0;
00333         s.c_cc[VTIME] = 0;
00334       }
00335     else
00336       {
00337         // Restore saved modes.
00338 
00339         s = save_term;
00340       }
00341 
00342     tcsetattr (tty_fd, wait ? TCSAFLUSH : TCSADRAIN, &s);
00343   }
00344 #elif defined (HAVE_TERMIO_H)
00345   {
00346     struct termio s;
00347     static struct termio save_term;
00348 
00349     if (on)
00350       {
00351         // Get terminal modes.
00352 
00353         ioctl (tty_fd, TCGETA, &s);
00354 
00355         // Save modes and set certain variables dependent on modes.
00356 
00357         save_term = s;
00358 //      ospeed = s.c_cflag & CBAUD;
00359 //      erase_char = s.c_cc[VERASE];
00360 //      kill_char = s.c_cc[VKILL];
00361 
00362         // Set the modes to the way we want them.
00363 
00364         s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
00365         s.c_oflag |=  (OPOST|ONLCR);
00366 #if defined (OCRNL)
00367         s.c_oflag &= ~(OCRNL);
00368 #endif
00369 #if defined (ONOCR)
00370         s.c_oflag &= ~(ONOCR);
00371 #endif
00372 #if defined (ONLRET)
00373         s.c_oflag &= ~(ONLRET);
00374 #endif
00375         s.c_cc[VMIN] = wait ? 1 : 0;
00376       }
00377     else
00378       {
00379         // Restore saved modes.
00380 
00381         s = save_term;
00382       }
00383 
00384     ioctl (tty_fd, TCSETAW, &s);
00385   }
00386 #elif defined (HAVE_SGTTY_H)
00387   {
00388     struct sgttyb s;
00389     static struct sgttyb save_term;
00390 
00391     if (on)
00392       {
00393         // Get terminal modes.
00394 
00395         ioctl (tty_fd, TIOCGETP, &s);
00396 
00397         // Save modes and set certain variables dependent on modes.
00398 
00399         save_term = s;
00400 //      ospeed = s.sg_ospeed;
00401 //      erase_char = s.sg_erase;
00402 //      kill_char = s.sg_kill;
00403 
00404         // Set the modes to the way we want them.
00405 
00406         s.sg_flags |= CBREAK;
00407         s.sg_flags &= ~(ECHO);
00408       }
00409     else
00410       {
00411         // Restore saved modes.
00412 
00413         s = save_term;
00414       }
00415 
00416     ioctl (tty_fd, TIOCSETN, &s);
00417   }
00418 #else
00419   warning ("no support for raw mode console I/O on this system");
00420 
00421   // Make sure the current mode doesn't toggle.
00422   on = curr_on;
00423 #endif
00424 
00425   curr_on = on;
00426 }
00427 
00428 FILE *
00429 octave_popen (const char *command, const char *mode)
00430 {
00431 #if defined (__MINGW32__) || defined (_MSC_VER)
00432   if (mode && mode[0] && ! mode[1])
00433     {
00434       char tmode[3];
00435       tmode[0] = mode[0];
00436       tmode[1] = 'b';
00437       tmode[2] = 0;
00438 
00439       return _popen (command, tmode);
00440     }
00441   else
00442     return _popen (command, mode);
00443 #else
00444   return popen (command, mode);
00445 #endif
00446 }
00447 
00448 int
00449 octave_pclose (FILE *f)
00450 {
00451 #if defined (__MINGW32__) || defined (_MSC_VER)
00452   return _pclose (f);
00453 #else
00454   return pclose (f);
00455 #endif
00456 }
00457 
00458 // Read one character from the terminal.
00459 
00460 int
00461 octave_kbhit (bool wait)
00462 {
00463 #ifdef HAVE__KBHIT
00464   int c = (! wait && ! _kbhit ()) ? 0 : std::cin.get ();
00465 #else
00466   raw_mode (true, wait);
00467 
00468   // Get current handler.
00469   octave_interrupt_handler saved_interrupt_handler
00470     = octave_ignore_interrupts ();
00471 
00472   // Restore it, disabling system call restarts (if possible) so the
00473   // read can be interrupted.
00474 
00475   octave_set_interrupt_handler (saved_interrupt_handler, false);
00476 
00477   int c = std::cin.get ();
00478 
00479   if (std::cin.fail () || std::cin.eof ())
00480     std::cin.clear ();
00481 
00482   // Restore it, enabling system call restarts (if possible).
00483   octave_set_interrupt_handler (saved_interrupt_handler, true);
00484 
00485   raw_mode (false, true);
00486 #endif
00487 
00488   return c;
00489 }
00490 
00491 std::string
00492 get_P_tmpdir (void)
00493 {
00494 #if defined (__WIN32__) && ! defined (_POSIX_VERSION)
00495 
00496   std::string retval;
00497 
00498 #if defined (P_tmpdir)
00499   retval = P_tmpdir;
00500 #endif
00501 
00502   // Apparently some versions of MinGW and MSVC either don't define
00503   // P_tmpdir, or they define it to a single backslash, neither of which
00504   // is particularly helpful.
00505 
00506   if (retval.empty () || retval == "\\")
00507     {
00508       retval = octave_env::getenv ("TEMP");
00509 
00510       if (retval.empty ())
00511         retval = octave_env::getenv ("TMP");
00512 
00513       if (retval.empty ())
00514         retval = "c:\\temp";
00515     }
00516 
00517   return retval;
00518 
00519 #elif defined (P_tmpdir)
00520 
00521   return P_tmpdir;
00522 
00523 #else
00524 
00525   return "/tmp";
00526 
00527 #endif
00528 }
00529 
00530 DEFUN (clc, , ,
00531   "-*- texinfo -*-\n\
00532 @deftypefn  {Built-in Function} {} clc ()\n\
00533 @deftypefnx {Built-in Function} {} home ()\n\
00534 Clear the terminal screen and move the cursor to the upper left corner.\n\
00535 @end deftypefn")
00536 {
00537   command_editor::clear_screen ();
00538 
00539   return octave_value_list ();
00540 }
00541 
00542 DEFALIAS (home, clc);
00543 
00544 DEFUN (getenv, args, ,
00545   "-*- texinfo -*-\n\
00546 @deftypefn {Built-in Function} {} getenv (@var{var})\n\
00547 Return the value of the environment variable @var{var}.  For example,\n\
00548 \n\
00549 @example\n\
00550 getenv (\"PATH\")\n\
00551 @end example\n\
00552 \n\
00553 @noindent\n\
00554 returns a string containing the value of your path.\n\
00555 @end deftypefn")
00556 {
00557   octave_value retval;
00558 
00559   int nargin = args.length ();
00560 
00561   if (nargin == 1)
00562     {
00563       std::string name = args(0).string_value ();
00564 
00565       if (! error_state)
00566         retval = octave_env::getenv (name);
00567     }
00568   else
00569     print_usage ();
00570 
00571   return retval;
00572 }
00573 
00574 DEFUN (putenv, args, ,
00575   "-*- texinfo -*-\n\
00576 @deftypefn  {Built-in Function} {} putenv (@var{var}, @var{value})\n\
00577 @deftypefnx {Built-in Function} {} setenv (@var{var}, @var{value})\n\
00578 Set the value of the environment variable @var{var} to @var{value}.\n\
00579 @end deftypefn")
00580 {
00581   octave_value_list retval;
00582 
00583   int nargin = args.length ();
00584 
00585   if (nargin == 2 || nargin == 1)
00586     {
00587       std::string var = args(0).string_value ();
00588 
00589       if (! error_state)
00590         {
00591           std::string val = (nargin == 2
00592                              ? args(1).string_value () : std::string ());
00593 
00594           if (! error_state)
00595             octave_env::putenv (var, val);
00596           else
00597             error ("putenv: VALUE must be a string");
00598         }
00599       else
00600         error ("putenv: VAR must be a string");
00601     }
00602   else
00603     print_usage ();
00604 
00605   return retval;
00606 }
00607 
00608 DEFALIAS (setenv, putenv);
00609 
00610 /*
00611 %!assert (ischar (getenv ("OCTAVE_HOME")));
00612 %!test
00613 %! setenv ("dummy_variable_that_cannot_matter", "foobar");
00614 %! assert (getenv ("dummy_variable_that_cannot_matter"), "foobar");
00615 */
00616 
00617 // FIXME -- perhaps kbhit should also be able to print a prompt?
00618 
00619 DEFUN (kbhit, args, ,
00620   "-*- texinfo -*-\n\
00621 @deftypefn {Built-in Function} {} kbhit ()\n\
00622 Read a single keystroke from the keyboard.  If called with one\n\
00623 argument, don't wait for a keypress.  For example,\n\
00624 \n\
00625 @example\n\
00626 x = kbhit ();\n\
00627 @end example\n\
00628 \n\
00629 @noindent\n\
00630 will set @var{x} to the next character typed at the keyboard as soon as\n\
00631 it is typed.\n\
00632 \n\
00633 @example\n\
00634 x = kbhit (1);\n\
00635 @end example\n\
00636 \n\
00637 @noindent\n\
00638 identical to the above example, but don't wait for a keypress,\n\
00639 returning the empty string if no key is available.\n\
00640 @end deftypefn")
00641 {
00642   octave_value retval;
00643 
00644   // FIXME -- add timeout and default value args?
00645 
00646   if (interactive || forced_interactive)
00647     {
00648       feval ("drawnow");
00649 
00650       int c = octave_kbhit (args.length () == 0);
00651 
00652       if (c == -1)
00653         c = 0;
00654 
00655       char *s = new char [2];
00656       s[0] = c;
00657       s[1] = '\0';
00658       retval = s;
00659     }
00660 
00661   return retval;
00662 }
00663 
00664 DEFUN (pause, args, ,
00665   "-*- texinfo -*-\n\
00666 @deftypefn {Built-in Function} {} pause (@var{seconds})\n\
00667 Suspend the execution of the program.  If invoked without any arguments,\n\
00668 Octave waits until you type a character.  With a numeric argument, it\n\
00669 pauses for the given number of seconds.  For example, the following\n\
00670 statement prints a message and then waits 5 seconds before clearing the\n\
00671 screen.\n\
00672 \n\
00673 @example\n\
00674 @group\n\
00675 fprintf (stderr, \"wait please...\\n\");\n\
00676 pause (5);\n\
00677 clc;\n\
00678 @end group\n\
00679 @end example\n\
00680 @end deftypefn")
00681 {
00682   octave_value_list retval;
00683 
00684   int nargin = args.length ();
00685 
00686   if (! (nargin == 0 || nargin == 1))
00687     {
00688       print_usage ();
00689       return retval;
00690     }
00691 
00692   if (nargin == 1)
00693     {
00694       double dval = args(0).double_value ();
00695 
00696       if (! error_state)
00697         {
00698           if (! xisnan (dval))
00699             {
00700               feval ("drawnow");
00701 
00702               if (xisinf (dval))
00703                 {
00704                   flush_octave_stdout ();
00705                   octave_kbhit ();
00706                 }
00707               else
00708                 octave_sleep (dval);
00709             }
00710           else
00711             warning ("pause: NaN is an invalid delay");
00712         }
00713     }
00714   else
00715     {
00716       feval ("drawnow");
00717       flush_octave_stdout ();
00718       octave_kbhit ();
00719     }
00720 
00721   return retval;
00722 }
00723 
00724 /*
00725 %!error (pause (1, 2));
00726 %!test
00727 %! pause (1);
00728 */
00729 
00730 DEFUN (sleep, args, ,
00731   "-*- texinfo -*-\n\
00732 @deftypefn {Built-in Function} {} sleep (@var{seconds})\n\
00733 Suspend the execution of the program for the given number of seconds.\n\
00734 @end deftypefn")
00735 {
00736   octave_value_list retval;
00737 
00738   if (args.length () == 1)
00739     {
00740       double dval = args(0).double_value ();
00741 
00742       if (! error_state)
00743         {
00744           if (xisnan (dval))
00745             warning ("sleep: NaN is an invalid delay");
00746           else
00747             {
00748               feval ("drawnow");
00749               octave_sleep (dval);
00750             }
00751         }
00752     }
00753   else
00754     print_usage ();
00755 
00756   return retval;
00757 }
00758 
00759 /*
00760 %!error (sleep ());
00761 %!error (sleep (1, 2));
00762 %!test
00763 %! sleep (1);
00764 */
00765 
00766 DEFUN (usleep, args, ,
00767   "-*- texinfo -*-\n\
00768 @deftypefn {Built-in Function} {} usleep (@var{microseconds})\n\
00769 Suspend the execution of the program for the given number of\n\
00770 microseconds.  On systems where it is not possible to sleep for periods\n\
00771 of time less than one second, @code{usleep} will pause the execution for\n\
00772 @code{round (@var{microseconds} / 1e6)} seconds.\n\
00773 @end deftypefn")
00774 {
00775   octave_value_list retval;
00776 
00777   if (args.length () == 1)
00778     {
00779       double dval = args(0).double_value ();
00780 
00781       if (! error_state)
00782         {
00783           if (xisnan (dval))
00784             warning ("usleep: NaN is an invalid delay");
00785           else
00786             {
00787               feval ("drawnow");
00788 
00789               int delay = NINT (dval);
00790 
00791               if (delay > 0)
00792                 octave_usleep (delay);
00793             }
00794         }
00795     }
00796   else
00797     print_usage ();
00798 
00799   return retval;
00800 }
00801 
00802 /*
00803 %!error (usleep ());
00804 %!error (usleep (1, 2));
00805 %!test
00806 %! usleep (1000);
00807 */
00808 
00809 // FIXME -- maybe this should only return 1 if IEEE floating
00810 // point functions really work.
00811 
00812 DEFUN (isieee, , ,
00813   "-*- texinfo -*-\n\
00814 @deftypefn {Built-in Function} {} isieee ()\n\
00815 Return true if your computer @emph{claims} to conform to the IEEE standard\n\
00816 for floating point calculations.  No actual tests are performed.\n\
00817 @end deftypefn")
00818 {
00819   oct_mach_info::float_format flt_fmt = oct_mach_info::native_float_format ();
00820 
00821   return octave_value (flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian
00822                        || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian);
00823 }
00824 
00825 /*
00826 %!assert (islogical (isieee ()));
00827 */
00828 
00829 DEFUN (native_float_format, , ,
00830   "-*- texinfo -*-\n\
00831 @deftypefn {Built-in Function} {} native_float_format ()\n\
00832 Return the native floating point format as a string\n\
00833 @end deftypefn")
00834 {
00835   oct_mach_info::float_format flt_fmt = oct_mach_info::native_float_format ();
00836 
00837   return octave_value (oct_mach_info::float_format_as_string (flt_fmt));
00838 }
00839 
00840 /*
00841 %!assert (ischar (native_float_format ()));
00842 */
00843 
00844 DEFUN (tilde_expand, args, ,
00845   "-*- texinfo -*-\n\
00846 @deftypefn {Built-in Function} {} tilde_expand (@var{string})\n\
00847 Perform tilde expansion on @var{string}.  If @var{string} begins with a\n\
00848 tilde character, (@samp{~}), all of the characters preceding the first\n\
00849 slash (or all characters, if there is no slash) are treated as a\n\
00850 possible user name, and the tilde and the following characters up to the\n\
00851 slash are replaced by the home directory of the named user.  If the\n\
00852 tilde is followed immediately by a slash, the tilde is replaced by the\n\
00853 home directory of the user running Octave.  For example:\n\
00854 \n\
00855 @example\n\
00856 @group\n\
00857 tilde_expand (\"~joeuser/bin\")\n\
00858      @result{} \"/home/joeuser/bin\"\n\
00859 tilde_expand (\"~/bin\")\n\
00860      @result{} \"/home/jwe/bin\"\n\
00861 @end group\n\
00862 @end example\n\
00863 @end deftypefn")
00864 {
00865   octave_value retval;
00866 
00867   int nargin = args.length ();
00868 
00869   if (nargin == 1)
00870     {
00871       octave_value arg = args(0);
00872 
00873       string_vector sv = arg.all_strings ();
00874 
00875       if (! error_state)
00876         {
00877           sv = file_ops::tilde_expand (sv);
00878 
00879           if (arg.is_cellstr ())
00880             retval = Cell (arg.dims (), sv);
00881           else
00882             retval = sv;
00883         }
00884       else
00885         error ("tilde_expand: expecting argument to be char or cellstr object");
00886     }
00887   else
00888     print_usage ();
00889 
00890   return retval;
00891 }
00892 
00893 /*
00894 %!test
00895 %! if (isempty (getenv ("HOME")))
00896 %!   setenv ("HOME", "foobar");
00897 %! endif
00898 %! home = getenv ("HOME");
00899 %! assert (tilde_expand ("~/foobar"), strcat (home, "/foobar"));
00900 %! assert (tilde_expand ("/foo/bar"), "/foo/bar");
00901 %! assert (tilde_expand ("foo/bar"), "foo/bar");
00902 */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines