Switch renderdoccmd to use vector<string> for passing args

This commit is contained in:
baldurk
2016-07-12 11:22:51 +02:00
parent 2373f0e445
commit b74b833121
4 changed files with 87 additions and 70 deletions
+55 -41
View File
@@ -50,27 +50,29 @@ uint32_t wtoi(wchar_t *str)
return ret;
}
bool argequal(const char *a, const char *b)
bool argequal(const std::string &a, const std::string &b)
{
if(a == NULL || b == NULL)
if(a.length() != b.length())
return false;
while(*a && *b)
for(size_t i = 0; i < a.length(); i++)
{
// only compare ASCII characters in UTF-8 string
if((*a & 0x80) == 0 && (*b & 0x80) == 0 && tolower(*a) != tolower(*b))
break;
char ca = a[i];
char cb = b[i];
a++;
b++;
// only compare ASCII characters in UTF-8 string
if((ca & 0x80) == 0 && (cb & 0x80) == 0 && tolower(ca) != tolower(cb))
return false;
}
// if both reached null terminator then strings are equal
return *a == 0 && *b == 0;
return true;
}
void readCapOpts(const char *str, CaptureOptions *opts)
void readCapOpts(const std::string &str, CaptureOptions *opts)
{
if(str.length() < sizeof(CaptureOptions))
return;
// serialise from string with two chars per byte
byte *b = (byte *)opts;
for(size_t i = 0; i < sizeof(CaptureOptions); i++)
@@ -131,7 +133,7 @@ void DisplayRendererPreview(ReplayRenderer *renderer)
DisplayRendererPreview(renderer, d);
}
int renderdoccmd(int argc, char **argv)
int renderdoccmd(const std::vector<std::string> &argv)
{
CaptureOptions opts;
@@ -142,18 +144,18 @@ int renderdoccmd(int argc, char **argv)
opts.DelayForDebugger = 5;
opts.HookIntoChildren = true;
if(argc >= 2)
if(argv.size() >= 2)
{
// fall through and print usage
if(argequal(argv[1], "--help") || argequal(argv[1], "-h"))
{
}
// if we were given a logfile, load it and continually replay it.
else if(strstr(argv[1], ".rdc") != NULL)
else if(strstr(argv[1].c_str(), ".rdc") != NULL)
{
float progress = 0.0f;
ReplayRenderer *renderer = NULL;
auto status = RENDERDOC_CreateReplayRenderer(argv[1], &progress, &renderer);
auto status = RENDERDOC_CreateReplayRenderer(argv[1].c_str(), &progress, &renderer);
if(renderer)
{
@@ -167,7 +169,7 @@ int renderdoccmd(int argc, char **argv)
// dump the image from a logfile
if(argequal(argv[1], "--thumb") || argequal(argv[1], "-t"))
{
if(argc >= 3)
if(argv.size() >= 3)
{
string jpgname = argv[2];
@@ -186,16 +188,16 @@ int renderdoccmd(int argc, char **argv)
}
uint32_t len = 0;
bool32 ret = RENDERDOC_GetThumbnail(argv[2], NULL, len);
bool32 ret = RENDERDOC_GetThumbnail(argv[2].c_str(), NULL, len);
if(!ret)
{
fprintf(stderr, "No thumbnail in '%s' or error retrieving it", argv[2]);
fprintf(stderr, "No thumbnail in '%s' or error retrieving it", argv[2].c_str());
}
else
{
byte *jpgbuf = new byte[len];
RENDERDOC_GetThumbnail(argv[2], jpgbuf, len);
RENDERDOC_GetThumbnail(argv[2].c_str(), jpgbuf, len);
FILE *f = fopen(jpgname.c_str(), "wb");
@@ -221,11 +223,11 @@ int renderdoccmd(int argc, char **argv)
// replay a logfile
else if(argequal(argv[1], "--replay") || argequal(argv[1], "-r"))
{
if(argc >= 3)
if(argv.size() >= 3)
{
float progress = 0.0f;
ReplayRenderer *renderer = NULL;
auto status = RENDERDOC_CreateReplayRenderer(argv[2], &progress, &renderer);
auto status = RENDERDOC_CreateReplayRenderer(argv[2].c_str(), &progress, &renderer);
if(renderer)
{
@@ -246,9 +248,9 @@ int renderdoccmd(int argc, char **argv)
// can't do this on other platforms as there's no nice extension
// and we don't want to just launch any single parameter in case it's
// -h or -help or some other guess/typo
else if(strstr(argv[1], ".exe") != NULL)
else if(strstr(argv[1].c_str(), ".exe") != NULL)
{
uint32_t ident = RENDERDOC_ExecuteAndInject(argv[1], NULL, NULL, NULL, &opts, false);
uint32_t ident = RENDERDOC_ExecuteAndInject(argv[1].c_str(), NULL, NULL, NULL, &opts, false);
if(ident == 0)
fprintf(stderr, "Failed to create & inject\n");
@@ -261,26 +263,28 @@ int renderdoccmd(int argc, char **argv)
// capture a program with default capture options
else if(argequal(argv[1], "--capture") || argequal(argv[1], "-c"))
{
if(argc >= 4)
if(argv.size() >= 4)
{
uint32_t ident = RENDERDOC_ExecuteAndInject(argv[2], NULL, argv[3], NULL, &opts, false);
uint32_t ident =
RENDERDOC_ExecuteAndInject(argv[2].c_str(), NULL, argv[3].c_str(), NULL, &opts, false);
if(ident == 0)
fprintf(stderr, "Failed to create & inject to '%s' with params \"%s\"\n", argv[2], argv[3]);
fprintf(stderr, "Failed to create & inject to '%s' with params \"%s\"\n", argv[2].c_str(),
argv[3].c_str());
else
fprintf(stderr, "Created & injected '%s' with params \"%s\" as %d\n", argv[2], argv[3],
ident);
fprintf(stderr, "Created & injected '%s' with params \"%s\" as %d\n", argv[2].c_str(),
argv[3].c_str(), ident);
return ident;
}
else if(argc >= 3)
else if(argv.size() >= 3)
{
uint32_t ident = RENDERDOC_ExecuteAndInject(argv[2], NULL, NULL, NULL, &opts, false);
uint32_t ident = RENDERDOC_ExecuteAndInject(argv[2].c_str(), NULL, NULL, NULL, &opts, false);
if(ident == 0)
fprintf(stderr, "Failed to create & inject to '%s'\n", argv[2]);
fprintf(stderr, "Failed to create & inject to '%s'\n", argv[2].c_str());
else
fprintf(stderr, "Created & injected '%s' as %d\n", argv[2], ident);
fprintf(stderr, "Created & injected '%s' as %d\n", argv[2].c_str(), ident);
return ident;
}
@@ -292,9 +296,9 @@ int renderdoccmd(int argc, char **argv)
// inject into a running process with default capture options
else if(argequal(argv[1], "--inject") || argequal(argv[1], "-i"))
{
if(argc >= 3)
if(argv.size() >= 3)
{
char *pid = argv[2];
const char *pid = argv[2].c_str();
while(*pid == '"' || isspace(*pid))
pid++;
@@ -323,10 +327,10 @@ int renderdoccmd(int argc, char **argv)
// replay a logfile over the network on a remote host
else if(argequal(argv[1], "--remotereplay") || argequal(argv[1], "-rr"))
{
if(argc >= 4)
if(argv.size() >= 4)
{
RemoteRenderer *remote = NULL;
auto status = RENDERDOC_CreateRemoteReplayConnection(argv[2], &remote);
auto status = RENDERDOC_CreateRemoteReplayConnection(argv[2].c_str(), &remote);
if(remote == NULL || status != eReplayCreate_Success)
return 1;
@@ -334,7 +338,7 @@ int renderdoccmd(int argc, char **argv)
float progress = 0.0f;
ReplayRenderer *renderer = NULL;
status = RemoteRenderer_CreateProxyRenderer(remote, 0, argv[3], &progress, &renderer);
status = RemoteRenderer_CreateProxyRenderer(remote, 0, argv[3].c_str(), &progress, &renderer);
if(renderer)
{
@@ -353,20 +357,20 @@ int renderdoccmd(int argc, char **argv)
// not documented/useful for manual use on the cmd line, used internally
else if(argequal(argv[1], "--cap32for64"))
{
if(argc >= 5)
if(argv.size() >= 5)
{
char *pid = argv[2];
const char *pid = argv[2].c_str();
while(*pid == '"' || isspace(*pid))
pid++;
uint32_t pidNum = (uint32_t)atoi(pid);
char *log = argv[3];
const char *log = argv[3].c_str();
if(log[0] == 0)
log = NULL;
CaptureOptions cmdopts;
readCapOpts(argv[4], &cmdopts);
readCapOpts(argv[4].c_str(), &cmdopts);
return RENDERDOC_InjectIntoProcess(pidNum, log, &cmdopts, false);
}
@@ -414,3 +418,13 @@ int renderdoccmd(int argc, char **argv)
return 1;
}
int renderdoccmd(int argc, char **c_argv)
{
std::vector<std::string> argv;
argv.resize(argc);
for(int i = 0; i < argc; i++)
argv[i] = c_argv[i];
return renderdoccmd(argv);
}
+7 -1
View File
@@ -163,6 +163,12 @@
<ItemGroup>
<ClCompile Include="..\renderdoc\3rdparty\miniz\miniz.c" />
<ClCompile Include="renderdoccmd.cpp" />
<ClCompile Include="renderdoccmd_android.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="renderdoccmd_apple.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="renderdoccmd_linux.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@@ -192,4 +198,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
@@ -7,6 +7,8 @@
<Filter>3rdparty</Filter>
</ClCompile>
<ClCompile Include="renderdoccmd_linux.cpp" />
<ClCompile Include="renderdoccmd_android.cpp" />
<ClCompile Include="renderdoccmd_apple.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h">
+23 -28
View File
@@ -265,9 +265,9 @@ void DisplayRendererPreview(ReplayRenderer *renderer, TextureDisplay displayCfg)
DestroyWindow(wnd);
}
int renderdoccmd(int argc, char **argv);
bool argequal(const char *a, const char *b);
void readCapOpts(const char *str, CaptureOptions *opts);
int renderdoccmd(const std::vector<std::string> &argv);
bool argequal(const std::string &a, const std::string &b);
void readCapOpts(const std::string &str, CaptureOptions *opts);
int WINAPI wWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine,
_In_ int nShowCmd)
@@ -277,29 +277,24 @@ int WINAPI wWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInstance, _In_
wargv = CommandLineToArgvW(GetCommandLine(), &argc);
std::vector<std::string> argv_storage;
std::vector<char *> argv_pointers;
std::vector<std::string> argv;
argv_storage.resize(argc);
argv_pointers.resize(argc);
for(int i = 0; i < argc; i++)
argv.resize(argc);
for(size_t i = 0; i < argv.size(); i++)
{
size_t len = wcslen(wargv[i]);
len *= 4; // worst case, every UTF-8 character takes 4 bytes
argv_storage[i].resize(len + 1);
argv_storage[i][len] = 0;
argv_pointers[i] = &argv_storage[i][0];
argv[i].resize(len + 1);
argv[i][len] = 0;
char *cstr = (char *)&argv[i][0];
WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv_pointers[i], (int)len + 1, NULL, NULL);
WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, cstr, (int)len + 1, NULL, NULL);
argv[i].resize(strlen(cstr));
}
char *argv_backup[] = {"", NULL};
char **argv = NULL;
if(argc > 0)
argv = &argv_pointers[0];
else
argv = argv_backup;
if(argv.empty())
argv.push_back("renderdoccmd");
LocalFree(wargv);
@@ -325,7 +320,7 @@ int WINAPI wWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInstance, _In_
}
// special WIN32 option for launching the crash handler
if(argc == 3 && !_stricmp(argv[1], "--update"))
if(argv.size() == 3 && argequal(argv[1], "--update"))
{
string originalpath = argv[2];
wstring wide_path;
@@ -527,7 +522,7 @@ int WINAPI wWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInstance, _In_
CrashGenerationServer *crashServer = NULL;
// special WIN32 option for launching the crash handler
if(argc == 2 && !_stricmp(argv[1], "--crashhandle"))
if(argv.size() == 2 && argequal(argv[1], "--crashhandle"))
{
wchar_t tempPath[MAX_PATH] = {0};
GetTempPathW(MAX_PATH - 1, tempPath);
@@ -706,15 +701,15 @@ int WINAPI wWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInstance, _In_
// this installs a global windows hook pointing at renderdocshim*.dll that filters all running
// processes and
// loads renderdoc.dll in the target one. In any other process it unloads as soon as possible
if(argc == 5 && argequal(argv[1], "--globalhook"))
if(argv.size() == 5 && argequal(argv[1], "--globalhook"))
{
char *pathmatch = argv[2];
char *log = argv[3];
std::string &pathmatch = argv[2];
std::string &log = argv[3];
size_t len = strlen(pathmatch);
size_t len = pathmatch.length();
wstring wpathmatch;
wpathmatch.resize(len);
MultiByteToWideChar(CP_UTF8, 0, pathmatch, -1, &wpathmatch[0], (int)len);
MultiByteToWideChar(CP_UTF8, 0, pathmatch.c_str(), -1, &wpathmatch[0], (int)len);
wpathmatch.resize(wcslen(wpathmatch.c_str()));
CaptureOptions cmdopts;
@@ -786,7 +781,7 @@ int WINAPI wWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInstance, _In_
wcsncpy_s(shimdata->pathmatchstring, wpathmatch.c_str(), _TRUNCATE);
wcsncpy_s(shimdata->rdocpath, rdocpath, _TRUNCATE);
strncpy_s(shimdata->log, log, _TRUNCATE);
strncpy_s(shimdata->log, log.c_str(), _TRUNCATE);
memcpy(shimdata->opts, &cmdopts, sizeof(CaptureOptions));
static_assert(sizeof(CaptureOptions) <= sizeof(shimdata->opts),
@@ -816,5 +811,5 @@ int WINAPI wWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInstance, _In_
return 0;
}
return renderdoccmd(argc, argv);
return renderdoccmd(argv);
}