Use command line parameters settings for GUI as well.

This commit is contained in:
Miodrag Milanovic 2018-07-13 09:14:48 +02:00
parent 499951cb65
commit 8e54ac1542
12 changed files with 183 additions and 152 deletions

View File

@ -93,7 +93,8 @@ int main(int argc, char *argv[])
}
if (vm.count("help") || argc == 1) {
std::cout << boost::filesystem::basename(argv[0]) << " -- Next Generation Place and Route (git "
std::cout << boost::filesystem::basename(argv[0])
<< " -- Next Generation Place and Route (git "
"sha1 " GIT_COMMIT_HASH_STR ")\n";
std::cout << "\n";
std::cout << options << "\n";
@ -101,7 +102,8 @@ int main(int argc, char *argv[])
}
if (vm.count("version")) {
std::cout << boost::filesystem::basename(argv[0]) << " -- Next Generation Place and Route (git "
std::cout << boost::filesystem::basename(argv[0])
<< " -- Next Generation Place and Route (git "
"sha1 " GIT_COMMIT_HASH_STR ")\n";
return 1;
}
@ -112,41 +114,51 @@ int main(int argc, char *argv[])
args.type = ArchArgs::LFE5U_45F;
args.package = "CABGA381";
args.speed = 6;
Context ctx(args);
std::unique_ptr<Context> ctx = std::unique_ptr<Context>(new Context(args));
if (vm.count("verbose")) {
ctx.verbose = true;
ctx->verbose = true;
}
if (vm.count("force")) {
ctx.force = true;
ctx->force = true;
}
if (vm.count("seed")) {
ctx.rngseed(vm["seed"].as<int>());
ctx->rngseed(vm["seed"].as<int>());
}
ctx->timing_driven = true;
if (vm.count("no-tmdriv"))
ctx->timing_driven = false;
#ifndef NO_GUI
if (vm.count("gui")) {
Application a(argc, argv);
MainWindow w(std::move(ctx));
w.show();
return a.exec();
}
#endif
if (vm.count("json")) {
std::string filename = vm["json"].as<std::string>();
std::ifstream f(filename);
if (!parse_json_file(f, filename, &ctx))
if (!parse_json_file(f, filename, ctx.get()))
log_error("Loading design failed.\n");
if (!pack_design(&ctx) && !ctx.force)
if (!pack_design(ctx.get()) && !ctx->force)
log_error("Packing design failed.\n");
if (vm.count("freq"))
ctx.target_freq = vm["freq"].as<double>() * 1e6;
assign_budget(&ctx);
ctx.check();
print_utilisation(&ctx);
ctx.timing_driven = true;
if (vm.count("no-tmdriv"))
ctx.timing_driven = false;
ctx->target_freq = vm["freq"].as<double>() * 1e6;
assign_budget(ctx.get());
ctx->check();
print_utilisation(ctx.get());
if (!ctx.place() && !ctx.force)
if (!ctx->place() && !ctx->force)
log_error("Placing design failed.\n");
ctx.check();
if (!ctx.route() && !ctx.force)
ctx->check();
if (!ctx->route() && !ctx->force)
log_error("Routing design failed.\n");
std::string basecfg;
@ -160,7 +172,7 @@ int main(int argc, char *argv[])
std::string textcfg;
if (vm.count("textcfg"))
textcfg = vm["textcfg"].as<std::string>();
write_bitstream(&ctx, basecfg, textcfg, bitstream);
write_bitstream(ctx.get(), basecfg, textcfg, bitstream);
}
#ifndef NO_PYTHON
@ -175,16 +187,6 @@ int main(int argc, char *argv[])
deinit_python();
}
#endif
#ifndef NO_GUI
if (vm.count("gui")) {
Application a(argc, argv);
MainWindow w;
w.show();
rc = a.exec();
}
#endif
return rc;
} catch (log_execution_error_exception) {
#if defined(_MSC_VER)

View File

@ -75,7 +75,8 @@ int main(int argc, char *argv[])
}
if (vm.count("help") || argc == 1) {
std::cout << boost::filesystem::basename(argv[0]) << " -- Next Generation Place and Route (git "
std::cout << boost::filesystem::basename(argv[0])
<< " -- Next Generation Place and Route (git "
"sha1 " GIT_COMMIT_HASH_STR ")\n";
std::cout << "\n";
std::cout << options << "\n";
@ -83,29 +84,40 @@ int main(int argc, char *argv[])
}
if (vm.count("version")) {
std::cout << boost::filesystem::basename(argv[0]) << " -- Next Generation Place and Route (git "
std::cout << boost::filesystem::basename(argv[0])
<< " -- Next Generation Place and Route (git "
"sha1 " GIT_COMMIT_HASH_STR ")\n";
return 1;
}
Context ctx(ArchArgs{});
std::unique_ptr<Context> ctx = std::unique_ptr<Context>(new Context(ArchArgs{}));
if (vm.count("verbose")) {
ctx.verbose = true;
ctx->verbose = true;
}
if (vm.count("force")) {
ctx.force = true;
ctx->force = true;
}
if (vm.count("seed")) {
ctx.rngseed(vm["seed"].as<int>());
ctx->rngseed(vm["seed"].as<int>());
}
#ifndef NO_GUI
if (vm.count("gui")) {
Application a(argc, argv);
MainWindow w(std::move(ctx));
w.show();
return a.exec();
}
#endif
#ifndef NO_PYTHON
if (vm.count("run")) {
init_python(argv[0], true);
python_export_global("ctx", ctx);
python_export_global("ctx", *ctx.get());
std::vector<std::string> files = vm["run"].as<std::vector<std::string>>();
for (auto filename : files)
@ -115,15 +127,6 @@ int main(int argc, char *argv[])
}
#endif
#ifndef NO_GUI
if (vm.count("gui")) {
Application a(argc, argv);
MainWindow w;
w.show();
rc = a.exec();
}
#endif
return rc;
} catch (log_execution_error_exception) {
#if defined(_MSC_VER)

View File

@ -36,7 +36,8 @@ static void initBasenameResource() { Q_INIT_RESOURCE(base); }
NEXTPNR_NAMESPACE_BEGIN
BaseMainWindow::BaseMainWindow(QWidget *parent) : QMainWindow(parent), ctx(nullptr)
BaseMainWindow::BaseMainWindow(std::unique_ptr<Context> context, QWidget *parent)
: QMainWindow(parent), ctx(std::move(context))
{
initBasenameResource();
qRegisterMetaType<std::string>();

View File

@ -40,9 +40,9 @@ class BaseMainWindow : public QMainWindow
Q_OBJECT
public:
explicit BaseMainWindow(QWidget *parent = 0);
explicit BaseMainWindow(std::unique_ptr<Context> context, QWidget *parent = 0);
virtual ~BaseMainWindow();
Context *getContext() { return ctx; }
Context *getContext() { return ctx.get(); }
protected:
void createMenusAndBars();
@ -59,7 +59,7 @@ class BaseMainWindow : public QMainWindow
void updateTreeView();
protected:
Context *ctx;
std::unique_ptr<Context> ctx;
QTabWidget *tabWidget;
QTabWidget *centralTabWidget;
InfoTab *info;

View File

@ -23,7 +23,7 @@ static void initMainResource() { Q_INIT_RESOURCE(nextpnr); }
NEXTPNR_NAMESPACE_BEGIN
MainWindow::MainWindow(QWidget *parent) : BaseMainWindow(parent)
MainWindow::MainWindow(std::unique_ptr<Context> context, QWidget *parent) : BaseMainWindow(std::move(context), parent)
{
initMainResource();
@ -31,6 +31,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseMainWindow(parent)
setWindowTitle(title.c_str());
createMenu();
Q_EMIT contextChanged(ctx.get());
}
MainWindow::~MainWindow() {}

View File

@ -29,7 +29,7 @@ class MainWindow : public BaseMainWindow
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
explicit MainWindow(std::unique_ptr<Context> context, QWidget *parent = 0);
virtual ~MainWindow();
public:

View File

@ -23,7 +23,7 @@ static void initMainResource() { Q_INIT_RESOURCE(nextpnr); }
NEXTPNR_NAMESPACE_BEGIN
MainWindow::MainWindow(QWidget *parent) : BaseMainWindow(parent)
MainWindow::MainWindow(std::unique_ptr<Context> context, QWidget *parent) : BaseMainWindow(std::move(context), parent)
{
initMainResource();
@ -31,6 +31,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseMainWindow(parent)
setWindowTitle(title.c_str());
createMenu();
Q_EMIT contextChanged(ctx.get());
}
MainWindow::~MainWindow() {}

View File

@ -29,7 +29,7 @@ class MainWindow : public BaseMainWindow
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
explicit MainWindow(std::unique_ptr<Context> context, QWidget *parent = 0);
virtual ~MainWindow();
public:

View File

@ -34,7 +34,8 @@ static void initMainResource() { Q_INIT_RESOURCE(nextpnr); }
NEXTPNR_NAMESPACE_BEGIN
MainWindow::MainWindow(QWidget *parent) : BaseMainWindow(parent), timing_driven(false)
MainWindow::MainWindow(std::unique_ptr<Context> context, QWidget *parent)
: BaseMainWindow(std::move(context), parent), timing_driven(false)
{
initMainResource();
@ -60,6 +61,8 @@ MainWindow::MainWindow(QWidget *parent) : BaseMainWindow(parent), timing_driven(
connect(this, SIGNAL(contextChanged(Context *)), task, SIGNAL(contextChanged(Context *)));
createMenu();
Q_EMIT contextChanged(ctx.get());
}
MainWindow::~MainWindow() { delete task; }
@ -75,7 +78,7 @@ void MainWindow::createMenu()
actionLoadJSON->setIcon(iconLoadJSON);
actionLoadJSON->setStatusTip("Open an existing JSON file");
connect(actionLoadJSON, SIGNAL(triggered()), this, SLOT(open_json()));
actionLoadJSON->setEnabled(false);
actionLoadJSON->setEnabled(true);
actionLoadPCF = new QAction("Open PCF", this);
QIcon iconLoadPCF;
@ -239,22 +242,36 @@ void MainWindow::new_proj()
if (ok && !item.isEmpty()) {
disableActions();
preload_pcf = "";
chipArgs.package = package.toStdString().c_str();
if (ctx)
delete ctx;
ctx = new Context(chipArgs);
ctx = std::unique_ptr<Context>(new Context(chipArgs));
Q_EMIT contextChanged(ctx);
actionLoadJSON->setEnabled(true);
Q_EMIT contextChanged(ctx.get());
}
}
}
void MainWindow::load_json(std::string filename, std::string pcf)
{
tabWidget->setCurrentWidget(info);
preload_pcf = pcf;
disableActions();
Q_EMIT task->loadfile(filename);
}
void MainWindow::load_pcf(std::string filename)
{
tabWidget->setCurrentWidget(info);
disableActions();
Q_EMIT task->loadpcf(filename);
}
void MainWindow::newContext(Context *ctx)
{
std::string title = "nextpnr-ice40 - " + ctx->getChipName() + " ( " + chipArgs.package + " )";
setWindowTitle(title.c_str());
info->clearBuffer();
}
void MainWindow::open_proj()
@ -272,12 +289,7 @@ void MainWindow::open_json()
{
QString fileName = QFileDialog::getOpenFileName(this, QString("Open JSON"), QString(), QString("*.json"));
if (!fileName.isEmpty()) {
tabWidget->setCurrentWidget(info);
std::string fn = fileName.toStdString();
disableActions();
timing_driven = false;
Q_EMIT task->loadfile(fn);
load_json(fileName.toStdString(), "");
}
}
@ -285,11 +297,7 @@ void MainWindow::open_pcf()
{
QString fileName = QFileDialog::getOpenFileName(this, QString("Open PCF"), QString(), QString("*.pcf"));
if (!fileName.isEmpty()) {
tabWidget->setCurrentWidget(info);
std::string fn = fileName.toStdString();
disableActions();
Q_EMIT task->loadpcf(fn);
load_pcf(fileName.toStdString());
}
}
@ -330,9 +338,12 @@ void MainWindow::loadfile_finished(bool status)
log("Loading design successful.\n");
actionLoadPCF->setEnabled(true);
actionPack->setEnabled(true);
if (!preload_pcf.empty())
load_pcf(preload_pcf);
Q_EMIT updateTreeView();
} else {
log("Loading design failed.\n");
preload_pcf = "";
}
}

View File

@ -30,12 +30,13 @@ class MainWindow : public BaseMainWindow
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
explicit MainWindow(std::unique_ptr<Context> context, QWidget *parent = 0);
virtual ~MainWindow();
public:
void createMenu();
void load_json(std::string filename, std::string pcf);
void load_pcf(std::string filename);
protected Q_SLOTS:
virtual void new_proj();
virtual void open_proj();
@ -78,6 +79,7 @@ class MainWindow : public BaseMainWindow
bool timing_driven;
ArchArgs chipArgs;
std::string preload_pcf;
};
NEXTPNR_NAMESPACE_END

View File

@ -33,9 +33,10 @@ class InfoTab : public QWidget
public:
explicit InfoTab(QWidget *parent = 0);
void info(std::string str);
public Q_SLOTS:
void clearBuffer();
private Q_SLOTS:
void showContextMenu(const QPoint &pt);
void clearBuffer();
private:
QPlainTextEdit *plainTextEdit;

View File

@ -47,21 +47,22 @@
USING_NEXTPNR_NAMESPACE
void svg_dump_decal(const Context &ctx, const DecalXY &decal)
void svg_dump_decal(const Context *ctx, const DecalXY &decal)
{
const float scale = 10.0, offset = 10.0;
const std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\"";
for (auto &el : ctx.getDecalGraphics(decal.decal)) {
for (auto &el : ctx->getDecalGraphics(decal.decal)) {
if (el.type == GraphicElement::G_BOX) {
std::cout << "<rect x=\"" << (offset + scale * (decal.x + el.x1)) << "\" y=\"" << (offset + scale * (decal.y + el.y1)) << "\" height=\""
<< (scale * (el.y2 - el.y1)) << "\" width=\"" << (scale * (el.x2 - el.x1)) << "\" " << style
<< "/>\n";
std::cout << "<rect x=\"" << (offset + scale * (decal.x + el.x1)) << "\" y=\""
<< (offset + scale * (decal.y + el.y1)) << "\" height=\"" << (scale * (el.y2 - el.y1))
<< "\" width=\"" << (scale * (el.x2 - el.x1)) << "\" " << style << "/>\n";
}
if (el.type == GraphicElement::G_LINE) {
std::cout << "<line x1=\"" << (offset + scale * (decal.x + el.x1)) << "\" y1=\"" << (offset + scale * (decal.y + el.y1)) << "\" x2=\""
<< (offset + scale * (decal.x + el.x2)) << "\" y2=\"" << (offset + scale * (decal.y + el.y2)) << "\" " << style << "/>\n";
std::cout << "<line x1=\"" << (offset + scale * (decal.x + el.x1)) << "\" y1=\""
<< (offset + scale * (decal.y + el.y1)) << "\" x2=\"" << (offset + scale * (decal.x + el.x2))
<< "\" y2=\"" << (offset + scale * (decal.y + el.y2)) << "\" " << style << "/>\n";
}
}
}
@ -130,7 +131,8 @@ int main(int argc, char *argv[])
if (vm.count("help") || argc == 1) {
help:
std::cout << boost::filesystem::basename(argv[0]) << " -- Next Generation Place and Route (git "
std::cout << boost::filesystem::basename(argv[0])
<< " -- Next Generation Place and Route (git "
"sha1 " GIT_COMMIT_HASH_STR ")\n";
std::cout << "\n";
std::cout << options << "\n";
@ -138,7 +140,8 @@ int main(int argc, char *argv[])
}
if (vm.count("version")) {
std::cout << boost::filesystem::basename(argv[0]) << " -- Next Generation Place and Route (git "
std::cout << boost::filesystem::basename(argv[0])
<< " -- Next Generation Place and Route (git "
"sha1 " GIT_COMMIT_HASH_STR ")\n";
return 1;
}
@ -269,110 +272,126 @@ int main(int argc, char *argv[])
return 1;
}
Context ctx(chipArgs);
std::unique_ptr<Context> ctx = std::unique_ptr<Context>(new Context(chipArgs));
if (vm.count("verbose")) {
ctx.verbose = true;
ctx->verbose = true;
}
if (vm.count("debug")) {
ctx.verbose = true;
ctx.debug = true;
ctx->verbose = true;
ctx->debug = true;
}
if (vm.count("force")) {
ctx.force = true;
ctx->force = true;
}
if (vm.count("seed")) {
ctx.rngseed(vm["seed"].as<int>());
ctx->rngseed(vm["seed"].as<int>());
}
if (vm.count("svg")) {
std::cout << "<svg xmlns=\"http://www.w3.org/2000/svg\" "
"xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n";
for (auto bel : ctx.getBels()) {
std::cout << "<!-- " << ctx.getBelName(bel).str(&ctx) << " -->\n";
svg_dump_decal(ctx, ctx.getBelDecal(bel));
for (auto bel : ctx->getBels()) {
std::cout << "<!-- " << ctx->getBelName(bel).str(ctx.get()) << " -->\n";
svg_dump_decal(ctx.get(), ctx->getBelDecal(bel));
}
std::cout << "<!-- Frame -->\n";
svg_dump_decal(ctx, ctx.getFrameDecal());
svg_dump_decal(ctx.get(), ctx->getFrameDecal());
std::cout << "</svg>\n";
}
if (vm.count("tmfuzz")) {
std::vector<WireId> src_wires, dst_wires;
/*for (auto w : ctx.getWires())
/*for (auto w : ctx->getWires())
src_wires.push_back(w);*/
for (auto b : ctx.getBels()) {
if (ctx.getBelType(b) == TYPE_ICESTORM_LC) {
src_wires.push_back(ctx.getWireBelPin(b, PIN_O));
for (auto b : ctx->getBels()) {
if (ctx->getBelType(b) == TYPE_ICESTORM_LC) {
src_wires.push_back(ctx->getWireBelPin(b, PIN_O));
}
if (ctx.getBelType(b) == TYPE_SB_IO) {
src_wires.push_back(ctx.getWireBelPin(b, PIN_D_IN_0));
if (ctx->getBelType(b) == TYPE_SB_IO) {
src_wires.push_back(ctx->getWireBelPin(b, PIN_D_IN_0));
}
}
for (auto b : ctx.getBels()) {
if (ctx.getBelType(b) == TYPE_ICESTORM_LC) {
dst_wires.push_back(ctx.getWireBelPin(b, PIN_I0));
dst_wires.push_back(ctx.getWireBelPin(b, PIN_I1));
dst_wires.push_back(ctx.getWireBelPin(b, PIN_I2));
dst_wires.push_back(ctx.getWireBelPin(b, PIN_I3));
dst_wires.push_back(ctx.getWireBelPin(b, PIN_CEN));
dst_wires.push_back(ctx.getWireBelPin(b, PIN_CIN));
for (auto b : ctx->getBels()) {
if (ctx->getBelType(b) == TYPE_ICESTORM_LC) {
dst_wires.push_back(ctx->getWireBelPin(b, PIN_I0));
dst_wires.push_back(ctx->getWireBelPin(b, PIN_I1));
dst_wires.push_back(ctx->getWireBelPin(b, PIN_I2));
dst_wires.push_back(ctx->getWireBelPin(b, PIN_I3));
dst_wires.push_back(ctx->getWireBelPin(b, PIN_CEN));
dst_wires.push_back(ctx->getWireBelPin(b, PIN_CIN));
}
if (ctx.getBelType(b) == TYPE_SB_IO) {
dst_wires.push_back(ctx.getWireBelPin(b, PIN_D_OUT_0));
dst_wires.push_back(ctx.getWireBelPin(b, PIN_OUTPUT_ENABLE));
if (ctx->getBelType(b) == TYPE_SB_IO) {
dst_wires.push_back(ctx->getWireBelPin(b, PIN_D_OUT_0));
dst_wires.push_back(ctx->getWireBelPin(b, PIN_OUTPUT_ENABLE));
}
}
ctx.shuffle(src_wires);
ctx.shuffle(dst_wires);
ctx->shuffle(src_wires);
ctx->shuffle(dst_wires);
for (int i = 0; i < int(src_wires.size()) && i < int(dst_wires.size()); i++) {
delay_t actual_delay;
WireId src = src_wires[i], dst = dst_wires[i];
if (!ctx.getActualRouteDelay(src, dst, actual_delay))
if (!ctx->getActualRouteDelay(src, dst, actual_delay))
continue;
printf("%s %s %.3f %.3f %d %d %d %d %d %d\n", ctx.getWireName(src).c_str(&ctx),
ctx.getWireName(dst).c_str(&ctx), ctx.getDelayNS(actual_delay),
ctx.getDelayNS(ctx.estimateDelay(src, dst)), ctx.chip_info->wire_data[src.index].x,
ctx.chip_info->wire_data[src.index].y, ctx.chip_info->wire_data[src.index].type,
ctx.chip_info->wire_data[dst.index].x, ctx.chip_info->wire_data[dst.index].y,
ctx.chip_info->wire_data[dst.index].type);
printf("%s %s %.3f %.3f %d %d %d %d %d %d\n", ctx->getWireName(src).c_str(ctx.get()),
ctx->getWireName(dst).c_str(ctx.get()), ctx->getDelayNS(actual_delay),
ctx->getDelayNS(ctx->estimateDelay(src, dst)), ctx->chip_info->wire_data[src.index].x,
ctx->chip_info->wire_data[src.index].y, ctx->chip_info->wire_data[src.index].type,
ctx->chip_info->wire_data[dst.index].x, ctx->chip_info->wire_data[dst.index].y,
ctx->chip_info->wire_data[dst.index].type);
}
}
if (vm.count("freq"))
ctx->target_freq = vm["freq"].as<double>() * 1e6;
ctx->timing_driven = true;
if (vm.count("no-tmdriv"))
ctx->timing_driven = false;
#ifndef NO_GUI
if (vm.count("gui")) {
Application a(argc, argv);
MainWindow w(std::move(ctx));
if (vm.count("json")) {
std::string filename = vm["json"].as<std::string>();
std::string pcf = "";
if (vm.count("pcf"))
pcf = vm["pcf"].as<std::string>();
w.load_json(filename, pcf);
}
w.show();
return a.exec();
}
#endif
if (vm.count("json")) {
std::string filename = vm["json"].as<std::string>();
std::ifstream f(filename);
if (!parse_json_file(f, filename, &ctx))
if (!parse_json_file(f, filename, ctx.get()))
log_error("Loading design failed.\n");
if (vm.count("pcf")) {
std::ifstream pcf(vm["pcf"].as<std::string>());
if (!apply_pcf(&ctx, pcf))
if (!apply_pcf(ctx.get(), pcf))
log_error("Loading PCF failed.\n");
}
if (!pack_design(&ctx) && !ctx.force)
if (!pack_design(ctx.get()) && !ctx->force)
log_error("Packing design failed.\n");
if (vm.count("freq"))
ctx.target_freq = vm["freq"].as<double>() * 1e6;
assign_budget(&ctx);
ctx.check();
print_utilisation(&ctx);
ctx.timing_driven = true;
if (vm.count("no-tmdriv"))
ctx.timing_driven = false;
assign_budget(ctx.get());
ctx->check();
print_utilisation(ctx.get());
if (!vm.count("pack-only")) {
if (!ctx.place() && !ctx.force)
if (!ctx->place() && !ctx->force)
log_error("Placing design failed.\n");
ctx.check();
if (!ctx.route() && !ctx.force)
ctx->check();
if (!ctx->route() && !ctx->force)
log_error("Routing design failed.\n");
}
}
@ -380,13 +399,13 @@ int main(int argc, char *argv[])
if (vm.count("asc")) {
std::string filename = vm["asc"].as<std::string>();
std::ofstream f(filename);
write_asc(&ctx, f);
write_asc(ctx.get(), f);
}
#ifndef NO_PYTHON
if (vm.count("run")) {
init_python(argv[0], true);
python_export_global("ctx", ctx);
python_export_global("ctx", *ctx.get());
std::vector<std::string> files = vm["run"].as<std::vector<std::string>>();
for (auto filename : files)
@ -395,16 +414,6 @@ int main(int argc, char *argv[])
deinit_python();
}
#endif
#ifndef NO_GUI
if (vm.count("gui")) {
Application a(argc, argv);
MainWindow w;
w.show();
rc = a.exec();
}
#endif
return rc;
} catch (log_execution_error_exception) {
#if defined(_MSC_VER)