00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
00159
00160
00161
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
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
00194 w32_sigint_init ();
00195
00196 w32_set_quiet_shutdown ();
00197 }
00198 #endif
00199
00200
00201
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
00211
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
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
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
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
00309
00310 tcgetattr (tty_fd, &s);
00311
00312
00313
00314 save_term = s;
00315
00316
00317
00318
00319
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
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
00352
00353 ioctl (tty_fd, TCGETA, &s);
00354
00355
00356
00357 save_term = s;
00358
00359
00360
00361
00362
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
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
00394
00395 ioctl (tty_fd, TIOCGETP, &s);
00396
00397
00398
00399 save_term = s;
00400
00401
00402
00403
00404
00405
00406 s.sg_flags |= CBREAK;
00407 s.sg_flags &= ~(ECHO);
00408 }
00409 else
00410 {
00411
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
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
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
00469 octave_interrupt_handler saved_interrupt_handler
00470 = octave_ignore_interrupts ();
00471
00472
00473
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
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
00503
00504
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
00612
00613
00614
00615
00616
00617
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
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
00726
00727
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
00761
00762
00763
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
00804
00805
00806
00807
00808
00809
00810
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
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
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
00895
00896
00897
00898
00899
00900
00901
00902