[SDK] One step further towards ReactOS source code tree restructure: the sdk folder...
[reactos.git] / reactos / sdk / lib / crt / misc / getargs.c
1 #include <precomp.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5
6 extern char*_acmdln;
7 extern wchar_t* _wcmdln;
8 #undef _pgmptr
9 extern char*_pgmptr;
10 #undef _wpgmptr
11 extern wchar_t*_wpgmptr;
12 #undef _environ
13 extern char**_environ;
14
15 #undef __argv
16 #undef __argc
17
18 char**__argv = NULL;
19 #undef __wargv
20 wchar_t**__wargv = NULL;
21 int __argc = 0;
22
23 extern wchar_t **__winitenv;
24
25 char* strndup(char const* name, size_t len)
26 {
27 char *s = malloc(len + 1);
28 if (s != NULL)
29 {
30 memcpy(s, name, len);
31 s[len] = 0;
32 }
33 return s;
34 }
35
36 wchar_t* wcsndup(wchar_t* name, size_t len)
37 {
38 wchar_t *s = malloc((len + 1) * sizeof(wchar_t));
39 if (s != NULL)
40 {
41 memcpy(s, name, len*sizeof(wchar_t));
42 s[len] = 0;
43 }
44 return s;
45 }
46
47 #define SIZE (4096 / sizeof(char*))
48
49 int wadd(wchar_t* name)
50 {
51 wchar_t** _new;
52 if ((__argc % SIZE) == 0)
53 {
54 if (__wargv == NULL)
55 _new = malloc(sizeof(wchar_t*) * (1 + SIZE));
56 else
57 _new = realloc(__wargv, sizeof(wchar_t*) * (__argc + 1 + SIZE));
58 if (_new == NULL)
59 return -1;
60 __wargv = _new;
61 }
62 __wargv[__argc++] = name;
63 __wargv[__argc] = NULL;
64 return 0;
65 }
66
67 int wexpand(wchar_t* name, int expand_wildcards)
68 {
69 wchar_t* s;
70 WIN32_FIND_DATAW fd;
71 HANDLE hFile;
72 BOOLEAN first = TRUE;
73 wchar_t buffer[256];
74 uintptr_t pos;
75
76 if (expand_wildcards && (s = wcspbrk(name, L"*?")))
77 {
78 hFile = FindFirstFileW(name, &fd);
79 if (hFile != INVALID_HANDLE_VALUE)
80 {
81 while(s != name && *s != L'/' && *s != L'\\')
82 s--;
83 pos = s - name;
84 if (*s == L'/' || *s == L'\\')
85 pos++;
86 wcsncpy(buffer, name, pos);
87 do
88 {
89 if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
90 {
91 wcscpy(&buffer[pos], fd.cFileName);
92 if (wadd(_wcsdup(buffer)) < 0)
93 {
94 FindClose(hFile);
95 return -1;
96 }
97 first = FALSE;
98 }
99 }
100 while(FindNextFileW(hFile, &fd));
101 FindClose(hFile);
102 }
103 }
104 if (first)
105 {
106 if (wadd(name) < 0)
107 return -1;
108 }
109 else
110 free(name);
111 return 0;
112 }
113
114 int aadd(char* name)
115 {
116 char** _new;
117 if ((__argc % SIZE) == 0)
118 {
119 if (__argv == NULL)
120 _new = malloc(sizeof(char*) * (1 + SIZE));
121 else
122 _new = realloc(__argv, sizeof(char*) * (__argc + 1 + SIZE));
123 if (_new == NULL)
124 return -1;
125 __argv = _new;
126 }
127 __argv[__argc++] = name;
128 __argv[__argc] = NULL;
129 return 0;
130 }
131
132 int aexpand(char* name, int expand_wildcards)
133 {
134 char* s;
135 WIN32_FIND_DATAA fd;
136 HANDLE hFile;
137 BOOLEAN first = TRUE;
138 char buffer[256];
139 uintptr_t pos;
140
141 if (expand_wildcards && (s = strpbrk(name, "*?")))
142 {
143 hFile = FindFirstFileA(name, &fd);
144 if (hFile != INVALID_HANDLE_VALUE)
145 {
146 while(s != name && *s != '/' && *s != '\\')
147 s--;
148 pos = s - name;
149 if (*s == '/' || *s == '\\')
150 pos++;
151 strncpy(buffer, name, pos);
152 do
153 {
154 if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
155 {
156 strcpy(&buffer[pos], fd.cFileName);
157 if (aadd(_strdup(buffer)) < 0)
158 {
159 FindClose(hFile);
160 return -1;
161 }
162 first = FALSE;
163 }
164 }
165 while(FindNextFileA(hFile, &fd));
166 FindClose(hFile);
167 }
168 }
169 if (first)
170 {
171 if (aadd(name) < 0)
172 return -1;
173 }
174 else
175 free(name);
176 return 0;
177 }
178
179 /*
180 * @implemented
181 */
182 void __getmainargs(int* argc, char*** argv, char*** env, int expand_wildcards, int* new_mode)
183 {
184 int i, afterlastspace, ignorespace, doexpand;
185 size_t len;
186 char* aNewCmdln;
187
188 /* missing threading init */
189
190 i = 0;
191 afterlastspace = 0;
192 ignorespace = 0;
193 doexpand = expand_wildcards;
194
195 if (__argv && _environ)
196 {
197 *argv = __argv;
198 *env = _environ;
199 *argc = __argc;
200 return;
201 }
202
203 __argc = 0;
204
205 len = strlen(_acmdln);
206
207 /* Allocate a temporary buffer to be used instead of the original _acmdln parameter. */
208 aNewCmdln = strndup(_acmdln, len);
209
210 while (aNewCmdln[i])
211 {
212 if (aNewCmdln[i] == '"')
213 {
214 if(ignorespace)
215 {
216 ignorespace = 0;
217 }
218 else
219 {
220 ignorespace = 1;
221 doexpand = 0;
222 }
223 memmove(aNewCmdln + i, aNewCmdln + i + 1, len - i);
224 len--;
225 continue;
226 }
227
228 if (aNewCmdln[i] == ' ' && !ignorespace)
229 {
230 aexpand(strndup(aNewCmdln + afterlastspace, i - afterlastspace), doexpand);
231 i++;
232 while (aNewCmdln[i] == ' ')
233 i++;
234 afterlastspace=i;
235 doexpand = expand_wildcards;
236 }
237 else
238 {
239 i++;
240 }
241 }
242
243 if (aNewCmdln[afterlastspace] != 0)
244 {
245 aexpand(strndup(aNewCmdln + afterlastspace, i - afterlastspace), doexpand);
246 }
247
248 /* Free the temporary buffer. */
249 free(aNewCmdln);
250
251 HeapValidate(GetProcessHeap(), 0, NULL);
252
253 *argc = __argc;
254 if (__argv == NULL)
255 {
256 __argv = (char**)malloc(sizeof(char*));
257 __argv[0] = 0;
258 }
259 *argv = __argv;
260 *env = _environ;
261 _pgmptr = _strdup(__argv[0]);
262
263 // if (new_mode) _set_new_mode(*new_mode);
264 }
265
266 /*
267 * @implemented
268 */
269 void __wgetmainargs(int* argc, wchar_t*** wargv, wchar_t*** wenv,
270 int expand_wildcards, int* new_mode)
271 {
272 int i, afterlastspace, ignorespace, doexpand;
273 size_t len;
274 wchar_t* wNewCmdln;
275
276 /* missing threading init */
277
278 i = 0;
279 afterlastspace = 0;
280 ignorespace = 0;
281 doexpand = expand_wildcards;
282
283 if (__wargv && __winitenv)
284 {
285 *wargv = __wargv;
286 *wenv = __winitenv;
287 *argc = __argc;
288 return;
289 }
290
291 __argc = 0;
292
293 len = wcslen(_wcmdln);
294
295 /* Allocate a temporary buffer to be used instead of the original _wcmdln parameter. */
296 wNewCmdln = wcsndup(_wcmdln, len);
297
298 while (wNewCmdln[i])
299 {
300 if (wNewCmdln[i] == L'"')
301 {
302 if(ignorespace)
303 {
304 ignorespace = 0;
305 }
306 else
307 {
308 ignorespace = 1;
309 doexpand = 0;
310 }
311 memmove(wNewCmdln + i, wNewCmdln + i + 1, (len - i) * sizeof(wchar_t));
312 len--;
313 continue;
314 }
315
316 if (wNewCmdln[i] == L' ' && !ignorespace)
317 {
318 wexpand(wcsndup(wNewCmdln + afterlastspace, i - afterlastspace), doexpand);
319 i++;
320 while (wNewCmdln[i] == L' ')
321 i++;
322 afterlastspace=i;
323 doexpand = expand_wildcards;
324 }
325 else
326 {
327 i++;
328 }
329 }
330
331 if (wNewCmdln[afterlastspace] != 0)
332 {
333 wexpand(wcsndup(wNewCmdln + afterlastspace, i - afterlastspace), doexpand);
334 }
335
336 /* Free the temporary buffer. */
337 free(wNewCmdln);
338
339 HeapValidate(GetProcessHeap(), 0, NULL);
340
341 *argc = __argc;
342 if (__wargv == NULL)
343 {
344 __wargv = (wchar_t**)malloc(sizeof(wchar_t*));
345 __wargv[0] = 0;
346 }
347 *wargv = __wargv;
348 *wenv = __winitenv;
349 _wpgmptr = _wcsdup(__wargv[0]);
350
351 // if (new_mode) _set_new_mode(*new_mode);
352 }
353
354 /*
355 * @implemented
356 */
357 int* __p___argc(void)
358 {
359 return &__argc;
360 }
361
362 /*
363 * @implemented
364 */
365 char*** __p___argv(void)
366 {
367 return &__argv;
368 }
369
370 /*
371 * @implemented
372 */
373 wchar_t*** __p___wargv(void)
374 {
375 return &__wargv;
376 }
377
378