Back to index

plt-scheme  4.2.1
msgprint.c
Go to the documentation of this file.
00001 
00002 #ifdef _WIN32
00003 __declspec(dllexport) void gc_fprintf(int ignored, const char *c, ...);
00004 # define GCPRINT gc_fprintf
00005 # define GCOUTF 0
00006 # define GCFLUSHOUT() /* empty */
00007 # define GCPRINT_TO_WINDOWS_CONSOLE
00008 #endif
00009 
00010 #ifndef GCPRINT
00011 # define GCPRINT fprintf
00012 # define GCOUTF stderr
00013 # define GCFLUSHOUT() fflush(NULL)
00014 #endif
00015 
00016 /**************** Windows stderr ****************/
00017 
00018 #ifdef GCPRINT_TO_WINDOWS_CONSOLE
00019 
00020 static BOOL WINAPI IgnoreEverything(DWORD evt)
00021 {
00022   return TRUE;
00023 }
00024 
00025 static void GC_prim_stringout(char *s, int len)
00026 {
00027   static HANDLE console;
00028   DWORD wrote;
00029 
00030   if (!console) {
00031     COORD size;
00032     CONSOLE_SCREEN_BUFFER_INFO info;
00033 
00034     console = GetStdHandle(STD_ERROR_HANDLE);
00035     if (!GetConsoleScreenBufferInfo(console, &info)) {
00036       /* Since getting the screen buffer info failed, 
00037         we must be in GUI mode. Create a console
00038         window --- and set the handler so that closing
00039         the window doesn't abort MrEd! */
00040       AllocConsole();
00041       console = GetStdHandle(STD_ERROR_HANDLE);
00042       GetConsoleScreenBufferInfo(console, &info);
00043       size = info.dwSize;
00044       if (size.Y < 500) {
00045        size.Y = 500;
00046        SetConsoleScreenBufferSize(console, size);
00047       }
00048       SetConsoleCtrlHandler(IgnoreEverything, TRUE);
00049     }
00050   }
00051 
00052   while (len) {
00053     if (WriteFile(console, s, len, &wrote, NULL)) {
00054       len -= wrote;
00055       s += wrote;
00056       if (len)
00057        Sleep(10);
00058     } else {
00059       /* Give up */
00060       break;
00061     }
00062   }
00063 }
00064 
00065 #include <stdarg.h>
00066 #include <ctype.h>
00067 
00068 #define NP_BUFSIZE 512
00069 
00070 /* Non-allocating printf. */
00071 void gc_fprintf(int ignored, const char *c, ...)
00072 {
00073   char buffer[NP_BUFSIZE];
00074   int pos;
00075   va_list args;
00076 
00077   va_start(args, c);
00078 
00079   pos = 0;
00080   while (*c) {
00081     if (*c == '%') {
00082       int len = -1, slen;
00083       int islong = 0;
00084       char *s;
00085 
00086       if (pos) {
00087        GC_prim_stringout(buffer, pos);
00088        pos = 0;
00089       }
00090 
00091       c++;
00092       if (isdigit(*c)) {
00093        len = 0;
00094        while (isdigit(*c)) {
00095          len = (len * 10) + (*c - '0');
00096          c++;
00097        }
00098       }
00099 
00100       if (*c == 'l') {
00101        islong = 1;
00102        c++;
00103       }
00104       while (isdigit(*c)) {
00105        c++;
00106       }
00107       if (*c == '.') {
00108        c++;
00109       }
00110       while (isdigit(*c)) {
00111        c++;
00112       }
00113       
00114       switch (*c) {
00115       case 'd':
00116       case 'x':
00117       case 'i':
00118       case 'p':
00119        {
00120          long v;
00121          int d, i;
00122 
00123          if (islong) {
00124            v = va_arg(args, long);
00125          } else {
00126            v = va_arg(args, int);
00127          }
00128          
00129          if (!v) {
00130            s = "0";
00131            slen = 1;
00132          } else {
00133            int neg = 0;
00134 
00135            i = NP_BUFSIZE - 2;
00136            
00137            if (v < 0) {
00138              neg = 1;
00139              v = -v;
00140            }
00141 
00142            d = (((*c) == 'd') ? 10 : 16);
00143            while (v) {
00144              int digit = (v % d);
00145              if (digit < 10)
00146               digit += '0';
00147              else
00148               digit += 'a' - 10;
00149              buffer[i--] = digit;
00150              v = v / d;
00151            }
00152            if (neg)
00153              buffer[i--] = '-';
00154 
00155            s = buffer + i + 1;
00156            slen = (NP_BUFSIZE - 2) - i;
00157          }
00158        }
00159        break;
00160       case 's':
00161        s = va_arg(args, char*);
00162        slen = strlen(s);
00163        break;
00164       case 'c':
00165        {
00166          int v;
00167          v = va_arg(args, int);
00168          s = buffer;
00169          buffer[0] = (char)v;
00170          slen = 1;
00171        }
00172        break;
00173       default:
00174        s = "???";
00175        slen = 3;
00176        break;
00177       }
00178 
00179       c++;
00180 
00181       if (len != -1) {
00182        if (slen > len)
00183          slen = len;
00184        else {
00185          int i;
00186          for (i = slen; i < len; i++)
00187            GC_prim_stringout(" ", 1);
00188        }
00189       }
00190       
00191       if (slen)
00192        GC_prim_stringout(s, slen);
00193     } else {
00194       if (pos == (NP_BUFSIZE - 1)) {
00195        GC_prim_stringout(buffer, pos);
00196        pos = 0;
00197       }
00198       buffer[pos++] = *(c++);
00199     }
00200   }
00201 
00202   if (pos)
00203     GC_prim_stringout(buffer, pos);
00204 
00205   /* Suggest a flush: */
00206   GC_prim_stringout(NULL, 0);
00207 
00208   va_end(args);
00209 }
00210 
00211 #endif