diff --git a/.editorconfig b/.editorconfig index 18a103b..7cf2d65 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,7 +6,7 @@ insert_final_newline = true charset = utf-8 indent_style = space -[*.{c,h,txt}] +[*.{c,h,txt,cmake}] indent_size = 4 [configure.ac] diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index c4fc96e..8c48e0e 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -46,57 +46,50 @@ jobs: if_true: '--enable-static' if_false: '--disable-static' - - name: Install dependencies + # cmake pulls ninja by default + - name: Install dependencies (MSYS) if: matrix.os == 'windows-2022' uses: msys2/setup-msys2@v2 with: msystem: ${{ matrix.msystem }} update: true install: >- - markdown - groff + git pacboy: >- - autotools:p - gcc:p - libxml2:p - iconv:p + toolchain:p glib2:p - 7zip:p + cmake:p - - name: Install dependencies + - name: Install dependencies (Ubuntu) if: matrix.os == 'ubuntu-22.04' run: > sudo apt-get install -y build-essential - automake + cmake + ninja-build libglib2.0-dev libxml2-utils - - name: Install dependencies + - name: Install dependencies (MacOS) if: matrix.os == 'macos-12' run: | - brew install automake + brew install cmake ninja - # env only useful for MSYS2 - name: Pre-build - env: - WANT_AUTOCONF: latest - WANT_AUTOMAKE: latest - run: >- - autoreconf -f -i -v - && ./configure ${{ steps.static_flag.outputs.value }} + run: | + mkdir build + cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=Release - name: Build - run: make all - - - name: Test suite - run: make check - - - name: Source dist check - if: matrix.os == 'ubuntu-22.04' - run: make distcheck + run: | + cmake --build build -v - - name: Windows binary dist check - if: matrix.os == 'windows-2022' - run: make -f dist-win.mk dist-win + - name: Test prefixed install + run: | + cmake --install build --prefix inst --strip -v + - name: CTest + env: + MSYS2_PATH_TYPE: inherit + run: | + cd build && ctest --output-on-failure -V diff --git a/.github/workflows/cmake_check.yml b/.github/workflows/cmake_check.yml new file mode 100644 index 0000000..96a8132 --- /dev/null +++ b/.github/workflows/cmake_check.yml @@ -0,0 +1,53 @@ +name: CMake compatibility check + +on: + workflow_dispatch: + +jobs: + check: + strategy: + fail-fast: false + matrix: + cmake_ver: + - 3.27.7 + - 3.26.5 + - 3.25.3 + - 3.24.4 + - 3.23.5 + - 3.22.6 + - 3.21.7 + - 3.20.6 + - 3.19.8 + - 3.18.6 + - 3.17.5 + - 3.16.9 + - 3.15.7 + - 3.14.7 + - 3.13.5 + - 3.12.4 + - 3.11.4 + - 3.10.3 + - 3.9.6 + - 3.8.2 + - 3.7.2 + - 3.6.3 + - 3.5.2 + - 3.4.3 + - 3.3.2 + - 3.2.3 + - 3.1.3 + - 3.0.2 + runs-on: macos-12 + steps: + - uses: actions/checkout@v4 + + - uses: lukka/get-cmake@latest + with: + cmakeVersion: ${{ matrix.cmake_ver }} + ninjaVersion: latest + + - name: Check cmake invocation + run: | + mkdir build + cmake -S . -B build -G Ninja + diff --git a/.gitignore b/.gitignore index 749a615..0fea4b6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,48 +1,12 @@ **/*.exe **/*.o -**/.deps **/Makefile -**/Makefile.in -/.dirstamp + +# IDE or editor files /.vscode -/ABOUT-NLS -/aclocal.m4 -/autom4te.cache -/compile -/config.cache -/config.guess -/config.h -/config.h.in -/config.log -/config.rpath -/config.status -/config.sub -/configure -/depcomp -/install-sh -/m4 -/missing -/mkinstalldirs -/po/*.gmo -/po/*.header -/po/*.mo -/po/*.pot -/po/*.sed -/po/insert-header.sin -/po/Makefile.in.in -/po/Makevars.template -/po/POTFILES -/po/remove-potcdate.sin -/po/Rules-quot -/po/stamp-it -/po/stamp-po -/src/rifiuti -/src/rifiuti-vista -/stamp-h1 -/test/atconfig -/test/atlocal -/test/package.m4 -/test/testsuite -/test/testsuite.dir -/test/testsuite.log -/test/test_glib_iconv +/.idea +**/*.bak +**/*~ + +# CMake +/build* diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..918e80c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,87 @@ +cmake_minimum_required(VERSION 3.17 FATAL_ERROR) # cmake -E rm + +project(rifiuti2 + VERSION 0.7.0 + HOMEPAGE_URL https://github.com/abelcheung/rifiuti2/ + LANGUAGES C) + +if(NOT WIN32) + include(GNUInstallDirs) +endif() + +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) + +set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb -Wall") +set(CMAKE_STATIC_LINKER_FLAGS "-static") +configure_file(config.h.in config.h) + +find_package(PkgConfig REQUIRED) +pkg_check_modules(GLIB REQUIRED "glib-2.0 >= 2.40.0") + +# Do static build in Windows, which require finding +# extra libraries +if (WIN32) +pkg_check_modules(ICONV REQUIRED "iconv") +list(APPEND GLIB_STATIC_CFLAGS_OTHER -DGLIB_STATIC_COMPILATION) +endif() + +foreach(bin rifiuti rifiuti-vista) + add_executable( + ${bin} + src/${bin}.c + src/${bin}.h + ) + target_include_directories( + ${bin} BEFORE + PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} + ) + target_sources( + ${bin} + PRIVATE + src/utils.c + src/utils.h + ) + if(WIN32) + target_sources(${bin} PRIVATE src/utils-win.c src/utils-win.h) + target_include_directories(${bin} PRIVATE + ${GLIB_STATIC_INCLUDE_DIRS} ${ICONV_STATIC_INCLUDE_DIRS}) + target_compile_options (${bin} PRIVATE + ${GLIB_STATIC_CFLAGS_OTHER} ${ICONV_STATIC_CFLAGS_OTHER}) + target_link_libraries (${bin} PRIVATE authz + ${GLIB_STATIC_LIBRARIES} ${ICONV_STATIC_LIBRARIES}) + target_link_directories (${bin} PRIVATE + ${GLIB_STATIC_LIBRARY_DIRS} ${ICONV_STATIC_LIBRARY_DIRS}) + target_link_options (${bin} BEFORE PRIVATE ${CMAKE_STATIC_LINKER_FLAGS}) + else() + target_include_directories(${bin} PRIVATE ${GLIB_INCLUDE_DIRS}) + target_compile_options (${bin} PRIVATE ${GLIB_CFLAGS_OTHER}) + target_link_libraries (${bin} PRIVATE ${GLIB_LIBRARIES}) + target_link_directories (${bin} PRIVATE ${GLIB_LIBRARY_DIRS}) + endif() +endforeach() + +install( + TARGETS + rifiuti + rifiuti-vista + RUNTIME +) +if(NOT WIN32) + install( + FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/rifiuti.1 + DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 + ) +endif() +install( + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE + ${CMAKE_CURRENT_SOURCE_DIR}/NEWS.md + ${CMAKE_CURRENT_SOURCE_DIR}/README.md + ${CMAKE_CURRENT_SOURCE_DIR}/docs/THANKS.txt + TYPE DOC +) + +include(CTest) +add_subdirectory(test) diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..0a576bf --- /dev/null +++ b/config.h.in @@ -0,0 +1,5 @@ +#cmakedefine PROJECT_NAME "@PROJECT_NAME@" +#cmakedefine PROJECT_VERSION "@PROJECT_VERSION@" +#cmakedefine PROJECT_HOMEPAGE_URL "@PROJECT_HOMEPAGE_URL@" + +#define G_LOG_DOMAIN PROJECT_NAME diff --git a/src/utils.c b/src/utils.c index 1542cba..3d9c728 100644 --- a/src/utils.c +++ b/src/utils.c @@ -9,9 +9,7 @@ #include #include #include -#if HAVE_SETLOCALE #include -#endif #include "utils.h" #include #include @@ -749,7 +747,7 @@ rifiuti_setup_opt_ctx (GOptionContext **context, bug_report_str = g_strdup_printf ( /* TRANSLATOR COMMENT: argument is bug report webpage */ - _("Report bugs to %s"), PACKAGE_BUGREPORT); + _("Report bugs to %s"), PROJECT_HOMEPAGE_URL); g_option_context_set_description (*context, bug_report_str); g_free (bug_report_str); @@ -1393,13 +1391,13 @@ move_temp_file (void) void print_version_and_exit (void) { - fprintf (stdout, "%s %s\n", PACKAGE, VERSION); + fprintf (stdout, "%s %s\n", PROJECT_NAME, PROJECT_VERSION); /* TRANSLATOR COMMENT: %s is software name */ fprintf (stdout, _("%s is distributed under the " - "BSD 3-Clause License.\n"), PACKAGE); + "BSD 3-Clause License.\n"), PROJECT_NAME); /* TRANSLATOR COMMENT: 1st argument is software name, 2nd is official URL */ fprintf (stdout, _("Information about %s can be found on\n\n\t%s\n"), - PACKAGE, PACKAGE_URL); + PROJECT_NAME, PROJECT_HOMEPAGE_URL); exit (R2_OK); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..68ccabe --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,77 @@ +set( + CMAKE_MODULE_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/cmake +) + +file( + CREATE_LINK + ${CMAKE_CURRENT_SOURCE_DIR}/samples + ${CMAKE_CURRENT_BINARY_DIR}/samples + SYMBOLIC +) + +function(add_test_using_shell name command) + if(WIN32) + add_test( + NAME ${name} + COMMAND pwsh -NonInteractive -NoProfile -Command "${command}" + ${ARGN}) + else() + add_test( + NAME ${name} + COMMAND sh -c "${command}" + ${ARGN}) + endif() +endfunction() + +macro(set_label is_info2) + set(label ${ARGN}) + if(is_info2) + list(APPEND label "info2") + else() + list(APPEND label "recycledir") + endif() +endmacro() + +macro(set_test_vars id is_info2 has_output has_fixture) + if(is_info2) + set(prefix f_${id}) + else() + set(prefix d_${id}) + endif() + set(sample_dir ${CMAKE_CURRENT_SOURCE_DIR}/samples) + if(${has_output}) + set(out ${CMAKE_CURRENT_BINARY_DIR}/${prefix}.txt) + endif() + if(${has_fixture}) + set(fixture $) + endif() +endmacro() + +# +# For some systems, glib may or may not be using system iconv +# (e.g. Solaris and FreeBSD), therefore simply finding out +# supported encoding from iconv program is not enough. +# +# In general, there is no cross platform way of specifying +# encoding names. To rub salt into wounds, even glib itself +# appears to append different encoding aliases on different +# OSes... (such as using win_iconv on Windows) +# Have to resort to checking runtime behavior instead. +# +add_executable(test_glib_iconv test_glib_iconv.c) +target_include_directories(test_glib_iconv PRIVATE ${GLIB_INCLUDE_DIRS}) +target_compile_options (test_glib_iconv PRIVATE ${GLIB_CFLAGS_OTHER}) +target_link_libraries (test_glib_iconv PRIVATE ${GLIB_LIBRARIES}) +target_link_directories (test_glib_iconv PRIVATE ${GLIB_LIBRARY_DIRS}) + +# +# The real tests +# +include(cli-option) +include(crafted) +include(encoding) +include(parse-info2) +include(parse-rdir) +include(read-write) +include(xml) diff --git a/test/cmake/_try_encoding.cmake b/test/cmake/_try_encoding.cmake new file mode 100644 index 0000000..6e6ac59 --- /dev/null +++ b/test/cmake/_try_encoding.cmake @@ -0,0 +1,37 @@ +# +# Execute encoding tests as external cmake script +# +# 1. $CMAKE_CURRENT_BINARY_DIR etc in cmake script aren't +# stable; they would change into wherever WORKING_DIRECTORY +# is set, so program paths must be supplied externally. +# 2. CHOICES (encoding list) is supplied as '|' separated +# list, in order to not collide with semicolon handling +# in cmake. +# + +string(REPLACE "|" ";" CHOICES "${CHOICES}") +list(LENGTH CHOICES len) + +if(len EQUAL 1) + set(encoding ${CHOICES}) +else() + execute_process( + COMMAND ${TEST_GLIB_ICONV} ${CHOICES} + RESULT_VARIABLE status + OUTPUT_VARIABLE encoding + # COMMAND_ECHO STDOUT + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT status EQUAL 0) + message(FATAL_ERROR "No suitable encoding found in glib") + endif() +endif() + +set(args -l ${encoding} ${INFO2}) +if(DEFINED OUTFILE) + list(APPEND args -o ${OUTFILE}) +endif() +execute_process( + COMMAND ${RIFIUTI} ${args} + # COMMAND_ECHO STDOUT + ERROR_VARIABLE err_result + ECHO_ERROR_VARIABLE) diff --git a/test/cmake/cli-option.cmake b/test/cmake/cli-option.cmake new file mode 100644 index 0000000..0b69cbc --- /dev/null +++ b/test/cmake/cli-option.cmake @@ -0,0 +1,220 @@ +function(addBareOptTest name) + add_test(NAME d_InvokeOpt${name} COMMAND rifiuti-vista ${ARGV1}) + add_test(NAME f_InvokeOpt${name} COMMAND rifiuti ${ARGV1}) + set_tests_properties(d_InvokeOpt${name} PROPERTIES LABELS "recycledir;arg") + set_tests_properties(f_InvokeOpt${name} PROPERTIES LABELS "info2;arg") + if(NOT DEFINED ARGV1 AND WIN32) + set_tests_properties(d_InvokeOpt${name} PROPERTIES DISABLED True) + set_tests_properties(f_InvokeOpt${name} PROPERTIES DISABLED True) + endif() +endfunction() + +addBareOptTest(None ) +addBareOptTest(ShortHelp1 -h ) +addBareOptTest(ShortHelp2 -? ) +addBareOptTest(ShortVer -v ) +addBareOptTest(LongHelp --help-all ) +addBareOptTest(LongVer --version ) +# if(WIN32) +# addBareOptTest(Live --live ) +# endif() + +function(addWithFileOptTest name) + add_test(NAME d_WithFileOpt${name} COMMAND rifiuti-vista ${ARGN} samples/dir-sample1) + add_test(NAME f_WithFileOpt${name} COMMAND rifiuti ${ARGN} samples/INFO2-sample1) + set_tests_properties(d_WithFileOpt${name} PROPERTIES LABELS "recycledir;arg") + set_tests_properties(f_WithFileOpt${name} PROPERTIES LABELS "info2;arg") +endfunction() + +addWithFileOptTest(LongHead --no-heading ) +addWithFileOptTest(LongSep --delimiter=: ) +addWithFileOptTest(LongTime --localtime ) +addWithFileOptTest(LongXml --xml ) +addWithFileOptTest(ShortHead -n ) +addWithFileOptTest(ShortSep -t : ) +addWithFileOptTest(ShortTime -z ) +addWithFileOptTest(ShortXml -x ) + + +function(addBadBareOptTest name) + add_test(NAME d_BadBareOpt${name} COMMAND rifiuti-vista ${ARGN}) + add_test(NAME f_BadBareOpt${name} COMMAND rifiuti ${ARGN}) + set_tests_properties(d_BadBareOpt${name} + PROPERTIES + LABELS "recycledir;arg" + PASS_REGULAR_EXPRESSION "Unknown option") + set_tests_properties(f_BadBareOpt${name} + PROPERTIES + LABELS "info2;arg" + PASS_REGULAR_EXPRESSION "Unknown option") +endfunction() + +addBadBareOptTest(Short -/) +addBadBareOptTest(Long --invalid) + + +function(addDupOptTest name) + add_test(NAME d_DupOpt${name} COMMAND + rifiuti-vista ${ARGN} samples/dir-sample1) + add_test(NAME f_DupOpt${name} COMMAND + rifiuti ${ARGN} samples/INFO2-sample1) + set_tests_properties(d_DupOpt${name} + PROPERTIES + LABELS "recycledir;arg" + PASS_REGULAR_EXPRESSION "Multiple .+ disallowed") + set_tests_properties(f_DupOpt${name} + PROPERTIES + LABELS "info2;arg" + PASS_REGULAR_EXPRESSION "Multiple .+ disallowed") +endfunction() + +addDupOptTest(ShortSep -t ":" -t "," ) +addDupOptTest(LongSep --delimiter=: --delimiter=/ ) +addDupOptTest(MixSep --delimiter=: -t / ) +addDupOptTest(ShortOut -o file1 -o file2 ) +addDupOptTest(LongOut --output=file1 --output=file2 ) +addDupOptTest(MixOut --output=file1 -o file2 ) + + +add_test(NAME f_DupOptShortEnc COMMAND + rifiuti -l ASCII -l CP1252 samples/INFO2-sample2) +add_test(NAME f_DupOptLongEnc COMMAND + rifiuti --legacy-filename=ASCII --legacy-filename=CP1252 samples/INFO2-sample2) +add_test(NAME f_DupOptMixEnc COMMAND + rifiuti -l ASCII --legacy-filename=CP1252 samples/INFO2-sample2) +set_tests_properties( + f_DupOptShortEnc + f_DupOptLongEnc + f_DupOptMixEnc + PROPERTIES + LABELS "info2;arg" + PASS_REGULAR_EXPRESSION "Multiple .+ disallowed") + + +add_test(NAME d_NullArgOptTestOut COMMAND rifiuti-vista -o "" samples/dir-sample1) +add_test(NAME f_NullArgOptTestOut COMMAND rifiuti -o "" samples/INFO2-sample1) +add_test(NAME f_NullArgOptTestEnc COMMAND rifiuti -l "" samples/INFO2-sample1) +set_tests_properties( + d_NullArgOptTestOut + PROPERTIES + LABELS "recycledir;arg" + PASS_REGULAR_EXPRESSION "Empty .+ disallowed") +set_tests_properties( + f_NullArgOptTestOut + f_NullArgOptTestEnc + PROPERTIES + LABELS "info2;arg" + PASS_REGULAR_EXPRESSION "Empty .+ disallowed") + + +function(addBadComboOptTest name) + add_test(NAME d_BadComboOptTest${name} COMMAND + rifiuti-vista ${ARGN} samples/dir-sample1) + add_test(NAME f_BadComboOptTest${name} COMMAND + rifiuti ${ARGN} samples/INFO2-sample1) + set_tests_properties( + d_BadComboOptTest${name} + PROPERTIES + LABELS "recycledir;arg" + PASS_REGULAR_EXPRESSION "can not be used in XML mode") + set_tests_properties( + f_BadComboOptTest${name} + PROPERTIES + LABELS "info2;arg" + PASS_REGULAR_EXPRESSION "can not be used in XML mode") +endfunction() + +addBadComboOptTest(1 -x -t:) +addBadComboOptTest(2 -n -x) + + +function(addMultiInputTest name) + add_test(NAME d_MultiInputTest${name} COMMAND rifiuti-vista ${ARGN}) + add_test(NAME f_MultiInputTest${name} COMMAND rifiuti ${ARGN}) + set_tests_properties( + d_MultiInputTest${name} + PROPERTIES + LABELS "recycledir;arg" + PASS_REGULAR_EXPRESSION "Must specify exactly one") + set_tests_properties( + f_MultiInputTest${name} + PROPERTIES + LABELS "info2;arg" + PASS_REGULAR_EXPRESSION "Must specify exactly one") +endfunction() + +addMultiInputTest(1 a a) +addMultiInputTest(2 foo bar baz) + + +function(addMissingInputTest name) + add_test(NAME d_MissingInputTest${name} COMMAND rifiuti-vista ${ARGN}) + add_test(NAME f_MissingInputTest${name} COMMAND rifiuti ${ARGN}) + set_tests_properties( + d_MissingInputTest${name} + PROPERTIES + LABELS "recycledir;arg" + PASS_REGULAR_EXPRESSION "Must specify exactly one") + set_tests_properties( + f_MissingInputTest${name} + PROPERTIES + LABELS "info2;arg" + PASS_REGULAR_EXPRESSION "Must specify exactly one") +endfunction() + +addMissingInputTest(1 -x) +addMissingInputTest(2 -t :) +addMissingInputTest(3 -z -o file1 -n) + + +function(SepCompareTest testid is_info2 sep) + set_label(is_info2 "arg") + set_test_vars(${testid} is_info2 1 1) + set(out ${CMAKE_CURRENT_BINARY_DIR}/${prefix}_o.txt) + set(ref ${CMAKE_CURRENT_BINARY_DIR}/${prefix}_r.txt) + if(is_info2) + set(prog rifiuti) + set(input INFO2-sample1) + else() + set(prog rifiuti-vista) + set(input dir-sample1) + endif() + add_test( + NAME ${prefix}_Prep1 + COMMAND ${prog} -t "${sep}" ${input} -o ${out} + WORKING_DIRECTORY ${sample_dir} + ) + if(WIN32) + string(REPLACE \\ ` sep ${sep}) + add_test_using_shell(${prefix}_Prep2 + "(Get-Content ${input}.txt).Replace(\"`t\", \"${sep}\") | Set-Content ${ref}" + WORKING_DIRECTORY ${sample_dir}) + else() + add_test_using_shell(${prefix}_Prep2 + "awk '{gsub(\"\\t\",\"${sep}\");print;}' ${input}.txt > ${ref}" + WORKING_DIRECTORY ${sample_dir}) + endif() + add_test( + NAME ${prefix} + COMMAND ${CMAKE_COMMAND} -E compare_files --ignore-eol ${out} ${ref} + ) + add_test( + NAME ${prefix}_Clean + COMMAND ${CMAKE_COMMAND} -E rm ${out} ${ref} + ) + + set_tests_properties(${prefix}_Prep1 PROPERTIES FIXTURES_SETUP ${fixture}) + set_tests_properties(${prefix}_Prep2 PROPERTIES FIXTURES_SETUP ${fixture}) + set_tests_properties(${prefix} PROPERTIES FIXTURES_REQUIRED ${fixture}) + set_tests_properties(${prefix}_Clean PROPERTIES FIXTURES_CLEANUP ${fixture}) + + set_tests_properties(${prefix} PROPERTIES LABELS "${label}") +endfunction() + +# "\\\\" converts to "\;" in cmake, can't do test on backslashes +set(nums 1 2 3 4) +set(seps "|" "xx" "\\n\\t" "%s") +foreach(item IN ZIP_LISTS nums seps) + SepCompareTest(SepCompare${item_0} 0 "${item_1}") + SepCompareTest(SepCompare${item_0} 1 "${item_1}") +endforeach() diff --git a/test/cmake/crafted.cmake b/test/cmake/crafted.cmake new file mode 100644 index 0000000..b1e34f9 --- /dev/null +++ b/test/cmake/crafted.cmake @@ -0,0 +1,100 @@ +# +# Mix different file versions into a single dir +# + +add_test( + NAME d_CraftedMixVer + COMMAND rifiuti-vista samples/dir-mixed +) + +set_tests_properties( + d_CraftedMixVer + PROPERTIES + LABELS "recycledir;crafted" + PASS_REGULAR_EXPRESSION "come from multiple versions") + +# +# Create dir with bad permission +# + +add_test( + NAME BadPermDirCopy + COMMAND ${CMAKE_COMMAND} -E copy_directory samples/dir-win10-01 dir-BadPerm +) + +if(WIN32) + add_test( + NAME BadPermDirPrepPerm + COMMAND icacls.exe dir-BadPerm /q /inheritance:r /grant:r "Users:(OI)(CI)(S,REA)" + ) + add_test( + NAME BadPermDirRestorePerm + COMMAND icacls.exe dir-BadPerm /q /reset + ) +else() + add_test( + NAME BadPermDirPrepPerm + COMMAND chmod u= dir-BadPerm + ) + add_test( + NAME BadPermDirRestorePerm + COMMAND chmod u=rwx dir-BadPerm + ) +endif() + +add_test( + NAME BadPermDirClean + COMMAND ${CMAKE_COMMAND} -E rm -r dir-BadPerm +) + +add_test( + NAME d_BadPermDir + COMMAND rifiuti-vista dir-BadPerm +) + +set_tests_properties( + d_BadPermDir + PROPERTIES + LABELS "recycledir;crafted" + PASS_REGULAR_EXPRESSION "Permission denied;disallowed under Windows ACL" +) + +set_tests_properties(BadPermDirCopy PROPERTIES FIXTURES_SETUP D_BADPERMDIR) +set_tests_properties(BadPermDirPrepPerm PROPERTIES FIXTURES_SETUP D_BADPERMDIR) +set_tests_properties(d_BadPermDir PROPERTIES FIXTURES_REQUIRED D_BADPERMDIR) +set_tests_properties(BadPermDirRestorePerm PROPERTIES FIXTURES_CLEANUP D_BADPERMDIR) +set_tests_properties(BadPermDirClean PROPERTIES FIXTURES_CLEANUP D_BADPERMDIR) + +set_tests_properties(BadPermDirPrepPerm PROPERTIES DEPENDS BadPermDirCopy) +set_tests_properties(BadPermDirClean PROPERTIES DEPENDS BadPermDirRestorePerm) + + +# +# Simulate bad UTF-16 path entries +# + +add_test(NAME d_BadUniEnc_Prep + COMMAND rifiuti-vista dir-bad-uni -o ${CMAKE_CURRENT_BINARY_DIR}/d_BadUniEnc.txt + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/samples +) + +add_test( + NAME d_BadUniEnc + COMMAND ${CMAKE_COMMAND} -E compare_files --ignore-eol d_BadUniEnc.txt samples/dir-bad-uni.txt +) + +add_test( + NAME d_BadUniEnc_Clean + COMMAND ${CMAKE_COMMAND} -E rm d_BadUniEnc.txt +) + +set_tests_properties(d_BadUniEnc_Prep PROPERTIES FIXTURES_SETUP D_BADUNIENC) +set_tests_properties(d_BadUniEnc PROPERTIES FIXTURES_REQUIRED D_BADUNIENC) +set_tests_properties(d_BadUniEnc_Clean PROPERTIES FIXTURES_CLEANUP D_BADUNIENC) + +set_tests_properties(d_BadUniEnc_Prep + PROPERTIES + PASS_REGULAR_EXPRESSION "displayed in escaped unicode sequences") +set_tests_properties(d_BadUniEnc + PROPERTIES + LABELS "recycledir;encoding;crafted") diff --git a/test/cmake/encoding.cmake b/test/cmake/encoding.cmake new file mode 100644 index 0000000..f146e2b --- /dev/null +++ b/test/cmake/encoding.cmake @@ -0,0 +1,192 @@ +function(add_encoding_test name) + set(args ${ARGN}) + list(PREPEND args -V) + list(APPEND args -DTEST_GLIB_ICONV=$) + list(APPEND args -DRIFIUTI=$) + list(APPEND args -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/_try_encoding.cmake) + add_test( + NAME ${name} + COMMAND ${CMAKE_COMMAND} ${args} + ) +endfunction() + + +function(add_encoding_test_with_cwd name cwd) + set(args ${ARGN}) + list(PREPEND args -V) + list(APPEND args -DTEST_GLIB_ICONV=$) + list(APPEND args -DRIFIUTI=$) + list(APPEND args -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/_try_encoding.cmake) + add_test( + NAME ${name} + COMMAND ${CMAKE_COMMAND} ${args} + WORKING_DIRECTORY ${cwd} + ) +endfunction() + + +# +# Encoding does not exist +# +add_encoding_test(f_EncNotExist -DCHOICES=xxx -DINFO2=dummy) +set_tests_properties( + f_EncNotExist + PROPERTIES + LABELS "encoding;info2" + PASS_REGULAR_EXPRESSION "'xxx' encoding is not supported" +) + + +# +# Legacy file (95-ME) requires encoding option +# +add_test( + NAME f_EncNeeded + COMMAND rifiuti INFO-95-ja-1 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/samples +) +set_tests_properties( + f_EncNeeded + PROPERTIES + LABELS "encoding;info2" + PASS_REGULAR_EXPRESSION "produced on a legacy system without Unicode" +) + + +# +# ASCII incompatible encoding +# +if(APPLE) + # iconv on Mac lacks many encodings + add_encoding_test(f_IncompatEnc -DCHOICES=UTF-32 -DINFO2=dummy) +else() + add_encoding_test(f_IncompatEnc -DCHOICES=IBM-037|IBM037|CP037 -DINFO2=dummy) +endif() +set_tests_properties( + f_IncompatEnc + PROPERTIES + LABELS "encoding;info2" + PASS_REGULAR_EXPRESSION "possibly be a code page or compatible encoding" +) + + +# +# Legacy path encoding - correct (case 1) +# + +add_encoding_test_with_cwd(f_LegacyEncOK1_Prep + ${CMAKE_CURRENT_SOURCE_DIR}/samples + -DINFO2=INFO2-sample1 + -DCHOICES=CP936|MS936|Windows-936|GBK|csGBK + -DOUTFILE=${CMAKE_CURRENT_BINARY_DIR}/f_LegacyEncOK1.txt +) + +add_test( + NAME f_LegacyEncOK1 + COMMAND ${CMAKE_COMMAND} -E compare_files --ignore-eol f_LegacyEncOK1.txt samples/INFO2-sample1-alt.txt +) + +add_test( + NAME f_LegacyEncOK1_Clean + COMMAND ${CMAKE_COMMAND} -E rm f_LegacyEncOK1.txt +) + +set_tests_properties(f_LegacyEncOK1_Prep PROPERTIES FIXTURES_SETUP F_LEGACYENCOK1) +set_tests_properties(f_LegacyEncOK1 PROPERTIES FIXTURES_REQUIRED F_LEGACYENCOK1) +set_tests_properties(f_LegacyEncOK1_Clean PROPERTIES FIXTURES_CLEANUP F_LEGACYENCOK1) + +set_tests_properties(f_LegacyEncOK1 PROPERTIES LABELS "info2;encoding") + + +# +# Legacy path encoding - correct (case 2) +# + +add_encoding_test_with_cwd(f_LegacyEncOK2_Prep + ${CMAKE_CURRENT_SOURCE_DIR}/samples + -DINFO2=INFO-95-ja-1 + -DCHOICES=CP932|Windows-932|IBM-943|SJIS|JIS_X0208|SHIFT_JIS|SHIFT-JIS + -DOUTFILE=${CMAKE_CURRENT_BINARY_DIR}/f_LegacyEncOK2.txt +) + +add_test( + NAME f_LegacyEncOK2 + COMMAND ${CMAKE_COMMAND} -E compare_files --ignore-eol f_LegacyEncOK2.txt samples/INFO-95-ja-1.txt +) + +add_test( + NAME f_LegacyEncOK2_Clean + COMMAND ${CMAKE_COMMAND} -E rm f_LegacyEncOK2.txt +) + +set_tests_properties(f_LegacyEncOK2_Prep PROPERTIES FIXTURES_SETUP F_LEGACYENCOK2) +set_tests_properties(f_LegacyEncOK2 PROPERTIES FIXTURES_REQUIRED F_LEGACYENCOK2) +set_tests_properties(f_LegacyEncOK2_Clean PROPERTIES FIXTURES_CLEANUP F_LEGACYENCOK2) + +set_tests_properties(f_LegacyEncOK2 PROPERTIES LABELS "info2;encoding") + + +# +# Legacy path encoding - wrong but still managed to get result +# +# Original file is in Windows ANSI (CP1252), but intentionally +# treat it as Shift-JIS, and got hex escapes +# + +add_encoding_test_with_cwd(f_LegacyEncWrong_Prep + ${CMAKE_CURRENT_SOURCE_DIR}/samples + -DINFO2=INFO2-sample2 + -DCHOICES=CP932|Windows-932|IBM-943|SJIS|JIS_X0208|SHIFT_JIS|SHIFT-JIS + -DOUTFILE=${CMAKE_CURRENT_BINARY_DIR}/f_LegacyEncWrong.txt +) + +add_test( + NAME f_LegacyEncWrong + COMMAND ${CMAKE_COMMAND} -E compare_files --ignore-eol f_LegacyEncWrong.txt samples/INFO2-sample2-wrong-enc.txt +) + +add_test( + NAME f_LegacyEncWrong_Clean + COMMAND ${CMAKE_COMMAND} -E rm f_LegacyEncWrong.txt +) + +set_tests_properties(f_LegacyEncWrong_Prep PROPERTIES FIXTURES_SETUP F_LEGACYENCWRONG) +set_tests_properties(f_LegacyEncWrong PROPERTIES FIXTURES_REQUIRED F_LEGACYENCWRONG) +set_tests_properties(f_LegacyEncWrong_Clean PROPERTIES FIXTURES_CLEANUP F_LEGACYENCWRONG) + +set_tests_properties(f_LegacyEncWrong_Prep + PROPERTIES + PASS_REGULAR_EXPRESSION "does not use specified codepage") +set_tests_properties(f_LegacyEncWrong + PROPERTIES + LABELS "info2;encoding") + + +# +# Legacy UNC entries +# + +add_encoding_test_with_cwd(f_LegacyUNC_Prep + ${CMAKE_CURRENT_SOURCE_DIR}/samples + -DINFO2=INFO2-2k-tw-uncpath + -DCHOICES=CP950|Windows-950|BIG5 + -DOUTFILE=${CMAKE_CURRENT_BINARY_DIR}/f_LegacyUNC.txt +) + +add_test( + NAME f_LegacyUNC + COMMAND ${CMAKE_COMMAND} -E compare_files --ignore-eol f_LegacyUNC.txt samples/INFO2-2k-tw-uncpath.txt +) + +add_test( + NAME f_LegacyUNC_Clean + COMMAND ${CMAKE_COMMAND} -E rm f_LegacyUNC.txt +) + +set_tests_properties(f_LegacyUNC_Prep PROPERTIES FIXTURES_SETUP F_LEGACYUNC) +set_tests_properties(f_LegacyUNC PROPERTIES FIXTURES_REQUIRED F_LEGACYUNC) +set_tests_properties(f_LegacyUNC_Clean PROPERTIES FIXTURES_CLEANUP F_LEGACYUNC) + +set_tests_properties(f_LegacyUNC + PROPERTIES + LABELS "info2;encoding") diff --git a/test/cmake/parse-info2.cmake b/test/cmake/parse-info2.cmake new file mode 100644 index 0000000..2657cba --- /dev/null +++ b/test/cmake/parse-info2.cmake @@ -0,0 +1,45 @@ +# +# Verify INFO2 results match existing golden files +# + +function(createInfo2TestSet prefix info2) + + set(fixture_name F_$) + set(out ${CMAKE_CURRENT_BINARY_DIR}/${prefix}.txt) + set(ref ${CMAKE_CURRENT_SOURCE_DIR}/samples/${info2}.txt) + set(args ${ARGN}) + + add_test(NAME f_${prefix}_Prepare + COMMAND rifiuti ${args} ${info2} -o ${out} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/samples + COMMAND_EXPAND_LISTS) + + add_test(NAME f_${prefix}_Clean + COMMAND ${CMAKE_COMMAND} -E rm ${out}) + + add_test(NAME f_${prefix} + COMMAND ${CMAKE_COMMAND} -E compare_files --ignore-eol ${out} ${ref}) + + set_tests_properties(f_${prefix}_Prepare PROPERTIES FIXTURES_SETUP ${fixture_name}) + set_tests_properties(f_${prefix}_Clean PROPERTIES FIXTURES_CLEANUP ${fixture_name}) + set_tests_properties(f_${prefix} PROPERTIES FIXTURES_REQUIRED ${fixture_name}) + + set_tests_properties(f_${prefix} + PROPERTIES + LABELS "info2;read") + +endfunction() + + +createInfo2TestSet(Info2Empty INFO2-empty) +createInfo2TestSet(Info2WinNT INFO-NT-en-1) +createInfo2TestSet(Info2Win98 INFO2-sample2 -l CP1252) +createInfo2TestSet(Info2WinME INFO2-ME-en-1 -l CP1252) +createInfo2TestSet(Info2Win2K INFO2-2k-cht-1) +createInfo2TestSet(Info2WinXP INFO2-sample1) +createInfo2TestSet(Info2UNCA1 INFO2-me-en-uncpath -l ASCII) +createInfo2TestSet(Info2UNCU1 INFO2-03-tw-uncpath) + +# In encoding.cmake now +# createInfo2TestSet(Info2Win95 INFO-95-ja-1 -l ${cp932}) +# createInfo2TestSet(Info2UNCA2 INFO2-2k-tw-uncpath -l ${cp950}) diff --git a/test/cmake/parse-rdir.cmake b/test/cmake/parse-rdir.cmake new file mode 100644 index 0000000..29e6942 --- /dev/null +++ b/test/cmake/parse-rdir.cmake @@ -0,0 +1,60 @@ +# +# Verify $Recycle.bin results match existing golden files +# + +function(createRdirTestSet prefix dir) + + set(fixture_name D_$) + set(out ${CMAKE_CURRENT_BINARY_DIR}/${prefix}.txt) + set(ref ${CMAKE_CURRENT_SOURCE_DIR}/samples/${dir}.txt) + + add_test(NAME d_${prefix}_Prepare + COMMAND rifiuti-vista ${dir} -o ${out} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/samples) + + add_test(NAME d_${prefix}_Clean + COMMAND ${CMAKE_COMMAND} -E rm ${out}) + + add_test(NAME d_${prefix} + COMMAND ${CMAKE_COMMAND} -E compare_files --ignore-eol ${out} ${ref}) + + set_tests_properties(d_${prefix}_Prepare PROPERTIES FIXTURES_SETUP ${fixture_name}) + set_tests_properties(d_${prefix}_Clean PROPERTIES FIXTURES_CLEANUP ${fixture_name}) + set_tests_properties(d_${prefix} PROPERTIES FIXTURES_REQUIRED ${fixture_name}) + + set_tests_properties(d_${prefix} PROPERTIES LABELS "recycledir;read") + +endfunction() + +createRdirTestSet(DirEmpty dir-empty) +createRdirTestSet(DirVista dir-sample1) +createRdirTestSet(DirWin10 dir-win10-01) +createRdirTestSet(DirUNC19 dir-2019-uncpath) + +# +# Similar to above, but only test single index file +# + +if(WIN32) + add_test_using_shell(d_DirOneIdx_PrepareRef + "Select-String -Path samples/dir-win10-01.txt -SimpleMatch 'IHO61YT' -Raw > d_DirOneIdx_r.txt") +else() + add_test_using_shell(d_DirOneIdx_PrepareRef + "grep 'IHO61YT' samples/dir-win10-01.txt > d_DirOneIdx_r.txt") +endif() + +add_test(NAME d_DirOneIdx_PrepareOut + COMMAND rifiuti-vista -n samples/dir-win10-01/$IHO61YT -o d_DirOneIdx_o.txt) + +add_test(NAME d_DirOneIdx_Clean + COMMAND ${CMAKE_COMMAND} -E rm d_DirOneIdx_r.txt d_DirOneIdx_o.txt) + +add_test(NAME d_DirOneIdx + COMMAND ${CMAKE_COMMAND} -E compare_files --ignore-eol d_DirOneIdx_o.txt d_DirOneIdx_r.txt) + +set_tests_properties(d_DirOneIdx_PrepareRef PROPERTIES FIXTURES_SETUP D_DIRONEIDX) +set_tests_properties(d_DirOneIdx_PrepareOut PROPERTIES FIXTURES_SETUP D_DIRONEIDX) +set_tests_properties(d_DirOneIdx_Clean PROPERTIES FIXTURES_CLEANUP D_DIRONEIDX) +set_tests_properties(d_DirOneIdx PROPERTIES FIXTURES_REQUIRED D_DIRONEIDX) + +set_tests_properties(d_DirOneIdx PROPERTIES LABELS "recycledir;read") diff --git a/test/cmake/read-write.cmake b/test/cmake/read-write.cmake new file mode 100644 index 0000000..17f6dff --- /dev/null +++ b/test/cmake/read-write.cmake @@ -0,0 +1,128 @@ +# +# Non-existant input file arg +# + +add_test(NAME d_InputNotExist COMMAND rifiuti-vista dUmMy) +add_test(NAME f_InputNotExist COMMAND rifiuti dUmMy) + +set_tests_properties(d_InputNotExist + PROPERTIES + LABELS "recycledir;read" + PASS_REGULAR_EXPRESSION "does not exist") +set_tests_properties(f_InputNotExist + PROPERTIES + LABELS "info2;read" + PASS_REGULAR_EXPRESSION "does not exist") + +# +# Special file +# +# g_file_test() is unuseful in Windows; NUL, CON etc are +# treated as regular files, therefore can't be determined +# ahead as unusable. They have to be actually opened. +# +if(WIN32) +add_test(NAME d_InputSpecialFile COMMAND rifiuti-vista nul) +add_test(NAME f_InputSpecialFile COMMAND rifiuti nul) +else() +add_test(NAME d_InputSpecialFile COMMAND rifiuti-vista /dev/null) +add_test(NAME f_InputSpecialFile COMMAND rifiuti /dev/null) +endif() + +set_tests_properties(d_InputSpecialFile + PROPERTIES + LABELS "recycledir;read" + PASS_REGULAR_EXPRESSION "fails validation;not a normal file") +set_tests_properties(f_InputSpecialFile + PROPERTIES + LABELS "info2;read" + PASS_REGULAR_EXPRESSION "fails validation;not a normal file") + +# TODO Consider symbolic links support + +# +# File output == Console output? +# + +function(createComparisonTestSet prefix sample_dir) + + set(fixture_name D_$) + set(out1 ${prefix}_f.txt) + set(out2 ${prefix}_c.txt) + + add_test(NAME d_${prefix}_PrepareFile + COMMAND rifiuti-vista -o ${out1} ${sample_dir}) + add_test_using_shell( + d_${prefix}_PrepareCon + "$ ${sample_dir} > ${out2}") + + set_tests_properties( + d_${prefix}_PrepareFile + d_${prefix}_PrepareCon + PROPERTIES + FIXTURES_SETUP ${fixture_name}) + + add_test(NAME d_${prefix}_CleanFile + COMMAND ${CMAKE_COMMAND} -E rm ${out1}) + add_test(NAME d_${prefix}_CleanCon + COMMAND ${CMAKE_COMMAND} -E rm ${out2}) + + set_tests_properties( + d_${prefix}_CleanFile + d_${prefix}_CleanCon + PROPERTIES + FIXTURES_CLEANUP ${fixture_name}) + + add_test(NAME d_${prefix} + COMMAND ${CMAKE_COMMAND} -E compare_files --ignore-eol ${out1} ${out2}) + + set_tests_properties(d_${prefix} + PROPERTIES + LABELS "recycledir;read;write" + FIXTURES_REQUIRED ${fixture_name}) + +endfunction() + +createComparisonTestSet(FileConDiffA samples/dir-sample1) +createComparisonTestSet(FileConDiffU samples/dir-win10-01) + +# +# Unicode filename / dir name should work +# + +function(UniInputPathTest testid is_info2 input ref) + + set_label(is_info2 "read" "encoding") + set_test_vars(${testid} is_info2 1 1) + set(out ${CMAKE_CURRENT_BINARY_DIR}/${prefix}.txt) + set(ref_fullpath ${sample_dir}/${ref}) + if(is_info2) + add_test( + NAME ${prefix}_Prep + COMMAND rifiuti ${input} -o ${out} + WORKING_DIRECTORY ${sample_dir}) + else() + add_test( + NAME ${prefix}_Prep + COMMAND rifiuti-vista ${input} -o ${out} + WORKING_DIRECTORY ${sample_dir}) + endif() + + add_test( + NAME ${prefix}_Clean + COMMAND ${CMAKE_COMMAND} -E rm ${out}) + + add_test( + NAME ${prefix} + COMMAND ${CMAKE_COMMAND} -E compare_files --ignore-eol ${out} ${ref_fullpath}) + + set_tests_properties(${prefix}_Prep PROPERTIES FIXTURES_SETUP ${fixture}) + set_tests_properties(${prefix}_Clean PROPERTIES FIXTURES_CLEANUP ${fixture}) + set_tests_properties(${prefix} PROPERTIES FIXTURES_REQUIRED ${fixture}) + + set_tests_properties(${prefix} PROPERTIES LABELS "${label}") + +endfunction() + +UniInputPathTest(UniFilePath 1 ./ごみ箱/INFO2-empty japanese-path-file.txt) +UniInputPathTest(UniRDirPath 0 ./ごみ箱/dir-empty japanese-path-dir.txt) diff --git a/test/cmake/xml.cmake b/test/cmake/xml.cmake new file mode 100644 index 0000000..fc7d85a --- /dev/null +++ b/test/cmake/xml.cmake @@ -0,0 +1,133 @@ +# Search xmllint + +add_test( + NAME FindCommand_xmllint + COMMAND xmllint --version +) + +set_tests_properties( + FindCommand_xmllint + PROPERTIES + FIXTURES_SETUP XMLLINT +) + +# XML well-formed validation for INFO2 + +add_test( + NAME f_CreateXmlOutput + COMMAND rifiuti -o f_sample1.xml -x samples/INFO2-sample1 +) + +add_test( + NAME f_CleanXmlOutput + COMMAND ${CMAKE_COMMAND} -E remove f_sample1.xml +) + +add_test( + NAME f_XmlValidate + COMMAND xmllint --noout f_sample1.xml +) + +set_tests_properties( + f_CreateXmlOutput + PROPERTIES + FIXTURES_SETUP F_XMLOUTPUT +) + +set_tests_properties( + f_CleanXmlOutput + PROPERTIES + FIXTURES_CLEANUP F_XMLOUTPUT +) + +set_tests_properties( + f_XmlValidate + PROPERTIES + FIXTURES_REQUIRED "XMLLINT;F_XMLOUTPUT" +) + +# XML well-formed validation for $Recycle.bin + +add_test( + NAME d_CreateXmlOutput + COMMAND rifiuti-vista -o d_sample1.xml -x samples/dir-sample1 +) + +add_test( + NAME d_CleanXmlOutput + COMMAND ${CMAKE_COMMAND} -E remove d_sample1.xml +) + +add_test( + NAME d_XmlValidate + COMMAND xmllint --noout d_sample1.xml +) + +set_tests_properties( + d_CreateXmlOutput + PROPERTIES + FIXTURES_SETUP D_XMLOUTPUT +) + +set_tests_properties( + d_CleanXmlOutput + PROPERTIES + FIXTURES_CLEANUP D_XMLOUTPUT +) +set_tests_properties( + d_XmlValidate + PROPERTIES + FIXTURES_REQUIRED "XMLLINT;D_XMLOUTPUT" +) + +# DTD validation for INFO2 + +add_test( + NAME f_DTDValidate + COMMAND xmllint --noout f_sample1.xml --dtdvalid ${CMAKE_CURRENT_SOURCE_DIR}/rifiuti.dtd +) + +set_tests_properties( + f_DTDValidate + PROPERTIES + FIXTURES_REQUIRED "XMLLINT;F_XMLOUTPUT" +) + +# DTD validation for $Recycle.bin + +add_test( + NAME d_DTDValidate + COMMAND xmllint --noout d_sample1.xml --dtdvalid ${CMAKE_CURRENT_SOURCE_DIR}/rifiuti.dtd +) + +set_tests_properties( + d_DTDValidate + PROPERTIES + FIXTURES_REQUIRED "XMLLINT;D_XMLOUTPUT" +) + +# Other properties + +set( + f_XmlTests + f_DTDValidate + f_XmlValidate +) + +set( + d_XmlTests + d_DTDValidate + d_XmlValidate +) + +set_tests_properties( + ${d_XmlTests} + PROPERTIES + LABELS "recycledir;xml" +) + +set_tests_properties( + ${f_XmlTests} + PROPERTIES + LABELS "info2;xml" +) diff --git a/test/test_glib_iconv.c b/test/test_glib_iconv.c index 822c5b7..8878d2c 100644 --- a/test/test_glib_iconv.c +++ b/test/test_glib_iconv.c @@ -1,23 +1,29 @@ +#include #include -int main (int argc, char **argv) +bool conv_established (char *enc) { - GIConv cd; - - if (argc < 2 || *(argv[1]) == '\0') { - return 2; - } + GIConv cd = g_iconv_open ("UTF-8", enc); - /* - * In rifiuti2 we only need → UTF-8 conversion, - * so we only test for this case. There are some odd OSes - * where even identity conversion can be unsupported (say - * CP936 → CP936), such as on Solaris. - */ - cd = g_iconv_open ("UTF-8", argv[1]); + if (cd != (GIConv) -1) { + g_iconv_close (cd); + return true; + } + return false; +} - if (cd != (GIConv) -1) - g_iconv_close (cd); +int main (int argc, char **argv) +{ + char *enc; - return (cd == (GIConv) -1); + for (int i = 1; i < argc; i++) { + enc = argv[i]; + if (*enc == '\0') + continue; + if (conv_established (enc)) { + g_print("%s\n", enc); + return 0; + } + } + return 1; }