diff --git a/CMakeLists.txt b/CMakeLists.txt index d117502..cefffda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ -cmake_minimum_required (VERSION 2.6) - +cmake_minimum_required (VERSION 3.5) +include(CheckFunctionExists) +include(FetchContent) project (vss2svg) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") @@ -48,14 +49,60 @@ if(USE_GCC) set(CMAKE_CXX_COMPILER "g++") set(CMAKE_CC_COMPILER "gcc") endif(USE_GCC) + +set(FMEM_NAME fmem${EXTERNAL_LIB_DIR_SUFFIX}) + +FetchContent_Declare( + fmem + GIT_REPOSITORY https://github.com/kreijstal/fmem.git + GIT_TAG master + PREFIX ${DEPS} + CMAKE_CACHE_ARGS + -DBUILD_TESTING:BOOL=FALSE + -DCMAKE_INSTALL_PREFIX:PATH=${DEPS} + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + ${PLATFORM_TOOLCHAIN_OPTION} + ${CMAKE_OSX_ARCHITECTURES_OPTION} +) + +FetchContent_MakeAvailable(fmem) +#set(EXTERNAL_FMEM "fmem") +message(STATUS "Configuring argp") +list(APPEND CMAKE_MESSAGE_INDENT " ") +message(STATUS "Checking if argp is provided by system libraries") +CHECK_FUNCTION_EXISTS(argp_parse HAVE_BUNDLED_ARGP_PARSE_FUNCTION) + +message(STATUS "Looking for standalone argp library") +set(CMAKE_REQUIRED_LIBRARIES argp) +CHECK_FUNCTION_EXISTS(argp_parse HAVE_EXTERNAL_ARGP_PARSE_FUNCTION) +list(POP_BACK CMAKE_MESSAGE_INDENT) +if(HAVE_BUNDLED_ARGP_PARSE_FUNCTION) + message(STATUS "Using bundled argp") +elseif(HAVE_EXTERNAL_ARGP_PARSE_FUNCTION) + message(STATUS "Using stand-alone argp") + set(EXTERNAL_ARGP "argp") +else() + message(STATUS "Building argp") + if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(EXTERNAL_ARGP "-Wl,-force_load,${DEPS}/lib/libargp-standalone.a") + else() + set(EXTERNAL_ARGP "argp-standalone") + endif() + + FetchContent_Declare( + argp_standalone + GIT_REPOSITORY https://github.com/tom42/argp-standalone.git + GIT_TAG 238d83d6fb4fbdbb3e0893f51698d8d54696bfb0 + # Optionally specify where to download the content + # SOURCE_DIR "${CMAKE_BINARY_DIR}/_deps/argp-src" + # BINARY_DIR "${CMAKE_BINARY_DIR}/_deps/argp-build" + ) + FetchContent_MakeAvailable(argp_standalone) + + # Assuming argp_standalone creates a target, you can link it directly. + # If not, you might still need to set up include directories or link libraries manually. +endif(HAVE_BUNDLED_ARGP_PARSE_FUNCTION) -# Build external dependancies if we are on OSX -IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - # Mac OS X specific code - set(EXTERNAL_MEMSTREAM "memstream") - set(EXTERNAL_ARGP "argp") - add_definitions(-DDARWIN) -ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") if(DEBUG) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g -DDEBUG") @@ -101,7 +148,7 @@ add_library(Visio2Svg ${SHARED} src/lib/visio2svg/Visio2Svg.cpp ) - +#add_dependencies(Visio2Svg ${FMEM_NAME}) set_target_properties(Visio2Svg PROPERTIES VERSION ${vss2svg_VERSION} @@ -129,6 +176,7 @@ target_link_libraries(Visio2Svg ${LIBXML2_LIBRARIES} TitleGenerator ${EXTERNAL_ARGP} + fmem ) target_link_libraries(vss2svg-conv diff --git a/README.md b/README.md index 33ce21a..85c5890 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,9 @@ $ vsd2svg-conv -i ./my.VSD -o ./out/ -s 7 $ ls out/ Page-1.svg Page-2.svg Page-3.svg Page-4.svg +# output to screen +$ vsd2svg-conv -i ./my.VSD + # help $ vsd2svg-conv --help ``` diff --git a/src/conv/vsd2svg.cpp b/src/conv/vsd2svg.cpp index 8eb0099..f83c664 100644 --- a/src/conv/vsd2svg.cpp +++ b/src/conv/vsd2svg.cpp @@ -40,13 +40,13 @@ static char doc[] = "vsd2svg -- Visio VSD to SVG converter"; static struct argp_option options[] = { {"input", 'i', "FILE", 0, "Input Visio .vsd file"}, - {"output", 'o', "DIR", 0, "Output directory"}, + {"output", 'o', "DIR", 0, "Write SVGs to output directory"}, {"scaling", 's', "FLOAT", 0, "Scaling factor"}, {"version", 'V', 0, 0, "Print vsd2svg version"}, {0}}; /* A description of the arguments we accept. */ -static char args_doc[] = "[options] -i -o "; +static char args_doc[] = "[options] -i "; struct arguments { char *args[2]; /* arg1 & arg2 */ @@ -120,11 +120,15 @@ int main(int argc, char *argv[]) { << "Missing --input=FILE argument\n"; return 1; } - - if (arguments.output == NULL) { - std::cerr << "[ERROR] " - << "Missing --output=DIR argument\n"; - return 1; + std::string outputdir(""); + if (arguments.output != NULL) { + std::string outputdir(arguments.output); + #ifdef _WIN32 + mkdir(arguments.output); +#else + mkdir(arguments.output, S_IRWXU); +#endif + } std::ifstream stin(arguments.input); @@ -143,27 +147,30 @@ int main(int argc, char *argv[]) { ret = converter.vsd2svg(in, out, scaling); - std::string outputdir(arguments.output); - mkdir(arguments.output, S_IRWXU); - for (const auto &rule_pair : out) { ofstream myfile; #ifdef SAFE_FILENAME std::regex e("[^A-Za-z0-9-]"); std::basic_string newfilename = - outputdir + "/" + std::regex_replace(rule_pair.first, e, "_") + - ".svg"; + outputdir + (arguments.output != NULL ? "/" : "") + std::regex_replace(rule_pair.first, e, "_") + ".svg"; #else std::basic_string newfilename = outputdir + rule_pair.first + ".svg"; #endif - myfile.open(newfilename); - myfile << rule_pair.second << std::endl; - myfile.close(); - if (!myfile) { - std::cerr << "[ERROR] " - << "Failed to write file '" << rule_pair.first << "'\n"; - ret = 1; + if (arguments.output != NULL) { + myfile.open(newfilename); + myfile << rule_pair.second << std::endl; + myfile.close(); + if (!myfile) { + std::cerr << "[ERROR] " + << "Failed to write file '" << rule_pair.first << "'\n"; + ret = 1; + } + } + else + { + std::cout << rule_pair.second << std::endl; + std::cout << "\n######################################\n"; } } diff --git a/src/conv/vss2svg.cpp b/src/conv/vss2svg.cpp index 0f3eaf9..a8c67e9 100644 --- a/src/conv/vss2svg.cpp +++ b/src/conv/vss2svg.cpp @@ -144,7 +144,11 @@ int main(int argc, char *argv[]) { ret = converter.vss2svg(in, out, scaling); std::string outputdir(arguments.output); + #ifdef _WIN32 + mkdir(arguments.output); +#else mkdir(arguments.output, S_IRWXU); +#endif for (const auto &rule_pair : out) { ofstream myfile; diff --git a/src/lib/visio2svg/Visio2Svg.cpp b/src/lib/visio2svg/Visio2Svg.cpp index 525ff08..2a380c2 100644 --- a/src/lib/visio2svg/Visio2Svg.cpp +++ b/src/lib/visio2svg/Visio2Svg.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef DARWIN #include "memstream.c" @@ -195,7 +196,17 @@ int wmf2svg_draw(char *content, size_t size, float wmf_width, float wmf_height, unsigned long flags; FILE *out_f; - out_f = open_memstream(out, out_length); + fmem fmem_stream; + + // Initialize the fmem structure + fmem_init(&fmem_stream); + + // Open a memory-backed file stream + out_f = fmem_open(&fmem_stream, "w"); + if (out_f == NULL) { + fmem_term(&fmem_stream); + return -1; // or handle the error appropriately + } ImageContext IC; @@ -275,8 +286,17 @@ int wmf2svg_draw(char *content, size_t size, float wmf_width, float wmf_height, err = wmf_play(API, 0, &d_r); status = explicit_wmf_error("play", err); } + void *buffer; + fmem_mem(&fmem_stream, &buffer, out_length); + + // Allocate memory for the output + *out = static_cast(malloc(*out_length)); + if (*out) { + memcpy(*out, buffer, *out_length); + } fclose(out_f); + fmem_term(&fmem_stream); wmf_api_destroy(API); #ifdef DEBUG