On Sat, Nov 25, 2006 at 05:38:14AM +0000, Pedro Alves wrote:
> Could you post then a final version with a ChangeLog entry?

Patch attached.

I've tested this with haret on a ce5 pda.  I've also made a test
program that had just main() defined.  However, I haven't stressed the
command-line argument stuff.

As discussed, I've moved the command-line parsing code from init.c to
winmain_ce.c.  I've also removed the call to GetCommandLineW and
replaced it with the passed in command-line parameter.


2006-11-25  Kevin O'Connor  <[EMAIL PROTECTED]>

        * Makefile.in, crt1_ce.c, winmain_ce.c: Implement
          WinMainCRTStartup for CE programs in its own CE specific
          file.  Implement a dummy WinMain function in winmain_ce.c
          for those CE programs that define main() instead of
          WinMain().  Modify the Makefile so that these two new CE
          specific files are only built for mingw32ce.

        * crt1.c, init.c, main.c: These are no longer used on
          mingw32ce, so revert them back to their x86 mingw
          originals.

Index: src/mingw/Makefile.in
===================================================================
--- src/mingw/Makefile.in       (revision 823)
+++ src/mingw/Makefile.in       (working copy)
@@ -167,13 +167,13 @@
 endif
 
 MINGW_OBJS = CRTglob.o CRTfmode.o CRTinit.o dllmain.o gccmain.o \
-            main.o crtst.o mthr_stub.o \
+            crtst.o mthr_stub.o \
             pseudo-reloc.o pseudo-reloc-list.o cpu_features.o
 
 ifneq (,$(findstring wince,$(target_alias)))
-MINGW_OBJS += abort.o atexit.o assert.o
+MINGW_OBJS += winmain_ce.o abort.o atexit.o assert.o
 else
-MINGW_OBJS += CRT_fp10.o txtmode.o
+MINGW_OBJS += main.o CRT_fp10.o txtmode.o
 endif
 
 MOLD_OBJS = isascii.o iscsym.o iscsymf.o toascii.o \
@@ -498,8 +498,13 @@
 CRTfmode.o: CRTfmode.c
 CRTglob.o: CRTglob.c
 CRTinit.o: CRTinit.c
+ifneq (,$(findstring wince,$(target_alias)))
+crt1.o: crt1_ce.c
+crt2.o: crt1_ce.c
+else
 crt1.o: crt1.c init.c
 crt2.o: crt1.c init.c
+endif
 crtmt.o: crtmt.c
 crtst.o: crtst.c
 ctype_old.o: ctype_old.c
@@ -507,6 +512,7 @@
 dllcrt2.o: dllcrt1.c
 dllmain.o: dllmain.c
 main.o: main.c
+winmain_ce.o: winmain_ce.c
 oldnames.o: oldnames.c
 string_old.o: string_old.c
 CRT_fp8.o: CRT_fp8.c
Index: src/mingw/init.c
===================================================================
--- src/mingw/init.c    (revision 823)
+++ src/mingw/init.c    (working copy)
@@ -35,10 +35,8 @@
   int newmode;
 } _startupinfo;
 extern void __getmainargs (int *, char ***, char ***, int, _startupinfo *);
-#elif defined (__CRTDLL__)
+#else
 extern void __GetMainArgs (int *, char ***, char ***, int);
-#elif defined (__COREDLL__)
-static void __GetMainArgs (int *, char ***, char ***, int);
 #endif
 
 /*
@@ -58,127 +56,12 @@
   /*
    * Microsoft's runtime provides a function for doing just that.
    */
-#if defined (__MSVCRT__)
+#ifdef __MSVCRT__
   (void) __getmainargs (&_argc, &_argv, &dummy_environ, _CRT_glob, 
                         &start_info);
 #else
-  /* CRTDLL/COREDLL version */
+  /* CRTDLL version */
   (void) __GetMainArgs (&_argc, &_argv, &dummy_environ, _CRT_glob);
 #endif
 }
 
-#ifdef __COREDLL__
-
-static int
-_parse_tokens(char* string, char*** tokens, int length)
-{
-    /* Extract whitespace- and quotes- delimited tokens from the given string
-        and put them into the tokens array. Returns number of tokens
-        extracted. Length specifies the current size of tokens[].
-        THIS METHOD MODIFIES string.  */
-
-    const char* whitespace = " \t\r\n";
-    char* tokenEnd;
-    const char* quoteCharacters = "\"\'";
-       char* end = string + strlen (string);
-
-    if (string == NULL)
-        return length;
-
-    while (1)
-    {
-               const char* q;
-        /* Skip over initial whitespace.  */
-        string += strspn(string, whitespace);
-        if (*string == '\0')
-            break;
-
-        for (q = quoteCharacters; *q; ++q) 
-               {
-            if (*string == *q) 
-                break;
-               }
-        if (*q) 
-        {
-            /* Token is quoted.  */
-                       char quote = *string++;
-            tokenEnd = strchr(string, quote);
-            /* If there is no endquote, the token is the rest of the string.  
*/
-            if (!tokenEnd)
-                tokenEnd = end;
-        } 
-        else 
-        {
-            tokenEnd = string + strcspn(string, whitespace);
-        }
-
-               *tokenEnd = '\0';
-
-               {
-            char** new_tokens;
-            int newlen = length + 1;
-            new_tokens = realloc (*tokens, sizeof (char**) * newlen);
-            if (!new_tokens)
-            {
-                /* Out of memory.  */
-                return -1;
-            }
-
-            *tokens = new_tokens;
-                       (*tokens)[length] = string;
-            length = newlen;
-               }
-        if (tokenEnd == end) 
-            break;
-        string = tokenEnd + 1;
-    }
-exit:
-    return length;
-}
-
-static void
-__GetMainArgs (int *argc, char ***argv, char *** env, int glob)
-{
-    wchar_t  cmdnameBufW[512];
-    char     buf[MAX_PATH];
-    int      cmdlineLen = 0;
-    wchar_t* cmdlinePtrW;
-    int modlen;
-    char* __cmdlinebuf;
-
-    /* argv[0] is the path of invoked program - get this from CE.  */
-    cmdnameBufW[0] = 0;
-    modlen = GetModuleFileNameW(NULL, cmdnameBufW, sizeof (cmdnameBufW)/sizeof 
(cmdnameBufW[0]));
-    cmdlinePtrW = GetCommandLineW();
-
-    if (!cmdlinePtrW)
-        cmdlineLen = 0;
-    else
-        cmdlineLen = wcslen(cmdlinePtrW);
-
-    __cmdlinebuf = malloc (modlen + 1 + cmdlineLen + 1);
-    if (!__cmdlinebuf)
-        ExitProcess(-1);
-
-    *argv = malloc (sizeof (char**) * 1);
-    if (!*argv)
-        ExitProcess(-1);
-
-    (*argv)[0] = __cmdlinebuf;
-    wcstombs((*argv)[0], cmdnameBufW, wcslen(cmdnameBufW) + 1);
-    /* Add one to account for argv[0] */
-    (*argc)++;
-
-    if (cmdlineLen > 0) 
-    {
-        char* argv1 = (*argv)[0] + strlen((*argv)[0]) + 1;
-        wcstombs(argv1, cmdlinePtrW, cmdlineLen + 1);
-        *argc = _parse_tokens(argv1, argv, 1);
-               if (*argc < 0)
-                 ExitProcess(-1);
-    }
-    (*argv)[*argc] = 0;
-    return;
-}
-
-#endif
Index: src/mingw/crt1.c
===================================================================
--- src/mingw/crt1.c    (revision 823)
+++ src/mingw/crt1.c    (working copy)
@@ -14,17 +14,12 @@
 #define __IN_MINGW_RUNTIME 
 #include <stdlib.h>
 #include <stdio.h>
-#ifndef __COREDLL__
 #include <io.h>
-#endif
 #include <process.h>
 #include <float.h>
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
-
-#ifndef __COREDLL__
 #include <signal.h>
-#endif
 
 /* NOTE: The code for initializing the _argv, _argc, and environ variables
  *       has been moved to a separate .c file which is included in both
@@ -32,18 +27,10 @@
  *       be manually synchronized, but it does lead to this not-generally-
  *       a-good-idea use of include. */
 #include "init.c"
-#include "cpu_features.h"
 
 extern void _pei386_runtime_relocator (void);
 
-#ifndef UNDER_CE
 extern int main (int, char **, char **);
-#else
-/* No environ.  */
-extern int main (int, char **);
-/* No atexit on coredll, we must initialize our private version.  */
-BOOL __atexit_init(void);
-#endif
 
 /*
  * Must have the correct app type for MSVCRT. 
@@ -56,8 +43,6 @@
 __MINGW_IMPORT void __set_app_type(int);
 #endif /* __MSVCRT__ */
 
-#ifndef __COREDLL__
-
 /*  Global _fmode for this .exe, not the one in msvcrt.dll,
     The default is set in txtmode.o in libmingw32.a */
 /* Override the dllimport'd declarations in stdlib.h */
@@ -66,6 +51,7 @@
 #ifdef __MSVCRT__
 extern int* __p__fmode(void); /* To access the dll _fmode */
 #endif
+
 /*
  * Setup the default file handles to have the _CRT_fmode mode, as well as
  * any new files created by the user.
@@ -102,16 +88,13 @@
     }
 
     /*  Now sync  the dll _fmode to the  one for this .exe.  */
-#if defined (__MSVCRT__)
+#ifdef __MSVCRT__
     *__p__fmode() = _fmode;    
-#elif defined (__CRTDLL__)
-    *__IMP(_fmode_dll) = _fmode;
+#else
+    *_imp___fmode_dll = _fmode;
 #endif
 }
-#endif
 
-#ifndef UNDER_CE
-
 /* This function will be called when a trap occurs. Thanks to Jacob
    Navia for his contribution. */
 static CALLBACK long
@@ -193,17 +176,14 @@
   return action;
 }
 
-#endif
-
 /*
- * The function __mingw_CRTStartup is called from the entry point for all 
programs.
+ * The function mainCRTStartup is the entry point for all console programs.
  */
 static void  __attribute__((noreturn))
 __mingw_CRTStartup (void)
 {
   int nRet;
 
-#ifdef __i386__
   /*
    * Set up the top-level exception handler so that signal handling
    * works as expected. The mapping between ANSI/POSIX signals and
@@ -211,15 +191,10 @@
    * 
    */
   SetUnhandledExceptionFilter (_gnu_exception_handler);
-#elif defined (__arm__)
-  /* Windows CE on RISC architectures uses table based seh. 
-     We could install a top-level handler using the same technique as cegcc.  
*/
-#endif
 
   /*
    * Initialize floating point unit.
    */
-  __cpu_features_init ();      /* Do we have SSE, etc.*/
   _fpreset ();                 /* Supplied by the runtime library. */
 
   /*
@@ -227,7 +202,6 @@
    */
   _mingw32_init_mainargs ();
 
-#ifndef __COREDLL__
   /*
    * Sets the default file mode.
    * If _CRT_fmode is set, also set mode for stdin, stdout
@@ -235,36 +209,21 @@
    * NOTE: DLLs don't do this because that would be rude!
    */
   _mingw32_init_fmode ();
-#endif
   
    /* Adust references to dllimported data that have non-zero offsets.  */
   _pei386_runtime_relocator ();
 
-#ifdef __i386__
   /* Align the stack to 16 bytes for the sake of SSE ops in main
      or in functions inlined into main.  */
   asm  __volatile__  ("andl $-16, %%esp" : : : "%esp");
-#endif
 
-#ifdef __COREDLL__
   /*
-   * Initialize the atexit table.
-  */
-  __atexit_init();
-#endif
-
-  /*
    * Call the main function. If the user does not supply one
    * the one in the 'libmingw32.a' library will be linked in, and
    * that one calls WinMain. See main.c in the 'lib' dir
    * for more details.
    */
-#ifndef UNDER_CE
   nRet = main (_argc, _argv, environ);
-#else
-  /* Windows CE has no environ.  */
-  nRet = main (_argc, _argv);
-#endif
 
   /*
    * Perform exit processing for the C library. This means
@@ -275,7 +234,6 @@
   ExitProcess (nRet);
 }
 
-#ifndef UNDER_CE
 /*
  * The function mainCRTStartup is the entry point for all console programs.
  */
@@ -288,8 +246,6 @@
   __mingw_CRTStartup ();
 }
 
-#endif
-
 /*
  * For now the GUI startup function is the same as the console one.
  * This simply gets rid of the annoying warning about not being able
@@ -304,24 +260,20 @@
   __mingw_CRTStartup ();
 }
 
-#ifndef UNDER_CE
-
 /*
  *  We force use of library version of atexit, which is only
- *  visible in import lib as __IMP(atexit)
+ *  visible in import lib as _imp__atexit
  */
-extern int (*__IMP(atexit))(void (*)(void));
+extern int (*_imp__atexit)(void (*)(void));
 int atexit (void (* pfn )(void) )
 {
-   return ( (*__IMP(atexit))(pfn));
+  return ( (*_imp__atexit)(pfn));
 }
 
 /* Likewise for non-ANSI _onexit */
-extern _onexit_t (*__IMP(_onexit))(_onexit_t);
+extern _onexit_t (*_imp___onexit)(_onexit_t);
 _onexit_t
 _onexit (_onexit_t pfn )
 {
-   return (*__IMP(_onexit))(pfn);
+  return (*_imp___onexit)(pfn);
 }
-
-#endif
Index: src/mingw/main.c
===================================================================
--- src/mingw/main.c    (revision 823)
+++ src/mingw/main.c    (working copy)
@@ -16,30 +16,19 @@
 
 #define ISSPACE(a)     (a == ' ' || a == '\t')
 
-#ifndef UNDER_CE
 extern int PASCAL WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, 
                            LPSTR szCmdLine, int nShow);
-#else
-extern int __cdecl WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, 
-                           LPWSTR szCmdLine, int nShow);
 
-#endif
-
 int
 main (int argc, char *argv[], char *environ[])
 {
+  char *szCmd;
+  STARTUPINFO startinfo;
   int nRet;
 
   /* Get the command line passed to the process. */
-#ifndef UNDER_CE
-  char *szCmd;
-  STARTUPINFOA startinfo;
   szCmd = GetCommandLineA ();
   GetStartupInfoA (&startinfo);
-#else
-  wchar_t *szCmd;
-  szCmd = GetCommandLineW ();
-#endif
 
   /* Strip off the name of the application and any leading
    * whitespace. */
@@ -81,13 +70,9 @@
        }
     }
 
-#ifndef UNDER_CE
   nRet = WinMain (GetModuleHandle (NULL), NULL, szCmd,
                  (startinfo.dwFlags & STARTF_USESHOWWINDOW) ?
                  startinfo.wShowWindow : SW_SHOWDEFAULT);
-#else
-  nRet = WinMain (GetModuleHandle (NULL), NULL, szCmd, SW_SHOW);
-#endif
 
   return nRet;
 }
--- /dev/null   2006-09-16 10:05:04.613854500 -0400
+++ src/mingw/crt1_ce.c 2006-11-24 23:03:19.000000000 -0500
@@ -0,0 +1,71 @@
+/*
+ * crt1_ce.c
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is a part of the mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within the package.
+ *
+ * Source code for the startup proceedures used by all programs on a
+ * wince system. This code is compiled to make crt1.o, which should be
+ * located in the library path.
+ *
+ */
+
+/* Hide the declaration of _fmode with dllimport attribute in stdlib.h to
+   avoid problems with older GCC. */
+#define __IN_MINGW_RUNTIME 
+#include <stdlib.h>
+#include <stdio.h>
+#include <process.h>
+#include <float.h>
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+extern void __gccmain ();
+extern void _pei386_runtime_relocator (void);
+
+/* No atexit on coredll, we must initialize our private version.  */
+BOOL __atexit_init(void);
+
+/*
+ * This function is called from the entry point for all programs.
+ */
+void
+WinMainCRTStartup (HINSTANCE hInst, HINSTANCE hPrevInst,
+                   LPWSTR lpCmdLine, int nCmdShow)
+{
+  int nRet;
+
+  /*
+   * Initialize floating point unit.
+   */
+  _fpreset ();                 /* Supplied by the runtime library. */
+
+   /* Adust references to dllimported data that have non-zero offsets.  */
+  _pei386_runtime_relocator ();
+
+  /*
+   * Initialize the atexit table.
+   */
+  __atexit_init();
+
+  /* From libgcc.a, __main calls global class constructors,
+     __do_global_ctors, which registers __do_global_dtors as the first
+     entry of the private atexit table we have just initialised  */
+  __gccmain();
+
+  /*
+   * Call the main function. If the user does not supply one the one
+   * in the 'libmingw32.a' library will be linked in, and that one
+   * calls main. See winmain_ce.c in the 'lib' dir for more details.
+   */
+
+  nRet = WinMain(hInst, hPrevInst, lpCmdLine, nCmdShow);
+
+  /*
+   * Perform exit processing for the C library. This means
+   * flushing output and calling 'atexit' registered functions.
+   */
+  _cexit ();
+
+  ExitProcess (nRet);
+}
--- /dev/null   2006-09-16 10:05:04.613854500 -0400
+++ src/mingw/winmain_ce.c      2006-11-25 08:33:56.000000000 -0500
@@ -0,0 +1,147 @@
+/*
+ * winmain_ce.c
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is a part of the mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within the package.
+ *
+ * Extra startup code for applications which do not have a WinMain
+ * function of their own (but do have a main). Generally these are
+ * non-GUI applications, but they don't *have* to be.
+ *
+ */
+
+#include <stdlib.h>
+#include <process.h>
+#include <windows.h>
+
+/*
+ * Access to a standard 'main'-like argument count and list. Also included
+ * is a table of environment variables.
+ */
+int _argc = 0;
+char **_argv = 0;
+
+static int
+_parse_tokens(char* string, char*** tokens, int length)
+{
+    /* Extract whitespace- and quotes- delimited tokens from the given string
+       and put them into the tokens array. Returns number of tokens
+       extracted. Length specifies the current size of tokens[].
+       THIS METHOD MODIFIES string.  */
+
+    const char* whitespace = " \t\r\n";
+    char* tokenEnd;
+    const char* quoteCharacters = "\"\'";
+    char* end = string + strlen (string);
+
+    if (string == NULL)
+        return length;
+
+    while (1)
+    {
+        const char* q;
+        /* Skip over initial whitespace.  */
+        string += strspn(string, whitespace);
+        if (*string == '\0')
+            break;
+
+        for (q = quoteCharacters; *q; ++q)
+        {
+            if (*string == *q)
+                break;
+        }
+        if (*q)
+        {
+            /* Token is quoted.  */
+            char quote = *string++;
+            tokenEnd = strchr(string, quote);
+            /* If there is no endquote, the token is the rest of the string.  
*/
+            if (!tokenEnd)
+                tokenEnd = end;
+        }
+        else
+        {
+            tokenEnd = string + strcspn(string, whitespace);
+        }
+
+        *tokenEnd = '\0';
+
+        {
+            char** new_tokens;
+            int newlen = length + 1;
+            new_tokens = realloc (*tokens, sizeof (char**) * newlen);
+            if (!new_tokens)
+            {
+                /* Out of memory.  */
+                return -1;
+            }
+
+            *tokens = new_tokens;
+            (*tokens)[length] = string;
+            length = newlen;
+        }
+        if (tokenEnd == end)
+            break;
+        string = tokenEnd + 1;
+    }
+exit:
+    return length;
+}
+
+static void
+__mainArgs(int *argc, char ***argv, wchar_t *cmdlinePtrW)
+{
+    wchar_t  cmdnameBufW[512];
+    char     buf[MAX_PATH];
+    int      cmdlineLen = 0;
+    int modlen;
+    char* __cmdlinebuf;
+
+    /* argv[0] is the path of invoked program - get this from CE.  */
+    cmdnameBufW[0] = 0;
+    modlen = GetModuleFileNameW(NULL, cmdnameBufW, sizeof (cmdnameBufW)/sizeof 
(cmdnameBufW[0]));
+
+    if (!cmdlinePtrW)
+        cmdlineLen = 0;
+    else
+        cmdlineLen = wcslen(cmdlinePtrW);
+
+    __cmdlinebuf = malloc (modlen + 1 + cmdlineLen + 1);
+    if (!__cmdlinebuf)
+        ExitProcess(-1);
+
+    *argv = malloc (sizeof (char**) * 1);
+    if (!*argv)
+        ExitProcess(-1);
+
+    (*argv)[0] = __cmdlinebuf;
+    wcstombs((*argv)[0], cmdnameBufW, wcslen(cmdnameBufW) + 1);
+    /* Add one to account for argv[0] */
+    (*argc)++;
+
+    if (cmdlineLen > 0)
+    {
+        char* argv1 = (*argv)[0] + strlen((*argv)[0]) + 1;
+        wcstombs(argv1, cmdlinePtrW, cmdlineLen + 1);
+        *argc = _parse_tokens(argv1, argv, 1);
+        if (*argc < 0)
+            ExitProcess(-1);
+    }
+    (*argv)[*argc] = 0;
+    return;
+}
+
+// Normally, the application will define a WinMain function.  However,
+// if the main application does not, this dummy WinMain will call a
+// main() function instead.
+extern int __cdecl
+WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
+        LPWSTR szCmdLine, int nShow)
+{
+  /*
+   * Set up __argc, __argv.
+   */
+  __mainArgs(&_argc, &_argv, szCmdLine);
+
+  return main(_argc, _argv);
+}
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Cegcc-devel mailing list
Cegcc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/cegcc-devel

Reply via email to