src/main/windows/SDL_windows_main.c
author Philipp Wiesemann <philipp.wiesemann@arcor.de>
Sat, 06 Jul 2013 15:56:06 +0200
changeset 7356 d1a0bbe64f15
parent 7281 cd5516b9263d
child 7450 29654d59c439
permissions -rw-r--r--
Added missing call to SDL_stack_free().
     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 #include "SDL_config.h"
     7 
     8 #ifdef __WIN32__
     9 
    10 #include <stdio.h>
    11 #include <stdlib.h>
    12 
    13 #define WIN32_LEAN_AND_MEAN
    14 #include <windows.h>
    15 
    16 /* Include the SDL main definition header */
    17 #include "SDL.h"
    18 #include "SDL_main.h"
    19 
    20 #ifdef main
    21 #  undef main
    22 #endif /* main */
    23 
    24 static void
    25 UnEscapeQuotes(char *arg)
    26 {
    27     char *last = NULL;
    28 
    29     while (*arg) {
    30         if (*arg == '"' && (last != NULL && *last == '\\')) {
    31             char *c_curr = arg;
    32             char *c_last = last;
    33 
    34             while (*c_curr) {
    35                 *c_last = *c_curr;
    36                 c_last = c_curr;
    37                 c_curr++;
    38             }
    39             *c_last = '\0';
    40         }
    41         last = arg;
    42         arg++;
    43     }
    44 }
    45 
    46 /* Parse a command line buffer into arguments */
    47 static int
    48 ParseCommandLine(char *cmdline, char **argv)
    49 {
    50     char *bufp;
    51     char *lastp = NULL;
    52     int argc, last_argc;
    53 
    54     argc = last_argc = 0;
    55     for (bufp = cmdline; *bufp;) {
    56         /* Skip leading whitespace */
    57         while (isspace(*bufp)) {
    58             ++bufp;
    59         }
    60         /* Skip over argument */
    61         if (*bufp == '"') {
    62             ++bufp;
    63             if (*bufp) {
    64                 if (argv) {
    65                     argv[argc] = bufp;
    66                 }
    67                 ++argc;
    68             }
    69             /* Skip over word */
    70             lastp = bufp;
    71             while (*bufp && (*bufp != '"' || *lastp == '\\')) {
    72                 lastp = bufp;
    73                 ++bufp;
    74             }
    75         } else {
    76             if (*bufp) {
    77                 if (argv) {
    78                     argv[argc] = bufp;
    79                 }
    80                 ++argc;
    81             }
    82             /* Skip over word */
    83             while (*bufp && !isspace(*bufp)) {
    84                 ++bufp;
    85             }
    86         }
    87         if (*bufp) {
    88             if (argv) {
    89                 *bufp = '\0';
    90             }
    91             ++bufp;
    92         }
    93 
    94         /* Strip out \ from \" sequences */
    95         if (argv && last_argc != argc) {
    96             UnEscapeQuotes(argv[last_argc]);
    97         }
    98         last_argc = argc;
    99     }
   100     if (argv) {
   101         argv[argc] = NULL;
   102     }
   103     return (argc);
   104 }
   105 
   106 /* Show an error message */
   107 static void
   108 ShowError(const char *title, const char *message)
   109 {
   110 /* If USE_MESSAGEBOX is defined, you need to link with user32.lib */
   111 #ifdef USE_MESSAGEBOX
   112     MessageBox(NULL, message, title, MB_ICONEXCLAMATION | MB_OK);
   113 #else
   114     fprintf(stderr, "%s: %s\n", title, message);
   115 #endif
   116 }
   117 
   118 /* Pop up an out of memory message, returns to Windows */
   119 static BOOL
   120 OutOfMemory(void)
   121 {
   122     ShowError("Fatal Error", "Out of memory - aborting");
   123     return FALSE;
   124 }
   125 
   126 #if defined(_MSC_VER)
   127 /* The VC++ compiler needs main defined */
   128 #define console_main main
   129 #endif
   130 
   131 /* This is where execution begins [console apps] */
   132 int
   133 console_main(int argc, char *argv[])
   134 {
   135     int status;
   136 
   137     SDL_SetMainReady();
   138 
   139     /* Run the application main() code */
   140     status = SDL_main(argc, argv);
   141 
   142     /* Exit cleanly, calling atexit() functions */
   143     exit(status);
   144 
   145     /* Hush little compiler, don't you cry... */
   146     return 0;
   147 }
   148 
   149 /* This is where execution begins [windowed apps] */
   150 int WINAPI
   151 WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
   152 {
   153     char **argv;
   154     int argc;
   155     char *cmdline;
   156 
   157     /* Grab the command line */
   158     TCHAR *text = GetCommandLine();
   159 #if UNICODE
   160     cmdline = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char *)(text), (SDL_wcslen(text)+1)*sizeof(WCHAR));
   161 #else
   162     cmdline = SDL_strdup(text);
   163 #endif
   164     if (cmdline == NULL) {
   165         return OutOfMemory();
   166     }
   167 
   168     /* Parse it into argv and argc */
   169     argc = ParseCommandLine(cmdline, NULL);
   170     argv = SDL_stack_alloc(char *, argc + 1);
   171     if (argv == NULL) {
   172         return OutOfMemory();
   173     }
   174     ParseCommandLine(cmdline, argv);
   175 
   176     /* Run the main program */
   177     console_main(argc, argv);
   178 
   179     SDL_stack_free(argv);
   180 
   181     SDL_free(cmdline);
   182 
   183     /* Hush little compiler, don't you cry... */
   184     return 0;
   185 }
   186 
   187 #endif /* __WIN32__ */
   188 
   189 /* vi: set ts=4 sw=4 expandtab: */