changelog shortlog tags changeset files revisions annotate raw

src/sysdep.cc

changeset 9846: 1d90fc211872
parent:c9636d98e5cd
author: John W. Eaton <jwe@octave.org>
date: Sat Nov 21 21:44:51 2009 -0500 (21 hours ago)
permissions: -rw-r--r--
description: configure.ac: report freetype, fontconfig, and fltk cflags and libs info
1/*
2
3Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2002, 2003,
4 2005, 2006, 2007, 2008, 2009 John W. Eaton
5
6This file is part of Octave.
7
8Octave is free software; you can redistribute it and/or modify it
9under the terms of the GNU General Public License as published by the
10Free Software Foundation; either version 3 of the License, or (at your
11option) any later version.
12
13Octave is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with Octave; see the file COPYING. If not, see
20<http://www.gnu.org/licenses/>.
21
22*/
23
24#ifdef HAVE_CONFIG_H
25#include <config.h>
26#endif
27
28#include <cfloat>
29#include <cstddef>
30#include <cstdio>
31#include <cstdlib>
32#include <cstring>
33
34#include <iostream>
35#include <string>
36
37#ifdef HAVE_UNISTD_H
38#ifdef HAVE_SYS_TYPES_H
39#include <sys/types.h>
40#endif
41#include <unistd.h>
42#endif
43
44#if defined (HAVE_TERMIOS_H)
45#include <termios.h>
46#elif defined (HAVE_TERMIO_H)
47#include <termio.h>
48#elif defined (HAVE_SGTTY_H)
49#include <sgtty.h>
50#endif
51
52#if defined (HAVE_CONIO_H)
53#include <conio.h>
54#endif
55
56#if defined (HAVE_SYS_IOCTL_H)
57#include <sys/ioctl.h>
58#endif
59
60#if defined (HAVE_FLOATINGPOINT_H)
61#include <floatingpoint.h>
62#endif
63
64#if defined (HAVE_IEEEFP_H)
65#include <ieeefp.h>
66#endif
67
68#if !defined (HAVE_GETHOSTNAME) && defined (HAVE_SYS_UTSNAME_H)
69#include <sys/utsname.h>
70#endif
71
72#include "cmd-edit.h"
73#include "file-ops.h"
74#include "lo-mappers.h"
75#include "lo-math.h"
76#include "mach-info.h"
77#include "oct-env.h"
78#include "quit.h"
79
80#include "Cell.h"
81#include "defun.h"
82#include "error.h"
83#include "input.h"
84#include "oct-obj.h"
85#include "ov.h"
86#include "pager.h"
87#include "parse.h"
88#include "sighandlers.h"
89#include "sysdep.h"
90#include "toplev.h"
91#include "utils.h"
92#include "file-stat.h"
93
94#ifndef STDIN_FILENO
95#define STDIN_FILENO 1
96#endif
97
98#if defined (__386BSD__) || defined (__FreeBSD__) || defined (__NetBSD__)
99static void
100BSD_init (void)
101{
102#if defined (HAVE_FLOATINGPOINT_H)
103 // Disable trapping on common exceptions.
104#ifndef FP_X_DNML
105#define FP_X_DNML 0
106#endif
107 fpsetmask (~(FP_X_OFL|FP_X_INV|FP_X_DZ|FP_X_DNML|FP_X_UFL|FP_X_IMP));
108#endif
109}
110#endif
111
112#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
113static void
114w32_set_octave_home (void)
115{
116 int n = 1024;
117
118 std::string bin_dir (n, '\0');
119
120 while (true)
121 {
122 HMODULE hMod = GetModuleHandle ("octinterp");
123 int status = GetModuleFileName (hMod, &bin_dir[0], n);
124
125 if (status < n)
126 {
127 bin_dir.resize (status);
128 break;
129 }
130 else
131 {
132 n *= 2;
133 bin_dir.resize (n);
134 }
135 }
136
137 if (! bin_dir.empty ())
138 {
139 size_t pos = bin_dir.rfind ("\\bin\\");
140
141 if (pos != std::string::npos)
142 octave_env::putenv ("OCTAVE_HOME", bin_dir.substr (0, pos));
143 }
144}
145
146void
147w32_set_quiet_shutdown (void)
148{
149 // Let the user close the console window or shutdown without the
150 // pesky dialog.
151 //
152 // FIXME -- should this be user configurable?
153 SetProcessShutdownParameters (0x280, SHUTDOWN_NORETRY);
154}
155
156void
157MINGW_signal_cleanup (void)
158{
159 w32_set_quiet_shutdown ();
160
161 w32_raise_final ();
162}
163#endif
164
165#if defined (__MINGW32__)
166static void
167MINGW_init (void)
168{
169 w32_set_octave_home ();
170
171 // Init mutex to protect setjmp/longjmp and get main thread context
172 w32_sigint_init ();
173
174 w32_set_quiet_shutdown ();
175}
176#endif
177
178#if defined (_MSC_VER)
179static void
180MSVC_init (void)
181{
182 w32_set_octave_home ();
183
184 // Init mutex to protect setjmp/longjmp and get main thread context
185 w32_sigint_init ();
186
187 w32_set_quiet_shutdown ();
188}
189#endif
190
191
192// Return TRUE if FILE1 and FILE2 refer to the same (physical) file.
193
194bool
195same_file_internal (const std::string& file1, const std::string& file2)
196{
197#ifdef OCTAVE_USE_WINDOWS_API
198
199 bool retval = false;
200
201 // Windows native code
202 // Reference: http://msdn2.microsoft.com/en-us/library/aa363788.aspx
203
204 HANDLE hfile1 = CreateFile (file1.c_str (), 0, FILE_SHARE_READ, 0,
205 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
206
207 if (hfile1 != INVALID_HANDLE_VALUE)
208 {
209 HANDLE hfile2 = CreateFile (file2.c_str (), 0, FILE_SHARE_READ, 0,
210 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
211
212 if (hfile2 != INVALID_HANDLE_VALUE)
213 {
214 BY_HANDLE_FILE_INFORMATION hfi1;
215 BY_HANDLE_FILE_INFORMATION hfi2;
216
217 if (GetFileInformationByHandle (hfile1, &hfi1)
218 && GetFileInformationByHandle (hfile2, &hfi2))
219
220 retval = (hfi1.dwVolumeSerialNumber == hfi2.dwVolumeSerialNumber
221 && hfi1.nFileIndexHigh == hfi2.nFileIndexHigh
222 && hfi1.nFileIndexLow == hfi2.nFileIndexLow);
223
224 CloseHandle (hfile2);
225 }
226
227 CloseHandle (hfile1);
228 }
229
230 return retval;
231
232#else
233
234 // POSIX Code
235
236 file_stat fs_file1 (file1);
237 file_stat fs_file2 (file2);
238
239 return (fs_file1 && fs_file2
240 && fs_file1.ino () == fs_file2.ino ()
241 && fs_file1.dev () == fs_file2.dev ());
242
243#endif
244}
245
246#if defined (__DECCXX)
247
248// These don't seem to be instantiated automatically...
249
250template std::istream&
251std::operator >> (std::istream&, std::complex<double>&);
252
253template std::string&
254std::string::append (const std::string&, size_t, size_t);
255
256#endif
257
258#if defined (NeXT)
259extern "C"
260{
261 typedef void (*_cplus_fcn_int) (int);
262 extern void (*malloc_error (_cplus_fcn_int)) (int);
263}
264
265static void
266malloc_handler (int code)
267{
268 if (code == 5)
269 warning ("hopefully recoverable malloc error: freeing wild pointer");
270 else
271 panic ("probably irrecoverable malloc error: code %d", code);
272}
273
274static void
275NeXT_init (void)
276{
277 malloc_error (malloc_handler);
278}
279#endif
280
281#if defined (__EMX__)
282OS2_init (void)
283{
284 _control87 ((EM_INVALID | EM_DENORMAL | EM_ZERODIVIDE | EM_OVERFLOW
285 | EM_UNDERFLOW | EM_INEXACT), MCW_EM);
286}
287#endif
288
289#if defined (SCO)
290static void
291SCO_init (void)
292{
293#if defined (HAVE_IEEEFP_H)
294 // Disable trapping on common exceptions.
295 fpsetmask (~(FP_X_OFL|FP_X_INV|FP_X_DZ|FP_X_DNML|FP_X_UFL|FP_X_IMP));
296#endif
297}
298#endif
299
300void
301sysdep_init (void)
302{
303#if defined (__386BSD__) || defined (__FreeBSD__) || defined(__NetBSD__)
304 BSD_init ();
305#elif defined (__MINGW32__)
306 MINGW_init ();
307#elif defined (_MSC_VER)
308 MSVC_init ();
309#elif defined (NeXT)
310 NeXT_init ();
311#elif defined (__EMX__)
312 OS2_init ();
313#elif defined (SCO)
314 SCO_init ();
315#endif
316
317 octave_ieee_init ();
318}
319
320void
321sysdep_cleanup (void)
322{
323 MINGW_SIGNAL_CLEANUP ();
324}
325
326// Set terminal in raw mode. From less-177.
327//
328// Change terminal to "raw mode", or restore to "normal" mode.
329// "Raw mode" means
330// 1. An outstanding read will complete on receipt of a single keystroke.
331// 2. Input is not echoed.
332// 3. On output, \n is mapped to \r\n.
333// 4. \t is NOT expanded into spaces.
334// 5. Signal-causing characters such as ctrl-C (interrupt),
335// etc. are NOT disabled.
336// It doesn't matter whether an input \n is mapped to \r, or vice versa.
337
338void
339raw_mode (bool on, bool wait)
340{
341 static bool curr_on = false;
342
343 int tty_fd = STDIN_FILENO;
344 if (! isatty (tty_fd))
345 {
346 if (interactive)
347 error ("stdin is not a tty!");
348 return;
349 }
350
351 if (on == curr_on)
352 return;
353
354#if defined (HAVE_TERMIOS_H)
355 {
356 struct termios s;
357 static struct termios save_term;
358
359 if (on)
360 {
361 // Get terminal modes.
362
363 tcgetattr (tty_fd, &s);
364
365 // Save modes and set certain variables dependent on modes.
366
367 save_term = s;
368// ospeed = s.c_cflag & CBAUD;
369// erase_char = s.c_cc[VERASE];
370// kill_char = s.c_cc[VKILL];
371
372 // Set the modes to the way we want them.
373
374 s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
375 s.c_oflag |= (OPOST|ONLCR);
376#if defined (OCRNL)
377 s.c_oflag &= ~(OCRNL);
378#endif
379#if defined (ONOCR)
380 s.c_oflag &= ~(ONOCR);
381#endif
382#if defined (ONLRET)
383 s.c_oflag &= ~(ONLRET);
384#endif
385 s.c_cc[VMIN] = wait ? 1 : 0;
386 s.c_cc[VTIME] = 0;
387 }
388 else
389 {
390 // Restore saved modes.
391
392 s = save_term;
393 }
394
395 tcsetattr (tty_fd, wait ? TCSAFLUSH : TCSADRAIN, &s);
396 }
397#elif defined (HAVE_TERMIO_H)
398 {
399 struct termio s;
400 static struct termio save_term;
401
402 if (on)
403 {
404 // Get terminal modes.
405
406 ioctl (tty_fd, TCGETA, &s);
407
408 // Save modes and set certain variables dependent on modes.
409
410 save_term = s;
411// ospeed = s.c_cflag & CBAUD;
412// erase_char = s.c_cc[VERASE];
413// kill_char = s.c_cc[VKILL];
414
415 // Set the modes to the way we want them.
416
417 s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
418 s.c_oflag |= (OPOST|ONLCR);
419#if defined (OCRNL)
420 s.c_oflag &= ~(OCRNL);
421#endif
422#if defined (ONOCR)
423 s.c_oflag &= ~(ONOCR);
424#endif
425#if defined (ONLRET)
426 s.c_oflag &= ~(ONLRET);
427#endif
428 s.c_cc[VMIN] = wait ? 1 : 0;
429 }
430 else
431 {
432 // Restore saved modes.
433
434 s = save_term;
435 }
436
437 ioctl (tty_fd, TCSETAW, &s);
438 }
439#elif defined (HAVE_SGTTY_H)
440 {
441 struct sgttyb s;
442 static struct sgttyb save_term;
443
444 if (on)
445 {
446 // Get terminal modes.
447
448 ioctl (tty_fd, TIOCGETP, &s);
449
450 // Save modes and set certain variables dependent on modes.
451
452 save_term = s;
453// ospeed = s.sg_ospeed;
454// erase_char = s.sg_erase;
455// kill_char = s.sg_kill;
456
457 // Set the modes to the way we want them.
458
459 s.sg_flags |= CBREAK;
460 s.sg_flags &= ~(ECHO);
461 }
462 else
463 {
464 // Restore saved modes.
465
466 s = save_term;
467 }
468
469 ioctl (tty_fd, TIOCSETN, &s);
470 }
471#else
472 warning ("no support for raw mode console I/O on this system");
473
474 // Make sure the current mode doesn't toggle.
475 on = curr_on;
476#endif
477
478 curr_on = on;
479}
480
481FILE *
482octave_popen (const char *command, const char *mode)
483{
484#if defined (__MINGW32__) || defined (_MSC_VER)
485 if (mode && mode[0] && ! mode[1])
486 {
487 char tmode[3];
488 tmode[0] = mode[0];
489 tmode[1] = 'b';
490 tmode[2] = 0;
491
492 return _popen (command, tmode);
493 }
494 else
495 return _popen (command, mode);
496#else
497 return popen (command, mode);
498#endif
499}
500
501int
502octave_pclose (FILE *f)
503{
504#if defined (__MINGW32__) || defined (_MSC_VER)
505 return _pclose (f);
506#else
507 return pclose (f);
508#endif
509}
510
511// Read one character from the terminal.
512
513int
514octave_kbhit (bool wait)
515{
516#ifdef HAVE__KBHIT
517 int c = (! wait && ! _kbhit ()) ? 0 : std::cin.get ();
518#else
519 raw_mode (true, wait);
520
521 // Get current handler.
522 octave_interrupt_handler saved_interrupt_handler
523 = octave_ignore_interrupts ();
524
525 // Restore it, disabling system call restarts (if possible) so the
526 // read can be interrupted.
527
528 octave_set_interrupt_handler (saved_interrupt_handler, false);
529
530 int c = std::cin.get ();
531
532 if (std::cin.fail () || std::cin.eof ())
533 std::cin.clear ();
534
535 // Restore it, enabling system call restarts (if possible).
536 octave_set_interrupt_handler (saved_interrupt_handler, true);
537
538 raw_mode (false, true);
539#endif
540
541 return c;
542}
543
544DEFUN (clc, , ,
545 "-*- texinfo -*-\n\
546@deftypefn {Built-in Function} {} clc ()\n\
547@deftypefnx {Built-in Function} {} home ()\n\
548Clear the terminal screen and move the cursor to the upper left corner.\n\
549@end deftypefn")
550{
551 command_editor::clear_screen ();
552
553 return octave_value_list ();
554}
555
556DEFALIAS (home, clc);
557
558DEFUN (getenv, args, ,
559 "-*- texinfo -*-\n\
560@deftypefn {Built-in Function} {} getenv (@var{var})\n\
561Return the value of the environment variable @var{var}. For example,\n\
562\n\
563@example\n\
564getenv (\"PATH\")\n\
565@end example\n\
566\n\
567@noindent\n\
568returns a string containing the value of your path.\n\
569@end deftypefn")
570{
571 octave_value retval;
572
573 int nargin = args.length ();
574
575 if (nargin == 1)
576 {
577 std::string name = args(0).string_value ();
578
579 if (! error_state)
580 retval = octave_env::getenv (name);
581 }
582 else
583 print_usage ();
584
585 return retval;
586}
587
588DEFUN (putenv, args, ,
589 "-*- texinfo -*-\n\
590@deftypefn {Built-in Function} {} putenv (@var{var}, @var{value})\n\
591@deftypefnx {Built-in Function} {} setenv (@var{var}, @var{value})\n\
592Set the value of the environment variable @var{var} to @var{value}.\n\
593@end deftypefn")
594{
595 octave_value_list retval;
596
597 int nargin = args.length ();
598
599 if (nargin == 2 || nargin == 1)
600 {
601 std::string var = args(0).string_value ();
602
603 if (! error_state)
604 {
605 std::string val = (nargin == 2
606 ? args(1).string_value () : std::string ());
607
608 if (! error_state)
609 octave_env::putenv (var, val);
610 else
611 error ("putenv: second argument should be a string");
612 }
613 else
614 error ("putenv: first argument should be a string");
615 }
616 else
617 print_usage ();
618
619 return retval;
620}
621DEFALIAS (setenv, putenv);
622
623// FIXME -- perhaps kbhit should also be able to print a prompt?
624
625DEFUN (kbhit, args, ,
626 "-*- texinfo -*-\n\
627@deftypefn {Built-in Function} {} kbhit ()\n\
628Read a single keystroke from the keyboard. If called with one\n\
629argument, don't wait for a keypress. For example,\n\
630\n\
631@example\n\
632x = kbhit ();\n\
633@end example\n\
634\n\
635@noindent\n\
636will set @var{x} to the next character typed at the keyboard as soon as\n\
637it is typed.\n\
638\n\
639@example\n\
640x = kbhit (1);\n\
641@end example\n\
642\n\
643@noindent\n\
644identical to the above example, but don't wait for a keypress,\n\
645returning the empty string if no key is available.\n\
646@end deftypefn")
647{
648 octave_value retval;
649
650 // FIXME -- add timeout and default value args?
651
652 if (interactive || forced_interactive)
653 {
654 feval ("drawnow");
655
656 int c = octave_kbhit (args.length () == 0);
657
658 if (c == -1)
659 c = 0;
660
661 char *s = new char [2];
662 s[0] = c;
663 s[1] = '\0';
664 retval = s;
665 }
666
667 return retval;
668}
669
670DEFUN (pause, args, ,
671 "-*- texinfo -*-\n\
672@deftypefn {Built-in Function} {} pause (@var{seconds})\n\
673Suspend the execution of the program. If invoked without any arguments,\n\
674Octave waits until you type a character. With a numeric argument, it\n\
675pauses for the given number of seconds. For example, the following\n\
676statement prints a message and then waits 5 seconds before clearing the\n\
677screen.\n\
678\n\
679@example\n\
680@group\n\
681fprintf (stderr, \"wait please...\\n\");\n\
682pause (5);\n\
683clc;\n\
684@end group\n\
685@end example\n\
686@end deftypefn")
687{
688 octave_value_list retval;
689
690 int nargin = args.length ();
691
692 if (! (nargin == 0 || nargin == 1))
693 {
694 print_usage ();
695 return retval;
696 }
697
698 if (nargin == 1)
699 {
700 double dval = args(0).double_value ();
701
702 if (! error_state)
703 {
704 if (! xisnan (dval))
705 {
706 feval ("drawnow");
707
708 if (xisinf (dval))
709 {
710 flush_octave_stdout ();
711 octave_kbhit ();
712 }
713 else
714 octave_sleep (dval);
715 }
716 else
717 warning ("pause: NaN is an invalid delay");
718 }
719 }
720 else
721 {
722 feval ("drawnow");
723 flush_octave_stdout ();
724 octave_kbhit ();
725 }
726
727 return retval;
728}
729
730DEFUN (sleep, args, ,
731 "-*- texinfo -*-\n\
732@deftypefn {Built-in Function} {} sleep (@var{seconds})\n\
733Suspend the execution of the program for the given number of seconds.\n\
734@end deftypefn")
735{
736 octave_value_list retval;
737
738 if (args.length () == 1)
739 {
740 double dval = args(0).double_value ();
741
742 if (! error_state)
743 {
744 if (xisnan (dval))
745 warning ("sleep: NaN is an invalid delay");
746 else
747 {
748 feval ("drawnow");
749 octave_sleep (dval);
750 }
751 }
752 }
753 else
754 print_usage ();
755
756 return retval;
757}
758
759DEFUN (usleep, args, ,
760 "-*- texinfo -*-\n\
761@deftypefn {Built-in Function} {} usleep (@var{microseconds})\n\
762Suspend the execution of the program for the given number of\n\
763microseconds. On systems where it is not possible to sleep for periods\n\
764of time less than one second, @code{usleep} will pause the execution for\n\
765@code{round (@var{microseconds} / 1e6)} seconds.\n\
766@end deftypefn")
767{
768 octave_value_list retval;
769
770 if (args.length () == 1)
771 {
772 double dval = args(0).double_value ();
773
774 if (! error_state)
775 {
776 if (xisnan (dval))
777 warning ("usleep: NaN is an invalid delay");
778 else
779 {
780 feval ("drawnow");
781
782 int delay = NINT (dval);
783
784 if (delay > 0)
785 octave_usleep (delay);
786 }
787 }
788 }
789 else
790 print_usage ();
791
792 return retval;
793}
794
795// FIXME -- maybe this should only return 1 if IEEE floating
796// point functions really work.
797
798DEFUN (isieee, , ,
799 "-*- texinfo -*-\n\
800@deftypefn {Built-in Function} {} isieee ()\n\
801Return 1 if your computer claims to conform to the IEEE standard for\n\
802floating point calculations.\n\
803@end deftypefn")
804{
805 oct_mach_info::float_format flt_fmt = oct_mach_info::native_float_format ();
806
807 return octave_value (flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian
808 || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian);
809}
810
811DEFUN (native_float_format, , ,
812 "-*- texinfo -*-\n\
813@deftypefn {Built-in Function} {} native_float_format ()\n\
814Return the native floating point format as a string\n\
815@end deftypefn")
816{
817 oct_mach_info::float_format flt_fmt = oct_mach_info::native_float_format ();
818
819 return octave_value (oct_mach_info::float_format_as_string (flt_fmt));
820}
821
822DEFUN (tilde_expand, args, ,
823 "-*- texinfo -*-\n\
824@deftypefn {Built-in Function} {} tilde_expand (@var{string})\n\
825Performs tilde expansion on @var{string}. If @var{string} begins with a\n\
826tilde character, (@samp{~}), all of the characters preceding the first\n\
827slash (or all characters, if there is no slash) are treated as a\n\
828possible user name, and the tilde and the following characters up to the\n\
829slash are replaced by the home directory of the named user. If the\n\
830tilde is followed immediately by a slash, the tilde is replaced by the\n\
831home directory of the user running Octave. For example,\n\
832\n\
833@example\n\
834@group\n\
835tilde_expand (\"~joeuser/bin\")\n\
836 @result{} \"/home/joeuser/bin\"\n\
837tilde_expand (\"~/bin\")\n\
838 @result{} \"/home/jwe/bin\"\n\
839@end group\n\
840@end example\n\
841@end deftypefn")
842{
843 octave_value retval;
844
845 int nargin = args.length ();
846
847 if (nargin == 1)
848 {
849 octave_value arg = args(0);
850
851 string_vector sv = arg.all_strings ();
852
853 if (! error_state)
854 {
855 sv = file_ops::tilde_expand (sv);
856
857 if (arg.is_cellstr ())
858 retval = Cell (arg.dims (), sv);
859 else
860 retval = sv;
861 }
862 else
863 error ("tilde_expand: expecting argument to be char or cellstr object");
864 }
865 else
866 print_usage ();
867
868 return retval;
869}
870
871#if defined (__EMX__) && defined (OS2)
872
873DEFUN (extproc, , ,
874 "extproc: ignored by Octave")
875{
876 return octave_value_list ();
877}
878
879DEFALIAS (EXTPROC, extproc);
880
881#endif
882
883/*
884;;; Local Variables: ***
885;;; mode: C++ ***
886;;; End: ***
887*/