Make the zlib compile against the tinycrt library.
[git-build-vc9.git] / tcrt / src / main.c
blob6aace759f01c43e10ddad5e7e0e3e472d84c07d3
1 /*=============================================================================
2 main.c :
4 Copyright © 2008 Bruno Santos <nayart3@gmail.com>
5 =============================================================================*/
7 #include <stdlib.h>
8 #include <string.h>
9 #include <errno.h>
10 #include <signal.h>
11 #include <windows.h>
12 #include "init.h"
14 ///////////////////////////////////////////////////////////////////////////////
15 static unsigned int get_command_line(char** dst)
17 wchar_t* cmd = GetCommandLineW();
18 int len;
20 len = WideCharToMultiByte(CP_UTF8, 0, cmd, -1, NULL, 0, NULL, NULL);
21 *dst = malloc(len);
22 return WideCharToMultiByte(CP_UTF8, 0, cmd, -1, *dst, len, NULL, NULL);
25 static char** init_argv(int* argc)
27 unsigned int quote;
28 unsigned int bslash;
29 unsigned int argn;
30 unsigned int len;
31 unsigned int i;
32 char** argv;
33 char* cmd;
35 len = get_command_line(&cmd);
36 /**
37 * - 2n backslashes followed by a quotation mark produce n backslashes
38 * followed by a quotation mark.
39 * - (2n) + 1 backslashes followed by a quotation mark again produce n
40 * backslashes followed by a quotation mark.
41 * - n backslashes not followed by a quotation mark simply produce n
42 * backslashes.
44 bslash = 0;
45 quote = 0;
46 argn = 0;
47 for (i = 0; i < len; ++i) {
48 if (cmd[i] == '\\') {
49 bslash += 1;
50 continue;
52 } else if (cmd[i] == '\"') {
53 if (bslash > 1) {
54 bslash -= (bslash / 2);
55 memmove(&cmd[i - bslash], &cmd[i], len - i);
56 len -= bslash;
57 i -= bslash;
59 } else if (quote) {
60 cmd[quote - 1] = '\0';
61 cmd[i] = '\0';
62 quote = 0;
63 if (cmd[i - 1] != '\0') {
64 argn += 1;
67 } else {
68 quote = i + 1;
70 } else if (cmd[i] == ' ' && !quote) {
71 cmd[i] = '\0';
72 if (i && cmd[i - 1] != '\0')
73 argn += 1;
75 } else if (cmd[i] == '\0') {
76 if (i && cmd[i - 1] != '\0')
77 argn += 1;
79 bslash = 0;
82 argv = realloc(cmd, ((argn + 1) * sizeof(char*)) + i);
83 cmd = memmove(argv + argn, argv, len);
84 for (i = 0; i < argn; ++i) {
85 do {
86 len = strlen(cmd);
87 argv[i] = cmd;
88 cmd += len + 1;
89 } while (!len);
91 argv[i] = cmd - 1;
93 *argc = argn;
94 return argv;
97 static char** init_env()
99 return NULL;
102 ///////////////////////////////////////////////////////////////////////////////
103 void mainCRTStartup(void)
105 char **argv;
106 char **env;
107 int mainret;
108 int argc;
110 g_process_heap = GetProcessHeap();
111 run_ctors();
112 argv = init_argv(&argc);
113 env = init_env();
114 mainret = main(argc, argv, env);
115 free(argv);
116 free(env);
117 exit(mainret);
120 void abort(void)
122 if (g_tcrt_sigaction_slot[SIGABRT].sa_handler != SIG_DFL)
123 g_tcrt_sigaction_slot[SIGABRT].sa_handler(SIGABRT);
125 for(;;) {
126 TerminateProcess(GetCurrentProcess(), EXIT_FAILURE);
127 __debugbreak();
131 void exit(int status)
133 run_dtors();
134 ExitProcess(status);
137 #if _M_IX86
138 long _InterlockedCompareExchange(long volatile*, long, long);
139 #elif _M_X64
140 __int64 _InterlockedCompareExchange64(__int64 volatile*, __int64, __int64);
141 #endif
143 static atexit_entry* atomic_cmpxchg(atexit_entry** dst, atexit_entry* value, atexit_entry* cmp)
145 #if _M_IX86
146 return (atexit_entry*) _InterlockedCompareExchange((long volatile*) dst, (long) value, (long) cmp);
147 #elif _M_X64
148 return (atexit_entry*) _InterlockedCompareExchange((__int64 volatile*) dst, (__int64) value, (__int64) cmp);
149 #endif
152 int atexit(void (*function)(void))
154 atexit_entry* old;
155 atexit_entry* entry;
157 entry = (atexit_entry*) malloc(sizeof(atexit_entry));
158 if (entry == NULL) {
159 errno = ENOMEM;
160 return -1;
163 entry->fn = function;
164 do {
165 old = g_atexit_list;
166 entry->next = old;
167 } while (atomic_cmpxchg(&g_atexit_list, entry, old) != old);
169 return 0;
172 void _purecall(void)
174 __debugbreak();
175 abort();
178 // EOF ////////////////////////////////////////////////////////////////////////