1 module runtime.entrypoint;
2 
3 import libd.datastructures.array;
4 
5 __gshared Array!bcstring g_programArgs;
6 
7 template _d_cmain()
8 {
9     import runtime.entrypoint : g_programArgs, _d_preInit, _d_parseArgs;
10     import runtime.system : _d_init_system;
11 
12     extern(C)
13     {
14         int _Dmain(char[][] args);
15 
16         int mainImpl(int argc, char **argv, char** envp)
17         {
18             import runtime.primitives.tls, libd.memory;
19 
20             version(Posix)
21             {
22                 import runtime.system.posix.auxvector;
23                 _d_loadAuxVector(envp);
24             }
25 
26             _d_preInit();
27             _d_memoryInit();
28             _d_init_system();
29             _d_parseArgs();
30             const exit = _Dmain(null);
31 
32             version(Windows)
33             {
34                 import runtime.system.windows;
35                 ExitProcess(exit); // Some winapi functions sneakily spawn extra threads.
36                                    // This causes the app to sometimes hang.
37                                    // ExitProcess cleans things up properly, so we're not left hanging.
38             }
39 
40             assert(false);
41         }
42 
43         version(Windows)
44         {
45             version(LDC)
46             {
47                 int wmain(int argc, char **argv)
48                 {
49                     return mainImpl(argc, argv, null);
50                 }
51             }
52             else
53             {
54                 int main(int argc, char **argv)
55                 {
56                     return mainImpl(argc, argv, null);
57                 }
58             }
59         }
60         else version(Posix)
61         {
62             int main(int argc, char** argv, char** envp)
63             {
64                 return mainImpl(argc, argv, envp);
65             }
66         }
67     }
68 }
69 
70 void _d_preInit()
71 {
72     import libd.util.cpuid, runtime.dynamicfuncs, libd.console.io;
73     cpuidInit();
74     _d_dynamicFuncsInit();
75     _d_console_io_init();
76 }
77 
78 void _d_parseArgs()
79 {
80     import runtime.system.windows, runtime.dynamicfuncs;
81 
82     version(Windows)
83     {
84         auto commandLinePtr = GetCommandLineA();
85         auto commandLineSlice = commandLinePtr[0..strlen(commandLinePtr)];
86         
87         size_t start = 0;
88         bool quoteMode = false;
89         for(size_t i = 0; i < commandLineSlice.length; i++)
90         {
91             const ch = commandLineSlice[i];
92             
93             if(!quoteMode && i > start && (ch == ' ' || ch == '\t' || ch == '\n'))
94             {
95                 g_programArgs.put(commandLineSlice[start..i]);
96                 start = i + 1;
97             }
98             else if(ch == '"')
99             {
100                 if(!quoteMode)
101                 {
102                     quoteMode = true;
103                     start = i+1;
104                 }
105                 else
106                 {
107                     quoteMode = false;
108                     g_programArgs.put(commandLineSlice[start..i]);
109                     start = i + 2;
110                 }
111             }
112         }
113     }
114 }