a80d815a0ff81fb28df8c2a477484e45580b695b
7 extern wchar_t* _wcmdln
;
11 extern wchar_t*_wpgmptr
;
13 extern char**_environ
;
20 wchar_t**__wargv
= NULL
;
23 extern wchar_t **__winitenv
;
25 char* strndup(char const* name
, size_t len
)
27 char *s
= malloc(len
+ 1);
36 wchar_t* wcsndup(wchar_t* name
, size_t len
)
38 wchar_t *s
= malloc((len
+ 1) * sizeof(wchar_t));
41 memcpy(s
, name
, len
*sizeof(wchar_t));
47 #define SIZE (4096 / sizeof(char*))
49 int wadd(wchar_t* name
)
52 if ((__argc
% SIZE
) == 0)
55 _new
= malloc(sizeof(wchar_t*) * (1 + SIZE
));
57 _new
= realloc(__wargv
, sizeof(wchar_t*) * (__argc
+ 1 + SIZE
));
62 __wargv
[__argc
++] = name
;
63 __wargv
[__argc
] = NULL
;
67 int wexpand(wchar_t* name
, int expand_wildcards
)
76 if (expand_wildcards
&& (s
= wcspbrk(name
, L
"*?")))
78 hFile
= FindFirstFileW(name
, &fd
);
79 if (hFile
!= INVALID_HANDLE_VALUE
)
81 while(s
!= name
&& *s
!= L
'/' && *s
!= L
'\\')
84 if (*s
== L
'/' || *s
== L
'\\')
86 wcsncpy(buffer
, name
, pos
);
89 if (!(fd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
91 wcscpy(&buffer
[pos
], fd
.cFileName
);
92 if (wadd(_wcsdup(buffer
)) < 0)
100 while(FindNextFileW(hFile
, &fd
));
117 if ((__argc
% SIZE
) == 0)
120 _new
= malloc(sizeof(char*) * (1 + SIZE
));
122 _new
= realloc(__argv
, sizeof(char*) * (__argc
+ 1 + SIZE
));
127 __argv
[__argc
++] = name
;
128 __argv
[__argc
] = NULL
;
132 int aexpand(char* name
, int expand_wildcards
)
137 BOOLEAN first
= TRUE
;
141 if (expand_wildcards
&& (s
= strpbrk(name
, "*?")))
143 hFile
= FindFirstFileA(name
, &fd
);
144 if (hFile
!= INVALID_HANDLE_VALUE
)
146 while(s
!= name
&& *s
!= '/' && *s
!= '\\')
149 if (*s
== '/' || *s
== '\\')
151 strncpy(buffer
, name
, pos
);
154 if (!(fd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
156 strcpy(&buffer
[pos
], fd
.cFileName
);
157 if (aadd(_strdup(buffer
)) < 0)
165 while(FindNextFileA(hFile
, &fd
));
182 void __getmainargs(int* argc
, char*** argv
, char*** env
, int expand_wildcards
, int* new_mode
)
184 int i
, doexpand
, slashesAdded
, escapedQuote
, inQuotes
, bufferIndex
;
188 /* missing threading init */
191 doexpand
= expand_wildcards
;
192 escapedQuote
= FALSE
;
197 if (__argv
&& _environ
)
207 len
= strlen(_acmdln
);
208 buffer
= malloc(sizeof(char) * len
);
210 // Reference: https://msdn.microsoft.com/en-us/library/a1y7w461(v=vs.71).aspx
213 // Arguments are delimited by white space, which is either a space or a tab.
214 if (i
>= len
|| ((_acmdln
[i
] == ' ' || _acmdln
[i
] == '\t') && !inQuotes
))
216 aexpand(strndup(buffer
, bufferIndex
), doexpand
);
217 // Copy the last element from buffer and quit the loop
223 while (_acmdln
[i
] == ' ' || _acmdln
[i
] == '\t')
227 escapedQuote
= FALSE
;
231 if (_acmdln
[i
] == '\\')
233 buffer
[bufferIndex
++] = _acmdln
[i
];
236 escapedQuote
= FALSE
;
240 if (_acmdln
[i
] == '\"')
242 if (slashesAdded
> 0)
244 if (slashesAdded
% 2 == 0)
246 // If an even number of backslashes is followed by a double quotation mark, then one backslash (\)
247 // is placed in the argv array for every pair of backslashes (\\), and the double quotation mark (")
248 // is interpreted as a string delimiter.
249 bufferIndex
-= slashesAdded
/ 2;
253 // If an odd number of backslashes is followed by a double quotation mark, then one backslash (\)
254 // is placed in the argv array for every pair of backslashes (\\) and the double quotation mark is
255 // interpreted as an escape sequence by the remaining backslash, causing a literal double quotation mark (")
256 // to be placed in argv.
257 bufferIndex
-= slashesAdded
/ 2 + 1;
258 buffer
[bufferIndex
++] = '\"';
266 else if (!inQuotes
&& i
> 0 && _acmdln
[i
- 1] == '\"' && !escapedQuote
)
268 buffer
[bufferIndex
++] = '\"';
274 escapedQuote
= FALSE
;
275 inQuotes
= !inQuotes
;
276 doexpand
= inQuotes
? FALSE
: expand_wildcards
;
281 buffer
[bufferIndex
++] = _acmdln
[i
];
283 escapedQuote
= FALSE
;
287 /* Free the temporary buffer. */
289 HeapValidate(GetProcessHeap(), 0, NULL
);
294 __argv
= (char**)malloc(sizeof(char*));
299 _pgmptr
= _strdup(__argv
[0]);
301 // if (new_mode) _set_new_mode(*new_mode);
307 void __wgetmainargs(int* argc
, wchar_t*** wargv
, wchar_t*** wenv
,
308 int expand_wildcards
, int* new_mode
)
310 int i
, doexpand
, slashesAdded
, escapedQuote
, inQuotes
, bufferIndex
;
314 /* missing threading init */
317 doexpand
= expand_wildcards
;
318 escapedQuote
= FALSE
;
323 if (__wargv
&& __winitenv
)
333 len
= wcslen(_wcmdln
);
334 buffer
= malloc(sizeof(wchar_t) * len
);
336 // Reference: https://msdn.microsoft.com/en-us/library/a1y7w461(v=vs.71).aspx
339 // Arguments are delimited by white space, which is either a space or a tab.
340 if (i
>= len
|| ((_wcmdln
[i
] == ' ' || _wcmdln
[i
] == '\t') && !inQuotes
))
342 wexpand(wcsndup(buffer
, bufferIndex
), doexpand
);
343 // Copy the last element from buffer and quit the loop
349 while (_wcmdln
[i
] == ' ' || _wcmdln
[i
] == '\t')
353 escapedQuote
= FALSE
;
357 if (_wcmdln
[i
] == '\\')
359 buffer
[bufferIndex
++] = _wcmdln
[i
];
362 escapedQuote
= FALSE
;
366 if (_wcmdln
[i
] == '\"')
368 if (slashesAdded
> 0)
370 if (slashesAdded
% 2 == 0)
372 // If an even number of backslashes is followed by a double quotation mark, then one backslash (\)
373 // is placed in the argv array for every pair of backslashes (\\), and the double quotation mark (")
374 // is interpreted as a string delimiter.
375 bufferIndex
-= slashesAdded
/ 2;
379 // If an odd number of backslashes is followed by a double quotation mark, then one backslash (\)
380 // is placed in the argv array for every pair of backslashes (\\) and the double quotation mark is
381 // interpreted as an escape sequence by the remaining backslash, causing a literal double quotation mark (")
382 // to be placed in argv.
383 bufferIndex
-= slashesAdded
/ 2 + 1;
384 buffer
[bufferIndex
++] = '\"';
392 else if (!inQuotes
&& i
> 0 && _wcmdln
[i
- 1] == '\"' && !escapedQuote
)
394 buffer
[bufferIndex
++] = '\"';
400 escapedQuote
= FALSE
;
401 inQuotes
= !inQuotes
;
402 doexpand
= inQuotes
? FALSE
: expand_wildcards
;
407 buffer
[bufferIndex
++] = _wcmdln
[i
];
409 escapedQuote
= FALSE
;
413 /* Free the temporary buffer. */
416 HeapValidate(GetProcessHeap(), 0, NULL
);
421 __wargv
= (wchar_t**)malloc(sizeof(wchar_t*));
426 _wpgmptr
= _wcsdup(__wargv
[0]);
428 // if (new_mode) _set_new_mode(*new_mode);
434 int* __p___argc(void)
442 char*** __p___argv(void)
450 wchar_t*** __p___wargv(void)