-
Notifications
You must be signed in to change notification settings - Fork 80
/
minizinc.cpp
138 lines (125 loc) · 4.07 KB
/
minizinc.cpp
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 <[email protected]>
* Gleb Belov <[email protected]>
*/
/* 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]);
#ifdef NDEBUG && !__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