AuroraRuntime/Source/Processes/AuArgvQuote.cpp

87 lines
2.3 KiB
C++

/*
* Copyright(C) 2011 - Daniel Colascione, Microsoft Corporation
* Public domain or equiv implied license
* Microsoft gave their engineer permission to publish this reference code in his advisory article on MSDN/TechNet operated by MS
* Stolen by commies and rebranded as GPL before -> https://fossies.org/linux/calibre/bypy/windows/portable.cpp
*
* CmdLine subsystem uses CommandLineToArgvW to parse commandline strings from Windows, just like **most** (not all) apps and crts in Windows land
* Unix programs merely passthrough unmodified strings using execv
*
*/
#include <Source/RuntimeInternal.hpp>
#include "AuArgvQuote.hpp"
void
ArgvQuote(
const AuString &argument,
AuString &outputString,
bool force
)
{
//
// Unless we're told otherwise, don't quote unless we actually
// need to do so --- hopefully avoid problems if programs won't
// parse quotes properly
//
if (!force &&
argument.size() &&
argument.find_first_of(" \t\n\v\"") == argument.npos)
{
outputString.append(argument);
return;
}
outputString.push_back('"');
for (auto itr = argument.begin() ; ; ++itr)
{
unsigned slashes = 0;
while (itr != argument.end() && *itr == '\\')
{
++itr;
++slashes;
}
if (itr == argument.end())
{
//
// Escape all backslashes, but let the terminating
// double quotation mark we add below be interpreted
// as a metacharacter.
//
outputString.append(slashes * 2, '\\');
break;
}
else if (*itr == '"')
{
//
// Escape all backslashes and the following
// double quotation mark.
//
outputString.append(slashes * 2 + 1, '\\');
outputString.push_back(*itr);
}
else
{
//
// Backslashes aren't special here.
//
if (AuString(" \t\n\v").find(*itr) != AuString::npos)
{
outputString.append(slashes, '\\');
}
outputString.push_back(*itr);
}
}
outputString.push_back('"');
}