AuroraRuntime/Source/CmdLine/AuCmdLine.cpp
Jamie Reece Wilson 83f34b0c47 [*] I was right. String views are [mostly] pointless (*)
03:28:55:638  17>2 of 53388 functions (<0.1%) were compiled, the rest were copied from previous compilation.
03:28:55:638  17>  0 functions were new in current compilation
03:28:55:638  17>  65 functions had inline decision re-evaluated but remain unchanged
03:28:56:749  17>Finished generating code

the header of const AuString & is the same as std::string_view therefore nothing changes. in fact, we still need to alloc strings a bunch of times for a zero terminated string. worse, <c++20 always allocs each time we want to access a hashmap with o(1) lookup, making small hashmaps kinda pointless when we always have to alloc+copy (thx std)

perhaps this will help some language binders
2024-04-19 05:58:08 +01:00

193 lines
5.1 KiB
C++

/***
Copyright (C) 2022-2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: AuCmdLine.cpp
Date: 2022-1-31
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "AuCmdLine.hpp"
#include "AuCmdLinePlatform.hpp"
namespace Aurora::CmdLine
{
static const AuString kEmptyString;
static AuList<AuString> gCmdFlags;
static AuList<AuString> gCmdValues;
static AuHashMap<AuString, AuString> gCmdValueMap;
static AuHashMap<AuString, AuList<AuString>> gCmdValueArrayMap;
static AuHashMap<AuString, bool> gCmdFlagLookup;
static AuList<AuString> gCmdLineString;
AUKN_SYM const AuList<AuString> &GetCommandLineArguments()
{
return gCmdLineString;
}
AUKN_SYM bool HasFlag(const AuROString &key)
{
return AuExists(gCmdFlagLookup, key);
}
AUKN_SYM bool HasValue(const AuROString &key)
{
return AuExists(gCmdValueArrayMap, key) ||
AuExists(gCmdValueMap, key);
}
AUKN_SYM const AuString &GetValue(const AuROString &key, const AuString &defaultValue)
{
auto itr = gCmdValueMap.find(key);
if (itr == gCmdValueMap.end())
{
return defaultValue;
}
else
{
return itr->second;
}
}
AUKN_SYM AuOptional<const AuString &> GetValue(const AuROString &key)
{
auto itr = gCmdValueMap.find(key);
if (itr == gCmdValueMap.end())
{
return AuOptional<const AuString &> {};
}
return itr->second;
}
AUKN_SYM const AuList<AuString> &GetValues(const AuROString &key)
{
static AuList<AuString> kMissing;
AuString temp(key);
auto itr = gCmdValueArrayMap.find(temp);
if (itr != gCmdValueArrayMap.end())
{
return itr->second;
}
return kMissing;
}
AUKN_SYM const AuList<AuString> &GetFlags()
{
return gCmdFlags;
}
AUKN_SYM const AuList<AuString> &GetValues()
{
return gCmdValues;
}
static void ProcessArgs()
{
AuString extendedLine;
AuString key;
//for (const auto &arg : gCmdLineString)
for (int i = 0; i < gCmdLineString.size(); i++)
{
const auto &arg = gCmdLineString[i];
#if defined(AURORA_PLATFORM_WIN32)
if (arg[arg.size() - 1] == '\\' && (arg.size() > 1))
{
extendedLine += arg.substr(0, arg.size() - 1);
if (arg[arg.size() - 2] != '\\')
{
extendedLine += ' ';
continue;
}
}
else
#endif
{
extendedLine += arg;
}
auto doesStartWithSwitch = [](auto &in)
{
return (in[0] == '/') ||
(in.find("--") == 0);
};
auto containsAssign = [](auto &in)
{
return (in.find("=") != AuString::npos);
};
auto valueAssignment = extendedLine.find('=');
if (valueAssignment == extendedLine.npos)
{
if (doesStartWithSwitch(extendedLine))
{
if (i != gCmdLineString.size() - 1)
{
const auto &next = gCmdLineString[i + 1];
if (!doesStartWithSwitch(next) && !containsAssign(next))
{
extendedLine += '=';
continue;
}
}
extendedLine = extendedLine.substr(1 + (extendedLine[0] != '/'));
}
gCmdFlags.push_back(extendedLine);
gCmdFlagLookup[extendedLine] = true;
}
else
{
key = extendedLine.substr(0, valueAssignment);
extendedLine = extendedLine.substr(valueAssignment + 1);
if (doesStartWithSwitch(key))
{
key = key.substr(1 + (key[0] != '/'));
}
gCmdValues.push_back(key);
{
auto itr = gCmdValueMap.find(key);
if (itr != gCmdValueMap.end())
{
auto val = (*itr).second;
gCmdValueMap.erase(itr);
auto &arry = gCmdValueArrayMap[key];
arry.push_back(val);
arry.push_back(extendedLine);
}
else
{
gCmdValueMap[key] = extendedLine;
}
}
}
extendedLine.clear();
}
}
void Init()
{
gCmdLineString = GetCmdString();
if (gCmdLineString.size())
{
gCmdLineString.erase(gCmdLineString.begin());
}
ProcessArgs();
}
void Deinit()
{
gCmdFlags.clear();
gCmdValues.clear();
gCmdValueMap.clear();
gCmdFlagLookup.clear();
gCmdLineString.clear();
}
}