Win32: unbreak solvespace-cli.
It was broken because of three bugs: * Uninitialized variables in RunCommand; * Trying to use (OEM-encoded) main() argc/argv arguments instead of GetCommandLineW(); * Trying to pass relative paths directly into ssfopen.
This commit is contained in:
parent
679a1f0ded
commit
4a0b4fd8d3
@ -41,14 +41,14 @@ static bool RunBenchmark(std::function<void()> setupFn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
InitPlatform();
|
std::vector<std::string> args = InitPlatform(argc, argv);
|
||||||
|
|
||||||
std::string mode, filename;
|
std::string mode, filename;
|
||||||
if(argc == 3) {
|
if(args.size() == 3) {
|
||||||
mode = argv[1];
|
mode = args[1];
|
||||||
filename = argv[2];
|
filename = args[2];
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Usage: %s [mode] [filename]\n", argv[0]);
|
fprintf(stderr, "Usage: %s [mode] [filename]\n", args[0].c_str());
|
||||||
fprintf(stderr, "Mode can be one of: load.\n");
|
fprintf(stderr, "Mode can be one of: load.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ void Slvs_MakeQuaternion(double ux, double uy, double uz,
|
|||||||
void Slvs_Solve(Slvs_System *ssys, Slvs_hGroup shg)
|
void Slvs_Solve(Slvs_System *ssys, Slvs_hGroup shg)
|
||||||
{
|
{
|
||||||
if(!IsInit) {
|
if(!IsInit) {
|
||||||
InitPlatform();
|
InitPlatform(0, NULL);
|
||||||
IsInit = 1;
|
IsInit = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,8 +10,8 @@ namespace SolveSpace {
|
|||||||
extern std::shared_ptr<Pixmap> framebuffer;
|
extern std::shared_ptr<Pixmap> framebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShowUsage(const char *argv0) {
|
static void ShowUsage(const std::string &argv0) {
|
||||||
fprintf(stderr, "Usage: %s <command> <options> <filename> [filename...]", argv0);
|
fprintf(stderr, "Usage: %s <command> <options> <filename> [filename...]", argv0.c_str());
|
||||||
//-----------------------------------------------------------------------------> 80 col */
|
//-----------------------------------------------------------------------------> 80 col */
|
||||||
fprintf(stderr, R"(
|
fprintf(stderr, R"(
|
||||||
When run, performs an action specified by <command> on every <filename>.
|
When run, performs an action specified by <command> on every <filename>.
|
||||||
@ -81,14 +81,14 @@ static void ShowUsage(const char *argv0) {
|
|||||||
FormatListFromFileFilter(SurfaceFileFilter).c_str());
|
FormatListFromFileFilter(SurfaceFileFilter).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool RunCommand(size_t argc, char **argv) {
|
static bool RunCommand(const std::vector<std::string> args) {
|
||||||
if(argc < 2) return false;
|
if(args.size() < 2) return false;
|
||||||
|
|
||||||
std::function<void(const std::string &)> runner;
|
std::function<void(const std::string &)> runner;
|
||||||
|
|
||||||
std::vector<std::string> inputFiles;
|
std::vector<std::string> inputFiles;
|
||||||
auto ParseInputFile = [&](size_t &argn) {
|
auto ParseInputFile = [&](size_t &argn) {
|
||||||
std::string arg = argv[argn];
|
std::string arg = args[argn];
|
||||||
if(arg[0] != '-') {
|
if(arg[0] != '-') {
|
||||||
inputFiles.push_back(arg);
|
inputFiles.push_back(arg);
|
||||||
return true;
|
return true;
|
||||||
@ -97,42 +97,42 @@ static bool RunCommand(size_t argc, char **argv) {
|
|||||||
|
|
||||||
std::string outputPattern;
|
std::string outputPattern;
|
||||||
auto ParseOutputPattern = [&](size_t &argn) {
|
auto ParseOutputPattern = [&](size_t &argn) {
|
||||||
if(argn + 1 < argc && (!strcmp(argv[argn], "--output") ||
|
if(argn + 1 < args.size() && (args[argn] == "--output" ||
|
||||||
!strcmp(argv[argn], "-o"))) {
|
args[argn] == "-o")) {
|
||||||
argn++;
|
argn++;
|
||||||
outputPattern = argv[argn];
|
outputPattern = args[argn];
|
||||||
return true;
|
return true;
|
||||||
} else return false;
|
} else return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector projUp, projRight;
|
Vector projUp = {}, projRight = {};
|
||||||
auto ParseViewDirection = [&](size_t &argn) {
|
auto ParseViewDirection = [&](size_t &argn) {
|
||||||
if(argn + 1 < argc && (!strcmp(argv[argn], "--view") ||
|
if(argn + 1 < args.size() && (args[argn] == "--view" ||
|
||||||
!strcmp(argv[argn], "-v"))) {
|
args[argn] == "-v")) {
|
||||||
argn++;
|
argn++;
|
||||||
if(!strcmp(argv[argn], "top")) {
|
if(args[argn] == "top") {
|
||||||
projRight = Vector::From(1, 0, 0);
|
projRight = Vector::From(1, 0, 0);
|
||||||
projUp = Vector::From(0, 1, 0);
|
projUp = Vector::From(0, 1, 0);
|
||||||
} else if(!strcmp(argv[argn], "bottom")) {
|
} else if(args[argn] == "bottom") {
|
||||||
projRight = Vector::From(-1, 0, 0);
|
projRight = Vector::From(-1, 0, 0);
|
||||||
projUp = Vector::From(0, 1, 0);
|
projUp = Vector::From(0, 1, 0);
|
||||||
} else if(!strcmp(argv[argn], "left")) {
|
} else if(args[argn] == "left") {
|
||||||
projRight = Vector::From(0, 1, 0);
|
projRight = Vector::From(0, 1, 0);
|
||||||
projUp = Vector::From(0, 0, 1);
|
projUp = Vector::From(0, 0, 1);
|
||||||
} else if(!strcmp(argv[argn], "right")) {
|
} else if(args[argn] == "right") {
|
||||||
projRight = Vector::From(0, -1, 0);
|
projRight = Vector::From(0, -1, 0);
|
||||||
projUp = Vector::From(0, 0, 1);
|
projUp = Vector::From(0, 0, 1);
|
||||||
} else if(!strcmp(argv[argn], "front")) {
|
} else if(args[argn] == "front") {
|
||||||
projRight = Vector::From(-1, 0, 0);
|
projRight = Vector::From(-1, 0, 0);
|
||||||
projUp = Vector::From(0, 0, 1);
|
projUp = Vector::From(0, 0, 1);
|
||||||
} else if(!strcmp(argv[argn], "back")) {
|
} else if(args[argn] == "back") {
|
||||||
projRight = Vector::From(1, 0, 0);
|
projRight = Vector::From(1, 0, 0);
|
||||||
projUp = Vector::From(0, 0, 1);
|
projUp = Vector::From(0, 0, 1);
|
||||||
} else if(!strcmp(argv[argn], "isometric")) {
|
} else if(args[argn] == "isometric") {
|
||||||
projRight = Vector::From(0.707, 0.000, -0.707);
|
projRight = Vector::From(0.707, 0.000, -0.707);
|
||||||
projUp = Vector::From(-0.408, 0.816, -0.408);
|
projUp = Vector::From(-0.408, 0.816, -0.408);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unrecognized view direction '%s'\n", argv[argn]);
|
fprintf(stderr, "Unrecognized view direction '%s'\n", args[argn].c_str());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else return false;
|
} else return false;
|
||||||
@ -140,33 +140,33 @@ static bool RunCommand(size_t argc, char **argv) {
|
|||||||
|
|
||||||
double chordTol = 1.0;
|
double chordTol = 1.0;
|
||||||
auto ParseChordTolerance = [&](size_t &argn) {
|
auto ParseChordTolerance = [&](size_t &argn) {
|
||||||
if(argn + 1 < argc && (!strcmp(argv[argn], "--chord-tol") ||
|
if(argn + 1 < args.size() && (args[argn] == "--chord-ol" ||
|
||||||
!strcmp(argv[argn], "-t"))) {
|
args[argn] == "-t")) {
|
||||||
argn++;
|
argn++;
|
||||||
if(sscanf(argv[argn], "%lf", &chordTol) == 1) {
|
if(sscanf(args[argn].c_str(), "%lf", &chordTol) == 1) {
|
||||||
return true;
|
return true;
|
||||||
} else return false;
|
} else return false;
|
||||||
} else return false;
|
} else return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
if(!strcmp(argv[1], "thumbnail")) {
|
if(args[1] == "thumbnail") {
|
||||||
unsigned width, height;
|
unsigned width = 0, height = 0;
|
||||||
auto ParseSize = [&](size_t &argn) {
|
auto ParseSize = [&](size_t &argn) {
|
||||||
if(argn + 1 < argc && !strcmp(argv[argn], "--size")) {
|
if(argn + 1 < args.size() && args[argn] == "--size") {
|
||||||
argn++;
|
argn++;
|
||||||
if(sscanf(argv[argn], "%ux%u", &width, &height) == 2) {
|
if(sscanf(args[argn].c_str(), "%ux%u", &width, &height) == 2) {
|
||||||
return true;
|
return true;
|
||||||
} else return false;
|
} else return false;
|
||||||
} else return false;
|
} else return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
for(size_t argn = 2; argn < argc; argn++) {
|
for(size_t argn = 2; argn < args.size(); argn++) {
|
||||||
if(!(ParseInputFile(argn) ||
|
if(!(ParseInputFile(argn) ||
|
||||||
ParseOutputPattern(argn) ||
|
ParseOutputPattern(argn) ||
|
||||||
ParseViewDirection(argn) ||
|
ParseViewDirection(argn) ||
|
||||||
ParseChordTolerance(argn) ||
|
ParseChordTolerance(argn) ||
|
||||||
ParseSize(argn))) {
|
ParseSize(argn))) {
|
||||||
fprintf(stderr, "Unrecognized option '%s'.\n", argv[argn]);
|
fprintf(stderr, "Unrecognized option '%s'.\n", args[argn].c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,13 +193,13 @@ static bool RunCommand(size_t argc, char **argv) {
|
|||||||
PaintGraphics();
|
PaintGraphics();
|
||||||
framebuffer->WritePng(output, /*flip=*/true);
|
framebuffer->WritePng(output, /*flip=*/true);
|
||||||
};
|
};
|
||||||
} else if(!strcmp(argv[1], "export-view")) {
|
} else if(args[1] == "export-view") {
|
||||||
for(size_t argn = 2; argn < argc; argn++) {
|
for(size_t argn = 2; argn < args.size(); argn++) {
|
||||||
if(!(ParseInputFile(argn) ||
|
if(!(ParseInputFile(argn) ||
|
||||||
ParseOutputPattern(argn) ||
|
ParseOutputPattern(argn) ||
|
||||||
ParseViewDirection(argn) ||
|
ParseViewDirection(argn) ||
|
||||||
ParseChordTolerance(argn))) {
|
ParseChordTolerance(argn))) {
|
||||||
fprintf(stderr, "Unrecognized option '%s'.\n", argv[argn]);
|
fprintf(stderr, "Unrecognized option '%s'.\n", args[argn].c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,12 +216,12 @@ static bool RunCommand(size_t argc, char **argv) {
|
|||||||
|
|
||||||
SS.ExportViewOrWireframeTo(output, /*exportWireframe=*/false);
|
SS.ExportViewOrWireframeTo(output, /*exportWireframe=*/false);
|
||||||
};
|
};
|
||||||
} else if(!strcmp(argv[1], "export-wireframe")) {
|
} else if(args[1] == "export-wireframe") {
|
||||||
for(size_t argn = 2; argn < argc; argn++) {
|
for(size_t argn = 2; argn < args.size(); argn++) {
|
||||||
if(!(ParseInputFile(argn) ||
|
if(!(ParseInputFile(argn) ||
|
||||||
ParseOutputPattern(argn) ||
|
ParseOutputPattern(argn) ||
|
||||||
ParseChordTolerance(argn))) {
|
ParseChordTolerance(argn))) {
|
||||||
fprintf(stderr, "Unrecognized option '%s'.\n", argv[argn]);
|
fprintf(stderr, "Unrecognized option '%s'.\n", args[argn].c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,12 +231,12 @@ static bool RunCommand(size_t argc, char **argv) {
|
|||||||
|
|
||||||
SS.ExportViewOrWireframeTo(output, /*exportWireframe=*/true);
|
SS.ExportViewOrWireframeTo(output, /*exportWireframe=*/true);
|
||||||
};
|
};
|
||||||
} else if(!strcmp(argv[1], "export-mesh")) {
|
} else if(args[1] == "export-mesh") {
|
||||||
for(size_t argn = 2; argn < argc; argn++) {
|
for(size_t argn = 2; argn < args.size(); argn++) {
|
||||||
if(!(ParseInputFile(argn) ||
|
if(!(ParseInputFile(argn) ||
|
||||||
ParseOutputPattern(argn) ||
|
ParseOutputPattern(argn) ||
|
||||||
ParseChordTolerance(argn))) {
|
ParseChordTolerance(argn))) {
|
||||||
fprintf(stderr, "Unrecognized option '%s'.\n", argv[argn]);
|
fprintf(stderr, "Unrecognized option '%s'.\n", args[argn].c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,11 +246,11 @@ static bool RunCommand(size_t argc, char **argv) {
|
|||||||
|
|
||||||
SS.ExportMeshTo(output);
|
SS.ExportMeshTo(output);
|
||||||
};
|
};
|
||||||
} else if(!strcmp(argv[1], "export-surfaces")) {
|
} else if(args[1] == "export-surfaces") {
|
||||||
for(size_t argn = 2; argn < argc; argn++) {
|
for(size_t argn = 2; argn < args.size(); argn++) {
|
||||||
if(!(ParseInputFile(argn) ||
|
if(!(ParseInputFile(argn) ||
|
||||||
ParseOutputPattern(argn))) {
|
ParseOutputPattern(argn))) {
|
||||||
fprintf(stderr, "Unrecognized option '%s'.\n", argv[argn]);
|
fprintf(stderr, "Unrecognized option '%s'.\n", args[argn].c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -260,7 +260,7 @@ static bool RunCommand(size_t argc, char **argv) {
|
|||||||
sfw.ExportSurfacesTo(output);
|
sfw.ExportSurfacesTo(output);
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unrecognized command '%s'.\n", argv[1]);
|
fprintf(stderr, "Unrecognized command '%s'.\n", args[1].c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,19 +279,22 @@ static bool RunCommand(size_t argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(const std::string &inputFile : inputFiles) {
|
for(const std::string &inputFile : inputFiles) {
|
||||||
|
std::string absInputFile = PathFromCurrentDirectory(inputFile);
|
||||||
|
|
||||||
std::string outputFile = outputPattern;
|
std::string outputFile = outputPattern;
|
||||||
size_t replaceAt = outputFile.find('%');
|
size_t replaceAt = outputFile.find('%');
|
||||||
if(replaceAt != std::string::npos) {
|
if(replaceAt != std::string::npos) {
|
||||||
outputFile.replace(replaceAt, 1, Basename(inputFile, /*stripExtension=*/true));
|
outputFile.replace(replaceAt, 1, Basename(inputFile, /*stripExtension=*/true));
|
||||||
}
|
}
|
||||||
|
std::string absOutputFile = PathFromCurrentDirectory(outputFile);
|
||||||
|
|
||||||
SS.Init();
|
SS.Init();
|
||||||
if(!SS.LoadFromFile(inputFile)) {
|
if(!SS.LoadFromFile(absInputFile)) {
|
||||||
fprintf(stderr, "Cannot load '%s'!\n", inputFile.c_str());
|
fprintf(stderr, "Cannot load '%s'!\n", inputFile.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
SS.AfterNewFile();
|
SS.AfterNewFile();
|
||||||
runner(outputFile);
|
runner(absOutputFile);
|
||||||
SK.Clear();
|
SK.Clear();
|
||||||
SS.Clear();
|
SS.Clear();
|
||||||
|
|
||||||
@ -302,14 +305,14 @@ static bool RunCommand(size_t argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
InitPlatform();
|
std::vector<std::string> args = InitPlatform(argc, argv);
|
||||||
|
|
||||||
if(argc == 1) {
|
if(args.size() == 1) {
|
||||||
ShowUsage(argv[0]);
|
ShowUsage(args[0]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!RunCommand(argc, argv)) {
|
if(!RunCommand(args)) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1161,7 +1161,7 @@ std::vector<std::string> SolveSpace::GetFontFiles() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename {
|
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename {
|
||||||
return SolveSpace::SS.OpenFile([filename UTF8String]);
|
return SolveSpace::SS.OpenFile(SolveSpace::PathFromCurrentDirectory([filename UTF8String]));
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)preferences:(id)sender {
|
- (IBAction)preferences:(id)sender {
|
||||||
|
@ -1590,7 +1590,7 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure the argument is valid UTF-8. */
|
/* Make sure the argument is valid UTF-8. */
|
||||||
SS.OpenFile(Glib::ustring(argv[1]));
|
SS.OpenFile(PathFromCurrentDirectory(Glib::ustring(argv[1])));
|
||||||
}
|
}
|
||||||
|
|
||||||
main.run(*GW);
|
main.run(*GW);
|
||||||
|
@ -80,6 +80,12 @@ std::string PathSepUnixToPlatform(const std::string &filename)
|
|||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string PathFromCurrentDirectory(const std::string &relFilename)
|
||||||
|
{
|
||||||
|
// On Unix we can just pass this to ssfopen directly.
|
||||||
|
return relFilename;
|
||||||
|
}
|
||||||
|
|
||||||
FILE *ssfopen(const std::string &filename, const char *mode)
|
FILE *ssfopen(const std::string &filename, const char *mode)
|
||||||
{
|
{
|
||||||
ssassert(filename.length() == strlen(filename.c_str()),
|
ssassert(filename.length() == strlen(filename.c_str()),
|
||||||
@ -251,8 +257,12 @@ void MemFree(void *p) {
|
|||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitPlatform(void) {
|
std::vector<std::string> InitPlatform(int argc, char **argv) {
|
||||||
/* nothing to do */
|
std::vector<std::string> args;
|
||||||
|
for(int i = 0; i < argc; i++) {
|
||||||
|
args.push_back(argv[i]);
|
||||||
|
}
|
||||||
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1463,27 +1463,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
ShowWindow(TextWnd, SW_SHOWNOACTIVATE);
|
ShowWindow(TextWnd, SW_SHOWNOACTIVATE);
|
||||||
ShowWindow(GraphicsWnd, SW_SHOW);
|
ShowWindow(GraphicsWnd, SW_SHOW);
|
||||||
|
|
||||||
// Create the heaps for all dynamic memory (AllocTemporary, MemAlloc)
|
std::vector<std::string> args = InitPlatform(0, NULL);
|
||||||
InitPlatform();
|
|
||||||
|
|
||||||
// Pull out the Unicode command line.
|
|
||||||
int argc;
|
|
||||||
LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
|
||||||
|
|
||||||
// A filename may have been specified on the command line; if so, then
|
|
||||||
// strip any quotation marks, and make it absolute.
|
|
||||||
std::wstring filenameRel, filename;
|
|
||||||
if(argc >= 2) {
|
|
||||||
filenameRel = argv[1];
|
|
||||||
if(filenameRel[0] == L'\"' && filenameRel[filenameRel.length() - 1] == L'\"') {
|
|
||||||
filenameRel.erase(0, 1);
|
|
||||||
filenameRel.erase(filenameRel.length() - 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD len = GetFullPathNameW(&filenameRel[0], 0, NULL, NULL);
|
|
||||||
filename.resize(len - 1);
|
|
||||||
GetFullPathNameW(&filenameRel[0], len, &filename[0], NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_SPACEWARE
|
#ifdef HAVE_SPACEWARE
|
||||||
// Initialize the SpaceBall, if present. Test if the driver is running
|
// Initialize the SpaceBall, if present. Test if the driver is running
|
||||||
@ -1501,8 +1481,17 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
|
|
||||||
// Call in to the platform-independent code, and let them do their init
|
// Call in to the platform-independent code, and let them do their init
|
||||||
SS.Init();
|
SS.Init();
|
||||||
if(!filename.empty())
|
|
||||||
SS.OpenFile(Narrow(filename));
|
// A filename may have been specified on the command line; if so, then
|
||||||
|
// strip any quotation marks, and make it absolute.
|
||||||
|
if(args.size() >= 2) {
|
||||||
|
std::string filename = args[1];
|
||||||
|
if(filename[0] == '\"' && filename[filename.length() - 1] == '\"') {
|
||||||
|
filename.erase(0, 1);
|
||||||
|
filename.erase(filename.length() - 1, 1);
|
||||||
|
}
|
||||||
|
SS.OpenFile(PathFromCurrentDirectory(filename));
|
||||||
|
}
|
||||||
|
|
||||||
// Repaint one more time, after we've set everything up.
|
// Repaint one more time, after we've set everything up.
|
||||||
PaintGraphics();
|
PaintGraphics();
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
// Include after solvespace.h to avoid identifier clashes.
|
// Include after solvespace.h to avoid identifier clashes.
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <shellapi.h>
|
||||||
|
|
||||||
namespace SolveSpace {
|
namespace SolveSpace {
|
||||||
static HANDLE PermHeap, TempHeap;
|
static HANDLE PermHeap, TempHeap;
|
||||||
@ -118,6 +119,19 @@ std::string PathSepUnixToPlatform(const std::string &filename)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string PathFromCurrentDirectory(const std::string &relFilename)
|
||||||
|
{
|
||||||
|
// On Windows, ssfopen needs an absolute UNC path proper, so get that.
|
||||||
|
std::wstring relFilenameW = Widen(relFilename);
|
||||||
|
std::wstring absFilenameW;
|
||||||
|
absFilenameW.resize(GetFullPathNameW(relFilenameW.c_str(), 0, NULL, NULL));
|
||||||
|
DWORD length = GetFullPathNameW(relFilenameW.c_str(), absFilenameW.length(),
|
||||||
|
&absFilenameW[0], NULL);
|
||||||
|
ssassert(length != 0, "Expected GetFullPathName to succeed");
|
||||||
|
absFilenameW.resize(length);
|
||||||
|
return Narrow(absFilenameW);
|
||||||
|
}
|
||||||
|
|
||||||
static std::string MakeUNCFilename(const std::string &filename)
|
static std::string MakeUNCFilename(const std::string &filename)
|
||||||
{
|
{
|
||||||
// Prepend \\?\ UNC prefix unless already an UNC path.
|
// Prepend \\?\ UNC prefix unless already an UNC path.
|
||||||
@ -192,7 +206,7 @@ void vl() {
|
|||||||
ssassert(HeapValidate(PermHeap, HEAP_NO_SERIALIZE, NULL), "Corrupted heap");
|
ssassert(HeapValidate(PermHeap, HEAP_NO_SERIALIZE, NULL), "Corrupted heap");
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitPlatform() {
|
std::vector<std::string> InitPlatform(int argc, char **argv) {
|
||||||
// Create the heap used for long-lived stuff (that gets freed piecewise).
|
// Create the heap used for long-lived stuff (that gets freed piecewise).
|
||||||
PermHeap = HeapCreate(HEAP_NO_SERIALIZE, 1024*1024*20, 0);
|
PermHeap = HeapCreate(HEAP_NO_SERIALIZE, 1024*1024*20, 0);
|
||||||
// Create the heap that we use to store Exprs and other temp stuff.
|
// Create the heap that we use to store Exprs and other temp stuff.
|
||||||
@ -203,6 +217,17 @@ void InitPlatform() {
|
|||||||
// and results in infinite WndProc recursion in GUI binaries.
|
// and results in infinite WndProc recursion in GUI binaries.
|
||||||
_set_abort_behavior(0, _WRITE_ABORT_MSG);
|
_set_abort_behavior(0, _WRITE_ABORT_MSG);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Extract the command-line arguments; the ones from main() are ignored,
|
||||||
|
// since they are in the OEM encoding.
|
||||||
|
int argcW;
|
||||||
|
LPWSTR *argvW = CommandLineToArgvW(GetCommandLineW(), &argcW);
|
||||||
|
std::vector<std::string> args;
|
||||||
|
for(int i = 0; i < argcW; i++) {
|
||||||
|
args.push_back(Narrow(argvW[i]));
|
||||||
|
}
|
||||||
|
LocalFree(argvW);
|
||||||
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -154,6 +154,7 @@ extern const bool FLIP_FRAMEBUFFER;
|
|||||||
bool PathEqual(const std::string &a, const std::string &b);
|
bool PathEqual(const std::string &a, const std::string &b);
|
||||||
std::string PathSepPlatformToUnix(const std::string &filename);
|
std::string PathSepPlatformToUnix(const std::string &filename);
|
||||||
std::string PathSepUnixToPlatform(const std::string &filename);
|
std::string PathSepUnixToPlatform(const std::string &filename);
|
||||||
|
std::string PathFromCurrentDirectory(const std::string &relFilename);
|
||||||
FILE *ssfopen(const std::string &filename, const char *mode);
|
FILE *ssfopen(const std::string &filename, const char *mode);
|
||||||
std::fstream ssfstream(const std::string &filename, std::ios_base::openmode mode);
|
std::fstream ssfstream(const std::string &filename, std::ios_base::openmode mode);
|
||||||
void ssremove(const std::string &filename);
|
void ssremove(const std::string &filename);
|
||||||
@ -289,12 +290,13 @@ std::string CnfThawString(const std::string &val, const std::string &name);
|
|||||||
uint32_t CnfThawInt(uint32_t val, const std::string &name);
|
uint32_t CnfThawInt(uint32_t val, const std::string &name);
|
||||||
float CnfThawFloat(float val, const std::string &name);
|
float CnfThawFloat(float val, const std::string &name);
|
||||||
|
|
||||||
|
std::vector<std::string> InitPlatform(int argc, char **argv);
|
||||||
|
|
||||||
void *AllocTemporary(size_t n);
|
void *AllocTemporary(size_t n);
|
||||||
void FreeTemporary(void *p);
|
void FreeTemporary(void *p);
|
||||||
void FreeAllTemporary();
|
void FreeAllTemporary();
|
||||||
void *MemAlloc(size_t n);
|
void *MemAlloc(size_t n);
|
||||||
void MemFree(void *p);
|
void MemFree(void *p);
|
||||||
void InitPlatform();
|
|
||||||
void vl(); // debug function to validate heaps
|
void vl(); // debug function to validate heaps
|
||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
@ -291,14 +291,14 @@ int Test::Case::Register(Test::Case testCase) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
InitPlatform();
|
std::vector<std::string> args = InitPlatform(argc, argv);
|
||||||
|
|
||||||
std::regex filter(".*");
|
std::regex filter(".*");
|
||||||
if(argc == 1) {
|
if(args.size() == 1) {
|
||||||
} else if(argc == 2) {
|
} else if(args.size() == 2) {
|
||||||
filter = argv[1];
|
filter = args[1];
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Usage: %s [test filter regex]\n", argv[0]);
|
fprintf(stderr, "Usage: %s [test filter regex]\n", args[0].c_str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user