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