in src/native/windows/src/cmdline.c [39:246]
LPAPXCMDLINE apxCmdlineParse(
APXHANDLE hPool,
APXCMDLINEOPT *lpOptions,
LPCWSTR *lpszCommands,
LPCWSTR *lpszAltcmds)
{
LPAPXCMDLINE lpCmdline = NULL;
DWORD l, i, s = 1;
LPWSTR p;
DWORD match;
WCHAR mh[SIZ_HUGLEN];
if (_st_sys_argc < 1)
return NULL;
if (!(lpCmdline = (LPAPXCMDLINE)apxPoolCalloc(hPool, sizeof(APXCMDLINE))))
return NULL;
lpCmdline->hPool = hPool;
lpCmdline->lpOptions = lpOptions;
if (GetModuleFileNameW(GetModuleHandle(NULL), mh, SIZ_HUGLEN)) {
GetLongPathNameW(mh, mh, SIZ_HUGLEN);
lpCmdline->szExePath = apxPoolStrdupW(hPool, mh);
lpCmdline->szArgv0 = apxPoolStrdupW(hPool, mh);
if (lpCmdline->szExePath == NULL || lpCmdline->szArgv0 == NULL)
return NULL;
if ((p = wcsrchr(lpCmdline->szExePath, L'\\')))
*p++ = L'\0';
else
return NULL;
}
else
return NULL;
lpCmdline->szExecutable = p;
p = wcsrchr(lpCmdline->szExecutable, L'.');
if (p && lstrcmpiW(p, EXE_SUFFIX) == 0)
*p = L'\0';
if ((p = wcsrchr(lpCmdline->szExecutable, L'.'))) {
if (lstrcmpiW(p, X86_SUFFIX) == 0) {
*p = L'\0';
}
else if (lstrcmpiW(p, X64_SUFFIX) == 0) {
*p = L'\0';
}
}
if (_st_sys_argc > 1 && lstrlenW(_st_sys_argvw[1]) > 2) {
LPWSTR cp = _st_sys_argvw[1];
LPWSTR cn = _st_sys_argc > 2 ? _st_sys_argvw[2] : NULL;
LPWSTR ca = cp;
i = 0;
if (ca[0] == L'/' && ca[1] == L'/') {
ca += 2;
if ((cn = wcschr(ca, L'/'))) {
*cn++ = L'\0';
while (*cn == L'/')
cn++;
if (*cn == L'\0')
cn = NULL;
}
if (cn == NULL)
cn = lpCmdline->szExecutable;
while (lpszCommands[i]) {
if (lstrcmpW(lpszCommands[i++], ca) == 0) {
lpCmdline->dwCmdIndex = i;
break;
}
}
if (lpCmdline->dwCmdIndex) {
lpCmdline->szApplication = cn;
s = 2;
}
else {
apxLogWrite(APXLOG_MARK_ERROR "Unrecognized cmd option %S", cp);
return NULL;
}
}
else {
while (lpszAltcmds[i]) {
if (lstrcmpW(lpszAltcmds[i++], ca) == 0) {
lpCmdline->dwCmdIndex = i;
break;
}
}
if (lpCmdline->dwCmdIndex) {
s = 2;
if (cn && iswalnum(*cn)) {
s++;
lpCmdline->szApplication = cn;
}
else
lpCmdline->szApplication = lpCmdline->szExecutable;
}
else {
apxLogWrite(APXLOG_MARK_ERROR "Unrecognized cmd option %S", cp);
return NULL;
}
}
}
else {
lpCmdline->szApplication = lpCmdline->szExecutable;
lpCmdline->dwCmdIndex = 1;
return lpCmdline;
}
for (i = s; i < (DWORD)_st_sys_argc; i++) {
LPWSTR e = NULL;
LPWSTR a = _st_sys_argvw[i];
BOOL add = FALSE;
if (a[0] == L'+' && a[1] == L'+')
add = TRUE;
else if (a[0] != L'-' || a[1] != L'-')
break;
p = a + 2;
/* Find if the option has '=' char
* for --option==value or --option value cases.
*/
while (*p) {
if (*p == L'=') {
*p = L'\0';
e = p + 1;
break;
}
else
p++;
}
match = 0;
for (l = 0; lpOptions[l].szName; l++) {
if (lstrcmpW(lpOptions[l].szName, a + 2) == 0) {
LPWSTR val;
/* check if arg is needed */
if (e)
val = e;
else if ((i + 1) < (DWORD)_st_sys_argc)
val = _st_sys_argvw[++i];
else {
lpOptions[l].dwValue = 0;
lpOptions[l].szValue = NULL;
lpOptions[l].dwType |= APXCMDOPT_FOUND;
break;
}
if (add) {
if (!(lpOptions[l].dwType & APXCMDOPT_FOUND)) {
/* Only set add flag in case there was no --option
*/
lpOptions[l].dwType |= APXCMDOPT_ADD;
}
}
else if (lpOptions[l].dwType & APXCMDOPT_ADD) {
/* We have ++option --option ...
* Discard earlier values and go over.
*/
lpOptions[l].dwType &= ~APXCMDOPT_ADD;
lpOptions[l].dwValue = 0;
lpOptions[l].szValue = 0;
}
if (lpOptions[l].dwType & APXCMDOPT_STR)
lpOptions[l].szValue = val;
else if (lpOptions[l].dwType & APXCMDOPT_INT)
lpOptions[l].dwValue = (DWORD)apxAtoulW(val);
else if (lpOptions[l].dwType & APXCMDOPT_MSZ) {
LPWSTR pp;
BOOL insquote = FALSE, indquote=FALSE;
DWORD sp = 0;
LPWSTR ov = lpOptions[l].szValue;
if (lpOptions[l].dwValue > 2) {
sp = (lpOptions[l].dwValue - sizeof(WCHAR)) / sizeof(WCHAR);
}
lpOptions[l].dwValue = (sp + lstrlenW(val) + 2) * sizeof(WCHAR);
lpOptions[l].szValue = (LPWSTR)apxPoolCalloc(hPool,
lpOptions[l].dwValue);
if (sp) {
AplMoveMemory(lpOptions[l].szValue, ov, sp * sizeof(WCHAR));
apxFree(ov);
}
pp = val;
while(*pp) {
if (*pp == L'\'')
insquote = !insquote;
else if (*pp == L'"') {
indquote = !indquote;
lpOptions[l].szValue[sp++] = L'"';
}
else if ((*pp == L'#' || *pp == L';') && !insquote && !indquote)
lpOptions[l].szValue[sp++] = L'\0';
else
lpOptions[l].szValue[sp++] = *pp;
pp++;
}
}
lpOptions[l].dwType |= APXCMDOPT_FOUND;
match = l + 1;
break;
}
}
if (match == 0) {
/* --unknown option
*
*/
apxLogWrite(APXLOG_MARK_ERROR "Unrecognized program option %S",
_st_sys_argvw[i]);
return NULL;
}
}
if (i < (DWORD)_st_sys_argc) {
lpCmdline->dwArgc = _st_sys_argc - i;
lpCmdline->lpArgvw = &_st_sys_argvw[i];
}
return lpCmdline;
}