1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Guido Tack <guido.tack@monash.edu>
* Gleb Belov <gleb.belov@monash.edu>
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* This (main) file coordinates flattening and solving.
* The corresponding modules are flexibly plugged in
* as derived classes, prospectively from DLLs.
* A flattening module should provide MinZinc::GetFlattener()
* A solving module should provide an object of a class derived from SolverFactory.
* Need to get more flexible for multi-pass & multi-solving stuff TODO
*/
#include <minizinc/solver.hh>
#include <chrono>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <ratio>
using namespace MiniZinc;
namespace {
int run(const std::string& exe, const std::vector<std::string>& args, bool jsonStream) {
try {
Timer startTime;
bool fSuccess = false;
MznSolver slv(std::cout, std::cerr, startTime);
try {
fSuccess = (slv.run(args, "", exe) != SolverInstance::ERROR);
} catch (const SignalRaised& e) {
// Interrupted, just terminate
if (slv.getFlagVerbose()) {
std::cerr << std::endl << "Interrupted." << std::endl;
std::cerr << " Done (";
std::cerr << "overall time " << startTime.stoptime() << ")." << std::endl;
}
// Re-raise signal
e.raise();
return static_cast<int>(!fSuccess);
} catch (const InternalError& e) {
if (slv.getFlagVerbose()) {
std::cerr << std::endl;
}
std::cerr << "MiniZinc has encountered an internal error. This is a bug." << std::endl;
std::cerr << "Please file a bug report using the MiniZinc bug tracker." << std::endl;
std::cerr << "The internal error message was: " << std::endl;
std::cerr << "\"" << e.msg() << "\"" << std::endl;
} catch (const Exception& e) {
if (jsonStream || slv.flagEncapsulateJSON) {
e.json(std::cout);
} else {
if (slv.getFlagVerbose()) {
std::cerr << std::endl;
}
e.print(std::cerr);
}
} catch (const std::exception& e) {
if (slv.getFlagVerbose()) {
std::cerr << std::endl;
}
std::cerr << e.what() << std::endl;
} catch (...) {
if (slv.getFlagVerbose()) {
std::cerr << std::endl;
}
std::cerr << " UNKNOWN EXCEPTION." << std::endl;
}
if (slv.getFlagVerbose()) {
std::cerr << " Done (";
std::cerr << "overall time " << startTime.stoptime() << ")." << std::endl;
}
return static_cast<int>(!fSuccess);
} catch (const Exception& e) {
std::string what = e.what();
std::cerr << what << (what.empty() ? "" : ": ") << e.msg() << std::endl;
std::exit(EXIT_FAILURE);
}
}
} // namespace
#ifdef _WIN32
#include <minizinc/interrupt.hh>
int wmain(int argc, wchar_t* argv[], wchar_t* envp[]) {
InterruptListener::run();
OverflowHandler::install();
std::vector<std::string> args(argc - 1);
bool jsonStream = false;
for (int i = 1; i < argc; i++) {
args[i - 1] = FileUtils::wide_to_utf8(argv[i]);
if (args[i - 1] == "--json-stream") {
jsonStream = true;
}
}
auto exe = FileUtils::wide_to_utf8(argv[0]);
#if defined(NDEBUG) && !defined(__MINGW32__)
// Lambda to prevent object unwinding not allowed with __try..__except
return ([&]() {
__try {
return run(exe, args, jsonStream);
} __except (OverflowHandler::filter(GetExceptionCode())) {
OverflowHandler::handle(GetExceptionCode());
}
})();
#else
// Let debugger catch SEH exceptions
return run(exe, args, jsonStream);
#endif
}
#else
int main(int argc, const char** argv) {
OverflowHandler::install(argv);
std::vector<std::string> args(argc - 1);
bool jsonStream = false;
for (int i = 1; i < argc; i++) {
args[i - 1] = argv[i];
if (args[i - 1] == "--json-stream") {
jsonStream = true;
}
}
return run(argv[0], args, jsonStream);
}
#endif
|