156 lines
3.6 KiB
C++
156 lines
3.6 KiB
C++
/***
|
|
Copyright (C) 2022-2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: AuCmdLinePlatform.cpp
|
|
Date: 2022-2-6
|
|
Author: Reece
|
|
***/
|
|
#include <Source/RuntimeInternal.hpp>
|
|
#include "AuCmdLine.hpp"
|
|
#include "AuCmdLinePlatform.hpp"
|
|
|
|
#if defined(AURORA_PLATFORM_WIN32)
|
|
#include <shellapi.h>
|
|
#endif
|
|
|
|
#if defined(AURORA_IS_XNU_DERIVED)
|
|
#include <crt_externs.h>
|
|
#endif
|
|
|
|
namespace Aurora::CmdLine
|
|
{
|
|
static AuList<AuString> gEntrypointString;
|
|
|
|
AUKN_SYM void InitCommandLineArguments(int argc, const char **argv)
|
|
{
|
|
gEntrypointString.clear();
|
|
|
|
for (int i = 0; i < argc; i++)
|
|
{
|
|
gEntrypointString.push_back(argv[i]);
|
|
}
|
|
}
|
|
|
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
|
static AuList<AuString> GetProcFSCmdString()
|
|
{
|
|
AuList<AuString> args;
|
|
AuString ret;
|
|
|
|
AuIOFS::ReadString("/proc/self/cmdline", ret);
|
|
|
|
AuUInt idx {};
|
|
for (int i = 0; i < ret.size(); i++)
|
|
{
|
|
if (ret[i] == 0)
|
|
{
|
|
if (i - idx)
|
|
{
|
|
args.push_back(AuString(ret.begin() + idx, ret.begin() + i));
|
|
}
|
|
idx = i + 1;
|
|
}
|
|
}
|
|
|
|
AuString last(ret.begin() + idx, ret.end());
|
|
while (last.size() && !last[last.size() - 1])
|
|
{
|
|
last.pop_back();
|
|
}
|
|
|
|
if (last.size())
|
|
{
|
|
args.push_back(last);
|
|
}
|
|
|
|
return args;
|
|
}
|
|
#endif
|
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
static AuList<AuString> GetCmdStringWin32()
|
|
{
|
|
AuList<AuString> ret;
|
|
|
|
#if defined(AURORA_PLATFORM_WIN32)
|
|
|
|
auto cmd = GetCommandLineW();
|
|
SysAssert(cmd);
|
|
|
|
if (!pCommandLineToArgvW)
|
|
{
|
|
return {};
|
|
}
|
|
|
|
int count {};
|
|
auto pTemp = pCommandLineToArgvW(cmd, &count);
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
ret.push_back(Locale::ConvertFromWChar(pTemp[i]));
|
|
}
|
|
|
|
LocalFree(pTemp);
|
|
|
|
#elif defined(__argc) || defined(_CRT_DECLARE_GLOBAL_VARIABLES_DIRECTLY)
|
|
|
|
InitCommandLineArguments(__argc, __argv);
|
|
return gEntrypointString;
|
|
|
|
#else
|
|
|
|
// https://github.com/wine-mirror/wine/blob/7ec5f555b05152dda53b149d5994152115e2c623/dlls/shell32/shell32_main.c#L58
|
|
// https://github.com/dotnet/runtime/blob/2755362aed8412f47a3ca6cc419a9a85f55b0314/src/coreclr/src/utilcode/util.cpp#L2795
|
|
// Yea, so, im not going to implement that. It isn't worth the energy
|
|
|
|
// TODO:
|
|
//
|
|
// pass one -> split when str[i - 1] != '\\' && str[i] == ' '
|
|
// sub pass -> if string begins and ends with quotes, cull -> substr(1, end - 2]
|
|
//
|
|
// pass two -> iterate over all entries -> if contains evil char, AuReplaceAll(..., '\\' + char, char)
|
|
//
|
|
// copy to gEntrypointString
|
|
//
|
|
//
|
|
// it'll be legal enough for UWP apps
|
|
|
|
#endif
|
|
|
|
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
#if defined(AURORA_IS_XNU_DERIVED)
|
|
static void XNUSetEntrypointString()
|
|
{
|
|
InitCommandLineArguments(_NSGetArgc(), _NSGetArgv());
|
|
}
|
|
#endif
|
|
|
|
AuList<AuString> GetCmdString()
|
|
{
|
|
AuList<AuString> ret;
|
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
ret = GetCmdStringWin32();
|
|
#endif
|
|
#if defined(AURORA_IS_POSIX_DERIVED)
|
|
ret = GetProcFSCmdString();
|
|
#endif
|
|
if (ret.size())
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
if (gEntrypointString.empty())
|
|
{
|
|
#if defined(AURORA_IS_XNU_DERIVED)
|
|
XNUSetEntrypointString();
|
|
#endif
|
|
}
|
|
|
|
return gEntrypointString;
|
|
}
|
|
} |