87 lines
2.3 KiB
C++
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 "ArgvQuote.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('"');
|
||
|
}
|