From 4ffb4c65825ab0a5ded00ff799b494097e7bd143 Mon Sep 17 00:00:00 2001 From: jaseg Date: Sat, 5 Jun 2021 23:33:44 +0200 Subject: Make svg-flatten auto-search for cargo dependencies in all call sites --- svg-flatten/Makefile | 3 +- svg-flatten/src/main.cpp | 70 ++--------------------------- svg-flatten/src/test/nopencv_test.cpp | 21 ++------- svg-flatten/src/test/svg_tests.py | 14 +++++- svg-flatten/src/util.cpp | 84 +++++++++++++++++++++++++++++++++++ svg-flatten/src/util.h | 24 ++++++++++ 6 files changed, 128 insertions(+), 88 deletions(-) create mode 100644 svg-flatten/src/util.cpp create mode 100644 svg-flatten/src/util.h diff --git a/svg-flatten/Makefile b/svg-flatten/Makefile index 4a45c7f..6822f47 100644 --- a/svg-flatten/Makefile +++ b/svg-flatten/Makefile @@ -26,6 +26,7 @@ SOURCES := src/svg_color.cpp \ src/out_dilater.cpp \ src/lambda_sink.cpp \ src/flatten.cpp \ + src/util.cpp \ src/nopencv.cpp \ $(UPSTREAM_DIR)/cpp-base64/base64.cpp \ $(UPSTREAM_DIR)/clipper-6.4.2/cpp/clipper.cpp \ @@ -68,7 +69,7 @@ $(BUILDDIR)/$(TARGET): $(SOURCES:%.cpp=$(BUILDDIR)/%.o) @mkdir -p $(dir $@) $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -$(BUILDDIR)/nopencv-test: src/test/nopencv_test.cpp src/nopencv.cpp +$(BUILDDIR)/nopencv-test: src/test/nopencv_test.cpp src/nopencv.cpp src/util.cpp @mkdir -p $(dir $@) $(CXX) $(CXXFLAGS) $(INCLUDES) -o $@ $^ $(LDFLAGS) diff --git a/svg-flatten/src/main.cpp b/svg-flatten/src/main.cpp index 1fce67b..d89da7c 100644 --- a/svg-flatten/src/main.cpp +++ b/svg-flatten/src/main.cpp @@ -1,18 +1,16 @@ #include #include -#include -#include #include #include #include #include #include #include -#include #include #include "vec_core.h" #include +#include "util.h" using argagg::parser_results; using argagg::parser; @@ -354,70 +352,8 @@ int main(int argc, char **argv) { } string dpi_str = to_string(dpi); - const char *homedir; - if ((homedir = getenv("HOME")) == NULL) { - homedir = getpwuid(getuid())->pw_dir; - } - string homedir_s(homedir); - string loc_in_home = homedir_s + "/.cargo/bin/usvg"; - - const char *command_line[] = {nullptr, "--keep-named-groups", "--dpi", dpi_str.c_str(), barf.c_str(), frob.c_str(), NULL}; - bool found_usvg = false; - int usvg_rc=-1; - for (int i=0; i<3; i++) { - const char *usvg_envvar; - switch (i) { - case 0: - if ((usvg_envvar = getenv("USVG")) == NULL) { - continue; - } else { - command_line[0] = "usvg"; - } - break; - - case 1: - command_line[0] = "usvg"; - break; - - case 2: - command_line[0] = loc_in_home.c_str(); - break; - } - - struct subprocess_s subprocess; - int rc = subprocess_create(command_line, subprocess_option_inherit_environment, &subprocess); - if (rc) { - cerr << "Error calling usvg!" << endl; - return EXIT_FAILURE; - } - - usvg_rc = -1; - rc = subprocess_join(&subprocess, &usvg_rc); - if (rc) { - cerr << "Error calling usvg!" << endl; - return EXIT_FAILURE; - } - - rc = subprocess_destroy(&subprocess); - if (rc) { - cerr << "Error calling usvg!" << endl; - return EXIT_FAILURE; - } - - if (usvg_rc == 255) { - continue; - } - found_usvg = true; - break; - } - - if (!found_usvg) { - cerr << "Error: Cannot find usvg. Is it installed and in $PATH?" << endl; - return EXIT_FAILURE; - } - - if (usvg_rc) { - cerr << "usvg returned an error code: " << usvg_rc << endl; + const char *command_line[] = {nullptr, "--keep-named-groups", "--dpi", dpi_str.c_str(), barf.c_str(), frob.c_str(), nullptr}; + if (run_cargo_command("usvg", command_line, "USVG")) { return EXIT_FAILURE; } } diff --git a/svg-flatten/src/test/nopencv_test.cpp b/svg-flatten/src/test/nopencv_test.cpp index e4cc078..13be6f8 100644 --- a/svg-flatten/src/test/nopencv_test.cpp +++ b/svg-flatten/src/test/nopencv_test.cpp @@ -5,6 +5,7 @@ #include #include +#include "util.h" #include "nopencv.hpp" #include @@ -158,24 +159,8 @@ MU_TEST(test_complex_example_from_paper) { } int render_svg(const char *in_svg, const char *out_png) { - const char *command_line[] = {"resvg", in_svg, out_png, nullptr}; - struct subprocess_s subprocess; - int rc = subprocess_create(command_line, subprocess_option_inherit_environment, &subprocess); - if (rc) - return rc; - - int resvg_rc = -1; - rc = subprocess_join(&subprocess, &resvg_rc); - if (rc) - return rc; - if (resvg_rc) - return -resvg_rc; - - rc = subprocess_destroy(&subprocess); - if (rc) - return rc; - - return 0; + const char *command_line[] = {nullptr, in_svg, out_png, nullptr}; + return run_cargo_command("resvg", command_line, "RESVG"); } static void testdata_roundtrip(const char *fn) { diff --git a/svg-flatten/src/test/svg_tests.py b/svg-flatten/src/test/svg_tests.py index f98e367..c2e5d50 100644 --- a/svg-flatten/src/test/svg_tests.py +++ b/svg-flatten/src/test/svg_tests.py @@ -39,6 +39,16 @@ def run_svg_flatten(input_file, output_file, *args, **kwargs): print(proc.stderr) raise +def run_cargo_cmd(cmd, args, **kwargs): + if cmd.upper() in os.environ: + return subprocess.run([os.environ[cmd.upper()], *args], **kwargs) + + try: + return subprocess.run([cmd, *args], **kwargs) + + except FileNotFoundError: + return subprocess.run([str(Path.home() / '.cargo' / 'bin' / cmd), *args], **kwargs) + class SVGRoundTripTests(unittest.TestCase): # Notes on test cases: @@ -131,8 +141,8 @@ class SVGRoundTripTests(unittest.TestCase): vectorizer='binary-contours') if not use_rsvg: # default! - subprocess.run(['resvg', tmp_out_svg.name, tmp_out_png.name], check=True, stdout=subprocess.DEVNULL) - subprocess.run(['resvg', test_in_svg, tmp_in_png.name], check=True, stdout=subprocess.DEVNULL) + run_cargo_cmd('resvg', [tmp_out_svg.name, tmp_out_png.name], check=True, stdout=subprocess.DEVNULL) + run_cargo_cmd('resvg', [test_in_svg, tmp_in_png.name], check=True, stdout=subprocess.DEVNULL) else: subprocess.run(['rsvg-convert', tmp_out_svg.name, '-f', 'png', '-o', tmp_out_png.name], check=True, stdout=subprocess.DEVNULL) diff --git a/svg-flatten/src/util.cpp b/svg-flatten/src/util.cpp new file mode 100644 index 0000000..e88f4e9 --- /dev/null +++ b/svg-flatten/src/util.cpp @@ -0,0 +1,84 @@ + +#include +#include +#include +#include + +#include +#include + +#include "util.h" + +using namespace std; + +int gerbolyze::run_cargo_command(const char *cmd_name, const char *cmdline[], const char *envvar) { + const char *homedir; + if ((homedir = getenv("HOME")) == NULL) { + homedir = getpwuid(getuid())->pw_dir; + } + string homedir_s(homedir); + string cargo_bin_dir = homedir_s + "/.cargo/bin/" + cmd_name; + + bool found = false; + int proc_rc = -1; + for (int i=0; i<3; i++) { + const char *envvar_val; + switch (i) { + case 0: + if ((envvar_val = getenv(envvar)) == NULL) { + continue; + } else { + cmdline[0] = envvar_val; + } + break; + + case 1: + cmdline[0] = cmd_name; + break; + + case 2: + cmdline[0] = cargo_bin_dir.c_str(); + break; + } + + struct subprocess_s subprocess; + int rc = subprocess_create(cmdline, subprocess_option_inherit_environment, &subprocess); + if (rc) { + cerr << "Error calling " << cmd_name << endl; + return EXIT_FAILURE; + } + + proc_rc = -1; + rc = subprocess_join(&subprocess, &proc_rc); + if (rc) { + cerr << "Error calling " << cmd_name << endl; + return EXIT_FAILURE; + } + + rc = subprocess_destroy(&subprocess); + if (rc) { + cerr << "Error calling " << cmd_name << endl; + return EXIT_FAILURE; + } + + /* Fail if the command given in the environment variable could not be found. */ + if (i > 0 && proc_rc == 255) { + continue; + } + found = true; + break; + } + + if (!found) { + cerr << "Error: Cannot find " << cmd_name << ". Is it installed and in $PATH?" << endl; + return EXIT_FAILURE; + } + + if (proc_rc) { + cerr << cmd_name << " returned an error code: " << proc_rc << endl; + return EXIT_FAILURE; + } + + return 0; +} + diff --git a/svg-flatten/src/util.h b/svg-flatten/src/util.h new file mode 100644 index 0000000..f3fbe32 --- /dev/null +++ b/svg-flatten/src/util.h @@ -0,0 +1,24 @@ +/* + * This file is part of gerbolyze, a vector image preprocessing toolchain + * Copyright (C) 2021 Jan Sebastian Götte + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#pragma once + +namespace gerbolyze { +int run_cargo_command(const char *cmd_name, const char *cmdline[], const char *envvar); +} + -- cgit