/* 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #ifdef HAVE_UNISTD_H #ifdef HAVE_SYS_TYPES_H #include #endif #include #endif #if defined (HAVE_TERMIOS_H) #include #elif defined (HAVE_TERMIO_H) #include #elif defined (HAVE_SGTTY_H) #include #else LOSE! LOSE! #endif #if defined (HAVE_SYS_IOCTL_H) #include #endif #if defined (HAVE_FLOATINGPOINT_H) #include #endif #if defined (HAVE_IEEEFP_H) #include #endif #if !defined (HAVE_GETHOSTNAME) && defined (HAVE_SYS_UTSNAME_H) #include #endif #include "cmd-edit.h" #include "file-ops.h" #include "lo-mappers.h" #include "mach-info.h" #include "oct-env.h" #include "defun.h" #include "error.h" #include "input.h" #include "oct-obj.h" #include "ov.h" #include "pager.h" #include "sysdep.h" #include "toplev.h" #include "utils.h" #ifndef STDIN_FILENO #define STDIN_FILENO 1 #endif #if defined (__386BSD__) || defined (__FreeBSD__) static void BSD_init (void) { #if defined (HAVE_FLOATINGPOINT_H) // Disable trapping on common exceptions. fpsetmask (~(FP_X_OFL|FP_X_INV|FP_X_DZ|FP_X_DNML|FP_X_UFL|FP_X_IMP)); #endif } #endif #if defined (NeXT) extern "C" { typedef void (*_cplus_fcn_int) (int); extern void (*malloc_error (_cplus_fcn_int)) (int); } static void malloc_handler (int code) { if (code == 5) warning ("hopefully recoverable malloc error: freeing wild pointer"); else panic ("probably irrecoverable malloc error: code %d", code); } static void NeXT_init (void) { malloc_error (malloc_handler); } #endif #if defined (__EMX__) OS2_init (void) { _control87 ((EM_INVALID | EM_DENORMAL | EM_ZERODIVIDE | EM_OVERFLOW | EM_UNDERFLOW | EM_INEXACT), MCW_EM); } #endif #if defined (SCO) static void SCO_init (void) { #if defined (HAVE_IEEEFP_H) // Disable trapping on common exceptions. fpsetmask (~(FP_X_OFL|FP_X_INV|FP_X_DZ|FP_X_DNML|FP_X_UFL|FP_X_IMP)); #endif } #endif void sysdep_init (void) { #if defined (__386BSD__) || defined (__FreeBSD__) BSD_init (); #elif defined (NeXT) NeXT_init (); #elif defined (__EMX__) OS2_init (); #elif defined (SCO) SCO_init (); #endif octave_ieee_init (); } // Set terminal in raw mode. From less-177. // // Change terminal to "raw mode", or restore to "normal" mode. // "Raw mode" means // 1. An outstanding read will complete on receipt of a single keystroke. // 2. Input is not echoed. // 3. On output, \n is mapped to \r\n. // 4. \t is NOT expanded into spaces. // 5. Signal-causing characters such as ctrl-C (interrupt), // etc. are NOT disabled. // It doesn't matter whether an input \n is mapped to \r, or vice versa. void raw_mode (int on) { static int curr_on = 0; int tty_fd = STDIN_FILENO; if (! isatty (tty_fd)) { if (interactive) error ("stdin is not a tty!"); return; } if (on == curr_on) return; #if defined (HAVE_TERMIOS_H) { struct termios s; static struct termios save_term; if (on) { // Get terminal modes. tcgetattr (tty_fd, &s); // Save modes and set certain variables dependent on modes. save_term = s; // ospeed = s.c_cflag & CBAUD; // erase_char = s.c_cc[VERASE]; // kill_char = s.c_cc[VKILL]; // Set the modes to the way we want them. s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL); s.c_oflag |= (OPOST|ONLCR); #if defined (OCRNL) s.c_oflag &= ~(OCRNL); #endif #if defined (ONOCR) s.c_oflag &= ~(ONOCR); #endif #if defined (ONLRET) s.c_oflag &= ~(ONLRET); #endif s.c_cc[VMIN] = 1; s.c_cc[VTIME] = 0; } else { // Restore saved modes. s = save_term; } tcsetattr (tty_fd, TCSAFLUSH, &s); } #elif defined (HAVE_TERMIO_H) { struct termio s; static struct termio save_term; if (on) { // Get terminal modes. ioctl (tty_fd, TCGETA, &s); // Save modes and set certain variables dependent on modes. save_term = s; // ospeed = s.c_cflag & CBAUD; // erase_char = s.c_cc[VERASE]; // kill_char = s.c_cc[VKILL]; // Set the modes to the way we want them. s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL); s.c_oflag |= (OPOST|ONLCR); #if defined (OCRNL) s.c_oflag &= ~(OCRNL); #endif #if defined (ONOCR) s.c_oflag &= ~(ONOCR); #endif #if defined (ONLRET) s.c_oflag &= ~(ONLRET); #endif s.c_cc[VMIN] = 1; s.c_cc[VTIME] = 0; } else { // Restore saved modes. s = save_term; } ioctl (tty_fd, TCSETAW, &s); } #elif defined (HAVE_SGTTY_H) { struct sgttyb s; static struct sgttyb save_term; if (on) { // Get terminal modes. ioctl (tty_fd, TIOCGETP, &s); // Save modes and set certain variables dependent on modes. save_term = s; // ospeed = s.sg_ospeed; // erase_char = s.sg_erase; // kill_char = s.sg_kill; // Set the modes to the way we want them. s.sg_flags |= CBREAK; s.sg_flags &= ~(ECHO); } else { // Restore saved modes. s = save_term; } ioctl (tty_fd, TIOCSETN, &s); } #else LOSE! LOSE! #endif curr_on = on; } // Read one character from the terminal. int kbhit (void) { int c; raw_mode (1); c = cin.get (); raw_mode (0); return c; } DEFUN (clc, , , "clc (): clear screen") { command_editor::clear_screen (); return octave_value_list (); } DEFALIAS (home, clc); DEFUN (getenv, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} getenv (@var{var})\n\ Return the value of the environment variable @var{var}. For example,\n\ \n\ @example\n\ getenv (\"PATH\")\n\ @end example\n\ \n\ @noindent\n\ returns a string containing the value of your path.\n\ @end deftypefn") { octave_value_list retval; int nargin = args.length (); if (nargin == 1) { string name = args(0).string_value (); if (! error_state) retval = octave_env::getenv (name); } else print_usage ("getenv"); return retval; } DEFUN (putenv, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} putenv (@var{var}, @var{value})\n\ Set the value of the environment variable @var{var} to @var{value}.\n\ @end deftypefn") { octave_value_list retval; int nargin = args.length (); if (nargin == 2) { string var = args(0).string_value (); if (! error_state) { string val = args(1).string_value (); if (! error_state) octave_env::putenv (var, val); else error ("putenv: second argument should be a string"); } else error ("putenv: first argument should be a string"); } else print_usage ("putenv"); return retval; } DEFUN (kbhit, , , "kbhit: get a single character from the terminal") { octave_value_list retval; // XXX FIXME XXX -- add timeout and default value args? if (interactive) { int c = kbhit (); char *s = new char [2]; s[0] = c; s[1] = '\0'; retval = s; } return retval; } DEFUN (pause, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} pause (@var{seconds})\n\ Suspend the execution of the program. If invoked without any arguments,\n\ Octave waits until you type a character. With a numeric argument, it\n\ pauses for the given number of seconds. For example, the following\n\ statement prints a message and then waits 5 seconds before clearing the\n\ screen.\n\ \n\ @example\n\ @group\n\ fprintf (stderr, \"wait please...\n\");\n\ pause (5);\n\ clc;\n\ @end group\n\ @end example\n\ @end deftypefn") { octave_value_list retval; int nargin = args.length (); if (! (nargin == 0 || nargin == 1)) { print_usage ("pause"); return retval; } if (nargin == 1) { double dval = args(0).double_value (); if (! error_state) { if (xisnan (dval)) warning ("pause: NaN is an invalid delay"); else if (xisinf (dval)) { flush_octave_stdout (); kbhit (); } else { int delay = NINT (dval); if (delay > 0) sleep (delay); } } } else { flush_octave_stdout (); kbhit (); } return retval; } DEFUN (sleep, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} sleep (@var{seconds})\n\ Suspend the execution of the program for the given number of seconds.\n\ @end deftypefn") { octave_value_list retval; if (args.length () == 1) { double dval = args(0).double_value (); if (! error_state) { if (xisnan (dval)) warning ("sleep: NaN is an invalid delay"); else { int delay = NINT (dval); if (delay > 0) sleep (delay); } } } else print_usage ("sleep"); return retval; } DEFUN (usleep, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} usleep (@var{microseconds})\n\ Suspend the execution of the program for the given number of\n\ microseconds. On systems where it is not possible to sleep for periods\n\ of time less than one second, @code{usleep} will pause the execution for\n\ @code{round (@var{microseconds} / 1e6)} seconds.\n\ @end deftypefn") { octave_value_list retval; if (args.length () == 1) { double dval = args(0).double_value (); if (! error_state) { if (xisnan (dval)) warning ("usleep: NaN is an invalid delay"); else { int delay = NINT (dval); if (delay > 0) octave_usleep (delay); } } } else print_usage ("usleep"); return retval; } // XXX FIXME XXX -- maybe this should only return 1 if IEEE floating // point functions really work. DEFUN (isieee, , , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} isieee ()\n\ Return 1 if your computer claims to conform to the IEEE standard for\n\ floating point calculations.\n\ @end deftypefn") { oct_mach_info::float_format flt_fmt = oct_mach_info::native_float_format (); return static_cast (flt_fmt == oct_mach_info::ieee_little_endian || flt_fmt == oct_mach_info::ieee_big_endian); } DEFUN (tilde_expand, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} tilde_expand (@var{string})\n\ Performs tilde expansion on @var{string}. If @var{string} begins with a\n\ tilde character, (@samp{~}), all of the characters preceding the first\n\ slash (or all characters, if there is no slash) are treated as a\n\ possible user name, and the tilde and the following characters up to the\n\ slash are replaced by the home directory of the named user. If the\n\ tilde is followed immediately by a slash, the tilde is replaced by the\n\ home directory of the user running Octave. For example,\n\ \n\ @example\n\ @group\n\ tilde_expand (\"~joeuser/bin\")\n\ @result{} \"/home/joeuser/bin\"\n\ tilde_expand (\"~/bin\")\n\ @result{} \"/home/jwe/bin\"\n\ @end group\n\ @end example\n\ @end deftypefn") { octave_value_list retval; int nargin = args.length (); if (nargin == 1) retval = file_ops::tilde_expand (args(0).all_strings ()); else print_usage ("tilde_expand"); return retval; } #if defined (__EMX__) && defined (OS2) DEFUN_TEXT (extproc, , , "extproc: ignored by Octave") { return octave_value_list (); } DEFALIAS (EXTPROC, extproc); #endif /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */