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