]> pd.if.org Git - pdclib/blob - platform/win32/crt0.c
f7f6a925243cc76ebb59e4b1fe0661abf4f1cd8d
[pdclib] / platform / win32 / crt0.c
1 #include <windows.h>\r
2 #include <string.h>\r
3 #include <stdlib.h>\r
4 #include <stdio.h>\r
5 #include <signal.h>\r
6 \r
7 static char ** argvToAnsi( wchar_t ** wargv, int argc )\r
8 {\r
9     char ** argv = malloc( sizeof( *argv ) * argc );\r
10     for ( int i = 0; i != argc; ++i ) {\r
11         int sz = WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_SEPCHARS,\r
12                                       wargv[i], -1, NULL, 0, NULL, NULL );\r
13         if(!(argv[i] = malloc(sz))) {\r
14             fputs("Error in C runtime initialization: "\r
15                   "unable to allocate buffer for argument", stderr);\r
16             abort();\r
17         }\r
18 \r
19         int rv = WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_SEPCHARS,\r
20                                       wargv[i], -1, argv[i], sz, NULL, NULL );\r
21 \r
22         if(rv != sz) {\r
23             fputs("Error in C runtime initialization: "\r
24                   "size mismatch during character set conversion", stderr);\r
25         }\r
26     }\r
27     return argv;\r
28 }\r
29 \r
30 static int        argc;\r
31 static wchar_t *  cl;\r
32 static wchar_t ** wargv;\r
33 static char    ** argv;\r
34 \r
35 static void freeArgs( void )\r
36 {\r
37     for(int i = 0; i != argc; i++) {\r
38         free( argv[i] );\r
39     }\r
40     free( argv );\r
41     LocalFree( wargv );\r
42 }\r
43 \r
44 extern void (*_PDCLIB_sigfpe)( int );\r
45 extern void (*_PDCLIB_sigill)( int );\r
46 extern void (*_PDCLIB_sigsegv)( int );\r
47 \r
48 static LPTOP_LEVEL_EXCEPTION_FILTER oldFilter;\r
49 static LONG CALLBACK sehExceptionFilter( EXCEPTION_POINTERS * exInfo )\r
50 {\r
51     int sig;\r
52     void (*handler)( int );\r
53 \r
54     switch( exInfo->ExceptionRecord->ExceptionCode ) {\r
55         case EXCEPTION_ACCESS_VIOLATION:\r
56         case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:\r
57         case EXCEPTION_DATATYPE_MISALIGNMENT:\r
58         case EXCEPTION_GUARD_PAGE:\r
59         case EXCEPTION_IN_PAGE_ERROR:\r
60         case EXCEPTION_STACK_OVERFLOW:\r
61             sig = SIGSEGV;\r
62             handler = _PDCLIB_sigsegv;\r
63             break;\r
64 \r
65         case EXCEPTION_ILLEGAL_INSTRUCTION:\r
66         case EXCEPTION_PRIV_INSTRUCTION:\r
67             sig = SIGILL;\r
68             handler = _PDCLIB_sigill;\r
69             break;\r
70 \r
71         case EXCEPTION_INT_DIVIDE_BY_ZERO:\r
72         case EXCEPTION_INT_OVERFLOW:\r
73         case EXCEPTION_FLT_DENORMAL_OPERAND:\r
74         case EXCEPTION_FLT_DIVIDE_BY_ZERO:\r
75         case EXCEPTION_FLT_INEXACT_RESULT:\r
76         case EXCEPTION_FLT_INVALID_OPERATION:\r
77         case EXCEPTION_FLT_OVERFLOW:\r
78         case EXCEPTION_FLT_STACK_CHECK:\r
79         case EXCEPTION_FLT_UNDERFLOW:\r
80             sig = SIGFPE;\r
81             handler = _PDCLIB_sigfpe;\r
82             break;\r
83 \r
84         default:\r
85             return oldFilter ? oldFilter( exInfo ) : EXCEPTION_EXECUTE_HANDLER;\r
86     }\r
87 \r
88     if(handler == SIG_DFL) {\r
89         return EXCEPTION_EXECUTE_HANDLER;\r
90     } else if(handler == SIG_IGN) {\r
91         return EXCEPTION_CONTINUE_EXECUTION;\r
92     } else {\r
93         handler( sig );\r
94         return EXCEPTION_CONTINUE_EXECUTION;\r
95     }\r
96 }\r
97 \r
98 extern int main( int argc, char ** argv, char ** envp );\r
99 _PDCLIB_noreturn void mainCRTStartup( void ) \r
100 {\r
101     stdin->handle  = GetStdHandle(STD_INPUT_HANDLE);\r
102     stdout->handle = GetStdHandle(STD_OUTPUT_HANDLE);\r
103     stderr->handle = GetStdHandle(STD_ERROR_HANDLE);\r
104 \r
105     oldFilter = SetUnhandledExceptionFilter( sehExceptionFilter );\r
106 \r
107     cl    = GetCommandLineW();\r
108     wargv = CommandLineToArgvW(cl, &argc);\r
109     argv  = argvToAnsi(wargv, argc);\r
110     atexit(freeArgs);\r
111 \r
112     int exitStatus = main(argc, argv, NULL);\r
113 \r
114     exit(exitStatus);\r
115 }\r