src/main/win32/SDL_main.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. ParseCommandLine
  2. ShowError
  3. OutOfMemory
  4. cleanup_output
  5. console_main
  6. WinMain

   1 /*
   2     SDL_main.c, placed in the public domain by Sam Lantinga  4/13/98
   3 
   4     The WinMain function -- calls your program's main() function 
   5 */
   6 
   7 #include <stdio.h>
   8 #include <string.h>
   9 #include <ctype.h>
  10 #include <stdlib.h>
  11 
  12 #include <windows.h>
  13 #include <malloc.h>             /* For _alloca() */
  14 
  15 /* Include the SDL main definition header */
  16 #include "SDL.h"
  17 #include "SDL_main.h"
  18 #ifdef main
  19 #undef main
  20 #endif
  21 
  22 /* The standard output files */
  23 #define STDOUT_FILE     "stdout.txt"
  24 #define STDERR_FILE     "stderr.txt"
  25 
  26 /* Parse a command line buffer into arguments */
  27 static int ParseCommandLine(char *cmdline, char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
  28 {
  29         char *bufp;
  30         int argc;
  31 
  32         argc = 0;
  33         for ( bufp = cmdline; *bufp; ) {
  34                 /* Skip leading whitespace */
  35                 while ( isspace(*bufp) ) {
  36                         ++bufp;
  37                 }
  38                 /* Skip over argument */
  39                 if ( *bufp == '"' ) {
  40                         ++bufp;
  41                         if ( *bufp ) {
  42                                 if ( argv ) {
  43                                         argv[argc] = bufp;
  44                                 }
  45                                 ++argc;
  46                         }
  47                         /* Skip over word */
  48                         while ( *bufp && (*bufp != '"') ) {
  49                                 ++bufp;
  50                         }
  51                 } else {
  52                         if ( *bufp ) {
  53                                 if ( argv ) {
  54                                         argv[argc] = bufp;
  55                                 }
  56                                 ++argc;
  57                         }
  58                         /* Skip over word */
  59                         while ( *bufp && ! isspace(*bufp) ) {
  60                                 ++bufp;
  61                         }
  62                 }
  63                 if ( *bufp ) {
  64                         if ( argv ) {
  65                                 *bufp = '\0';
  66                         }
  67                         ++bufp;
  68                 }
  69         }
  70         if ( argv ) {
  71                 argv[argc] = NULL;
  72         }
  73         return(argc);
  74 }
  75 
  76 /* Show an error message */
  77 static void ShowError(const char *title, const char *message)
     /* [<][>][^][v][top][bottom][index][help] */
  78 {
  79 /* If USE_MESSAGEBOX is defined, you need to link with user32.lib */
  80 #ifdef USE_MESSAGEBOX
  81         MessageBox(NULL, message, title, MB_ICONEXCLAMATION|MB_OK);
  82 #else
  83         fprintf(stderr, "%s: %s\n", title, message);
  84 #endif
  85 }
  86 
  87 /* Pop up an out of memory message, returns to Windows */
  88 static BOOL OutOfMemory(void)
     /* [<][>][^][v][top][bottom][index][help] */
  89 {
  90         ShowError("Fatal Error", "Out of memory - aborting");
  91         return FALSE;
  92 }
  93 
  94 /* Remove the output files if there was no output written */
  95 static void cleanup_output(void)
     /* [<][>][^][v][top][bottom][index][help] */
  96 {
  97         FILE *file;
  98         int empty;
  99 
 100         /* Flush the output in case anything is queued */
 101         fclose(stdout);
 102         fclose(stderr);
 103 
 104         /* See if the files have any output in them */
 105         file = fopen(STDOUT_FILE, "rb");
 106         if ( file ) {
 107                 empty = (fgetc(file) == EOF) ? 1 : 0;
 108                 fclose(file);
 109                 if ( empty ) {
 110                         remove(STDOUT_FILE);
 111                 }
 112         }
 113         file = fopen(STDERR_FILE, "rb");
 114         if ( file ) {
 115                 empty = (fgetc(file) == EOF) ? 1 : 0;
 116                 fclose(file);
 117                 if ( empty ) {
 118                         remove(STDERR_FILE);
 119                 }
 120         }
 121 }
 122 
 123 #ifdef _MSC_VER /* The VC++ compiler needs main defined */
 124 #define console_main main
 125 #endif
 126 
 127 /* This is where execution begins [console apps] */
 128 int console_main(int argc, char *argv[])
     /* [<][>][^][v][top][bottom][index][help] */
 129 {
 130         int n;
 131         char *bufp, *appname;
 132 
 133         /* Get the class name from argv[0] */
 134         appname = argv[0];
 135         if ( (bufp=strrchr(argv[0], '\\')) != NULL ) {
 136                 appname = bufp+1;
 137         } else
 138         if ( (bufp=strrchr(argv[0], '/')) != NULL ) {
 139                 appname = bufp+1;
 140         }
 141 
 142         if ( (bufp=strrchr(appname, '.')) == NULL )
 143                 n = strlen(appname);
 144         else
 145                 n = (bufp-appname);
 146 
 147         bufp = (char *)alloca(n+1);
 148         if ( bufp == NULL ) {
 149                 return OutOfMemory();
 150         }
 151         strncpy(bufp, appname, n);
 152         bufp[n] = '\0';
 153         appname = bufp;
 154 
 155         /* Load SDL dynamic link library */
 156         if ( SDL_Init(SDL_INIT_NOPARACHUTE) < 0 ) {
 157                 ShowError("WinMain() error", SDL_GetError());
 158                 return(FALSE);
 159         }
 160         atexit(cleanup_output);
 161         atexit(SDL_Quit);
 162 
 163         /* Create and register our class, then run main code */
 164         if ( SDL_RegisterApp(appname, CS_BYTEALIGNCLIENT, 
 165                              GetModuleHandle(NULL)) < 0 ) {
 166                 ShowError("WinMain() error", SDL_GetError());
 167                 exit(1);
 168         }
 169         SDL_main(argc, argv);
 170 
 171         /* Exit cleanly, calling atexit() functions */
 172         exit(0);
 173 }
 174 
 175 /* This is where execution begins [windowed apps] */
 176 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
     /* [<][>][^][v][top][bottom][index][help] */
 177 {
 178         HINSTANCE handle;
 179         char **argv;
 180         int argc;
 181         char *cmdline;
 182         char *bufp;
 183 #ifndef NO_STDIO_REDIRECT
 184         FILE *newfp;
 185 #endif
 186 
 187         /* Start up DDHELP.EXE before opening any files, so DDHELP doesn't
 188            keep them open.  This is a hack.. hopefully it will be fixed 
 189            someday.  DDHELP.EXE starts up the first time DDRAW.DLL is loaded.
 190          */
 191         handle = LoadLibrary("DDRAW.DLL");
 192         if ( handle != NULL ) {
 193                 FreeLibrary(handle);
 194         }
 195 
 196 #ifndef NO_STDIO_REDIRECT
 197         /* Redirect standard input and standard output */
 198         newfp = freopen(STDOUT_FILE, "w", stdout);
 199         if ( newfp == NULL ) {  /* This happens on NT */
 200 #if !defined(stdout)
 201                 stdout = fopen(STDOUT_FILE, "w");
 202 #else
 203                 newfp = fopen(STDOUT_FILE, "w");
 204                 if ( newfp ) {
 205                         *stdout = *newfp;
 206                 }
 207 #endif
 208         }
 209         newfp = freopen(STDERR_FILE, "w", stderr);
 210         if ( newfp == NULL ) {  /* This happens on NT */
 211 #if !defined(stderr)
 212                 stderr = fopen(STDERR_FILE, "w");
 213 #else
 214                 newfp = fopen(STDERR_FILE, "w");
 215                 if ( newfp ) {
 216                         *stderr = *newfp;
 217                 }
 218 #endif
 219         }
 220         setvbuf(stdout, NULL, _IOLBF, BUFSIZ);  /* Line buffered */
 221         setbuf(stderr, NULL);                   /* No buffering */
 222 #endif /* !NO_STDIO_REDIRECT */
 223 
 224         /* Grab the command line (use alloca() on Windows) */
 225         bufp = GetCommandLine();
 226         cmdline = (char *)alloca(strlen(bufp)+1);
 227         if ( cmdline == NULL ) {
 228                 return OutOfMemory();
 229         }
 230         strcpy(cmdline, bufp);
 231 
 232         /* Parse it into argv and argc */
 233         argc = ParseCommandLine(cmdline, NULL);
 234         argv = (char **)alloca((argc+1)*(sizeof *argv));
 235         if ( argv == NULL ) {
 236                 return OutOfMemory();
 237         }
 238         ParseCommandLine(cmdline, argv);
 239 
 240         /* Run the main program (after a little SDL initialization) */
 241         return(console_main(argc, argv));
 242 }

/* [<][>][^][v][top][bottom][index][help] */