AuroraRuntime/Source/CmdLine/AuCmdLinePlatform.cpp
2023-09-17 21:33:14 +01:00

149 lines
3.5 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[0]);
}
}
#if defined(AURORA_IS_POSIX_DERIVED)
static AuList<AuString> GetProcFSCmdString()
{
AuList<AuString> args;
AuByteBuffer ret;
AuIOFS::ReadFile("/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;
auto cmd = GetCommandLineW();
SysAssert(cmd);
#if defined(AURORA_PLATFORM_WIN32)
if (!pCommandLineToArgvW)
{
return {};
}
int count {};
auto temp = pCommandLineToArgvW(cmd, &count);
for (int i = 0; i < count; i++)
{
ret.push_back(Locale::ConvertFromWChar(temp[i]));
}
#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;
}
}