diff --git a/.gitignore b/.gitignore index ac8dc47..0df2891 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,5 @@ CMakeCache.txt cmake_install.cmake src/intern/.dirstamp .DS_Store +libs/MT/Release/dxfrw.lib +libs/MT/Release/libiconv.lib diff --git a/CMakeLists.txt b/CMakeLists.txt index 12d8d03..e9bb914 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,22 @@ cmake_minimum_required(VERSION 3.10 FATAL_ERROR) project(libdxfrw VERSION 0.6.3) +set(WIN_RUNTIME "MT" CACHE STRING "Windows runtime") +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) +endif() + +if(WIN32) + message(STATUS "Configuring with runtime ${WIN_RUNTIME}") + if(WIN_RUNTIME STREQUAL "MT") + set(CMAKE_CXX_FLAGS_RELEASE "-MT") + set(CMAKE_CXX_FLAGS_DEBUG "-MTd") + elseif(WIN_RUNTIME STREQUAL "MD") + set(CMAKE_CXX_FLAGS_RELEASE "-MD") + set(CMAKE_CXX_FLAGS_DEBUG "-MDd") + endif() +endif() + # Enable testing enable_testing() @@ -10,8 +26,10 @@ file(GLOB libdxfrw_intern_sources src/intern/*.cpp) # Find iconv library if(WIN32) - include_directories(vs2013/packages/libiconv.1.14.0.11/build/native/include) - link_directories(vs2013/packages/libiconv.1.14.0.11/build/native/lib) + message(STATUS "CMAKE_SOURCE_DIR = ${CMAKE_SOURCE_DIR}") + include_directories( PRIVATE ${CMAKE_SOURCE_DIR}/include) + # include_directories(${CMAKE_SOURCE_DIR}/../LightRightApp/core/template/iconv.h) + # link_directories(${CMAKE_SOURCE_DIR}/packages/libiconv.1.14.0.11/build/native/lib) set(ICONV_LIBRARY iconv) else() # On Unix-like systems (Linux, macOS) @@ -28,7 +46,10 @@ endif() include_directories(include) add_library(dxfrw STATIC ${libdxfrw_sources} ${libdxfrw_intern_sources}) -target_link_libraries(dxfrw ${ICONV_LIBRARY}) +target_compile_definitions(dxfrw PUBLIC LIBICONV_PLUG) +if(NOT WIN32) + target_link_libraries(dxfrw PUBLIC ${ICONV_LIBRARY}) +endif() install(FILES ${libdxfrw_headers} DESTINATION include) @@ -47,68 +68,70 @@ else() ARCHIVE DESTINATION lib) endif() -# Tests +# Tests (not built on Windows: iconv is provided by the consuming project) +if(NOT WIN32) add_executable(test_basic tests/test_basic.cpp) target_include_directories(test_basic PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests) -target_link_libraries(test_basic dxfrw ${ICONV_LIBRARY}) +target_link_libraries(test_basic dxfrw) add_test(NAME BasicTests COMMAND test_basic) add_executable(test_entities tests/test_entities.cpp) target_include_directories(test_entities PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests) -target_link_libraries(test_entities dxfrw ${ICONV_LIBRARY}) +target_link_libraries(test_entities dxfrw) add_test(NAME EntityTests COMMAND test_entities) add_executable(test_polylines tests/test_polylines.cpp) target_include_directories(test_polylines PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests) -target_link_libraries(test_polylines dxfrw ${ICONV_LIBRARY}) +target_link_libraries(test_polylines dxfrw) add_test(NAME PolylineTests COMMAND test_polylines) add_executable(test_text tests/test_text.cpp) target_include_directories(test_text PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests) -target_link_libraries(test_text dxfrw ${ICONV_LIBRARY}) +target_link_libraries(test_text dxfrw) add_test(NAME TextTests COMMAND test_text) add_executable(test_tables tests/test_tables.cpp) target_include_directories(test_tables PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests) -target_link_libraries(test_tables dxfrw ${ICONV_LIBRARY}) +target_link_libraries(test_tables dxfrw) add_test(NAME TableTests COMMAND test_tables) add_executable(test_blocks tests/test_blocks.cpp) target_include_directories(test_blocks PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests) -target_link_libraries(test_blocks dxfrw ${ICONV_LIBRARY}) +target_link_libraries(test_blocks dxfrw) add_test(NAME BlockTests COMMAND test_blocks) add_executable(test_versions tests/test_versions.cpp) target_include_directories(test_versions PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests) -target_link_libraries(test_versions dxfrw ${ICONV_LIBRARY}) +target_link_libraries(test_versions dxfrw) add_test(NAME VersionTests COMMAND test_versions) add_executable(test_errors tests/test_errors.cpp) target_include_directories(test_errors PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests) -target_link_libraries(test_errors dxfrw ${ICONV_LIBRARY}) +target_link_libraries(test_errors dxfrw) add_test(NAME ErrorTests COMMAND test_errors) add_executable(test_dimensions tests/test_dimensions.cpp) target_include_directories(test_dimensions PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests) -target_link_libraries(test_dimensions dxfrw ${ICONV_LIBRARY}) +target_link_libraries(test_dimensions dxfrw) add_test(NAME DimensionTests COMMAND test_dimensions) add_executable(test_annotations tests/test_annotations.cpp) target_include_directories(test_annotations PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests) -target_link_libraries(test_annotations dxfrw ${ICONV_LIBRARY}) +target_link_libraries(test_annotations dxfrw) add_test(NAME AnnotationTests COMMAND test_annotations) add_executable(test_attributes tests/test_attributes.cpp) target_include_directories(test_attributes PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests) -target_link_libraries(test_attributes dxfrw ${ICONV_LIBRARY}) +target_link_libraries(test_attributes dxfrw) add_test(NAME AttributeTests COMMAND test_attributes) add_executable(test_class_underflow tests/test_class_underflow.cpp) target_include_directories(test_class_underflow PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests) -target_link_libraries(test_class_underflow dxfrw ${ICONV_LIBRARY}) +target_link_libraries(test_class_underflow dxfrw) add_test(NAME ClassUnderflowTests COMMAND test_class_underflow) add_executable(test_dwg_classes tests/test_dwg_classes.cpp) target_include_directories(test_dwg_classes PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests) -target_link_libraries(test_dwg_classes dxfrw ${ICONV_LIBRARY}) +target_link_libraries(test_dwg_classes dxfrw) add_test(NAME DWGClassParsingTests COMMAND test_dwg_classes) +endif() diff --git a/include/iconv.h b/include/iconv.h new file mode 100644 index 0000000..87b43b6 --- /dev/null +++ b/include/iconv.h @@ -0,0 +1,131 @@ +/* Copyright (C) 1999-2003 Free Software Foundation, Inc. + This file is part of the GNU LIBICONV Library. + + The GNU LIBICONV Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + The GNU LIBICONV Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU LIBICONV Library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, Inc., 59 Temple Place - + Suite 330, Boston, MA 02111-1307, USA. */ + +/* When installed, this file is called "iconv.h". */ + +#ifndef _LIBICONV_H +#define _LIBICONV_H + +#define _LIBICONV_VERSION 0x0109 /* version number: (major<<8) + minor */ +extern int _libiconv_version; /* Likewise */ + +/* We would like to #include any system header file which could define + iconv_t, 1. in order to eliminate the risk that the user gets compilation + errors because some other system header file includes /usr/include/iconv.h + which defines iconv_t or declares iconv after this file, 2. when compiling + for LIBICONV_PLUG, we need the proper iconv_t type in order to produce + binary compatible code. + But gcc's #include_next is not portable. Thus, once libiconv's iconv.h + has been installed in /usr/local/include, there is no way any more to + include the original /usr/include/iconv.h. We simply have to get away + without it. + Ad 1. The risk that a system header file does + #include "iconv.h" or #include_next "iconv.h" + is small. They all do #include . + Ad 2. The iconv_t type is a pointer type in all cases I have seen. (It + has to be a scalar type because (iconv_t)(-1) is a possible return value + from iconv_open().) */ + +/* Define iconv_t ourselves. */ +#undef iconv_t +#define iconv_t libiconv_t +typedef void* iconv_t; + +/* Get size_t declaration. */ +#include + +/* Get errno declaration and values. */ +#include +/* Some systems, like SunOS 4, don't have EILSEQ. Some systems, like BSD/OS, + have EILSEQ in a different header. On these systems, define EILSEQ + ourselves. */ +#ifndef EILSEQ +#define EILSEQ @EILSEQ@ +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Allocates descriptor for code conversion from encoding `fromcode' to + encoding `tocode'. */ +#ifndef LIBICONV_PLUG +#define iconv_open libiconv_open +#endif +extern iconv_t iconv_open (const char* tocode, const char* fromcode); + +/* Converts, using conversion descriptor `cd', at most `*inbytesleft' bytes + starting at `*inbuf', writing at most `*outbytesleft' bytes starting at + `*outbuf'. + Decrements `*inbytesleft' and increments `*inbuf' by the same amount. + Decrements `*outbytesleft' and increments `*outbuf' by the same amount. */ +#ifndef LIBICONV_PLUG +#define iconv libiconv +#endif +extern size_t iconv (iconv_t cd, const char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft); + +/* Frees resources allocated for conversion descriptor `cd'. */ +#ifndef LIBICONV_PLUG +#define iconv_close libiconv_close +#endif +extern int iconv_close (iconv_t cd); + + +#ifndef LIBICONV_PLUG + +/* Nonstandard extensions. */ + +/* Control of attributes. */ +#define iconvctl libiconvctl +extern int iconvctl (iconv_t cd, int request, void* argument); + +/* Requests for iconvctl. */ +#define ICONV_TRIVIALP 0 /* int *argument */ +#define ICONV_GET_TRANSLITERATE 1 /* int *argument */ +#define ICONV_SET_TRANSLITERATE 2 /* const int *argument */ +#define ICONV_GET_DISCARD_ILSEQ 3 /* int *argument */ +#define ICONV_SET_DISCARD_ILSEQ 4 /* const int *argument */ + +/* Listing of locale independent encodings. */ +#define iconvlist libiconvlist +extern void iconvlist (int (*do_one) (unsigned int namescount, + const char * const * names, + void* data), + void* data); + +/* Support for relocatable packages. */ + +/* Sets the original and the current installation prefix of the package. + Relocation simply replaces a pathname starting with the original prefix + by the corresponding pathname with the current prefix instead. Both + prefixes should be directory names without trailing slash (i.e. use "" + instead of "/"). */ +extern void libiconv_set_relocation_prefix (const char *orig_prefix, + const char *curr_prefix); + +#endif + + +#ifdef __cplusplus +} +#endif + + +#endif /* _LIBICONV_H */ diff --git a/lib/libiconv.lib b/lib/libiconv.lib new file mode 100644 index 0000000..47265ca Binary files /dev/null and b/lib/libiconv.lib differ diff --git a/src/intern/drw_textcodec.cpp b/src/intern/drw_textcodec.cpp index c9d9180..a4f0f79 100644 --- a/src/intern/drw_textcodec.cpp +++ b/src/intern/drw_textcodec.cpp @@ -477,14 +477,18 @@ std::string DRW_ExtConverter::convertByiconv(const char *in_encode, const int BUF_SIZE = 1000; static char in_buf[BUF_SIZE], out_buf[BUF_SIZE]; - char *in_ptr = in_buf; + const char *in_ptr = in_buf; char *out_ptr = out_buf; strncpy(in_buf, s->c_str(), BUF_SIZE); iconv_t ic; ic = iconv_open(out_encode, in_encode); + if (ic == iconv_t(-1)) + { + return std::string(in_ptr); + } size_t il = BUF_SIZE-1, ol = BUF_SIZE-1; - iconv(ic , (char**)&in_ptr, &il, &out_ptr, &ol); + iconv(ic, &in_ptr, &il, &out_ptr, &ol); iconv_close(ic); return std::string(out_buf);