home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / octave-1.1.1p1-src.tgz / tar.out / fsf / octave / src / sysdep.cc < prev    next >
C/C++ Source or Header  |  1996-09-28  |  10KB  |  558 lines

  1. // sysdep.cc                                              -*- C++ -*-
  2. /*
  3.  
  4. Copyright (C) 1993, 1994, 1995 John W. Eaton
  5.  
  6. This file is part of Octave.
  7.  
  8. Octave is free software; you can redistribute it and/or modify it
  9. under the terms of the GNU General Public License as published by the
  10. Free Software Foundation; either version 2, or (at your option) any
  11. later version.
  12.  
  13. Octave is distributed in the hope that it will be useful, but WITHOUT
  14. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with Octave; see the file COPYING.  If not, write to the Free
  20. Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. */
  23.  
  24. /*
  25.  
  26. The function gethostname was adapted from a similar function from GNU
  27. Bash, the Bourne Again SHell, copyright (C) 1987, 1989, 1991 Free
  28. Software Foundation, Inc.
  29.  
  30. */
  31.  
  32. #ifdef HAVE_CONFIG_H
  33. #include "config.h"
  34. #endif
  35.  
  36. #include <sys/types.h>
  37. #ifdef HAVE_UNISTD_H
  38. #include <unistd.h>
  39. #endif
  40. #include <math.h>
  41. #include <float.h>
  42. #include <stddef.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include <stdio.h>
  46.  
  47. #include "tree-const.h"
  48. #include "octave.h"
  49. #include "help.h"
  50. #include "input.h"
  51. #include "utils.h"
  52. #include "oct-obj.h"
  53. #include "error.h"
  54. #include "sysdep.h"
  55. #include "defun.h"
  56.  
  57. extern "C"
  58. {
  59. #include <readline/readline.h>
  60.  
  61. extern char *term_clrpag;
  62. extern void _rl_output_character_function ();
  63.  
  64. #if defined (HAVE_TERMIOS_H)
  65. #include <termios.h>
  66. #elif defined (HAVE_TERMIO_H)
  67. #include <termio.h>
  68. #elif defined (HAVE_SGTTY_H)
  69. #include <sgtty.h>
  70. #else
  71. LOSE! LOSE!
  72. #endif
  73. }
  74.  
  75. #ifndef STDIN_FILENO
  76. #define STDIN_FILENO 1
  77. #endif
  78.  
  79. // Octave's idea of infinity.
  80. double octave_Inf;
  81.  
  82. // Octave's idea of not a number.
  83. double octave_NaN;
  84.  
  85. #if defined (HAVE_FLOATINGPOINT_H)
  86. #include <floatingpoint.h>
  87. #endif
  88.  
  89. #ifdef NeXT
  90. extern "C"
  91. {
  92.   typedef void (*_cplus_fcn_int) (int);
  93.   extern void (*malloc_error (_cplus_fcn_int)) (int);
  94. }
  95.  
  96. static void
  97. malloc_handler (int code)
  98. {
  99.   if (code == 5)
  100.     warning ("hopefully recoverable malloc error: freeing wild pointer");
  101.   else
  102.     {
  103.       panic ("probably irrecoverable malloc error: code %d", code);
  104.     }
  105. }
  106.  
  107. static void
  108. NeXT_init (void)
  109. {
  110.   malloc_error (malloc_handler);
  111. }
  112. #endif
  113.  
  114. static void
  115. octave_ieee_init (void)
  116. {
  117. #if defined (HAVE_ISINF) || defined (HAVE_FINITE)
  118.  
  119. // Some version of gcc on some old version of Linux used to crash when
  120. // trying to make Inf and NaN.
  121.  
  122. #if defined (HAVE_INFINITY)
  123.   octave_Inf = (double) infinity ();
  124. #elif defined (linux)
  125.   octave_Inf = HUGE_VAL;
  126. #elif defined (__alpha__)
  127.   extern unsigned int DINFINITY[2];
  128.   octave_Inf =  (*((double *) (DINFINITY)));
  129. #else
  130.   double tmp = 1e+10;
  131.   octave_Inf = tmp;
  132.   for (;;)
  133.     {
  134.       octave_Inf *= 1e+10;
  135.       if (octave_Inf == tmp)
  136.     break;
  137.       tmp = octave_Inf;
  138.     }
  139. #endif
  140.  
  141. #if defined (HAVE_QUIET_NAN)
  142.   octave_NaN = (double) quiet_nan ();
  143. #elif defined (linux)
  144.   octave_NaN = NAN;
  145. #elif defined (__alpha__)
  146.   extern unsigned int DQNAN[2];
  147.   octave_NaN = (*((double *) (DQNAN)));
  148. #else
  149.   octave_NaN = octave_Inf / octave_Inf;
  150. #endif
  151.  
  152. #else
  153.  
  154. // This is sort of cheesy, but what can we do, other than blowing it
  155. // off completely, or writing an entire IEEE emulation package?
  156.  
  157.   octave_Inf = DBL_MAX;
  158.   octave_NaN = DBL_MAX;
  159.  
  160. #endif
  161. }
  162.  
  163. #if defined (EXCEPTION_IN_MATH)
  164. extern "C"
  165. {
  166. int
  167. matherr (struct exception *x)
  168. {
  169. // Possibly print our own message someday.  Should probably be
  170. // user-switchable.
  171.  
  172.   switch (x->type)
  173.     {
  174.     case DOMAIN:
  175.     case SING:
  176.     case OVERFLOW:
  177.     case UNDERFLOW:
  178.     case TLOSS:
  179.     case PLOSS:
  180.     default:
  181.       break;
  182.     }
  183.  
  184. // But don't print the system message.
  185.  
  186.   return 1;
  187. }
  188. }
  189. #endif
  190.  
  191. void
  192. sysdep_init (void)
  193. {
  194. #if defined (__386BSD__) || defined (__FreeBSD__)
  195. #if defined (HAVE_FLOATINGPOINT_H)
  196. // Disable trapping on common exceptions.
  197.   fpsetmask (~(FP_X_OFL|FP_X_INV|FP_X_DZ|FP_X_DNML|FP_X_UFL|FP_X_IMP));
  198. #endif
  199. #endif
  200.  
  201. #ifdef NeXT
  202.   NeXT_init ();
  203. #endif
  204.  
  205.   octave_ieee_init ();
  206. }
  207.  
  208. // Set terminal in raw mode.  From less-177.
  209. //
  210. // Change terminal to "raw mode", or restore to "normal" mode.
  211. // "Raw mode" means 
  212. //    1. An outstanding read will complete on receipt of a single keystroke.
  213. //    2. Input is not echoed.  
  214. //    3. On output, \n is mapped to \r\n.
  215. //    4. \t is NOT expanded into spaces.
  216. //    5. Signal-causing characters such as ctrl-C (interrupt),
  217. //       etc. are NOT disabled.
  218. // It doesn't matter whether an input \n is mapped to \r, or vice versa.
  219.  
  220. void
  221. raw_mode (int on)
  222. {
  223.   static int curr_on = 0;
  224.  
  225.   int tty_fd = STDIN_FILENO;
  226.   if (! isatty (tty_fd))
  227.     {
  228.       if (interactive)
  229.     error ("stdin is not a tty!");
  230.       return;
  231.     }
  232.  
  233.   if (on == curr_on)
  234.     return;
  235.  
  236. #if defined (HAVE_TERMIOS_H)
  237.   {
  238.     struct termios s;
  239.     static struct termios save_term;
  240.  
  241.     if (on)
  242.       {
  243. // Get terminal modes.
  244.  
  245.     tcgetattr (tty_fd, &s);
  246.  
  247. // Save modes and set certain variables dependent on modes.
  248.  
  249.     save_term = s;
  250. //    ospeed = s.c_cflag & CBAUD;
  251. //    erase_char = s.c_cc[VERASE];
  252. //    kill_char = s.c_cc[VKILL];
  253.  
  254. // Set the modes to the way we want them.
  255.  
  256.     s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
  257.     s.c_oflag |=  (OPOST|ONLCR);
  258. #if defined (OCRNL)
  259.     s.c_oflag &= ~(OCRNL);
  260. #endif
  261. #if defined (ONOCR)
  262.     s.c_oflag &= ~(ONOCR);
  263. #endif
  264. #if defined (ONLRET)
  265.     s.c_oflag &= ~(ONLRET);
  266. #endif
  267.     s.c_cc[VMIN] = 1;
  268.     s.c_cc[VTIME] = 0;
  269.       }      
  270.     else
  271.       {
  272. // Restore saved modes.
  273.     s = save_term;
  274.       }
  275.     tcsetattr (tty_fd, TCSAFLUSH, &s);
  276.   }
  277. #elif defined (HAVE_TERMIO_H)
  278.   {
  279.     struct termio s;
  280.     static struct termio save_term;
  281.  
  282.     if (on)
  283.       {
  284. // Get terminal modes.
  285.  
  286.     ioctl (tty_fd, TCGETA, &s);
  287.  
  288. // Save modes and set certain variables dependent on modes.
  289.  
  290.     save_term = s;
  291. //    ospeed = s.c_cflag & CBAUD;
  292. //    erase_char = s.c_cc[VERASE];
  293. //    kill_char = s.c_cc[VKILL];
  294.  
  295. // Set the modes to the way we want them.
  296.  
  297.     s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
  298.     s.c_oflag |=  (OPOST|ONLCR);
  299. #if defined (OCRNL)
  300.     s.c_oflag &= ~(OCRNL);
  301. #endif
  302. #if defined (ONOCR)
  303.     s.c_oflag &= ~(ONOCR);
  304. #endif
  305. #if defined (ONLRET)
  306.     s.c_oflag &= ~(ONLRET);
  307. #endif
  308.     s.c_cc[VMIN] = 1;
  309.     s.c_cc[VTIME] = 0;
  310.       }      
  311.     else
  312.       {
  313. // Restore saved modes.
  314.     s = save_term;
  315.       }
  316.     ioctl (tty_fd, TCSETAW, &s);
  317.   }
  318. #elif defined (HAVE_SGTTY_H)
  319.   {
  320.     struct sgttyb s;
  321.     static struct sgttyb save_term;
  322.  
  323.     if (on)
  324.       {
  325. // Get terminal modes.
  326.  
  327.     ioctl (tty_fd, TIOCGETP, &s);
  328.  
  329. // Save modes and set certain variables dependent on modes.
  330.  
  331.     save_term = s;
  332. //    ospeed = s.sg_ospeed;
  333. //    erase_char = s.sg_erase;
  334. //    kill_char = s.sg_kill;
  335.  
  336. // Set the modes to the way we want them.
  337.  
  338.     s.sg_flags |= CBREAK;
  339.     s.sg_flags &= ~(ECHO);
  340.       } 
  341.     else
  342.       {
  343. // Restore saved modes.
  344.     s = save_term;
  345.       }
  346.     ioctl (tty_fd, TIOCSETN, &s);
  347.   }
  348. #else
  349. LOSE! LOSE!
  350. #endif
  351.  
  352.   curr_on = on;
  353. }
  354.  
  355. // Read one character from the terminal.
  356.  
  357. int
  358. kbhit (void)
  359. {
  360.   int c;
  361.   raw_mode (1);
  362.   c = cin.get ();
  363.   raw_mode (0);
  364.   return c;
  365. }
  366.  
  367. char *
  368. octave_getcwd (char *buf, int len)
  369. {
  370. #if defined (__EMX__)
  371.   return _getcwd2 (buf, len);
  372. #else
  373.   return getcwd (buf, len);
  374. #endif
  375. }
  376.  
  377. int
  378. octave_chdir (const char *path)
  379. {
  380. #if defined (__EMX__)
  381.   int retval = -1;
  382.  
  383.   if (strlen (path) == 2 && path[1] == ':')
  384.     {
  385.       char *upper_case_dir_name = strupr (path);
  386.       _chdrive (upper_case_dir_name[0]);
  387.       if (_getdrive () == upper_case_dir_name[0])
  388.     retval = _chdir2 ("/");
  389.     }
  390.   else
  391.     retval = _chdir2 (path);
  392.  
  393.   return retval;
  394. #else
  395.   return chdir (path);
  396. #endif
  397. }
  398.  
  399. DEFUN ("clc", Fclc, Sclc, 0, 0,
  400.   "clc (): clear screen")
  401. {
  402.   Octave_object retval;
  403.  
  404.   rl_beg_of_line ();
  405.   rl_kill_line (1);
  406.  
  407. #if ! defined (_GO32_)
  408.   if (term_clrpag)
  409.     tputs (term_clrpag, 1, _rl_output_character_function);
  410.   else
  411.     crlf ();
  412. #else
  413.   crlf ();
  414. #endif
  415.  
  416.   fflush (rl_outstream);
  417.  
  418.   return retval;
  419. }
  420.  
  421. DEFALIAS (home, clc);
  422.  
  423. DEFUN ("getenv", Fgetenv, Sgetenv, 1, 1,
  424.   "getenv (STRING): get environment variable values")
  425. {
  426.   Octave_object retval;
  427.  
  428.   int nargin = args.length ();
  429.  
  430.   if (nargin == 1)
  431.     {
  432.       char *name = args(0).string_value ();
  433.  
  434.       if (! error_state)
  435.     {
  436.       char *value = getenv (name);
  437.       if (value)
  438.         retval = value;
  439.       else
  440.         retval = "";
  441.     }
  442.     }
  443.   else
  444.     print_usage ("getenv");
  445.  
  446.   return retval;
  447. }
  448.  
  449. DEFUN ("kbhit", Fkbhit, Skbhit, 0, 1,
  450.   "kbhit: get a single character from the terminal")
  451. {
  452.   Octave_object retval;
  453.  
  454. // XXX FIXME XXX -- add timeout and default value args?
  455.  
  456.   if (interactive)
  457.     {
  458.       int c = kbhit ();
  459.       char *s = new char [2];
  460.       s[0] = c;
  461.       s[1] = '\0';
  462.       retval = s;
  463.     }
  464.  
  465.   return retval;
  466. }
  467.  
  468. DEFUN ("pause", Fpause, Spause, 1, 1,
  469.   "pause (seconds): suspend program execution")
  470. {
  471.   Octave_object retval;
  472.  
  473.   int nargin = args.length ();
  474.  
  475.   if (! (nargin == 0 || nargin == 1))
  476.     {
  477.       print_usage ("pause");
  478.       return retval;
  479.     }
  480.  
  481.   if (interactive)
  482.     {
  483.       switch (nargin)
  484.     {
  485.     case 1:
  486.       {
  487.         double dval = args(0).double_value ();
  488.  
  489.         if (! error_state)
  490.           {
  491.         if (xisnan (dval))
  492.           warning ("pause: NaN is an invalid delay");
  493.         else
  494.           {
  495.             int delay = NINT (dval);
  496.             if (delay > 0)
  497.               sleep (delay);
  498.           }
  499.           }
  500.       }
  501.       break;
  502.  
  503.     default:
  504.       if (kbhit () == EOF)
  505.         clean_up_and_exit (0);
  506.       break;
  507.     }
  508.     }
  509.  
  510.   return retval;
  511. }
  512.  
  513. // XXX FIXME XXX -- maybe this should only return 1 if IEEE floating
  514. // point functions really work.
  515.  
  516. DEFUN ("isieee", Fisieee, Sisieee, 1, 1,
  517.   "isieee (): return 1 if host uses IEEE floating point")
  518. {
  519.   Octave_object retval;
  520.  
  521. #if defined (IEEE_BIG_ENDIAN) || defined (IEEE_LITTLE_ENDIAN)
  522.   retval = 1.0;
  523. #else
  524.   retval = 0.0;
  525. #endif
  526.  
  527.   return retval;
  528. }
  529.  
  530. #if !defined (HAVE_GETHOSTNAME) && defined (HAVE_SYS_UTSNAME_H)
  531. extern "C"
  532. {
  533. #include <sys/utsname.h>
  534. int
  535. gethostname (char *name, int namelen)
  536. {
  537.   int i;
  538.   struct utsname ut;
  539.  
  540.   --namelen;
  541.  
  542.   uname (&ut);
  543.   i = strlen (ut.nodename) + 1;
  544.   strncpy (name, ut.nodename, i < namelen ? i : namelen);
  545.   name[namelen] = '\0';
  546.  
  547.   return 0;
  548. }
  549. }
  550. #endif
  551.  
  552. /*
  553. ;;; Local Variables: ***
  554. ;;; mode: C++ ***
  555. ;;; page-delimiter: "^/\\*" ***
  556. ;;; End: ***
  557. */
  558.