ReactOS 0.4.16-dev-122-g325d74c
getargs.c
Go to the documentation of this file.
1#include <precomp.h>
2#include <stdlib.h>
3#include <string.h>
4
5
6extern char*_acmdln;
7extern wchar_t* _wcmdln;
8#undef _pgmptr
9extern char*_pgmptr;
10#undef _wpgmptr
11extern wchar_t*_wpgmptr;
12#undef _environ
13extern char**_environ;
14
15#undef __argv
16#undef __argc
17
18char**__argv = NULL;
19#undef __wargv
20wchar_t**__wargv = NULL;
21int __argc = 0;
22
23extern wchar_t **__winitenv;
24
25char* 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
36wchar_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
49int 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;
64 return 0;
65}
66
67int wexpand(wchar_t* name, int expand_wildcards)
68{
69 wchar_t* s;
73 wchar_t buffer[MAX_PATH];
75
76 if (expand_wildcards && (s = wcspbrk(name, L"*?")))
77 {
80 {
81 while(s != name && *s != L'/' && *s != L'\\')
82 s--;
83 pos = s - name;
84 if (*s == L'/' || *s == L'\\')
85 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 {
95 return -1;
96 }
97 first = FALSE;
98 }
99 }
100 while(FindNextFileW(hFile, &fd));
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
114int 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
132int aexpand(char* name, int expand_wildcards)
133{
134 char* s;
138 char buffer[MAX_PATH];
140
141 if (expand_wildcards && (s = strpbrk(name, "*?")))
142 {
145 {
146 while(s != name && *s != '/' && *s != '\\')
147 s--;
148 pos = s - name;
149 if (*s == '/' || *s == '\\')
150 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 {
160 return -1;
161 }
162 first = FALSE;
163 }
164 }
165 while(FindNextFileA(hFile, &fd));
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 */
182void __getmainargs(int* argc, char*** argv, char*** env, int expand_wildcards, int* new_mode)
183{
184 int i, doexpand, slashesAdded, escapedQuote, inQuotes, bufferIndex, anyLetter;
185 size_t len;
186 char* buffer;
187
188 /* missing threading init */
189
190 i = 0;
191 doexpand = expand_wildcards;
192 escapedQuote = FALSE;
193 anyLetter = FALSE;
194 slashesAdded = 0;
195 inQuotes = 0;
196 bufferIndex = 0;
197
198 if (__argv && _environ)
199 {
200 *argv = __argv;
201 *env = _environ;
202 *argc = __argc;
203 return;
204 }
205
206 __argc = 0;
207
208 len = strlen(_acmdln);
209 buffer = malloc(sizeof(char) * len);
210
211 // Reference: https://msdn.microsoft.com/en-us/library/a1y7w461.aspx
212 while (TRUE)
213 {
214 // Arguments are delimited by white space, which is either a space or a tab.
215 if (i >= len || ((_acmdln[i] == ' ' || _acmdln[i] == '\t') && !inQuotes))
216 {
217 // Handle the case when empty spaces are in the end of the cmdline
218 if (anyLetter)
219 {
220 aexpand(strndup(buffer, bufferIndex), doexpand);
221 }
222 // Copy the last element from buffer and quit the loop
223 if (i >= len)
224 {
225 break;
226 }
227
228 while (_acmdln[i] == ' ' || _acmdln[i] == '\t')
229 ++i;
230 anyLetter = FALSE;
231 bufferIndex = 0;
232 slashesAdded = 0;
233 escapedQuote = FALSE;
234 continue;
235 }
236
237 anyLetter = TRUE;
238
239 if (_acmdln[i] == '\\')
240 {
242 ++slashesAdded;
243 ++i;
244 escapedQuote = FALSE;
245 continue;
246 }
247
248 if (_acmdln[i] == '\"')
249 {
250 if (slashesAdded > 0)
251 {
252 if (slashesAdded % 2 == 0)
253 {
254 // If an even number of backslashes is followed by a double quotation mark, then one backslash (\‍)
255 // is placed in the argv array for every pair of backslashes (\\‍), and the double quotation mark (")
256 // is interpreted as a string delimiter.
257 bufferIndex -= slashesAdded / 2;
258 }
259 else
260 {
261 // If an odd number of backslashes is followed by a double quotation mark, then one backslash (\‍)
262 // is placed in the argv array for every pair of backslashes (\\‍) and the double quotation mark is
263 // interpreted as an escape sequence by the remaining backslash, causing a literal double quotation mark (")
264 // to be placed in argv.
265 bufferIndex -= slashesAdded / 2 + 1;
266 buffer[bufferIndex++] = '\"';
267 slashesAdded = 0;
268 escapedQuote = TRUE;
269 ++i;
270 continue;
271 }
272 slashesAdded = 0;
273 }
274 else if (!inQuotes && i > 0 && _acmdln[i - 1] == '\"' && !escapedQuote)
275 {
276 buffer[bufferIndex++] = '\"';
277 ++i;
278 escapedQuote = TRUE;
279 continue;
280 }
281 slashesAdded = 0;
282 escapedQuote = FALSE;
283 inQuotes = !inQuotes;
284 doexpand = inQuotes ? FALSE : expand_wildcards;
285 ++i;
286 continue;
287 }
288
290 slashesAdded = 0;
291 escapedQuote = FALSE;
292 ++i;
293 }
294
295 /* Free the temporary buffer. */
296 free(buffer);
297
298 *argc = __argc;
299 if (__argv == NULL)
300 {
301 __argv = (char**)malloc(sizeof(char*));
302 __argv[0] = 0;
303 }
304 *argv = __argv;
305 *env = _environ;
306
307 _pgmptr = malloc(MAX_PATH * sizeof(char));
308 if (_pgmptr)
309 {
311 _pgmptr[0] = '\0';
312 else
313 _pgmptr[MAX_PATH - 1] = '\0';
314 }
315 else
316 {
317 _pgmptr = _strdup(__argv[0]);
318 }
319
321
322 // if (new_mode) _set_new_mode(*new_mode);
323}
324
325/*
326 * @implemented
327 */
328void __wgetmainargs(int* argc, wchar_t*** wargv, wchar_t*** wenv,
329 int expand_wildcards, int* new_mode)
330{
331 int i, doexpand, slashesAdded, escapedQuote, inQuotes, bufferIndex, anyLetter;
332 size_t len;
333 wchar_t* buffer;
334
335 /* missing threading init */
336
337 i = 0;
338 doexpand = expand_wildcards;
339 escapedQuote = FALSE;
340 anyLetter = TRUE;
341 slashesAdded = 0;
342 inQuotes = 0;
343 bufferIndex = 0;
344
345 if (__wargv && __winitenv)
346 {
347 *wargv = __wargv;
348 *wenv = __winitenv;
349 *argc = __argc;
350 return;
351 }
352
353 __argc = 0;
354
355 len = wcslen(_wcmdln);
356 buffer = malloc(sizeof(wchar_t) * len);
357
358 // Reference: https://msdn.microsoft.com/en-us/library/a1y7w461.aspx
359 while (TRUE)
360 {
361 // Arguments are delimited by white space, which is either a space or a tab.
362 if (i >= len || ((_wcmdln[i] == ' ' || _wcmdln[i] == '\t') && !inQuotes))
363 {
364 // Handle the case when empty spaces are in the end of the cmdline
365 if (anyLetter)
366 {
367 wexpand(wcsndup(buffer, bufferIndex), doexpand);
368 }
369 // Copy the last element from buffer and quit the loop
370 if (i >= len)
371 {
372 break;
373 }
374
375 while (_wcmdln[i] == ' ' || _wcmdln[i] == '\t')
376 ++i;
377 anyLetter = FALSE;
378 bufferIndex = 0;
379 slashesAdded = 0;
380 escapedQuote = FALSE;
381 continue;
382 }
383
384 anyLetter = TRUE;
385
386 if (_wcmdln[i] == '\\')
387 {
389 ++slashesAdded;
390 ++i;
391 escapedQuote = FALSE;
392 continue;
393 }
394
395 if (_wcmdln[i] == '\"')
396 {
397 if (slashesAdded > 0)
398 {
399 if (slashesAdded % 2 == 0)
400 {
401 // If an even number of backslashes is followed by a double quotation mark, then one backslash (\‍)
402 // is placed in the argv array for every pair of backslashes (\\‍), and the double quotation mark (")
403 // is interpreted as a string delimiter.
404 bufferIndex -= slashesAdded / 2;
405 }
406 else
407 {
408 // If an odd number of backslashes is followed by a double quotation mark, then one backslash (\‍)
409 // is placed in the argv array for every pair of backslashes (\\‍) and the double quotation mark is
410 // interpreted as an escape sequence by the remaining backslash, causing a literal double quotation mark (")
411 // to be placed in argv.
412 bufferIndex -= slashesAdded / 2 + 1;
413 buffer[bufferIndex++] = '\"';
414 slashesAdded = 0;
415 escapedQuote = TRUE;
416 ++i;
417 continue;
418 }
419 slashesAdded = 0;
420 }
421 else if (!inQuotes && i > 0 && _wcmdln[i - 1] == '\"' && !escapedQuote)
422 {
423 buffer[bufferIndex++] = '\"';
424 ++i;
425 escapedQuote = TRUE;
426 continue;
427 }
428 slashesAdded = 0;
429 escapedQuote = FALSE;
430 inQuotes = !inQuotes;
431 doexpand = inQuotes ? FALSE : expand_wildcards;
432 ++i;
433 continue;
434 }
435
437 slashesAdded = 0;
438 escapedQuote = FALSE;
439 ++i;
440 }
441
442 /* Free the temporary buffer. */
443 free(buffer);
444
445 *argc = __argc;
446 if (__wargv == NULL)
447 {
448 __wargv = (wchar_t**)malloc(sizeof(wchar_t*));
449 __wargv[0] = 0;
450 }
451 *wargv = __wargv;
452 *wenv = __winitenv;
453
454 _wpgmptr = malloc(MAX_PATH * sizeof(wchar_t));
455 if (_wpgmptr)
456 {
458 _wpgmptr[0] = '\0';
459 else
460 _wpgmptr[MAX_PATH - 1] = '\0';
461 }
462 else
463 {
465 }
466
468
469 // if (new_mode) _set_new_mode(*new_mode);
470}
471
472/*
473 * @implemented
474 */
475int* __p___argc(void)
476{
477 return &__argc;
478}
479
480/*
481 * @implemented
482 */
483char*** __p___argv(void)
484{
485 return &__argv;
486}
487
488/*
489 * @implemented
490 */
491wchar_t*** __p___wargv(void)
492{
493 return &__wargv;
494}
495
496
unsigned char BOOLEAN
static int argc
Definition: ServiceArgs.c:12
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
char * strpbrk(const char *String, const char *Delimiters)
Definition: utclib.c:302
unsigned int uintptr_t
Definition: crtdefs.h:321
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:170
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define _strdup
Definition: debug_ros.c:7
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
HANDLE WINAPI FindFirstFileA(IN LPCSTR lpFileName, OUT LPWIN32_FIND_DATAA lpFindFileData)
Definition: find.c:263
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
BOOL WINAPI FindNextFileA(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAA lpFindFileData)
Definition: find.c:336
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:539
GLdouble s
Definition: gl.h:2039
GLuint buffer
Definition: glext.h:5915
const GLint * first
Definition: glext.h:5794
GLuint bufferIndex
Definition: glext.h:7857
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
BOOL WINAPI HeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem)
Definition: heapmem.c:156
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
wchar_t * _wpgmptr
Definition: environ.c:29
char * _acmdln
Definition: environ.c:18
int wexpand(wchar_t *name, int expand_wildcards)
Definition: getargs.c:67
wchar_t *** __p___wargv(void)
Definition: getargs.c:491
char ** __argv
Definition: getargs.c:18
int * __p___argc(void)
Definition: getargs.c:475
int aadd(char *name)
Definition: getargs.c:114
int aexpand(char *name, int expand_wildcards)
Definition: getargs.c:132
int __argc
Definition: getargs.c:21
wchar_t ** __winitenv
Definition: environ.c:25
wchar_t * _wcmdln
Definition: environ.c:19
void __wgetmainargs(int *argc, wchar_t ***wargv, wchar_t ***wenv, int expand_wildcards, int *new_mode)
Definition: getargs.c:328
char * strndup(char const *name, size_t len)
Definition: getargs.c:25
char * _pgmptr
Definition: environ.c:27
char *** __p___argv(void)
Definition: getargs.c:483
void __getmainargs(int *argc, char ***argv, char ***env, int expand_wildcards, int *new_mode)
Definition: getargs.c:182
wchar_t * wcsndup(wchar_t *name, size_t len)
Definition: getargs.c:36
char ** _environ
Definition: environ.c:22
int wadd(wchar_t *name)
Definition: getargs.c:49
wchar_t ** __wargv
Definition: getargs.c:20
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define argv
Definition: mplay32.c:18
_In_ HANDLE hFile
Definition: mswsock.h:90
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define L(x)
Definition: ntvdm.h:50
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcspbrk(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_Control)
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
_Check_return_ _CRTIMP wchar_t *__cdecl _wcsdup(_In_z_ const wchar_t *_Str)
static int fd
Definition: io.c:51
Definition: name.c:39