home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mitsch75.zip / scheme-7_5_17-src.zip / scheme-7.5.17 / src / microcode / outf.c < prev    next >
C/C++ Source or Header  |  2000-12-05  |  6KB  |  215 lines

  1. /* -*-C-*-
  2.  
  3. $Id: outf.c,v 1.12 2000/12/05 21:23:47 cph Exp $
  4.  
  5. Copyright (c) 1993-2000 Massachusetts Institute of Technology
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful, but
  13. WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. /*
  23.   OUTF system
  24.     
  25.   outf_channel i/o is a substitute for <stdio.h>.  On text based unix-like
  26.   systems it is implmented in terms of stdio.  On windowing systems, however,
  27.   we have to be able to report problems withou having an obvious text output.
  28.   
  29.   There are three channels for output:
  30.     
  31.     console_output - for normal output to the user
  32.     error_output   - for output of exceptional things
  33.     fatal_output   - for details of an impending crash
  34.       
  35.   Use outf where you would normally think of using fprintf and outf_flush
  36.   where you would normally use fflush.
  37.     
  38.   outf_flush(fatal_output) is special.  It causes the buffered fatal_output
  39.   data to be displayed.  On windowing systems this may cause a window to be
  40.   created to display the information, or allow the window containging the
  41.   information to stay visible `after' the termination of Scheme.
  42. */
  43.  
  44. #include <stdio.h>
  45. #include "scheme.h"
  46.  
  47. #ifdef STDC_HEADERS
  48. #  include <string.h>
  49. #  include <stdarg.h>
  50. #  define VA_START(args, lastarg) va_start(args, lastarg)
  51. #  define VA_DCL
  52. #else
  53. #  include <varargs.h>
  54. #  define VA_START(args, lastarg) va_start(args)
  55. #  define VA_DCL va_dcl
  56. #endif
  57.  
  58. #ifdef __WIN32__
  59. #  include <windows.h>
  60. #  include "ntscreen.h"
  61. #endif
  62.  
  63. /* forward reference */
  64. extern void EXFUN
  65.   (voutf, (CONST outf_channel chan, CONST char * format, va_list ap));
  66.  
  67. #define make_outf_variants(outputter,flusher,chan)            \
  68. void                                    \
  69. DEFUN (outputter, (format, va_alist), CONST char *format DOTS)        \
  70.      VA_DCL                                \
  71. {                                    \
  72.     va_list args;                            \
  73.     VA_START(args, format);                        \
  74.     voutf((chan), format, args);                    \
  75. }                                    \
  76. void                                    \
  77. DEFUN_VOID (flusher)                            \
  78. {                                    \
  79.     outf_flush (chan);                            \
  80. }
  81.  
  82. make_outf_variants(outf_console, outf_flush_console, console_output)
  83. make_outf_variants(outf_error,   outf_flush_error,   error_output)
  84. make_outf_variants(outf_fatal,   outf_flush_fatal,   fatal_output)
  85.  
  86. void
  87. DEFUN (outf, (chan, format, va_alist),
  88.        outf_channel chan AND
  89.        CONST char *format DOTS)
  90.      VA_DCL
  91. {
  92.     va_list ap;
  93.     VA_START(ap, format);
  94.     voutf(chan, format, ap);
  95. }
  96.  
  97. static FILE *
  98. DEFUN (outf_channel_to_FILE, (chan), outf_channel chan)
  99. {
  100.     if (chan==fatal_output)   return  stderr;
  101.     if (chan==error_output)   return  stderr;
  102.     if (chan==console_output) return  stdout;
  103.     return  (FILE*)chan;
  104. }
  105.  
  106. #ifdef __WIN32__
  107.  
  108. #define USE_WINDOWED_OUTPUT
  109. #define MAX_FATAL_BUF 1000
  110. static char fatal_buf[MAX_FATAL_BUF + 1] = {0};
  111.  
  112. #ifdef CL386
  113. #  define VSNPRINTF(buffer,length,format,args)                \
  114.      _vsnprintf ((buffer), (length), (format), (args))
  115. #else
  116. #  ifdef __WATCOMC__
  117. #    define VSNPRINTF(buffer,length,format,args)            \
  118.        vsprintf ((buffer), (format), (args))
  119. #  endif
  120. #endif
  121.  
  122. void
  123. DEFUN (voutf_fatal, (format, args), CONST char *format AND va_list args)
  124. {
  125.     int end = strlen(fatal_buf);
  126.     VSNPRINTF (&fatal_buf[end], MAX_FATAL_BUF - end, format, args);
  127. }
  128.  
  129. void
  130. DEFUN_VOID (popup_outf_flush_fatal)
  131. {
  132.     fprintf(stderr,"%s", fatal_buf); fflush(stderr);
  133.     MessageBox(0,fatal_buf,"MIT-Scheme terminating", MB_OK|MB_TASKMODAL);
  134.     fatal_buf[0] = 0;
  135. }
  136.  
  137. void
  138. DEFUN (voutf_master_tty, (chan, format, args),
  139.        outf_channel chan  AND  CONST char *format  AND  va_list args)
  140. {
  141.     extern HANDLE master_tty_window;
  142.     char buf[1000];
  143.  
  144.     if (master_tty_window) {
  145.       VSNPRINTF (buf, 1000, format, args);
  146.       Screen_WriteText (master_tty_window, buf);
  147.     } else {
  148.       vfprintf (outf_channel_to_FILE(chan), format, args);
  149.     }
  150. }
  151.  
  152. #else /* not __WIN32__ */
  153. #ifdef __OS2__
  154.  
  155. extern char * OS2_thread_fatal_error_buffer (void);
  156. extern void OS2_message_box (const char *, const char *, int);
  157.  
  158. #define USE_WINDOWED_OUTPUT
  159.  
  160. static void
  161. voutf_fatal (const char * format, va_list args)
  162. {
  163.   char * buffer = (OS2_thread_fatal_error_buffer ());
  164.   unsigned int end = (strlen (buffer));
  165.   vsprintf ((& (buffer [end])), format, args);
  166. }
  167.  
  168. static void
  169. popup_outf_flush_fatal (void)
  170. {
  171.   char * buffer = (OS2_thread_fatal_error_buffer ());
  172.   OS2_message_box ("Scheme Terminating", buffer, 1);
  173.   (buffer[0]) = '\0';
  174. }
  175.  
  176. static void
  177. voutf_master_tty (const outf_channel chan, const char * format, va_list args)
  178. {
  179.   extern void OS2_console_write (const char *, size_t);
  180.   char buffer [4096];
  181.   vsprintf (buffer, format, args);
  182.   OS2_console_write (buffer, (strlen (buffer)));
  183. }
  184.  
  185. #endif /* __OS2__ */
  186. #endif /* not __WIN32__ */
  187.  
  188. void
  189. DEFUN (voutf, (chan, format, ap),
  190.        CONST outf_channel chan AND
  191.        CONST char * format AND
  192.        va_list ap)
  193. {
  194. #ifdef USE_WINDOWED_OUTPUT
  195.  
  196.   if (chan == fatal_output)
  197.     voutf_fatal (format, ap);
  198.   else if ((chan == console_output) || (chan == error_output))
  199.     voutf_master_tty (chan, format, ap);
  200.   else
  201. #endif
  202.     vfprintf ((outf_channel_to_FILE (chan)), format, ap);
  203. }
  204.  
  205. void
  206. DEFUN (outf_flush, (chan), outf_channel chan)
  207. {
  208. #ifdef USE_WINDOWED_OUTPUT
  209.   if (chan == fatal_output)
  210.     popup_outf_flush_fatal ();
  211.   else
  212. #endif
  213.     fflush (outf_channel_to_FILE (chan));
  214. }
  215.