Unicode support for CRT startup
Jan Hlavatý <[email protected]> Mon, 12 May 2003 05:21:33 +0200
| Newsgroups | gmane.comp.gnu.mingw.patches |
|---|---|
| Organization | Bohemia Interactive Studio |
| Message-ID | <[email protected]> |
Hi, I've been playing tonight with Unicode support in mingw32. Found that there were no unicode startup objects, so I patched together these. To use Unicode entrypoints, in addition to defining UNICODE and _UNICODE you must set executable's entrypoint to _wWinMainCRTStartup (or _wmainCRTStartup) using -Wl,--entry=_wWinMainCRTStartup I'd like to see something like this integrated into runtime so we can build dual unicode/ansi builds as intended with tchar.h and company... diff1 - diff of changes against runtime 3.0 and w32api 2.3 diff2 - how to make wmain.c out of main.c Jan
diff1.txt
(text/plain, 5.9 KB)
diff -r -c mingworig/runtime/Makefile.in mingwr/runtime/Makefile.in
*** mingworig/runtime/Makefile.in Tue May 6 16:01:52 2003
--- mingwr/runtime/Makefile.in Mon May 12 02:24:46 2003
***************
*** 151,157 ****
CRT0S = crt1.o dllcrt1.o crt2.o dllcrt2.o CRT_noglob.o crtmt.o crtst.o \
CRT_fp8.o CRT_fp10.o txtmode.o binmode.o
MINGW_OBJS = CRTglob.o CRTfmode.o CRTinit.o dllmain.o gccmain.o \
! main.o crtst.o mthr_stub.o CRT_fp10.o txtmode.o \
pseudo-reloc.o pseudo-reloc-list.o
MOLD_OBJS = ctype_old.o string_old.o
--- 151,157 ----
CRT0S = crt1.o dllcrt1.o crt2.o dllcrt2.o CRT_noglob.o crtmt.o crtst.o \
CRT_fp8.o CRT_fp10.o txtmode.o binmode.o
MINGW_OBJS = CRTglob.o CRTfmode.o CRTinit.o dllmain.o gccmain.o \
! main.o wmain.o crtst.o mthr_stub.o CRT_fp10.o txtmode.o \
pseudo-reloc.o pseudo-reloc-list.o
MOLD_OBJS = ctype_old.o string_old.o
***************
*** 163,169 ****
SRCDIST_FILES = CRT_noglob.c CRTfmode.c CRTglob.c CRTinit.c ChangeLog \
Makefile.in README TODO config.guess config.sub configure configure.in \
crt1.c crtdll.def crtmt.c crtst.c ctype_old.c dllcrt1.c dllmain.c \
! gccmain.c init.c install-sh jamfile main.c mkinstalldirs \
moldname.def.in msvcrt.def.in \
mthr.c mthr_init.c mthr_stub.c readme.txt string_old.c \
CRT_fp8.c CRT_fp10.c test_headers.c txtmode.c binmode.c pseudo-reloc.c \
--- 163,169 ----
SRCDIST_FILES = CRT_noglob.c CRTfmode.c CRTglob.c CRTinit.c ChangeLog \
Makefile.in README TODO config.guess config.sub configure configure.in \
crt1.c crtdll.def crtmt.c crtst.c ctype_old.c dllcrt1.c dllmain.c \
! gccmain.c init.c install-sh jamfile main.c wmain.c mkinstalldirs \
moldname.def.in msvcrt.def.in \
mthr.c mthr_init.c mthr_stub.c readme.txt string_old.c \
CRT_fp8.c CRT_fp10.c test_headers.c txtmode.c binmode.c pseudo-reloc.c \
***************
*** 428,433 ****
--- 428,434 ----
dllcrt2.o: dllcrt1.c
dllmain.o: dllmain.c
main.o: main.c
+ wmain.o: wmain.c
oldnames.o: oldnames.c
string_old.o: string_old.c
CRT_fp8.o: CRT_fp8.c
diff -r -c mingworig/runtime/crt1.c mingwr/runtime/crt1.c
*** mingworig/runtime/crt1.c Mon Jan 6 21:14:18 2003
--- mingwr/runtime/crt1.c Mon May 12 02:31:40 2003
***************
*** 229,234 ****
--- 229,290 ----
return 0;
}
+
+ static int
+ __mingw_wCRTStartup ()
+ {
+ int nRet;
+
+ /*
+ * Set up the top-level exception handler so that signal handling
+ * works as expected. The mapping between ANSI/POSIX signals and
+ * Win32 SE is not 1-to-1, so caveat emptore.
+ *
+ */
+ SetUnhandledExceptionFilter (_gnu_exception_handler);
+
+ /*
+ * Initialize floating point unit.
+ */
+ _fpreset (); /* Supplied by the runtime library. */
+
+ /*
+ * Set up __argc, __argv and _environ.
+ */
+ _mingw32_init_wmainargs ();
+
+ /*
+ * Sets the default file mode.
+ * If _CRT_fmode is set, also set mode for stdin, stdout
+ * and stderr, as well
+ * NOTE: DLLs don't do this because that would be rude!
+ */
+ _mingw32_init_fmode ();
+
+
+ /* Adust references to dllimported data that have non-zero offsets. */
+ _pei386_runtime_relocator ();
+
+ /*
+ * 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.
+ */
+ nRet = wmain (_argc, _argv, environ);
+
+ /*
+ * Perform exit processing for the C library. This means
+ * flushing output and calling 'atexit' registered functions.
+ */
+ _cexit ();
+
+ ExitProcess (nRet);
+
+ return 0;
+ }
+
+
/*
* The function mainCRTStartup is the entry point for all console programs.
*/
***************
*** 242,247 ****
--- 298,313 ----
return 0;
}
+ int
+ wmainCRTStartup ()
+ {
+ #ifdef __MSVCRT__
+ __set_app_type (__CONSOLE_APP);
+ #endif
+ __mingw_wCRTStartup ();
+ return 0;
+ }
+
/*
* 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
***************
*** 256,261 ****
--- 322,340 ----
__mingw_CRTStartup ();
return 0;
}
+
+ int
+ wWinMainCRTStartup ()
+ {
+ #ifdef __MSVCRT__
+ __set_app_type (__GUI_APP);
+ #endif
+ __mingw_wCRTStartup ();
+ return 0;
+ }
+
+
+
/*
* We force use of library version of atexit, which is only
diff -r -c mingworig/runtime/include/tchar.h mingwr/runtime/include/tchar.h
*** mingworig/runtime/include/tchar.h Wed May 7 02:36:14 2003
--- mingwr/runtime/include/tchar.h Mon May 12 02:27:40 2003
***************
*** 70,76 ****
#define __TEXT(q) L##q
/* for porting from other Windows compilers */
! #if 0 /* no wide startup module */
#define _tmain wmain
#define _tWinMain wWinMain
#define _tenviron _wenviron
--- 70,76 ----
#define __TEXT(q) L##q
/* for porting from other Windows compilers */
! #if 1 /* no wide startup module */
#define _tmain wmain
#define _tWinMain wWinMain
#define _tenviron _wenviron
diff -r -c mingworig/runtime/init.c mingwr/runtime/init.c
*** mingworig/runtime/init.c Tue Jun 5 00:26:30 2001
--- mingwr/runtime/init.c Mon May 12 02:33:12 2003
***************
*** 82,84 ****
--- 82,106 ----
#endif
}
+ static void
+ _mingw32_init_wmainargs ()
+ {
+ /* The environ variable is provided directly in stdlib.h through
+ * a dll function call. */
+ char **dummy_environ;
+ #ifdef __MSVCRT__
+ _startupinfo start_info;
+ start_info.newmode = 0;
+ #endif
+
+ /*
+ * Microsoft's runtime provides a function for doing just that.
+ */
+ #ifdef __MSVCRT__
+ (void) __wgetmainargs (&_argc, &_argv, &dummy_environ, _CRT_glob,
+ &start_info);
+ #else
+ /* CRTDLL version */
+ (void) __GetMainArgs (&_argc, &_argv, &dummy_environ, _CRT_glob);
+ #endif
+ }
Only in mingwr/runtime: msvcrt.def
Only in mingwr/runtime: msvcrtd.def
Only in mingwr/runtime: wmain.c
diff2.txt
(text/plain, 2.6 KB)
*** main.c Tue Jun 5 00:26:30 2001 --- wmain.c Mon May 12 02:35:56 2003 *************** *** 1,30 **** /* ! * main.c ! * ! * Extra startup code for applications which do not have a main function ! * of their own (but do have a WinMain). Generally these are GUI ! * applications, but they don't *have* to be. ! * ! * This file is part of the Mingw32 package. ! * ! * Contributors: ! * Created by Colin Peters <[email protected]> ! * Maintained by Mumit Khan <[email protected]> ! * ! * THIS SOFTWARE IS NOT COPYRIGHTED ! * ! * This source code is offered for use in the public domain. You may ! * use, modify or distribute it freely. ! * ! * This code is distributed in the hope that it will be useful but ! * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY ! * DISCLAMED. This includes but is not limited to warrenties of ! * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! * ! * $Revision: 1.2 $ ! * $Author: earnie $ ! * $Date: 2001/06/05 00:26:30 $ * */ #include <stdlib.h> --- 1,7 ---- /* ! * wmain.c * + * clone of main.c with Unicode support */ #include <stdlib.h> *************** *** 33,51 **** #define ISSPACE(a) (a == ' ' || a == '\t') ! extern int PASCAL WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, ! LPSTR szCmdLine, int nShow); int ! main (int argc, char *argv[], char *environ[]) { ! char *szCmd; STARTUPINFO startinfo; int nRet; /* Get the command line passed to the process. */ ! szCmd = GetCommandLineA (); ! GetStartupInfoA (&startinfo); /* Strip off the name of the application and any leading * whitespace. */ --- 10,28 ---- #define ISSPACE(a) (a == ' ' || a == '\t') ! extern int PASCAL wWinMain (HINSTANCE hInst, HINSTANCE hPrevInst, ! LPWSTR szCmdLine, int nShow); int ! wmain (int argc, wchar_t *argv[], wchar_t *environ[]) { ! wchar_t *szCmd; STARTUPINFO startinfo; int nRet; /* Get the command line passed to the process. */ ! szCmd = GetCommandLineW (); ! GetStartupInfoW (&startinfo); /* Strip off the name of the application and any leading * whitespace. */ *************** *** 87,93 **** } } ! nRet = WinMain (GetModuleHandle (NULL), NULL, szCmd, (startinfo.dwFlags & STARTF_USESHOWWINDOW) ? startinfo.wShowWindow : SW_SHOWDEFAULT); --- 64,70 ---- } } ! nRet = wWinMain (GetModuleHandle (NULL), NULL, szCmd, (startinfo.dwFlags & STARTF_USESHOWWINDOW) ? startinfo.wShowWindow : SW_SHOWDEFAULT);