diff -Nru libofx-0.10.5/cmake/modules/FindOpenSP.cmake libofx-0.10.9/cmake/modules/FindOpenSP.cmake --- libofx-0.10.5/cmake/modules/FindOpenSP.cmake 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/cmake/modules/FindOpenSP.cmake 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,155 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindOpenSP +---------- + +Try to find the OpenSP library. + +.. versionadded:: 3.25 + +Result Variables +^^^^^^^^^^^^^^^^ + +This will define the following variables: + +``OpenSP_FOUND`` + True if (the requested version of) ``OpenSP`` is available + +``OpenSP_VERSION`` + The version of ``OpenSP`` + +``OpenSP_VERSION_MAJOR`` + The major version of ``OpenSP`` + +``OpenSP_VERSION_MINOR`` + The minor version of ``OpenSP`` + +``OpenSP_VERSION_PATCH`` + The patch version of ``OpenSP`` + +``OpenSP_INCLUDE_DIRS`` + The include dirs of ``OpenSP`` with its headers + +``OpenSP_LIBRARIES`` + The OpenSP library for use with target_link_libraries(). + This can be passed to target_link_libraries() instead of + the :prop_tgt:`IMPORTED` ``OpenSP::OpenSP`` target + +``OpenSP_MULTI_BYTE`` + True if ``SP_MULTI_BYTE`` was found to be defined in OpenSP's ``config.h`` + header file, which indicates that the ``OpenSP`` library was compiled with + support for multi-byte characters. The consuming target needs to define the + ``SP_MULTI_BYTE`` to match this value in order to avoid issues with character + decoding. + +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +This module defines the :prop_tgt:`IMPORTED` target ``OpenSP::OpenSP``, if +OpenSP has been found. + +Cache variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``OpenSP_INCLUDE_DIR`` + the OpenSP include directory + +``OpenSP_LIBRARY`` + the absolute path of the osp library + +#]=======================================================================] + +if (NOT OpenSP_INCLUDE_DIR AND NOT OpenSP_LIBRARY) + find_package(PkgConfig) + if (PkgConfig_FOUND) + pkg_check_modules(OpenSP IMPORTED_TARGET GLOBAL opensp) + + if (OpenSP_FOUND) + add_library(OpenSP::OpenSP INTERFACE IMPORTED) + target_link_libraries(OpenSP::OpenSP INTERFACE PkgConfig::OpenSP) + + set(OpenSP_INCLUDE_DIR ${OpenSP_INCLUDE_DIRS}) + set(OpenSP_LIBRARY ${OpenSP_LIBRARIES}) + endif () + endif () +endif () + +if (NOT OpenSP_INCLUDE_DIR) + find_path(OpenSP_INCLUDE_DIR + NAMES ParserEventGeneratorKit.h + PATH_SUFFIXES OpenSP opensp + DOC "The OpenSP include directory" + ) +endif () + +if (NOT OpenSP_LIBRARY) + find_library(OpenSP_LIBRARY_RELEASE + NAMES osp libosp opensp libopensp sp133 libsp + ) + + find_library(OpenSP_LIBRARY_DEBUG + NAMES ospd libospd openspd libopenspd sp133d libspd + ) + + include(SelectLibraryConfigurations) + select_library_configurations(OpenSP) +endif () + +if (OpenSP_INCLUDE_DIR AND OpenSP_LIBRARY) + if (EXISTS "${OpenSP_INCLUDE_DIR}/config.h") + if (NOT OpenSP_VERSION) + file(STRINGS "${OpenSP_INCLUDE_DIR}/config.h" opensp_version_str REGEX "^#define[\t ]+SP_VERSION[\t ]+\".*\"") + string(REGEX REPLACE "^.*SP_VERSION[\t ]+\"([^\"]*)\".*$" "\\1" OpenSP_VERSION "${opensp_version_str}") + unset(opensp_version_str) + endif () + + if (OpenSP_VERSION MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=]) + set(OpenSP_VERSION_MAJOR "${CMAKE_MATCH_1}") + set(OpenSP_VERSION_MINOR "${CMAKE_MATCH_2}") + set(OpenSP_VERSION_PATCH "${CMAKE_MATCH_3}") + endif () + + include(CheckCXXSymbolExists) + check_cxx_symbol_exists(SP_MULTI_BYTE "${OpenSP_INCLUDE_DIR}/config.h" OpenSP_MULTI_BYTE) + endif () + + if (NOT TARGET OpenSP::OpenSP) + set(OpenSP_INCLUDE_DIRS ${OpenSP_INCLUDE_DIR}) + + add_library(OpenSP::OpenSP UNKNOWN IMPORTED) + set_target_properties(OpenSP::OpenSP PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${OpenSP_INCLUDE_DIRS}") + + if (OpenSP_LIBRARY_RELEASE) + set_target_properties(OpenSP::OpenSP PROPERTIES IMPORTED_LOCATION_RELEASE "${OpenSP_LIBRARY_RELEASE}") + set_property(TARGET OpenSP::OpenSP APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) + endif () + + if (OpenSP_LIBRARY_DEBUG) + set_target_properties(OpenSP::OpenSP PROPERTIES IMPORTED_LOCATION_DEBUG "${OpenSP_LIBRARY_DEBUG}") + set_property(TARGET OpenSP::OpenSP APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) + endif () + + if (NOT OpenSP_LIBRARY_RELEASE AND NOT OpenSP_LIBRARY_DEBUG) + set_property(TARGET OpenSP::OpenSP APPEND PROPERTY IMPORTED_LOCATION "${OpenSP_LIBRARY}") + endif () + endif () +endif () + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OpenSP + FOUND_VAR OpenSP_FOUND + REQUIRED_VARS OpenSP_LIBRARY OpenSP_INCLUDE_DIR + VERSION_VAR OpenSP_VERSION +) + +mark_as_advanced(OpenSP_INCLUDE_DIR OpenSP_LIBRARY OpenSP_MULTI_BYTE) + +include(FeatureSummary) +set_package_properties(OpenSP PROPERTIES + URL "http://openjade.sourceforge.net/doc/index.htm" + DESCRIPTION "An SGML System Conforming to International Standard ISO 8879" +) diff -Nru libofx-0.10.5/CMakeLists.txt libofx-0.10.9/CMakeLists.txt --- libofx-0.10.5/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/CMakeLists.txt 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,254 @@ +# SPDX-FileCopyrightText: 2022 Dawid Wróbel +# SPDX-License-Identifier: GPL-2.0-or-later + +cmake_minimum_required(VERSION 3.12) + +if (${CMAKE_VERSION} VERSION_LESS 3.25.0) + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) +endif () + +include(GNUInstallDirs) +include(CMakeDependentOption) +include(FeatureSummary) + +# set-up tool features; this needs to be done early to let the vcpkg auto-download all the optional dependencies +option(ENABLE_ICONV "Build with ICONV" ON) +add_feature_info("iconv" ENABLE_ICONV "Enables ICONV support for encoding conversion") +if (ENABLE_ICONV) + list(APPEND VCPKG_MANIFEST_FEATURES "iconv") +endif () + +option(ENABLE_OFXCONNECT "Enable ofxconnect tool" ON) +add_feature_info("ofxconnect" ENABLE_OFXCONNECT "Enables ofxconnect utility which allows to test OFX Direct Connect") +if (ENABLE_OFXCONNECT) + list(APPEND VCPKG_MANIFEST_FEATURES "ofxconnect") +endif () + +option(ENABLE_OFXDUMP "Enable ofxdump tool" ON) +add_feature_info("ofxdump" ENABLE_OFXDUMP "Enables ofxdump utility which prints, in human readable form, everything the library understands about a file") +if (ENABLE_OFXDUMP) + list(APPEND VCPKG_MANIFEST_FEATURES "ofxdump") +endif () + +option(ENABLE_OFX2QIF "Enable ofx2qif tool" ON) +add_feature_info("ofx2qif" ENABLE_OFX2QIF "Enables OFX file to QIF (Quicken Interchange Format) file converter") +if (ENABLE_OFX2QIF) + list(APPEND VCPKG_MANIFEST_FEATURES "ofx2qif") +endif () + +# actually set up the project +project(libofx) + +# This is the project version +set(LIBOFX_MAJOR_VERSION 0) +set(LIBOFX_MINOR_VERSION 10) +set(LIBOFX_MICRO_VERSION 9) +set(LIBOFX_VERSION_RELEASE_STRING ${LIBOFX_MAJOR_VERSION}.${LIBOFX_MINOR_VERSION}.${LIBOFX_MICRO_VERSION}) + +# This is the library version (SONAME) so affects ABI +# LIBOFX_LIBRARY_SONAME must be changed when ABI is broken (backwards compat) +# LIBOFX_LIBRARY_VERSION must be changed if just adding new functions and such (backwards compat not broken) +# Note that these are used by write_basic_package_version_file() to generate LibOFXConfigVersion.cmake +set(LIBOFX_LIBRARY_SONAME 7) +set(LIBOFX_LIBRARY_VERSION ${LIBOFX_LIBRARY_SONAME}.0.4) + +# If no build type is set, use "Release with Debug Info" +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE RelWithDebInfo) +endif (NOT CMAKE_BUILD_TYPE) +include(CTest) + +# locate required dependencies +find_package(OpenSP) +set_package_properties(OpenSP PROPERTIES TYPE REQUIRED PURPOSE "The underlying library that the LibOFX builds upon, we cannot build without it!") + +# locate optional dependencies +if (ENABLE_OFXCONNECT) + find_package(CURL) + set_package_properties(CURL PROPERTIES TYPE REQUIRED PURPOSE "ENABLE_OFXCONNECT is ON, so we need curl for the ofxconnect tool to perform downloading of the statements") + if (CURL_FOUND) + set(HAVE_LIBCURL 1) + endif () + + find_package(PkgConfig) + set_package_properties(PkgConfig PROPERTIES TYPE REQUIRED PURPOSE "ENABLE_OFXCONNECT is ON, so we need PkgConfig to locate the libxml++ library") + + if (PkgConfig_FOUND) + pkg_check_modules(LIBXMLPP REQUIRED IMPORTED_TARGET libxml++-2.6>=2.6) + #TODO: if not found, handle the feature_summary by hand somehow + endif () +endif () + +if (ENABLE_ICONV) + find_package(Iconv) + set_package_properties(Iconv PROPERTIES TYPE REQUIRED PURPOSE "ENABLE_ICONV is on, so we need Iconv to build") + + if (Iconv_FOUND) + set(HAVE_ICONV 1) + include(CheckCXXSourceCompiles) + set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${Iconv_INCLUDE_DIRS}) + set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${Iconv_LIBRARIES}) + check_cxx_source_compiles( + " + #include + int main(){ + const char* inbuf = 0; + size_t inbytesleft = 0; + char* outbuf = 0; + size_t outbytesleft = 0; + iconv(0, &inbuf, &inbytesleft, &outbuf, &outbytesleft); + return 0; + } + " + HAVE_ICONV_CONST + ) + endif () +endif () + +# Build a shared lib by default, set this to OFF to build statically +option(BUILD_SHARED_LIBS "Decides whether to build ${CMAKE_PROJECT_NAME} as a shared or static library" ON) +add_feature_info("shared" BUILD_SHARED_LIBS "Enables compiling ${CMAKE_PROJECT_NAME} as a shared library (as opposed to statically)") + +if (BUILD_SHARED_LIBS AND MSVC) + add_compile_definitions(LIBOFX_DLL=1) +endif () + +# set up SP_MULTI_BYTE +set(FORCE_OPENSP_MULTIBYTE AUTO CACHE STRING "Whether to let FindOpenSP CMake module auto-detect the SP_MULTIBYTE value (leave 'AUTO'), or to override it with 'ON' or 'OFF'") +set_property(CACHE FORCE_OPENSP_MULTIBYTE PROPERTY STRINGS AUTO ON OFF) + +# CheckCXXSymbolExists returns "" if symbol is not found +if (NOT OpenSP_MULTI_BYTE) + set(OpenSP_MULTI_BYTE 0) +endif() + +message(CHECK_START "Setting up the SP_MULTI_BYTE") +set(SP_MULTI_BYTE OpenSP_MULTI_BYTE) +if (NOT FORCE_OPENSP_MULTIBYTE STREQUAL "AUTO") + if (NOT FORCE_OPENSP_MULTIBYTE EQUAL OpenSP_MULTI_BYTE) + message(CHECK_PASS "detected by FindOpenSP to be ${OpenSP_MULTI_BYTE}, but overriding to ${FORCE_OPENSP_MULTIBYTE}, as set by FORCE_OPENSP_MULTIBYTE. If this is not indeded, it can cause wide character processing issues!") + set(SP_MULTI_BYTE ${FORCE_OPENSP_MULTIBYTE}) + else () + message(CHECK_PASS "detected by FindOpenSP to be ${OpenSP_MULTI_BYTE}, with FORCE_OPENSP_MULTIBYTE also set to ${FORCE_OPENSP_MULTIBYTE}") + endif () +else () + message(CHECK_PASS "detected by FindOpenSP to be ${OpenSP_MULTI_BYTE}. Use FORCE_OPENSP_MULTIBYTE to set a different value") +endif () + +# Disable CRT warnings +if (MSVC) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) +endif () + +# create the libofx.h file out of the libofx.h.in +configure_file("inc/libofx.h.in" "${CMAKE_CURRENT_BINARY_DIR}/inc/libofx.h") + +# create the config.h file out of the config.h.cmake +configure_file("config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/config.h") + +# Handle the getopt in a cross-platform way +add_subdirectory(getopt) + +# libofx itself +add_subdirectory(lib) + +# ofxconnect +if (ENABLE_OFXCONNECT) + add_subdirectory(ofxconnect) +endif () + +# ofxdump +if (ENABLE_OFXDUMP) + add_subdirectory(ofxdump) +endif () + +# ofx2qif +if (ENABLE_OFX2QIF) + add_subdirectory(ofx2qif) +endif () + +# TODO: wire up docs +# TODO: wire up tests + +# set up vcpkg integration +option(ENABLE_VCPKG_INTEGRATION "Enable vcpkg integration" OFF) +add_feature_info("vcpkg" ENABLE_VCPKG_INTEGRATION "Enables integration with vcpkg, a C++ library manager") + +if (ENABLE_VCPKG_INTEGRATION AND DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE) + set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "") + message(STATUS "VCPKG found: $ENV{VCPKG_ROOT}") + message(STATUS "Using VCPKG integration") + message(STATUS "VCPKG_MANIFEST_FEATURES: ${VCPKG_MANIFEST_FEATURES}") +elseif (DEFINED CMAKE_TOOLCHAIN_FILE) + message(STATUS "Using toolchain: ${CMAKE_TOOLCHAIN_FILE}") + if (CMAKE_TOOLCHAIN_FILE MATCHES "vcpkg.cmake") + message(STATUS "Toolchain uses VCPKG integration") + message(STATUS "VCPKG_MANIFEST_FEATURES: ${VCPKG_MANIFEST_FEATURES}") + set(ENABLE_VCPKG_INTEGRATION ON) + endif () +endif () + +# TODO: once Autotools build stuff is gone, remove these and set them directly in libofx.pc.in itself +set(OPENSPLIBS ${OpenSP_LIBRARIES}) +set(OPENSPINCLUDES ${OpenSP_INCLUDE_DIRS}) +set(VERSION ${LIBOFX_VERSION_RELEASE_STRING}) +set(prefix "${CMAKE_INSTALL_PREFIX}") +set(exec_prefix "\${prefix}") +set(libdir "\${prefix}/${CMAKE_INSTALL_LIBDIR}") +set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") + +# create the libofx.pc pkg-config file out of the libofx.pc.in +configure_file("libofx.pc.in" "${CMAKE_BINARY_DIR}/libofx.pc") + +include(CMakePackageConfigHelpers) +configure_package_config_file(LibOFXConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/LibOFXConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libofx + PATH_VARS CMAKE_INSTALL_INCLUDEDIR CMAKE_INSTALL_LIBDIR CMAKE_INSTALL_BINDIR CMAKE_INSTALL_DATADIR + ) +write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/LibOFXConfigVersion.cmake + VERSION ${LIBOFX_LIBRARY_VERSION} + COMPATIBILITY SameMajorVersion + ) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/LibOFXConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/LibOFXConfigVersion.cmake + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/FindOpenSP.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libofx + ) + +install(DIRECTORY dtd DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/libofx FILES_MATCHING PATTERN "*.dtd" PATTERN "*.dcl") +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/inc/libofx.h" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libofx) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libofx.pc" DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) +install(EXPORT LibOFXTargets + FILE LibOFXTargets.cmake + NAMESPACE libofx:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libofx + ) + +feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND + DESCRIPTION "The following REQUIRED packages have not been found:") + +feature_summary(WHAT OPTIONAL_PACKAGES_NOT_FOUND + DESCRIPTION "The following OPTIONAL packages have not been found:") + +feature_summary(WHAT ENABLED_FEATURES + DESCRIPTION "The following features have been enabled:") + +feature_summary(WHAT DISABLED_FEATURES + DESCRIPTION "The following features have been disabled:") + +# ############################################################ +# Package creation rules + +if(UNIX) + set(CPACK_GENERATOR "TGZ") + set(CPACK_SOURCE_GENERATOR "TGZ") +endif() + +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "This library is a client and file format implementation for the financial format OFX (Open Financial Exchange)") +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") +set(CPACK_PACKAGE_VERSION_MAJOR ${LIBOFX_MAJOR_VERSION}) +set(CPACK_PACKAGE_VERSION_MINOR ${LIBOFX_MINOR_VERSION}) +set(CPACK_PACKAGE_VERSION_PATCH ${LIBOFX_MICRO_VERSION}) +set(CPACK_SOURCE_IGNORE_FILES "/build.*/;/\\\\.git/;.*~;\\\\.vscode;\\\\.github") + +include (CPack) diff -Nru libofx-0.10.5/config.h.cmake libofx-0.10.9/config.h.cmake --- libofx-0.10.5/config.h.cmake 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/config.h.cmake 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,15 @@ +/* config.h. Generated from config.h.cmake by cmake */ + +/* Name of package */ +#define PACKAGE "libofx" + +/* Version number of package */ +#define VERSION "@LIBOFX_VERSION_RELEASE_STRING@" + +#cmakedefine HAVE_LIBCURL 1 + +#cmakedefine HAVE_ICONV 1 + +#cmakedefine HAVE_ICONV_CONST 1 + +#cmakedefine SP_MULTI_BYTE 1 diff -Nru libofx-0.10.5/configure.ac libofx-0.10.9/configure.ac --- libofx-0.10.5/configure.ac 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/configure.ac 2022-10-03 20:22:59.000000000 +0000 @@ -8,37 +8,20 @@ # FUNCTION: # implements checks for a variety of system-specific functions -AC_INIT(inc/libofx.h.in) -AM_CONFIG_HEADER(config.h) +AC_INIT([libofx], [0.10.9]) # must repeat the version number here, sorry +AC_SUBST([LIBOFX_MAJOR_VERSION], [0]) +AC_SUBST([LIBOFX_MINOR_VERSION], [10]) +AC_SUBST([LIBOFX_MICRO_VERSION], [9]) + +LIBOFX_VERSION_RELEASE_STRING="$LIBOFX_MAJOR_VERSION.$LIBOFX_MINOR_VERSION.$LIBOFX_MICRO_VERSION" + +AC_CONFIG_SRCDIR(inc/libofx.h.in) +AM_CONFIG_HEADER([config.h]) AC_CONFIG_AUX_DIR(config) AC_CONFIG_MACRO_DIR(m4) AC_PROG_CC AC_PROG_CXX -LIBOFX_MAJOR_VERSION=0 -LIBOFX_MINOR_VERSION=10 -LIBOFX_MICRO_VERSION=5 -# this number is just incremented for every major change in CVS, also across -# releases to emulate the Revision variable of SVN (which isn't available -# with CVS) -LIBOFX_BUILD_VERSION=0 -LIBOFX_TAG_VERSION="stable" - -case "$LIBOFX_TAG_VERSION" in - cvs|svn|git) - LIBOFX_VERSION_RELEASE_STRING="$LIBOFX_MAJOR_VERSION.$LIBOFX_MINOR_VERSION.$LIBOFX_MICRO_VERSION.$LIBOFX_TAG_VERSION${LIBOFX_BUILD_VERSION}" - ;; - stable) - LIBOFX_VERSION_RELEASE_STRING="$LIBOFX_MAJOR_VERSION.$LIBOFX_MINOR_VERSION.$LIBOFX_MICRO_VERSION" - ;; - *) - LIBOFX_VERSION_RELEASE_STRING="$LIBOFX_MAJOR_VERSION.$LIBOFX_MINOR_VERSION.$LIBOFX_MICRO_VERSION" - - # add TAG - LIBOFX_VERSION_RELEASE_STRING="${LIBOFX_VERSION_RELEASE_STRING}${GWENHYWFAR_VERSION_TAG}" - ;; -esac - ### Check for GCC symbol visibility extensions AC_CACHE_CHECK([for symbol visibility extensions], ac_cv_sym_visibility, [ @@ -72,16 +55,14 @@ LIBOFX_VERSION=$LIBOFX_MAJOR_VERSION.$LIBOFX_MINOR_VERSION.$LIBOFX_MICRO_VERSION -AC_SUBST(LIBOFX_MAJOR_VERSION) -AC_SUBST(LIBOFX_MINOR_VERSION) -AC_SUBST(LIBOFX_MICRO_VERSION) +LIBOFX_BUILD_VERSION=0 AC_SUBST(LIBOFX_BUILD_VERSION) AC_SUBST(LIBOFX_VERSION_RELEASE_STRING) AC_SUBST(LIBOFX_VERSION) -AM_INIT_AUTOMAKE(libofx,$LIBOFX_VERSION_RELEASE_STRING) +AM_INIT_AUTOMAKE LIBOFX_SO_CURRENT=7 -LIBOFX_SO_REVISION=2 +LIBOFX_SO_REVISION=4 LIBOFX_SO_AGE=0 LIBOFX_SO_EFFECTIVE="`echo \$(($LIBOFX_SO_CURRENT-$LIBOFX_SO_AGE))`" AC_SUBST(LIBOFX_SO_CURRENT) @@ -271,9 +252,9 @@ [# FreeBSD has a gnugetopt library for this AC_CHECK_LIB([gnugetopt],[getopt_long],[AC_DEFINE([HAVE_GETOPT_LONG])], [# use the GNU replacement + AC_CONFIG_LIBOBJ_DIR(getopt) AC_LIBOBJ(getopt) - AC_LIBOBJ(getopt1) - AC_CONFIG_LINKS([lib/getopt.h:lib/gnugetopt.h])])])]) + AC_LIBOBJ(getopt1)])])]) dnl check for getopt in standard library adl_FUNC_GETOPT_LONG @@ -327,13 +308,35 @@ # [AC_DEFINE(HAVE_QT, 1, [Defined if Qt Gui is available])], # [AC_MSG_WARN([Qt is not available. Some experimental direct connect samples will not be fully functional.])]) +# check if building tools +# ---------------------------------------------------------------------------- + +AC_ARG_ENABLE(tools, + AS_HELP_STRING(--disable-tools,[Disable building of CLI tools: ofx2qif, ofxdump, ofxconnect] (no)), +[case "${enableval}" in + yes) tools=yes ;; + no) tools=no ;; + *) AC_MSG_ERROR([bad value ${enableval} for --disable-tools]) ;; +esac],[tools=yes]) + +build_ofx2qif=no +build_ofxdump=no build_ofxconnect=no -if test "$libcurl_available" = yes; then - if test "$have_libxmlpp" = yes; then - build_ofxconnect=yes + +if test x$tools = xyes ; then + build_ofx2qif=yes + build_ofxdump=yes + + if test "$libcurl_available" = yes; then + if test "$have_libxmlpp" = yes; then + build_ofxconnect=yes + fi fi fi -AM_CONDITIONAL([BUILD_OFXCONNECT], [test "$build_ofxconnect" = yes]) + +AM_CONDITIONAL([BUILD_OFX2QIF], [test "x$build_ofx2qif" = xyes]) +AM_CONDITIONAL([BUILD_OFXDUMP], [test x"$build_ofxdump" = xyes]) +AM_CONDITIONAL([BUILD_OFXCONNECT], [test "x$build_ofxconnect" = xyes]) # check for iconv # ---------------------------------------------------------------------------- @@ -407,6 +410,7 @@ inc/libofx.h dtd/Makefile doc/Makefile + getopt/Makefile ofx2qif/Makefile ofxdump/Makefile ofxconnect/Makefile diff -Nru libofx-0.10.5/debian/changelog libofx-0.10.9/debian/changelog --- libofx-0.10.5/debian/changelog 2022-07-22 20:53:53.000000000 +0000 +++ libofx-0.10.9/debian/changelog 2022-11-10 09:59:51.000000000 +0000 @@ -1,3 +1,14 @@ +libofx (1:0.10.9-1) unstable; urgency=medium + + [ Dylan Aïssi ] + * New upstream version 0.10.9 + * Update debian/copyright + + [ Debian Janitor ] + * Avoid explicitly specifying -Wl,--as-needed linker flag. + + -- Dylan Aïssi Thu, 10 Nov 2022 10:59:51 +0100 + libofx (1:0.10.5-1) unstable; urgency=medium * New upstream version diff -Nru libofx-0.10.5/debian/copyright libofx-0.10.9/debian/copyright --- libofx-0.10.5/debian/copyright 2022-07-22 20:53:53.000000000 +0000 +++ libofx-0.10.9/debian/copyright 2022-11-10 09:59:51.000000000 +0000 @@ -4,12 +4,13 @@ Source: https://github.com/libofx/libofx Files: * -Copyright: 2002-2011 Benoit Grégoire +Copyright: 2002-2022 Benoit Grégoire 2005 Ace Jones 2007 Martin Preuss License: GPL-2+ -Files: lib/getopt.c lib/getopt1.c lib/gnugetopt.h +Files: getopt/getopt.* + getopt/getopt1.c Copyright: 1987-2001 Free Software Founddation, Inc License: LGPL-2.1+ @@ -71,6 +72,7 @@ 2008 Chris Lamb 2011 Bryan Donlan 2014 Sébastien Villemot + 2017-2022 Dylan Aïssi License: GPL-2+ License: GPL-2+ diff -Nru libofx-0.10.5/debian/rules libofx-0.10.9/debian/rules --- libofx-0.10.5/debian/rules 2022-07-22 20:53:53.000000000 +0000 +++ libofx-0.10.9/debian/rules 2022-11-10 09:59:51.000000000 +0000 @@ -4,7 +4,6 @@ PACKNAME=libofx7 export DEB_BUILD_MAINT_OPTIONS = hardening=+all -export DEB_LDFLAGS_MAINT_APPEND=-Wl,--as-needed %: dh $@ --no-parallel diff -Nru libofx-0.10.5/debian/salsa-ci.yml libofx-0.10.9/debian/salsa-ci.yml --- libofx-0.10.5/debian/salsa-ci.yml 2022-07-22 20:53:53.000000000 +0000 +++ libofx-0.10.9/debian/salsa-ci.yml 2022-11-10 09:59:51.000000000 +0000 @@ -2,3 +2,6 @@ include: - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml + +reprotest: + allow_failure: true diff -Nru libofx-0.10.5/doc/ofx_sample_files/downcast.ofx libofx-0.10.9/doc/ofx_sample_files/downcast.ofx --- libofx-0.10.5/doc/ofx_sample_files/downcast.ofx 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/doc/ofx_sample_files/downcast.ofx 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,11 @@ + + + + + + + + + + + diff -Nru libofx-0.10.5/doc/ofx_sample_files/heap-buffer-overflow-1.ofx libofx-0.10.9/doc/ofx_sample_files/heap-buffer-overflow-1.ofx --- libofx-0.10.5/doc/ofx_sample_files/heap-buffer-overflow-1.ofx 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/doc/ofx_sample_files/heap-buffer-overflow-1.ofx 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,10 @@ + + + + + + + + + + Binary files /tmp/tmpv0hoqkot/CaN4sUD6Qr/libofx-0.10.5/doc/ofx_sample_files/heap-buffer-overflow-2.ofx and /tmp/tmpv0hoqkot/A8e7v7R01I/libofx-0.10.9/doc/ofx_sample_files/heap-buffer-overflow-2.ofx differ diff -Nru libofx-0.10.5/doc/ofx_sample_files/null-ptr-deref-1.ofx libofx-0.10.9/doc/ofx_sample_files/null-ptr-deref-1.ofx --- libofx-0.10.5/doc/ofx_sample_files/null-ptr-deref-1.ofx 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/doc/ofx_sample_files/null-ptr-deref-1.ofx 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,7 @@ + + +0 + + \ No newline at end of file diff -Nru libofx-0.10.5/doc/ofx_sample_files/null-ptr-deref-2.ofx libofx-0.10.9/doc/ofx_sample_files/null-ptr-deref-2.ofx --- libofx-0.10.5/doc/ofx_sample_files/null-ptr-deref-2.ofx 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/doc/ofx_sample_files/null-ptr-deref-2.ofx 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,8 @@ + +< + + + +> + + \ No newline at end of file diff -Nru libofx-0.10.5/doc/ofx_sample_files/use-after-free.ofx libofx-0.10.9/doc/ofx_sample_files/use-after-free.ofx --- libofx-0.10.5/doc/ofx_sample_files/use-after-free.ofx 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/doc/ofx_sample_files/use-after-free.ofx 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,7 @@ + +NRS> + + + + + \ No newline at end of file diff -Nru libofx-0.10.5/FAQ libofx-0.10.9/FAQ --- libofx-0.10.5/FAQ 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/FAQ 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -INSTALL: --------------------------------------------------------------------------------- - -Make sure you have the OpenSP library installed (libosp.so) before compiling. Yo can grab it at http://openjade.sourceforge.net/ -The recommended version is OpenSP 1.5 -If you have a version of OpenJade or OpenSP already installed before compiling OpenSP, make sure that you use ./configure --prefix=/usr to build OpenSP. Otherwise, LibOFX will probably link with the older, incompatible version of OpenSP. - -Then type: -./autogen.sh (For libofx CVS) -./configure (For a distributed tarball) -make -And as root type: -make install - -LibOFX <==> OpenSP compatibility matrix: -OpenSP version Status -1.3.4 (included in most NOT COMPATIBLE -distro with OpenJADE 1.3.1) OpenSP doesn't parse OFX files correctly - LibOFX < 0.23 will probably only output garbage. -1.4 NOT TESTED -1.5pre5 COMPATIBLE with all versions -1.5pre8 COMPATIBLE with LibOFX >= 0.23 -1.5 COMPATIBLE with LibOFX >= 0.23 - -FAQ: --------------------------------------------------------------------------------- - -(1) Getting "configure: error: unable to link a test program, is OpenSP installed?" - --BE CAREFUL: When you compile OpenSP, by default it will install in /usr/local. On many versions of linux (Most RedHat, All Mandrake up to 8.3) /usr/local/lib/ is not part of /etc/ld.so.conf . In this case LibOFX will either -1-Fail to link at all -2-Link with libosp.so.0 (1.3.4, which probably got installed as part of OpenJade) and not work. -Even if you add /usr/local/lib/ to /etc/ld.so.conf, LibOFX will probably still link with OpenSP 1.3.4 at runtime. Symptoms will be complaints of many unclosed statements when running ofxdump on an ofx file. - -I STRONGLY URGE YOU to avoid these problems and compile OpenSP using - ./configure --prefix=/usr -If you really want to install OpenSP in /usr/local/lib, you must add --with-opensp-libs=/usr/local/lib to libofx's ./configure or ./autogen.sh - - -(2) Problems compiling OpenSP 1.4 - -If you are getting errors like: -../include/Message.h:157: `class OpenSP::Messenger' is inaccessible nsgmls.cxx:60: within this context) - -Try to change private to protected in file OpenSP-1.4/nsgmls/RasEventHandler.h, on line 105. - -(3) ofxdump does now work right. It seems some values are cut in half, or one out of two letter is missing. - -LibOFX must know if OpenSP's was compiled with SP_MULTI_BYTE defined. The default is to assume that it was. If you see things such as "SAEET" instead of "STATEMENT" in ofxdump's output, try the following: -You can force libofx to assume that OpenSP was NOT compiled with SP_MULTI_BYTE defined by using: -./configure --with-no-opensp-multibyte -or for CVS: -./autogen.sh --with-no-opensp-multibyte - -Unfortunately, the auto-detection of this option was too fragile to release, because distros do not always distribute the config.h OpenSP was truly compiled with. If the devel package for opensp was not compiled at the same time as the lib, it may give wrong value. diff -Nru libofx-0.10.5/getopt/CMakeLists.txt libofx-0.10.9/getopt/CMakeLists.txt --- libofx-0.10.5/getopt/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/getopt/CMakeLists.txt 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,48 @@ +# SPDX-FileCopyrightText: 2022 Dawid Wróbel +# SPDX-License-Identifier: GPL-2.0-or-later + +include(CheckIncludeFile) +include(CheckSymbolExists) +check_include_file("getopt.h" HAVE_GETOPT_H) +check_symbol_exists("getopt_long" "getopt.h" HAVE_GETOPT_LONG) + +if (HAVE_GETOPT_H) + set(HAVE_GETOPT_H 1 PARENT_SCOPE) +endif () +if (HAVE_GETOPT_LONG) + set(HAVE_GETOPT_LONG 1 PARENT_SCOPE) +endif () + +# C library on non-POSIX systems does not come with `getopt` by default. +# Some third-party libraries, however, are commonly used. `vcpkg`, for example, provides `getopt-win32` for Windows, +# based on https://github.com/libimobiledevice-win32/getopt +# Another commonly-used implementation is https://github.com/takamin/win-c +find_library(GETOPT_LIBRARY NAMES getopt DOC "A non-glibc, external getopt library") + +if (GETOPT_LIBRARY) + message(STATUS "Found an external getopt library: ${GETOPT_LIBRARY}") + + if (NOT HAVE_GETOPT_LONG) + find_path(GETOPT_INCLUDE_DIR NAMES getopt.h) + if (GETOPT_INCLUDE_DIR) + message(STATUS "Found getopt includes: ${GETOPT_INCLUDE_DIR}") + else () + message(ERROR "Couldn't locate matching includes for the external library!") + endif () + endif () + + if (NOT TARGET getopt) + add_library(getopt UNKNOWN IMPORTED GLOBAL) + if (GETOPT_INCLUDE_DIR) + set_target_properties(getopt PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${GETOPT_INCLUDE_DIR}") + endif () + set_property(TARGET getopt APPEND PROPERTY IMPORTED_LOCATION "${GETOPT_LIBRARY}") + endif () +else () + # If we're not on POSIX system and an external library wasn't found, let's fallback to our copy of the glibc code + if (NOT HAVE_GETOPT_LONG AND NOT TARGET getopt) + message(STATUS "A 3rd-party getopt library was not found, so using own copy.") + add_library(getopt STATIC getopt.c getopt1.c getopt.h) + set_target_properties(getopt PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}") + endif () +endif () diff -Nru libofx-0.10.5/getopt/getopt1.c libofx-0.10.9/getopt/getopt1.c --- libofx-0.10.5/getopt/getopt1.c 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/getopt/getopt1.c 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,188 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "getopt.h" + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +#include +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +#define ELIDE_CODE +#endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +#include + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff -Nru libofx-0.10.5/getopt/getopt.c libofx-0.10.9/getopt/getopt.c --- libofx-0.10.5/getopt/getopt.c 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/getopt/getopt.c 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,1055 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. */ +# if defined HAVE_LIBINTL_H || defined _LIBC +# include +# ifndef _ +# define _(msgid) gettext (msgid) +# endif +# else +# define _(msgid) (msgid) +# endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +# include +# define my_index strchr +#else + +# if HAVE_STRING_H || defined(_MSC_VER) +# include +# else +# include +# endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (); +#endif + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Stored original parameters. + XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ +extern int __libc_argc; +extern char **__libc_argv; + +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +# ifdef USE_NONOPTION_FLAGS +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; +# endif + +# ifdef USE_NONOPTION_FLAGS +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +# else +# define SWAP_FLAGS(ch1, ch2) +# endif +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); +#endif +static const char * +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#if defined _LIBC && defined USE_NONOPTION_FLAGS + if (posixly_correct == NULL + && argc == __libc_argc && argv == __libc_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + int print_errors = opterr; + if (optstring[0] == ':') + print_errors = 0; + + if (argc < 1) + return -1; + + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#if defined _LIBC && defined USE_NONOPTION_FLAGS +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else if (long_only + || pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + } + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (print_errors) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (print_errors) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff -Nru libofx-0.10.5/getopt/getopt.h libofx-0.10.9/getopt/getopt.h --- libofx-0.10.5/getopt/getopt.h 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/getopt/getopt.h 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,180 @@ +/* Declarations for getopt. + Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _GETOPT_H + +#ifndef __need_getopt +# define _GETOPT_H 1 +#endif + +/* If __GNU_LIBRARY__ is not already defined, either we are being used + standalone, or this is the first header included in the source file. + If we are being used with glibc, we need to include , but + that does not exist if we are standalone. So: if __GNU_LIBRARY__ is + not defined, include , which will pull in for us + if it's from glibc. (Why ctype.h? It's guaranteed to exist and it + doesn't flood the namespace with stuff the way some other headers do.) */ +#if !defined __GNU_LIBRARY__ +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +#ifndef __need_getopt +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +# if (defined __STDC__ && __STDC__) || defined __cplusplus + const char *name; +# else + char *name; +# endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ + + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, `optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU `getopt'. + + The argument `--' causes premature termination of argument + scanning, explicitly telling `getopt' that there are no more + options. + + If OPTS begins with `--', then non-option arguments are treated as + arguments to the option '\0'. This behavior is specific to the GNU + `getopt'. */ + +#if (defined __STDC__ && __STDC__) || defined __cplusplus +# ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int __argc, char *const *__argv, const char *__shortopts); +# else /* not __GNU_LIBRARY__ */ +extern int getopt (); +# endif /* __GNU_LIBRARY__ */ + +# ifndef __need_getopt +extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts, + const struct option *__longopts, int *__longind); +extern int getopt_long_only (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only); +# endif +#else /* not __STDC__ */ +extern int getopt (); +# ifndef __need_getopt +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +# endif +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* getopt.h */ diff -Nru libofx-0.10.5/getopt/Makefile.am libofx-0.10.9/getopt/Makefile.am --- libofx-0.10.5/getopt/Makefile.am 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/getopt/Makefile.am 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,5 @@ +EXTRA_DIST = \ + CMakeLists.txt \ + getopt1.c \ + getopt.c \ + getopt.h diff -Nru libofx-0.10.5/.github/workflows/c-cpp.yml libofx-0.10.9/.github/workflows/c-cpp.yml --- libofx-0.10.5/.github/workflows/c-cpp.yml 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/.github/workflows/c-cpp.yml 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,46 @@ +name: C/C++ CI + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Prepare packages + run: | + sudo apt-get update + sudo apt-get install -y libxml++2.6-dev libosp-dev libcurl4-gnutls-dev libgetoptions-dev doc-base sgml-data + sudo apt-get install doxygen gengetopt + + - name: autotools + run: | + ./autogen.sh + mkdir build + + - name: configure + working-directory: build + run: ../configure + + - name: make + working-directory: build + run: make -j4 + + - name: make check + working-directory: build + run: make check && rm -rf doc/ofx_sample_files + + - name: make doc + working-directory: build + run: make doc + + - name: make distcheck + working-directory: build + run: make -j4 distcheck diff -Nru libofx-0.10.5/.github/workflows/cmake.yml libofx-0.10.9/.github/workflows/cmake.yml --- libofx-0.10.5/.github/workflows/cmake.yml 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/.github/workflows/cmake.yml 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,38 @@ +name: CMake + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. + # You can convert this to a matrix build if you need cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Prepare ubuntu packages + run: | + sudo apt-get update + sudo apt-get install -y libxml++2.6-dev libosp-dev libcurl4-gnutls-dev libgetoptions-dev doc-base sgml-data + + - name: Configure CMake + # Configure CMake in a 'build' subdirectory. + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + + - name: Build + # Build your program with the given configuration + run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + + - name: Test + working-directory: ${{github.workspace}}/build + # Execute tests defined by CMake configuration. + run: ctest -C ${{env.BUILD_TYPE}} diff -Nru libofx-0.10.5/.gitignore libofx-0.10.9/.gitignore --- libofx-0.10.5/.gitignore 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/.gitignore 2022-10-03 20:22:59.000000000 +0000 @@ -26,3 +26,9 @@ stamp-h.in stamp-h1 .vscode +build*/ +out/ +**/CMakeFiles/ +cmake_install.cmake +CMakeCache.txt +CMakeLists.txt.user diff -Nru libofx-0.10.5/inc/libofx.h.in libofx-0.10.9/inc/libofx.h.in --- libofx-0.10.5/inc/libofx.h.in 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/inc/libofx.h.in 2022-10-03 20:22:59.000000000 +0000 @@ -44,11 +44,22 @@ #ifdef IN_LIBOFX # include "config.h" -# ifdef HAVE_GCC_VISIBILITY_EXTS +# ifdef __GNUC__ # pragma GCC visibility push(default) # endif #endif +#ifdef LIBOFX_DLL +# ifdef IN_LIBOFX +# define LIBOFX_API __declspec(dllexport) +# else +# define LIBOFX_API __declspec(dllimport) +# endif +#else +#define LIBOFX_API +#endif + + #ifdef __cplusplus extern "C" { #else @@ -1436,24 +1447,24 @@ //@} -extern int ofx_PARSER_msg; /**< If set to true, parser events will be printed to the console */ -extern int ofx_DEBUG_msg;/**< If set to true, general debug messages will be printed to the console */ -extern int ofx_DEBUG1_msg;/**< If set to true, debug level 1 messages will be printed to the console */ -extern int ofx_DEBUG2_msg;/**< If set to true, debug level 2 messages will be printed to the console */ -extern int ofx_DEBUG3_msg;/**< If set to true, debug level 3 messages will be printed to the console */ -extern int ofx_DEBUG4_msg;/**< If set to true, debug level 4 messages will be printed to the console */ -extern int ofx_DEBUG5_msg;/**< If set to true, debug level 5 messages will be printed to the console */ -extern int ofx_STATUS_msg;/**< If set to true, status messages will be printed to the console */ -extern int ofx_INFO_msg;/**< If set to true, information messages will be printed to the console */ -extern int ofx_WARNING_msg;/**< If set to true, warning messages will be printed to the console */ -extern int ofx_ERROR_msg;/**< If set to true, error messages will be printed to the console */ -extern int ofx_show_position;/**< If set to true, the line number will be shown after any error */ +extern LIBOFX_API int ofx_PARSER_msg; /**< If set to true, parser events will be printed to the console */ +extern LIBOFX_API int ofx_DEBUG_msg;/**< If set to true, general debug messages will be printed to the console */ +extern LIBOFX_API int ofx_DEBUG1_msg;/**< If set to true, debug level 1 messages will be printed to the console */ +extern LIBOFX_API int ofx_DEBUG2_msg;/**< If set to true, debug level 2 messages will be printed to the console */ +extern LIBOFX_API int ofx_DEBUG3_msg;/**< If set to true, debug level 3 messages will be printed to the console */ +extern LIBOFX_API int ofx_DEBUG4_msg;/**< If set to true, debug level 4 messages will be printed to the console */ +extern LIBOFX_API int ofx_DEBUG5_msg;/**< If set to true, debug level 5 messages will be printed to the console */ +extern LIBOFX_API int ofx_STATUS_msg;/**< If set to true, status messages will be printed to the console */ +extern LIBOFX_API int ofx_INFO_msg;/**< If set to true, information messages will be printed to the console */ +extern LIBOFX_API int ofx_WARNING_msg;/**< If set to true, warning messages will be printed to the console */ +extern LIBOFX_API int ofx_ERROR_msg;/**< If set to true, error messages will be printed to the console */ +extern LIBOFX_API int ofx_show_position;/**< If set to true, the line number will be shown after any error */ #ifdef __cplusplus } // end of extern "C" #endif -#if defined(HAVE_GCC_VISIBILITY_EXTS) && defined(IN_LIBOFX) +#if __GNUC__ && defined(IN_LIBOFX) # pragma GCC visibility pop #endif diff -Nru libofx-0.10.5/lib/CMakeLists.txt libofx-0.10.9/lib/CMakeLists.txt --- libofx-0.10.5/lib/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/lib/CMakeLists.txt 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,73 @@ +set(ofx_SRCS + messages.cpp + ofx_utilities.cpp + file_preproc.cpp + context.cpp + ofx_preproc.cpp + ofx_container_generic.cpp + ofx_container_main.cpp + ofx_container_security.cpp + ofx_container_statement.cpp + ofx_container_account.cpp + ofx_container_transaction.cpp + ofx_container_position.cpp + ofx_containers_misc.cpp + ofx_request.cpp + ofx_request_accountinfo.cpp + ofx_request_statement.cpp + ofx_sgml.cpp + ofc_sgml.cpp +) + +set(ofx_HEADERS + messages.hh + ofx_preproc.hh + file_preproc.hh + context.hh + ofx_sgml.hh + ofc_sgml.hh + ofx_aggregate.hh + ofx_error_msg.hh + ofx_containers.hh + ofx_request.hh + ofx_request_accountinfo.hh + ofx_request_statement.hh + ofx_utilities.hh + tree.hh +) + +if (WIN32) + set(ofx_SRCS ${ofx_SRCS} win32.cpp) + set(ofx_HEADERS ${ofx_HEADERS} win32.hh) +endif () + +add_library(libofx ${ofx_SRCS} ${ofx_HEADERS}) +set_target_properties(libofx PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) +set_target_properties(libofx PROPERTIES SOVERSION ${LIBOFX_LIBRARY_SONAME}) +set_target_properties(libofx PROPERTIES VERSION ${LIBOFX_LIBRARY_VERSION}) +set_target_properties(libofx PROPERTIES PREFIX "") + +target_link_libraries(libofx OpenSP::OpenSP) +target_include_directories(libofx BEFORE + PUBLIC $ $ + PRIVATE ${CMAKE_BINARY_DIR} +) +target_compile_definitions(libofx PRIVATE IN_LIBOFX=1 MAKEFILE_DTD_PATH="${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/libofx/dtd/") + +if (CMAKE_COMPILER_IS_GNUCXX) + set_target_properties(libofx PROPERTIES CXX_VISIBILITY_PRESET hidden) +endif (CMAKE_COMPILER_IS_GNUCXX) + +if (MSVC) + set_target_properties(libofx PROPERTIES OUTPUT_NAME "ofx") +endif () + +if (Iconv_FOUND) + target_link_libraries(libofx Iconv::Iconv) +endif () + +install(TARGETS libofx + EXPORT LibOFXTargets + LIBRARY + DESTINATION ${CMAKE_INSTALL_LIBDIR} +) diff -Nru libofx-0.10.5/lib/getopt1.c libofx-0.10.9/lib/getopt1.c --- libofx-0.10.5/lib/getopt1.c 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/lib/getopt1.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,188 +0,0 @@ -/* getopt_long and getopt_long_only entry points for GNU getopt. - Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "getopt.h" - -#if !defined __STDC__ || !__STDC__ -/* This is a separate conditional since some stdc systems - reject `defined (const)'. */ -#ifndef const -#define const -#endif -#endif - -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#define GETOPT_INTERFACE_VERSION 2 -#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 -#include -#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION -#define ELIDE_CODE -#endif -#endif - -#ifndef ELIDE_CODE - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#include -#endif - -#ifndef NULL -#define NULL 0 -#endif - -int -getopt_long (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 0); -} - -/* Like getopt_long, but '-' as well as '--' can indicate a long option. - If an option that starts with '-' (not '--') doesn't match a long option, - but does match a short option, it is parsed as a short option - instead. */ - -int -getopt_long_only (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 1); -} - - -#endif /* Not ELIDE_CODE. */ - -#ifdef TEST - -#include - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - int option_index = 0; - static struct option long_options[] = - { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} - }; - - c = getopt_long (argc, argv, "abc:d:0123456789", - long_options, &option_index); - if (c == -1) - break; - - switch (c) - { - case 0: - printf ("option %s", long_options[option_index].name); - if (optarg) - printf (" with arg %s", optarg); - printf ("\n"); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case 'd': - printf ("option d with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff -Nru libofx-0.10.5/lib/getopt.c libofx-0.10.9/lib/getopt.c --- libofx-0.10.5/lib/getopt.c 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/lib/getopt.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1055 +0,0 @@ -/* Getopt for GNU. - NOTE: getopt is now part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to drepper@gnu.org - before changing it! - Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* This tells Alpha OSF/1 not to define a getopt prototype in . - Ditto for AIX 3.2 and . */ -#ifndef _NO_PROTO -# define _NO_PROTO -#endif - -#ifdef HAVE_CONFIG_H -# include -#endif - -#if !defined __STDC__ || !__STDC__ -/* This is a separate conditional since some stdc systems - reject `defined (const)'. */ -# ifndef const -# define const -# endif -#endif - -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#define GETOPT_INTERFACE_VERSION 2 -#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 -# include -# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION -# define ELIDE_CODE -# endif -#endif - -#ifndef ELIDE_CODE - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -/* Don't include stdlib.h for non-GNU C libraries because some of them - contain conflicting prototypes for getopt. */ -# include -# include -#endif /* GNU C library. */ - -#ifdef VMS -# include -# if HAVE_STRING_H - 0 -# include -# endif -#endif - -#ifndef _ -/* This is for other GNU distributions with internationalized messages. */ -# if defined HAVE_LIBINTL_H || defined _LIBC -# include -# ifndef _ -# define _(msgid) gettext (msgid) -# endif -# else -# define _(msgid) (msgid) -# endif -#endif - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Setting the environment variable POSIXLY_CORRECT disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - -#include "getopt.h" - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -/* 1003.2 says this must be 1 before any call. */ -int optind = 1; - -/* Formerly, initialization of getopt depended on optind==0, which - causes problems with re-calling getopt as programs generally don't - know that. */ - -int __getopt_initialized; - -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -int optopt = '?'; - -/* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters. - - PERMUTE is the default. We permute the contents of ARGV as we scan, - so that eventually all the non-options are at the end. This allows options - to be given in any order, even with programs that were not written to - expect this. - - RETURN_IN_ORDER is an option available to programs that were written - to expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. - Using `-' as the first character of the list of option characters - selects this mode of operation. - - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return -1 with `optind' != ARGC. */ - -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; - -/* Value of POSIXLY_CORRECT environment variable. */ -static char *posixly_correct; - -#ifdef __GNU_LIBRARY__ -/* We want to avoid inclusion of string.h with non-GNU libraries - because there are many ways it can cause trouble. - On some systems, it contains special magic macros that don't work - in GCC. */ -# include -# define my_index strchr -#else - -# if HAVE_STRING_H -# include -# else -# include -# endif - -/* Avoid depending on library functions or files - whose names are inconsistent. */ - -#ifndef getenv -extern char *getenv (); -#endif - -static char * -my_index (str, chr) - const char *str; - int chr; -{ - while (*str) - { - if (*str == chr) - return (char *) str; - str++; - } - return 0; -} - -/* If using GCC, we can safely declare strlen this way. - If not using GCC, it is ok not to declare it. */ -#ifdef __GNUC__ -/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. - That was relevant to code that was here before. */ -# if (!defined __STDC__ || !__STDC__) && !defined strlen -/* gcc with -traditional declares the built-in strlen to return int, - and has done so at least since version 2.4.5. -- rms. */ -extern int strlen (const char *); -# endif /* not __STDC__ */ -#endif /* __GNUC__ */ - -#endif /* not __GNU_LIBRARY__ */ - -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; - -#ifdef _LIBC -/* Stored original parameters. - XXX This is no good solution. We should rather copy the args so - that we can compare them later. But we must not use malloc(3). */ -extern int __libc_argc; -extern char **__libc_argv; - -/* Bash 2.0 gives us an environment variable containing flags - indicating ARGV elements that should not be considered arguments. */ - -# ifdef USE_NONOPTION_FLAGS -/* Defined in getopt_init.c */ -extern char *__getopt_nonoption_flags; - -static int nonoption_flags_max_len; -static int nonoption_flags_len; -# endif - -# ifdef USE_NONOPTION_FLAGS -# define SWAP_FLAGS(ch1, ch2) \ - if (nonoption_flags_len > 0) \ - { \ - char __tmp = __getopt_nonoption_flags[ch1]; \ - __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ - __getopt_nonoption_flags[ch2] = __tmp; \ - } -# else -# define SWAP_FLAGS(ch1, ch2) -# endif -#else /* !_LIBC */ -# define SWAP_FLAGS(ch1, ch2) -#endif /* _LIBC */ - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. - - `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. */ - -#if defined __STDC__ && __STDC__ -static void exchange (char **); -#endif - -static void -exchange (argv) - char **argv; -{ - int bottom = first_nonopt; - int middle = last_nonopt; - int top = optind; - char *tem; - - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - /* First make sure the handling of the `__getopt_nonoption_flags' - string can work normally. Our top argument must be in the range - of the string. */ - if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) - { - /* We must extend the array. The user plays games with us and - presents new arguments. */ - char *new_str = malloc (top + 1); - if (new_str == NULL) - nonoption_flags_len = nonoption_flags_max_len = 0; - else - { - memset (__mempcpy (new_str, __getopt_nonoption_flags, - nonoption_flags_max_len), - '\0', top + 1 - nonoption_flags_max_len); - nonoption_flags_max_len = top + 1; - __getopt_nonoption_flags = new_str; - } - } -#endif - - while (top > middle && middle > bottom) - { - if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } - else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - SWAP_FLAGS (bottom + i, middle + i); - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - - /* Update records for the slots the non-options now occupy. */ - - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; -} - -/* Initialize the internal data when the first call is made. */ - -#if defined __STDC__ && __STDC__ -static const char *_getopt_initialize (int, char *const *, const char *); -#endif -static const char * -_getopt_initialize (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; -{ - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - first_nonopt = last_nonopt = optind; - - nextchar = NULL; - - posixly_correct = getenv ("POSIXLY_CORRECT"); - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (posixly_correct != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - if (posixly_correct == NULL - && argc == __libc_argc && argv == __libc_argv) - { - if (nonoption_flags_max_len == 0) - { - if (__getopt_nonoption_flags == NULL - || __getopt_nonoption_flags[0] == '\0') - nonoption_flags_max_len = -1; - else - { - const char *orig_str = __getopt_nonoption_flags; - int len = nonoption_flags_max_len = strlen (orig_str); - if (nonoption_flags_max_len < argc) - nonoption_flags_max_len = argc; - __getopt_nonoption_flags = - (char *) malloc (nonoption_flags_max_len); - if (__getopt_nonoption_flags == NULL) - nonoption_flags_max_len = -1; - else - memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), - '\0', nonoption_flags_max_len - len); - } - } - nonoption_flags_len = nonoption_flags_max_len; - } - else - nonoption_flags_len = 0; -#endif - - return optstring; -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If `getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If `getopt' finds another option character, it returns that character, - updating `optind' and `nextchar' so that the next call to `getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, `getopt' returns -1. - Then `optind' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return '?' after printing an error message. If you set `opterr' to - zero, the error message is suppressed but we still return '?'. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `optarg'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in `optarg', otherwise `optarg' is set to zero. - - If OPTSTRING starts with `-' or `+', it requests different methods of - handling the non-option ARGV-elements. - See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - - Long-named options begin with `--' instead of `-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a `=', or else the in next ARGV-element. - When `getopt' finds a long-named option, it returns 0 if that option's - `flag' field is nonzero, the value of the option's `val' field - if the `flag' field is zero. - - The elements of ARGV aren't really const, because we permute them. - But we pretend they're const in the prototype to be compatible - with other systems. - - LONGOPTS is a vector of `struct option' terminated by an - element containing a name which is zero. - - LONGIND returns the index in LONGOPT of the long-named option found. - It is only valid when a long-named option has been found by the most - recent call. - - If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. */ - -int -_getopt_internal (argc, argv, optstring, longopts, longind, long_only) - int argc; - char *const *argv; - const char *optstring; - const struct option *longopts; - int *longind; - int long_only; -{ - int print_errors = opterr; - if (optstring[0] == ':') - print_errors = 0; - - if (argc < 1) - return -1; - - optarg = NULL; - - if (optind == 0 || !__getopt_initialized) - { - if (optind == 0) - optind = 1; /* Don't scan ARGV[0], the program name. */ - optstring = _getopt_initialize (argc, argv, optstring); - __getopt_initialized = 1; - } - - /* Test whether ARGV[optind] points to a non-option argument. - Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. The later information - is only used when the used in the GNU libc. */ -#if defined _LIBC && defined USE_NONOPTION_FLAGS -# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ - || (optind < nonoption_flags_len \ - && __getopt_nonoption_flags[optind] == '1')) -#else -# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') -#endif - - if (nextchar == NULL || *nextchar == '\0') - { - /* Advance to the next ARGV-element. */ - - /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ - if (last_nonopt > optind) - last_nonopt = optind; - if (first_nonopt > optind) - first_nonopt = optind; - - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; - - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (optind < argc && NONOPTION_P) - optind++; - last_nonopt = optind; - } - - /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (optind != argc && !strcmp (argv[optind], "--")) - { - optind++; - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return -1; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if (NONOPTION_P) - { - if (ordering == REQUIRE_ORDER) - return -1; - optarg = argv[optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if (longopts != NULL - && (argv[optind][1] == '-' - || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) - == (unsigned int) strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else if (long_only - || pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (print_errors) - fprintf (stderr, _("%s: option `%s' is ambiguous\n"), - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - optopt = 0; - return '?'; - } - - if (pfound != NULL) - { - option_index = indfound; - optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (print_errors) - { - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - _("%s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); - else - /* +option or -option */ - fprintf (stderr, - _("%s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[optind - 1][0], pfound->name); - } - - nextchar += strlen (nextchar); - - optopt = pfound->val; - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (print_errors) - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' - || my_index (optstring, *nextchar) == NULL) - { - if (print_errors) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf (stderr, _("%s: unrecognized option `--%s'\n"), - argv[0], nextchar); - else - /* +option or -option */ - fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), - argv[0], argv[optind][0], nextchar); - } - nextchar = (char *) ""; - optind++; - optopt = 0; - return '?'; - } - } - - /* Look at and handle the next short option-character. */ - - { - char c = *nextchar++; - char *temp = my_index (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; - - if (temp == NULL || c == ':') - { - if (print_errors) - { - if (posixly_correct) - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, _("%s: illegal option -- %c\n"), - argv[0], c); - else - fprintf (stderr, _("%s: invalid option -- %c\n"), - argv[0], c); - } - optopt = c; - return '?'; - } - /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';') - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; - - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - - /* optarg is now the argument, see if it's in the - table of longopts. */ - - for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) - { - if (print_errors) - fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - return '?'; - } - if (pfound != NULL) - { - option_index = indfound; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (print_errors) - fprintf (stderr, _("\ -%s: option `-W %s' doesn't allow an argument\n"), - argv[0], pfound->name); - - nextchar += strlen (nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (print_errors) - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - nextchar = NULL; - return 'W'; /* Let the application handle it. */ - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = NULL; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, - _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } -} - -int -getopt (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; -{ - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); -} - -#endif /* Not ELIDE_CODE. */ - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of `getopt'. */ - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == -1) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff -Nru libofx-0.10.5/lib/gnugetopt.h libofx-0.10.9/lib/gnugetopt.h --- libofx-0.10.5/lib/gnugetopt.h 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/lib/gnugetopt.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,180 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _GETOPT_H - -#ifndef __need_getopt -# define _GETOPT_H 1 -#endif - -/* If __GNU_LIBRARY__ is not already defined, either we are being used - standalone, or this is the first header included in the source file. - If we are being used with glibc, we need to include , but - that does not exist if we are standalone. So: if __GNU_LIBRARY__ is - not defined, include , which will pull in for us - if it's from glibc. (Why ctype.h? It's guaranteed to exist and it - doesn't flood the namespace with stuff the way some other headers do.) */ -#if !defined __GNU_LIBRARY__ -# include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int opterr; - -/* Set to an option character which was unrecognized. */ - -extern int optopt; - -#ifndef __need_getopt -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct option -{ -# if (defined __STDC__ && __STDC__) || defined __cplusplus - const char *name; -# else - char *name; -# endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -# define no_argument 0 -# define required_argument 1 -# define optional_argument 2 -#endif /* need getopt */ - - -/* Get definitions and prototypes for functions to process the - arguments in ARGV (ARGC of them, minus the program name) for - options given in OPTS. - - Return the option character from OPTS just read. Return -1 when - there are no more options. For unrecognized options, or options - missing arguments, `optopt' is set to the option letter, and '?' is - returned. - - The OPTS string is a list of characters which are recognized option - letters, optionally followed by colons, specifying that that letter - takes an argument, to be placed in `optarg'. - - If a letter in OPTS is followed by two colons, its argument is - optional. This behavior is specific to the GNU `getopt'. - - The argument `--' causes premature termination of argument - scanning, explicitly telling `getopt' that there are no more - options. - - If OPTS begins with `--', then non-option arguments are treated as - arguments to the option '\0'. This behavior is specific to the GNU - `getopt'. */ - -#if (defined __STDC__ && __STDC__) || defined __cplusplus -# ifdef __GNU_LIBRARY__ -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ -extern int getopt (int __argc, char *const *__argv, const char *__shortopts); -# else /* not __GNU_LIBRARY__ */ -extern int getopt (); -# endif /* __GNU_LIBRARY__ */ - -# ifndef __need_getopt -extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts, - const struct option *__longopts, int *__longind); -extern int getopt_long_only (int __argc, char *const *__argv, - const char *__shortopts, - const struct option *__longopts, int *__longind); - -/* Internal only. Users should not call this directly. */ -extern int _getopt_internal (int __argc, char *const *__argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - int __long_only); -# endif -#else /* not __STDC__ */ -extern int getopt (); -# ifndef __need_getopt -extern int getopt_long (); -extern int getopt_long_only (); - -extern int _getopt_internal (); -# endif -#endif /* __STDC__ */ - -#ifdef __cplusplus -} -#endif - -/* Make sure we later can get all the definitions and declarations. */ -#undef __need_getopt - -#endif /* getopt.h */ diff -Nru libofx-0.10.5/lib/Makefile.am libofx-0.10.9/lib/Makefile.am --- libofx-0.10.5/lib/Makefile.am 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/lib/Makefile.am 2022-10-03 20:22:59.000000000 +0000 @@ -1,6 +1,6 @@ lib_LTLIBRARIES = libofx.la -EXTRA_DIST = gnugetopt.h getopt.c getopt1.c +EXTRA_DIST = CMakeLists.txt libofx_la_SOURCES = messages.cpp \ ofx_utilities.cpp \ @@ -45,8 +45,8 @@ -I${OPENSPINCLUDES} \ -DMAKEFILE_DTD_PATH=\"${LIBOFX_DTD_DIR}\" -#libofx_la_LIBADD = @LIBOBJS@ ${OPENSPLIBS} -lstdc++ -libofx_la_LIBADD = $(OPENSPLIBS) $(ICONV_LIBS) -lstdc++ +#libofx_la_LIBADD = @LIBOBJS@ ${OPENSPLIBS} +libofx_la_LIBADD = $(OPENSPLIBS) $(ICONV_LIBS) libofx_la_LDFLAGS = -no-undefined -version-info @LIBOFX_SO_CURRENT@:@LIBOFX_SO_REVISION@:@LIBOFX_SO_AGE@ diff -Nru libofx-0.10.5/lib/messages.cpp libofx-0.10.9/lib/messages.cpp --- libofx-0.10.5/lib/messages.cpp 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/lib/messages.cpp 2022-10-03 20:22:59.000000000 +0000 @@ -24,21 +24,27 @@ #include "config.h" #include "libofx.h" +#ifdef LIBOFX_DLL +# define LIBOFX_API __declspec(dllexport) +#else +# define LIBOFX_API +#endif + SGMLApplication::OpenEntityPtr entity_ptr; /**< Global for determining the line number in OpenSP */ SGMLApplication::Position position; /**< Global for determining the line number in OpenSP */ -int ofx_PARSER_msg = false; /**< If set to true, parser events will be printed to the console */ -int ofx_DEBUG_msg = false;/**< If set to true, general debug messages will be printed to the console */ -int ofx_DEBUG1_msg = false;/**< If set to true, debug level 1 messages will be printed to the console */ -int ofx_DEBUG2_msg = false;/**< If set to true, debug level 2 messages will be printed to the console */ -int ofx_DEBUG3_msg = false;/**< If set to true, debug level 3 messages will be printed to the console */ -int ofx_DEBUG4_msg = false;/**< If set to true, debug level 4 messages will be printed to the console */ -int ofx_DEBUG5_msg = false;/**< If set to true, debug level 5 messages will be printed to the console */ -int ofx_STATUS_msg = false;/**< If set to true, status messages will be printed to the console */ -int ofx_INFO_msg = false;/**< If set to true, information messages will be printed to the console */ -int ofx_WARNING_msg = false;/**< If set to true, warning messages will be printed to the console */ -int ofx_ERROR_msg = true;/**< If set to true, error messages will be printed to the console */ -int ofx_show_position = true;/**< If set to true, the line number will be shown after any error */ +LIBOFX_API int ofx_PARSER_msg = false; /**< If set to true, parser events will be printed to the console */ +LIBOFX_API int ofx_DEBUG_msg = false;/**< If set to true, general debug messages will be printed to the console */ +LIBOFX_API int ofx_DEBUG1_msg = false;/**< If set to true, debug level 1 messages will be printed to the console */ +LIBOFX_API int ofx_DEBUG2_msg = false;/**< If set to true, debug level 2 messages will be printed to the console */ +LIBOFX_API int ofx_DEBUG3_msg = false;/**< If set to true, debug level 3 messages will be printed to the console */ +LIBOFX_API int ofx_DEBUG4_msg = false;/**< If set to true, debug level 4 messages will be printed to the console */ +LIBOFX_API int ofx_DEBUG5_msg = false;/**< If set to true, debug level 5 messages will be printed to the console */ +LIBOFX_API int ofx_STATUS_msg = false;/**< If set to true, status messages will be printed to the console */ +LIBOFX_API int ofx_INFO_msg = false;/**< If set to true, information messages will be printed to the console */ +LIBOFX_API int ofx_WARNING_msg = false;/**< If set to true, warning messages will be printed to the console */ +LIBOFX_API int ofx_ERROR_msg = true;/**< If set to true, error messages will be printed to the console */ +LIBOFX_API int ofx_show_position = true;/**< If set to true, the line number will be shown after any error */ void show_line_number() { diff -Nru libofx-0.10.5/lib/ofc_sgml.cpp libofx-0.10.9/lib/ofc_sgml.cpp --- libofx-0.10.5/lib/ofc_sgml.cpp 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/lib/ofc_sgml.cpp 2022-10-03 20:22:59.000000000 +0000 @@ -63,8 +63,7 @@ */ void startElement (const StartElementEvent & event) { - std::string identifier; - CharStringtostring (event.gi, identifier); + std::string identifier = CharStringtostring (event.gi); message_out(PARSER, "startElement event received from OpenSP for element " + identifier); position = event.pos; @@ -116,7 +115,7 @@ { message_out (PARSER, "Element " + identifier + " found"); //STMTRS ignored, we will process it's attributes directly inside the STATEMENT, - if (curr_container_element->type != "STATEMENT") + if (curr_container_element == NULL || curr_container_element->type != "STATEMENT") { message_out(ERROR, "Element " + identifier + " found while not inside a STATEMENT container"); } @@ -208,11 +207,8 @@ */ void endElement (const EndElementEvent & event) { - std::string identifier; - bool end_element_for_data_element; - - CharStringtostring (event.gi, identifier); - end_element_for_data_element = is_data_element; + std::string identifier = CharStringtostring (event.gi); + bool end_element_for_data_element = is_data_element; message_out(PARSER, "endElement event received from OpenSP for element " + identifier); position = event.pos; @@ -293,7 +289,6 @@ void error (const ErrorEvent & event) { std::string message; - std::string string_buf; OfxMsgType error_type = ERROR; position = event.pos; @@ -327,7 +322,7 @@ default: message = message + "OpenSP sent an unknown error to LibOFX (You probably have a newer version of OpenSP):"; } - message = message + "\n" + CharStringtostring (event.message, string_buf); + message = message + "\n" + CharStringtostring (event.message); message_out (error_type, message); } diff -Nru libofx-0.10.5/lib/ofx_container_account.cpp libofx-0.10.9/lib/ofx_container_account.cpp --- libofx-0.10.5/lib/ofx_container_account.cpp 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/lib/ofx_container_account.cpp 2022-10-03 20:22:59.000000000 +0000 @@ -50,7 +50,9 @@ OFX elements will set this attribute elsewhere */ ASSIGN(data.account_type, data.OFX_INVESTMENT); } - if (parentcontainer != NULL && ((OfxStatementContainer*)parentcontainer)->data.currency_valid == true) + if (parentcontainer != NULL + && parentcontainer->type == "STATEMENT" + && ((OfxStatementContainer*)parentcontainer)->data.currency_valid == true) { ASSIGN_STRNCPY(data.currency, std::string(((OfxStatementContainer*)parentcontainer)->data.currency)); } diff -Nru libofx-0.10.5/lib/ofx_container_main.cpp libofx-0.10.9/lib/ofx_container_main.cpp --- libofx-0.10.5/lib/ofx_container_main.cpp 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/lib/ofx_container_main.cpp 2022-10-03 20:22:59.000000000 +0000 @@ -59,7 +59,9 @@ message_out(DEBUG, "OfxMainContainer::add_container for element " + container->tag_identifier + "; destroying the generic container"); /* Call gen_event anyway, it could be a status container or similar */ container->gen_event(); - delete container; + if (container != this) { + delete container; + } return 0; } diff -Nru libofx-0.10.5/lib/ofx_preproc.cpp libofx-0.10.9/lib/ofx_preproc.cpp --- libofx-0.10.5/lib/ofx_preproc.cpp 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/lib/ofx_preproc.cpp 2022-10-03 20:22:59.000000000 +0000 @@ -35,13 +35,13 @@ #include #endif -#ifdef __WIN32__ +#ifdef _WIN32 # define DIRSEP "\\" #else # define DIRSEP "/" #endif -#ifdef __WIN32__ +#ifdef _WIN32 # include "win32.hh" # include // for GetModuleFileName() # undef ERROR @@ -107,7 +107,7 @@ mkTempFileName("libofxtmpXXXXXX", tmp_filename, sizeof(tmp_filename)); message_out(DEBUG, "ofx_proc_file(): Creating temp file: " + std::string(tmp_filename)); -#ifdef __WIN32__ +#ifdef _WIN32 tmp_file_fd = mkstemp_win32(tmp_filename); #else tmp_file_fd = mkstemp(tmp_filename); @@ -190,20 +190,23 @@ } message_out(DEBUG, "ofx_proc_file(): or has been found"); + static char sp_charset_fixed[] = "SP_CHARSET_FIXED=1"; + if (putenv(sp_charset_fixed) != 0) + { + message_out(ERROR, "ofx_proc_file(): putenv failed"); + } +#define OPENSP_UTF8_WARNING_TEXT "ofx_proc_file(): OpenSP cannot process an UTF-8 XML file without garbling it. Furthermore, on windows the support for UTF-8 encode SGML files is broken. This is worked around by forcing a single byte encoding. If the file is indeed UTF-8, it should pass through unmolested, but you will likely get 'non SGML character number' errors, even though the output is correct." if (file_is_xml == true) { - static char sp_charset_fixed[] = "SP_CHARSET_FIXED=1"; - if (putenv(sp_charset_fixed) != 0) - { - message_out(ERROR, "ofx_proc_file(): putenv failed"); - } - /* Normally the following would be "xml". - * Unfortunately, opensp's generic api will garble UTF-8 if this is - * set to xml. So we set any single byte encoding to avoid messing - * up UTF-8. Unfortunately this means that non-UTF-8 files will not - * get properly translated. We'd need to manually detect the - * encoding in the XML header and convert the xml with iconv like we - * do for SGML to work around the problem. Most unfortunate. */ + /* Normally the following would be "SP_ENCODING=xml". + * Unfortunately, opensp's generic api will garble UTF-8 if this + * is set to xml. So we set a single byte encoding that uses most + * values to avoid messing up the UTF-8. + * Unfortunately this means that non-UTF-8 files will not + * get properly translated. We'd need to manually detect the + * encoding in the XML header and convert the xml with iconv like + * we do for SGML to work around the problem. Most unfortunate. */ + message_out(WARNING, OPENSP_UTF8_WARNING_TEXT); static char sp_encoding[] = "SP_ENCODING=ms-dos"; if (putenv(sp_encoding) != 0) { @@ -212,12 +215,7 @@ } else { - static char sp_charset_fixed[] = "SP_CHARSET_FIXED=1"; - if (putenv(sp_charset_fixed) != 0) - { - message_out(ERROR, "ofx_proc_file(): putenv failed"); - } - static char sp_encoding[] = "SP_ENCODING=ms-dos"; //Any single byte encoding will do, we don't want opensp messing up UTF-8; + static char sp_encoding[] = "SP_ENCODING=ms-dos"; // Like the above, force a single byte encoding in every case, we don't want opensp messing up UTF-8 if (putenv(sp_encoding) != 0) { message_out(ERROR, "ofx_proc_file(): putenv failed"); @@ -250,6 +248,7 @@ { //While "UNICODE" isn't a legal value, some cyrilic files do specify it as such... fromcode = "UTF-8"; + message_out(WARNING, OPENSP_UTF8_WARNING_TEXT); } else { @@ -270,8 +269,9 @@ //Header processing header_name.assign(s_buffer.substr(0, header_separator_idx)); header_value.assign(s_buffer.substr(header_separator_idx + 1)); - while ( header_value[header_value.length() - 1 ] == '\n' || - header_value[header_value.length() - 1 ] == '\r' ) + while ( header_value.length() > 0 && + ( header_value[header_value.length() - 1 ] == '\n' || + header_value[header_value.length() - 1 ] == '\r' )) header_value.erase(header_value.length() - 1); message_out(DEBUG, "ofx_proc_file():Header: " + header_name + " with value: " + header_value + " has been found"); if (header_name.compare("ENCODING") == 0) @@ -309,8 +309,12 @@ const char* inchar = s_buffer.c_str(); char * outchar = iconv_buffer; int iconv_retval = iconv (conversion_descriptor, - const_cast(&inchar), &inbytesleft, - &outchar, &outbytesleft); +#ifdef HAVE_ICONV_CONST + &inchar, +#else + const_cast(&inchar), +#endif + &inbytesleft, &outchar, &outbytesleft); if (iconv_retval == -1) { message_out(ERROR, "ofx_proc_file(): Iconv conversion error"); @@ -511,7 +515,7 @@ } -#ifdef __WIN32__ +#ifdef _WIN32 static std::string get_dtd_installation_directory() { // Partial implementation of @@ -544,10 +548,11 @@ It will look, in (order) - 1- The environment variable OFX_DTD_PATH (if present) + 1- A folder set by libofx_set_dtd_dir(), if any 2- On windows only, a relative path specified by get_dtd_installation_directory() - 3- The path specified by the makefile in MAKEFILE_DTD_PATH, thru LIBOFX_DTD_DIR in configure (if present) - 4- Any hardcoded paths in DTD_SEARCH_PATH + 3- The environment variable OFX_DTD_PATH (if present) + 4- The path specified by the makefile in MAKEFILE_DTD_PATH, thru LIBOFX_DTD_DIR in configure (if present) + 5- Any hardcoded paths in DTD_SEARCH_PATH */ std::string find_dtd(LibofxContextPtr ctx, const std::string& dtd_filename) { @@ -566,7 +571,7 @@ } } -#ifdef __WIN32__ +#ifdef _WIN32 dtd_path_filename = get_dtd_installation_directory(); if (!dtd_path_filename.empty()) { @@ -584,7 +589,7 @@ env_dtd_path = getenv("OFX_DTD_PATH"); if (env_dtd_path) { - dtd_path_filename.append(env_dtd_path); + dtd_path_filename = env_dtd_path; dtd_path_filename.append(DIRSEP); dtd_path_filename.append(dtd_filename); std::ifstream dtd_file(dtd_path_filename.c_str()); diff -Nru libofx-0.10.5/lib/ofx_sgml.cpp libofx-0.10.9/lib/ofx_sgml.cpp --- libofx-0.10.5/lib/ofx_sgml.cpp 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/lib/ofx_sgml.cpp 2022-10-03 20:22:59.000000000 +0000 @@ -37,6 +37,7 @@ OfxMainContainer * MainContainer = NULL; extern SGMLApplication::OpenEntityPtr entity_ptr; extern SGMLApplication::Position position; +static const std::string MESSAGE_NON_SGML_CHAR = "non SGML character"; /** \brief This object is driven by OpenSP as it parses the SGML from the ofx file(s) @@ -49,6 +50,7 @@ bool is_data_element; /**< If the SGML element contains data, this flag is raised */ std::string incoming_data; /**< The raw data from the SGML data element */ LibofxContext * libofx_context; + unsigned errorCountToIgnore = 0; public: @@ -64,14 +66,15 @@ message_out(DEBUG, "Entering the OFXApplication's destructor"); } + unsigned getErrorCountToIgnore() const { return errorCountToIgnore; } + /** \brief Callback: Start of an OFX element * An OpenSP callback, get's called when the opening tag of an OFX element appears in the file */ void startElement (const StartElementEvent & event) { - std::string identifier; - CharStringtostring (event.gi, identifier); + std::string identifier = CharStringtostring (event.gi); message_out(PARSER, "startElement event received from OpenSP for element " + identifier); position = event.pos; @@ -137,7 +140,7 @@ else if (identifier == "STMTTRN") { message_out (PARSER, "Element " + identifier + " found"); - if (curr_container_element->type == "INVESTMENT") + if (curr_container_element && curr_container_element->type == "INVESTMENT") { //push up to the INVBANKTRAN OfxInvestmentTransactionContainer curr_container_element = new OfxPushUpContainer (libofx_context, curr_container_element, identifier); @@ -197,10 +200,11 @@ { message_out (PARSER, "Element " + identifier + " found"); /* check the container to avoid creating multiple statements for TRANSFERs */ - if (curr_container_element->type == "STATEMENT" + if (curr_container_element && + ( curr_container_element->type == "STATEMENT" || curr_container_element->tag_identifier == "BANKACCTINFO" || curr_container_element->tag_identifier == "CCACCTINFO" - || curr_container_element->tag_identifier == "INVACCTINFO") + || curr_container_element->tag_identifier == "INVACCTINFO")) curr_container_element = new OfxAccountContainer (libofx_context, curr_container_element, identifier); else // no new account or statement for a @@ -266,11 +270,8 @@ */ void endElement (const EndElementEvent & event) { - std::string identifier; - bool end_element_for_data_element; - - CharStringtostring (event.gi, identifier); - end_element_for_data_element = is_data_element; + std::string identifier = CharStringtostring (event.gi); + bool end_element_for_data_element = is_data_element; message_out(PARSER, "endElement event received from OpenSP for element " + identifier); position = event.pos; @@ -375,8 +376,8 @@ void error (const ErrorEvent & event) { std::string message; - std::string string_buf; OfxMsgType error_type = ERROR; + const std::string eventMessage = CharStringtostring (event.message); position = event.pos; message = message + "OpenSP parser: "; @@ -395,8 +396,18 @@ error_type = ERROR; break; case SGMLApplication::ErrorEvent::otherError: - message = message + "otherError (misc parse error):"; - error_type = ERROR; + // #60: If the SGML parser encounters a non-ascii char, it sends an error + // message, even though those characters are being forwarded just fine. + // Hence we count the occurrence of those errors and subtract it from the + // final number of errors. + if (eventMessage.find(MESSAGE_NON_SGML_CHAR) != std::string::npos) { + ++errorCountToIgnore; + message = message + "ignored character error:"; + error_type = INFO; + } else { + message = message + "otherError (misc parse error):"; + error_type = ERROR; + } break; case SGMLApplication::ErrorEvent::warning: message = message + "warning (Not actually an error.):"; @@ -409,7 +420,7 @@ default: message = message + "OpenSP sent an unknown error to LibOFX (You probably have a newer version of OpenSP):"; } - message = message + "\n" + CharStringtostring (event.message, string_buf); + message = message + "\n" + eventMessage; message_out (error_type, message); } @@ -443,7 +454,8 @@ EventGenerator *egp = parserKit.makeEventGenerator (argc, argv); egp->inhibitMessages (true); /* Error output is handled by libofx not OpenSP */ OFXApplication app(libofx_context); - unsigned nErrors = egp->run (app); /* Begin parsing */ + unsigned originalErrorCount = egp->run (app); /* Begin parsing */ + unsigned nErrors = originalErrorCount - app.getErrorCountToIgnore(); // but ignore certain known errors that we want to ignore delete egp; //Note that this is where bug is triggered return nErrors > 0; } diff -Nru libofx-0.10.5/lib/ofx_utilities.cpp libofx-0.10.9/lib/ofx_utilities.cpp --- libofx-0.10.5/lib/ofx_utilities.cpp 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/lib/ofx_utilities.cpp 2022-10-03 20:22:59.000000000 +0000 @@ -28,7 +28,7 @@ #include "messages.hh" #include "ofx_utilities.hh" -#ifdef __WIN32__ +#ifdef _WIN32 # define DIRSEP "\\" /* MSWin calls it _mkgmtime instead of timegm */ # define timegm(tm) _mkgmtime(tm) @@ -37,58 +37,22 @@ #endif -/** - Convert an OpenSP CharString directly to a C++ stream, to enable the use of cout directly for debugging. -*/ -/*ostream &operator<<(ostream &os, SGMLApplication::CharString s) - { - for (size_t i = 0; i < s.len; i++) - { - os << ((char *)(s.ptr))[i*sizeof(SGMLApplication::Char)]; - } - return os; - }*/ - -/*wostream &operator<<(wostream &os, SGMLApplication::CharString s) - { - for (size_t i = 0; i < s.len; i++) - {//cout<(source.ptr[i]); } - return dest; + return result; } -std::string AppendCharStringtostring(const SGMLApplication::CharString source, std::string &dest) +void AppendCharStringtostring(const SGMLApplication::CharString source, std::string &dest) { - size_t i; - for (i = 0; i < source.len; i++) - { - dest += (char)(((source.ptr)[i])); - } - return dest; + const std::string toBeAppended = CharStringtostring(source); + dest.append(toBeAppended); } /** @@ -234,7 +198,7 @@ if (var) return var; var = getenv("TEMP"); if (var) return var; -#ifdef __WIN32__ +#ifdef _WIN32 return "C:\\"; #else return "/tmp"; diff -Nru libofx-0.10.5/lib/ofx_utilities.hh libofx-0.10.9/lib/ofx_utilities.hh --- libofx-0.10.5/lib/ofx_utilities.hh 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/lib/ofx_utilities.hh 2022-10-03 20:22:59.000000000 +0000 @@ -51,17 +51,11 @@ */ #define ASSIGN_STRNCPY(DEST, VALUE) STRNCPY(DEST, VALUE); DEST ## _valid = true -///Convert OpenSP CharString to a C++ stream -std::ostream &operator<<(std::ostream &os, SGMLApplication::CharString s); - -///Convert OpenSP CharString and put it in the C wchar_t string provided -wchar_t* CharStringtowchar_t(SGMLApplication::CharString source, wchar_t *dest); - ///Convert OpenSP CharString to a C++ STL string -std::string CharStringtostring(const SGMLApplication::CharString source, std::string &dest); +std::string CharStringtostring(const SGMLApplication::CharString source); ///Append an OpenSP CharString to an existing C++ STL string -std::string AppendCharStringtostring(const SGMLApplication::CharString source, std::string &dest); +void AppendCharStringtostring(const SGMLApplication::CharString source, std::string &dest); ///Convert a C++ string containing a time in OFX format to a C time_t time_t ofxdate_to_time_t(const std::string& ofxdate); diff -Nru libofx-0.10.5/lib/win32.cpp libofx-0.10.9/lib/win32.cpp --- libofx-0.10.5/lib/win32.cpp 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/lib/win32.cpp 2022-10-03 20:22:59.000000000 +0000 @@ -18,14 +18,24 @@ #include #include #include +#ifdef HAVE_UNISTD_H #include +#endif #include #include #include -#ifdef __WIN32__ +#ifdef _WIN32 + +#ifdef _MSC_VER +#include +#include +#define strcasecmp strcmpi +#define snprintf _snprintf +#define open _open +#endif int mkstemp_win32(char *tmpl) { diff -Nru libofx-0.10.5/lib/win32.hh libofx-0.10.9/lib/win32.hh --- libofx-0.10.5/lib/win32.hh 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/lib/win32.hh 2022-10-03 20:22:59.000000000 +0000 @@ -21,7 +21,7 @@ #endif -#ifdef __WIN32__ +#ifdef _WIN32 int mkstemp_win32(char *tmpl); diff -Nru libofx-0.10.5/LibOFXConfig.cmake.in libofx-0.10.9/LibOFXConfig.cmake.in --- libofx-0.10.5/LibOFXConfig.cmake.in 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/LibOFXConfig.cmake.in 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,39 @@ +# LibOFXConfig.cmake provides information about the installed LibOFX library. +# It can be used directly from CMake via find_package(libofx NO_MODULE) +# +# The following CMake variables are provided: +# LibOFX_INCLUDE_DIR - the include directory +# LibOFX_LIBDIR - the library directory +# LibOFX_DATADIR - the data dir, contains the .dtd/.dcl files +# +# The following imported library targets are created, which may be used directly +# with target_link_libraries(): +# libofx::libofx - the LibOFX library + +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/LibOFXTargets.cmake") + +include(CMakeFindDependencyMacro) + +if (${CMAKE_VERSION} VERSION_LESS 3.25.0) + set("${CMAKE_FIND_PACKAGE_NAME}_CMAKE_MODULE_PATH_save" "${CMAKE_MODULE_PATH}") + list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}") + + find_dependency(OpenSP) + + set(CMAKE_MODULE_PATH "${${CMAKE_FIND_PACKAGE_NAME}_CMAKE_MODULE_PATH_save}") + unset("${CMAKE_FIND_PACKAGE_NAME}_CMAKE_MODULE_PATH_save") +else() + find_dependency(OpenSP) +endif() + +if(@ENABLE_ICONV@) + find_dependency(Iconv) +endif() + +set_and_check(LibOFX_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@") +set_and_check(LibOFX_LIBDIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@") +set_and_check(LibOFX_DATADIR "@PACKAGE_CMAKE_INSTALL_DATADIR@") + +check_required_components(LibOFX) diff -Nru libofx-0.10.5/Makefile.am libofx-0.10.9/Makefile.am --- libofx-0.10.5/Makefile.am 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/Makefile.am 2022-10-03 20:22:59.000000000 +0000 @@ -1,10 +1,19 @@ ACLOCAL_AMFLAGS = -I m4 +if BUILD_OFX2QIF + MAYBE_OFX2QIF = ofx2qif +endif + +if BUILD_OFXDUMP + MAYBE_OFXDUMP = ofxdump +endif + if BUILD_OFXCONNECT MAYBE_OFXCONNECT = ofxconnect endif -DIST_SUBDIRS = m4 inc dtd lib doc . ofx2qif ofxdump ofxconnect -SUBDIRS = m4 inc dtd lib doc . ofx2qif ofxdump $(MAYBE_OFXCONNECT) + +DIST_SUBDIRS = m4 inc dtd lib doc . getopt ofx2qif ofxdump ofxconnect +SUBDIRS = m4 inc dtd lib doc . $(MAYBE_OFX2QIF) $(MAYBE_OFXDUMP) $(MAYBE_OFXCONNECT) doc_DATA = \ AUTHORS \ @@ -16,6 +25,10 @@ totest.txt EXTRA_DIST = \ + CMakeLists.txt \ + cmake/modules/FindOpenSP.cmake \ + config.h.cmake \ + LibOFXConfig.cmake.in \ libofx.spec.in \ libofx.spec \ libofx.pc \ diff -Nru libofx-0.10.5/NEWS libofx-0.10.9/NEWS --- libofx-0.10.5/NEWS 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/NEWS 2022-10-03 20:22:59.000000000 +0000 @@ -1,3 +1,34 @@ +2022-10-03, LibOFX 0.10.9: + +- Fix library name on Windows (#88) +- Fix several more memory issues (#90) + +2022-09-27, LibOFX 0.10.8: + + - Fix null pointer dereference bugs (#87) + - Initial support for exporting Config.cmake with targets (#81) + - Fix version and tools description in vcpkg.json + - Add cpack rules for "make source_package" + - Fix installation path of libofx.h (#83) + - Rename some variables that shadowed others to clarify different meanings #75 (#80) + +2022-09-08, LibOFX 0.10.7: + + - autotools: fix LIBOFX_MAJOR_VERSION and friends in libofx.h (#76) + - CMake: miscellaneous fixes (#73) + +2022-09-04, LibOFX 0.10.6: + + - Update FindOpenSP; also allow to forcefully ENABLE SP_MULTI_BYTE (#71) + - Add support for CMake build system (#63) + - Minor code cleanup in CharStringtostring function and its header (#65) + - Ignore SGML parser character error because the char is accepted fine (#60) (#64) + - Fix find_dtd() when OFX_DTD_PATH env var is used (#66) + - Add ./configure option to disable CLI tools + - Only link ofx2qif against C++ STD lib + - Win32 code fixes for MSVC compilation + - Don't deconst iconv input buffer under Windows (#51) + 2022-04-19, LibOFX 0.10.5: - Fix missing include for ptrdiff_t on Homebrew (#57) diff -Nru libofx-0.10.5/ofx2qif/CMakeLists.txt libofx-0.10.9/ofx2qif/CMakeLists.txt --- libofx-0.10.5/ofx2qif/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/ofx2qif/CMakeLists.txt 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2022 Dawid Wróbel +# SPDX-License-Identifier: GPL-2.0-or-later + +set(ofx2qif_SRCS + ofx2qif.c +) + +add_executable(ofx2qif ${ofx2qif_SRCS}) +target_link_libraries(ofx2qif libofx) + +install(TARGETS ofx2qif RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff -Nru libofx-0.10.5/ofx2qif/Makefile.am libofx-0.10.9/ofx2qif/Makefile.am --- libofx-0.10.5/ofx2qif/Makefile.am 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/ofx2qif/Makefile.am 2022-10-03 20:22:59.000000000 +0000 @@ -1,5 +1,6 @@ bin_PROGRAMS = ofx2qif -ofx2qif_LDADD = $(top_builddir)/lib/libofx.la +ofx2qif_LDADD = $(top_builddir)/lib/libofx.la -lstdc++ ofx2qif_SOURCES = ofx2qif.c AM_CPPFLAGS = \ -I${top_builddir}/inc +EXTRA_DIST = CMakeLists.txt diff -Nru libofx-0.10.5/ofxconnect/CMakeLists.txt libofx-0.10.9/ofxconnect/CMakeLists.txt --- libofx-0.10.5/ofxconnect/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/ofxconnect/CMakeLists.txt 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,28 @@ +# SPDX-FileCopyrightText: 2022 Dawid Wróbel +# SPDX-License-Identifier: GPL-2.0-or-later + +set(ofxconnect_SRCS + cmdline.c + ofxconnect.cpp + ofxpartner.cpp + nodeparser.cpp +) + +# required by libxml++ +if (CMAKE_CXX_STANDARD LESS 11) + set(CMAKE_CXX_STANDARD 11) +endif() + +add_executable(ofxconnect ${ofxconnect_SRCS}) +target_link_libraries(ofxconnect libofx CURL::libcurl PkgConfig::LIBXMLPP) +target_compile_definitions(ofxconnect PRIVATE + CMDLINE_PARSER_PACKAGE="ofxconnect" + CMDLINE_PARSER_PACKAGE_NAME="ofxconnect" + CMDLINE_PARSER_VERSION="${LIBOFX_VERSION_RELEASE_STRING}" +) + +if (TARGET getopt) + target_link_libraries(ofxconnect getopt) +endif () + +install(TARGETS ofxconnect RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff -Nru libofx-0.10.5/ofxconnect/cmdline.c libofx-0.10.9/ofxconnect/cmdline.c --- libofx-0.10.5/ofxconnect/cmdline.c 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/ofxconnect/cmdline.c 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,1026 @@ +/* + File autogenerated by gengetopt version 2.23 + generated with the following command: + gengetopt --unamed-opts -i cmdline.ggo + + The developers of gengetopt consider the fixed text that goes in all + gengetopt output files to be in the public domain: + we make no copyright claims on it. +*/ + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#ifndef FIX_UNUSED +#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ +#endif + +#include + +#include "cmdline.h" + +const char *gengetopt_args_info_purpose = "prints to stdout the created OFX file based on the options you pass it.\ncurrently it will only create a statement request file. you can POST this to\nan OFX server to request a statement from that financial institution for that\naccount."; + +const char *gengetopt_args_info_usage = "Usage: " CMDLINE_PARSER_PACKAGE " [OPTION]... [FILE]..."; + +const char *gengetopt_args_info_versiontext = ""; + +const char *gengetopt_args_info_description = ""; + +const char *gengetopt_args_info_help[] = { + " -h, --help Print help and exit", + " -V, --version Print version and exit", + " --fipid=STRING FI partner identifier (looks up fid, org & url from\n partner server)", + " --fid=STRING FI identifier", + " --org=STRING FI org tag", + " --bank=STRING IBAN bank identifier", + " --broker=STRING Broker identifier", + " --user=STRING User name", + " --pass=STRING Password", + " --acct=STRING Account ID", + " --type=INT Account Type 1=checking 2=invest 3=ccard", + " --past=LONG How far back to look from today (in days)", + " --url=STRING Url to POST the data to (otherwise goes to stdout)", + " --trid=INT Transaction id", + "\n Group: command", + " -s, --statement-req Request for a statement", + " -a, --accountinfo-req Request for a list of accounts", + " -p, --payment-req Request to make a payment", + " -i, --paymentinquiry-req Request to inquire about the status of a payment", + " -b, --bank-list List all known banks", + " -f, --bank-fipid List all fipids for a given bank", + " -v, --bank-services List supported services for a given fipid", + " --allsupport List all banks which support online banking", + 0 +}; + +typedef enum {ARG_NO + , ARG_STRING + , ARG_INT + , ARG_LONG +} cmdline_parser_arg_type; + +static +void clear_given (struct gengetopt_args_info *args_info); +static +void clear_args (struct gengetopt_args_info *args_info); + +static int +cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error); + + +static char * +gengetopt_strdup (const char *s); + +static +void clear_given (struct gengetopt_args_info *args_info) +{ + args_info->help_given = 0 ; + args_info->version_given = 0 ; + args_info->fipid_given = 0 ; + args_info->fid_given = 0 ; + args_info->org_given = 0 ; + args_info->bank_given = 0 ; + args_info->broker_given = 0 ; + args_info->user_given = 0 ; + args_info->pass_given = 0 ; + args_info->acct_given = 0 ; + args_info->type_given = 0 ; + args_info->past_given = 0 ; + args_info->url_given = 0 ; + args_info->trid_given = 0 ; + args_info->statement_req_given = 0 ; + args_info->accountinfo_req_given = 0 ; + args_info->payment_req_given = 0 ; + args_info->paymentinquiry_req_given = 0 ; + args_info->bank_list_given = 0 ; + args_info->bank_fipid_given = 0 ; + args_info->bank_services_given = 0 ; + args_info->allsupport_given = 0 ; + args_info->command_group_counter = 0 ; +} + +static +void clear_args (struct gengetopt_args_info *args_info) +{ + FIX_UNUSED (args_info); + args_info->fipid_arg = NULL; + args_info->fipid_orig = NULL; + args_info->fid_arg = NULL; + args_info->fid_orig = NULL; + args_info->org_arg = NULL; + args_info->org_orig = NULL; + args_info->bank_arg = NULL; + args_info->bank_orig = NULL; + args_info->broker_arg = NULL; + args_info->broker_orig = NULL; + args_info->user_arg = NULL; + args_info->user_orig = NULL; + args_info->pass_arg = NULL; + args_info->pass_orig = NULL; + args_info->acct_arg = NULL; + args_info->acct_orig = NULL; + args_info->type_orig = NULL; + args_info->past_orig = NULL; + args_info->url_arg = NULL; + args_info->url_orig = NULL; + args_info->trid_orig = NULL; + +} + +static +void init_args_info(struct gengetopt_args_info *args_info) +{ + + + args_info->help_help = gengetopt_args_info_help[0] ; + args_info->version_help = gengetopt_args_info_help[1] ; + args_info->fipid_help = gengetopt_args_info_help[2] ; + args_info->fid_help = gengetopt_args_info_help[3] ; + args_info->org_help = gengetopt_args_info_help[4] ; + args_info->bank_help = gengetopt_args_info_help[5] ; + args_info->broker_help = gengetopt_args_info_help[6] ; + args_info->user_help = gengetopt_args_info_help[7] ; + args_info->pass_help = gengetopt_args_info_help[8] ; + args_info->acct_help = gengetopt_args_info_help[9] ; + args_info->type_help = gengetopt_args_info_help[10] ; + args_info->past_help = gengetopt_args_info_help[11] ; + args_info->url_help = gengetopt_args_info_help[12] ; + args_info->trid_help = gengetopt_args_info_help[13] ; + args_info->statement_req_help = gengetopt_args_info_help[15] ; + args_info->accountinfo_req_help = gengetopt_args_info_help[16] ; + args_info->payment_req_help = gengetopt_args_info_help[17] ; + args_info->paymentinquiry_req_help = gengetopt_args_info_help[18] ; + args_info->bank_list_help = gengetopt_args_info_help[19] ; + args_info->bank_fipid_help = gengetopt_args_info_help[20] ; + args_info->bank_services_help = gengetopt_args_info_help[21] ; + args_info->allsupport_help = gengetopt_args_info_help[22] ; + +} + +void +cmdline_parser_print_version (void) +{ + printf ("%s %s\n", + (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE), + CMDLINE_PARSER_VERSION); + + if (strlen(gengetopt_args_info_versiontext) > 0) + printf("\n%s\n", gengetopt_args_info_versiontext); +} + +static void print_help_common(void) +{ + size_t len_purpose = strlen(gengetopt_args_info_purpose); + size_t len_usage = strlen(gengetopt_args_info_usage); + + if (len_usage > 0) { + printf("%s\n", gengetopt_args_info_usage); + } + if (len_purpose > 0) { + printf("%s\n", gengetopt_args_info_purpose); + } + + if (len_usage || len_purpose) { + printf("\n"); + } + + if (strlen(gengetopt_args_info_description) > 0) { + printf("%s\n\n", gengetopt_args_info_description); + } +} + +void +cmdline_parser_print_help (void) +{ + int i = 0; + print_help_common(); + while (gengetopt_args_info_help[i]) + printf("%s\n", gengetopt_args_info_help[i++]); +} + +void +cmdline_parser_init (struct gengetopt_args_info *args_info) +{ + clear_given (args_info); + clear_args (args_info); + init_args_info (args_info); + + args_info->inputs = 0; + args_info->inputs_num = 0; +} + +void +cmdline_parser_params_init(struct cmdline_parser_params *params) +{ + if (params) + { + params->override = 0; + params->initialize = 1; + params->check_required = 1; + params->check_ambiguity = 0; + params->print_errors = 1; + } +} + +struct cmdline_parser_params * +cmdline_parser_params_create(void) +{ + struct cmdline_parser_params *params = + (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); + cmdline_parser_params_init(params); + return params; +} + +static void +free_string_field (char **s) +{ + if (*s) + { + free (*s); + *s = 0; + } +} + + +static void +cmdline_parser_release (struct gengetopt_args_info *args_info) +{ + unsigned int i; + free_string_field (&(args_info->fipid_arg)); + free_string_field (&(args_info->fipid_orig)); + free_string_field (&(args_info->fid_arg)); + free_string_field (&(args_info->fid_orig)); + free_string_field (&(args_info->org_arg)); + free_string_field (&(args_info->org_orig)); + free_string_field (&(args_info->bank_arg)); + free_string_field (&(args_info->bank_orig)); + free_string_field (&(args_info->broker_arg)); + free_string_field (&(args_info->broker_orig)); + free_string_field (&(args_info->user_arg)); + free_string_field (&(args_info->user_orig)); + free_string_field (&(args_info->pass_arg)); + free_string_field (&(args_info->pass_orig)); + free_string_field (&(args_info->acct_arg)); + free_string_field (&(args_info->acct_orig)); + free_string_field (&(args_info->type_orig)); + free_string_field (&(args_info->past_orig)); + free_string_field (&(args_info->url_arg)); + free_string_field (&(args_info->url_orig)); + free_string_field (&(args_info->trid_orig)); + + + for (i = 0; i < args_info->inputs_num; ++i) + free (args_info->inputs [i]); + + if (args_info->inputs_num) + free (args_info->inputs); + + clear_given (args_info); +} + + +static void +write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) +{ + FIX_UNUSED (values); + if (arg) { + fprintf(outfile, "%s=\"%s\"\n", opt, arg); + } else { + fprintf(outfile, "%s\n", opt); + } +} + + +int +cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) +{ + int i = 0; + + if (!outfile) + { + fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE); + return EXIT_FAILURE; + } + + if (args_info->help_given) + write_into_file(outfile, "help", 0, 0 ); + if (args_info->version_given) + write_into_file(outfile, "version", 0, 0 ); + if (args_info->fipid_given) + write_into_file(outfile, "fipid", args_info->fipid_orig, 0); + if (args_info->fid_given) + write_into_file(outfile, "fid", args_info->fid_orig, 0); + if (args_info->org_given) + write_into_file(outfile, "org", args_info->org_orig, 0); + if (args_info->bank_given) + write_into_file(outfile, "bank", args_info->bank_orig, 0); + if (args_info->broker_given) + write_into_file(outfile, "broker", args_info->broker_orig, 0); + if (args_info->user_given) + write_into_file(outfile, "user", args_info->user_orig, 0); + if (args_info->pass_given) + write_into_file(outfile, "pass", args_info->pass_orig, 0); + if (args_info->acct_given) + write_into_file(outfile, "acct", args_info->acct_orig, 0); + if (args_info->type_given) + write_into_file(outfile, "type", args_info->type_orig, 0); + if (args_info->past_given) + write_into_file(outfile, "past", args_info->past_orig, 0); + if (args_info->url_given) + write_into_file(outfile, "url", args_info->url_orig, 0); + if (args_info->trid_given) + write_into_file(outfile, "trid", args_info->trid_orig, 0); + if (args_info->statement_req_given) + write_into_file(outfile, "statement-req", 0, 0 ); + if (args_info->accountinfo_req_given) + write_into_file(outfile, "accountinfo-req", 0, 0 ); + if (args_info->payment_req_given) + write_into_file(outfile, "payment-req", 0, 0 ); + if (args_info->paymentinquiry_req_given) + write_into_file(outfile, "paymentinquiry-req", 0, 0 ); + if (args_info->bank_list_given) + write_into_file(outfile, "bank-list", 0, 0 ); + if (args_info->bank_fipid_given) + write_into_file(outfile, "bank-fipid", 0, 0 ); + if (args_info->bank_services_given) + write_into_file(outfile, "bank-services", 0, 0 ); + if (args_info->allsupport_given) + write_into_file(outfile, "allsupport", 0, 0 ); + + + i = EXIT_SUCCESS; + return i; +} + +int +cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) +{ + FILE *outfile; + int i = 0; + + outfile = fopen(filename, "w"); + + if (!outfile) + { + fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); + return EXIT_FAILURE; + } + + i = cmdline_parser_dump(outfile, args_info); + fclose (outfile); + + return i; +} + +void +cmdline_parser_free (struct gengetopt_args_info *args_info) +{ + cmdline_parser_release (args_info); +} + +/** @brief replacement of strdup, which is not standard */ +char * +gengetopt_strdup (const char *s) +{ + char *result = 0; + if (!s) + return result; + + result = (char*)malloc(strlen(s) + 1); + if (result == (char*)0) + return (char*)0; + strcpy(result, s); + return result; +} + +static void +reset_group_command(struct gengetopt_args_info *args_info) +{ + if (! args_info->command_group_counter) + return; + + args_info->statement_req_given = 0 ; + args_info->accountinfo_req_given = 0 ; + args_info->payment_req_given = 0 ; + args_info->paymentinquiry_req_given = 0 ; + args_info->bank_list_given = 0 ; + args_info->bank_fipid_given = 0 ; + args_info->bank_services_given = 0 ; + args_info->allsupport_given = 0 ; + + args_info->command_group_counter = 0; +} + +int +cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info) +{ + return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); +} + +int +cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params) +{ + int result; + result = cmdline_parser_internal (argc, argv, args_info, params, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) +{ + int result; + struct cmdline_parser_params params; + + params.override = override; + params.initialize = initialize; + params.check_required = check_required; + params.check_ambiguity = 0; + params.print_errors = 1; + + result = cmdline_parser_internal (argc, argv, args_info, ¶ms, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) +{ + FIX_UNUSED (args_info); + FIX_UNUSED (prog_name); + return EXIT_SUCCESS; +} + + +static char *package_name = 0; + +/** + * @brief updates an option + * @param field the generic pointer to the field to update + * @param orig_field the pointer to the orig field + * @param field_given the pointer to the number of occurrence of this option + * @param prev_given the pointer to the number of occurrence already seen + * @param value the argument for this option (if null no arg was specified) + * @param possible_values the possible values for this option (if specified) + * @param default_value the default value (in case the option only accepts fixed values) + * @param arg_type the type of this option + * @param check_ambiguity @see cmdline_parser_params.check_ambiguity + * @param override @see cmdline_parser_params.override + * @param no_free whether to free a possible previous value + * @param multiple_option whether this is a multiple option + * @param long_opt the corresponding long option + * @param short_opt the corresponding short option (or '-' if none) + * @param additional_error possible further error specification + */ +static +int update_arg(void *field, char **orig_field, + unsigned int *field_given, unsigned int *prev_given, + char *value, const char *possible_values[], + const char *default_value, + cmdline_parser_arg_type arg_type, + int check_ambiguity, int override, + int no_free, int multiple_option, + const char *long_opt, char short_opt, + const char *additional_error) +{ + char *stop_char = 0; + const char *val = value; + int found; + char **string_field; + FIX_UNUSED (field); + + stop_char = 0; + found = 0; + + if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) + { + if (short_opt != '-') + fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", + package_name, long_opt, short_opt, + (additional_error ? additional_error : "")); + else + fprintf (stderr, "%s: `--%s' option given more than once%s\n", + package_name, long_opt, + (additional_error ? additional_error : "")); + return 1; /* failure */ + } + + FIX_UNUSED (default_value); + + if (field_given && *field_given && ! override) + return 0; + if (prev_given) + (*prev_given)++; + if (field_given) + (*field_given)++; + if (possible_values) + val = possible_values[found]; + + switch(arg_type) { + case ARG_INT: + if (val) *((int *)field) = strtol (val, &stop_char, 0); + break; + case ARG_LONG: + if (val) *((long *)field) = (long)strtol (val, &stop_char, 0); + break; + case ARG_STRING: + if (val) { + string_field = (char **)field; + if (!no_free && *string_field) + free (*string_field); /* free previous string */ + *string_field = gengetopt_strdup (val); + } + break; + default: + break; + }; + + /* check numeric conversion */ + switch(arg_type) { + case ARG_INT: + case ARG_LONG: + if (val && !(stop_char && *stop_char == '\0')) { + fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val); + return 1; /* failure */ + } + break; + default: + ; + }; + + /* store the original value */ + switch(arg_type) { + case ARG_NO: + break; + default: + if (value && orig_field) { + if (no_free) { + *orig_field = value; + } else { + if (*orig_field) + free (*orig_field); /* free previous string */ + *orig_field = gengetopt_strdup (value); + } + } + }; + + return 0; /* OK */ +} + + +int +cmdline_parser_internal ( + int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error) +{ + int c; /* Character of the parsed option. */ + + int error_occurred = 0; + struct gengetopt_args_info local_args_info; + + int override; + int initialize; + int check_required; + int check_ambiguity; + + package_name = argv[0]; + + /* TODO: Why is this here? It is not used anywhere. */ + override = params->override; + FIX_UNUSED(override); + + initialize = params->initialize; + check_required = params->check_required; + + /* TODO: Why is this here? It is not used anywhere. */ + check_ambiguity = params->check_ambiguity; + FIX_UNUSED(check_ambiguity); + + if (initialize) + cmdline_parser_init (args_info); + + cmdline_parser_init (&local_args_info); + + optarg = 0; + optind = 0; + opterr = params->print_errors; + optopt = '?'; + + while (1) + { + int option_index = 0; + + static struct option long_options[] = { + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'V' }, + { "fipid", 1, NULL, 0 }, + { "fid", 1, NULL, 0 }, + { "org", 1, NULL, 0 }, + { "bank", 1, NULL, 0 }, + { "broker", 1, NULL, 0 }, + { "user", 1, NULL, 0 }, + { "pass", 1, NULL, 0 }, + { "acct", 1, NULL, 0 }, + { "type", 1, NULL, 0 }, + { "past", 1, NULL, 0 }, + { "url", 1, NULL, 0 }, + { "trid", 1, NULL, 0 }, + { "statement-req", 0, NULL, 's' }, + { "accountinfo-req", 0, NULL, 'a' }, + { "payment-req", 0, NULL, 'p' }, + { "paymentinquiry-req", 0, NULL, 'i' }, + { "bank-list", 0, NULL, 'b' }, + { "bank-fipid", 0, NULL, 'f' }, + { "bank-services", 0, NULL, 'v' }, + { "allsupport", 0, NULL, 0 }, + { 0, 0, 0, 0 } + }; + + c = getopt_long (argc, argv, "hVsapibfv", long_options, &option_index); + + if (c == -1) break; /* Exit from `while (1)' loop. */ + + switch (c) + { + case 'h': /* Print help and exit. */ + cmdline_parser_print_help (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'V': /* Print version and exit. */ + cmdline_parser_print_version (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 's': /* Request for a statement. */ + + if (args_info->command_group_counter && override) + reset_group_command (args_info); + args_info->command_group_counter += 1; + + if (update_arg( 0 , + 0 , &(args_info->statement_req_given), + &(local_args_info.statement_req_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "statement-req", 's', + additional_error)) + goto failure; + + break; + case 'a': /* Request for a list of accounts. */ + + if (args_info->command_group_counter && override) + reset_group_command (args_info); + args_info->command_group_counter += 1; + + if (update_arg( 0 , + 0 , &(args_info->accountinfo_req_given), + &(local_args_info.accountinfo_req_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "accountinfo-req", 'a', + additional_error)) + goto failure; + + break; + case 'p': /* Request to make a payment. */ + + if (args_info->command_group_counter && override) + reset_group_command (args_info); + args_info->command_group_counter += 1; + + if (update_arg( 0 , + 0 , &(args_info->payment_req_given), + &(local_args_info.payment_req_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "payment-req", 'p', + additional_error)) + goto failure; + + break; + case 'i': /* Request to inquire about the status of a payment. */ + + if (args_info->command_group_counter && override) + reset_group_command (args_info); + args_info->command_group_counter += 1; + + if (update_arg( 0 , + 0 , &(args_info->paymentinquiry_req_given), + &(local_args_info.paymentinquiry_req_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "paymentinquiry-req", 'i', + additional_error)) + goto failure; + + break; + case 'b': /* List all known banks. */ + + if (args_info->command_group_counter && override) + reset_group_command (args_info); + args_info->command_group_counter += 1; + + if (update_arg( 0 , + 0 , &(args_info->bank_list_given), + &(local_args_info.bank_list_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "bank-list", 'b', + additional_error)) + goto failure; + + break; + case 'f': /* List all fipids for a given bank. */ + + if (args_info->command_group_counter && override) + reset_group_command (args_info); + args_info->command_group_counter += 1; + + if (update_arg( 0 , + 0 , &(args_info->bank_fipid_given), + &(local_args_info.bank_fipid_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "bank-fipid", 'f', + additional_error)) + goto failure; + + break; + case 'v': /* List supported services for a given fipid. */ + + if (args_info->command_group_counter && override) + reset_group_command (args_info); + args_info->command_group_counter += 1; + + if (update_arg( 0 , + 0 , &(args_info->bank_services_given), + &(local_args_info.bank_services_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "bank-services", 'v', + additional_error)) + goto failure; + + break; + + case 0: /* Long option with no short option */ + /* FI partner identifier (looks up fid, org & url from partner server). */ + if (strcmp (long_options[option_index].name, "fipid") == 0) + { + + + if (update_arg( (void *)&(args_info->fipid_arg), + &(args_info->fipid_orig), &(args_info->fipid_given), + &(local_args_info.fipid_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "fipid", '-', + additional_error)) + goto failure; + + } + /* FI identifier. */ + else if (strcmp (long_options[option_index].name, "fid") == 0) + { + + + if (update_arg( (void *)&(args_info->fid_arg), + &(args_info->fid_orig), &(args_info->fid_given), + &(local_args_info.fid_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "fid", '-', + additional_error)) + goto failure; + + } + /* FI org tag. */ + else if (strcmp (long_options[option_index].name, "org") == 0) + { + + + if (update_arg( (void *)&(args_info->org_arg), + &(args_info->org_orig), &(args_info->org_given), + &(local_args_info.org_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "org", '-', + additional_error)) + goto failure; + + } + /* IBAN bank identifier. */ + else if (strcmp (long_options[option_index].name, "bank") == 0) + { + + + if (update_arg( (void *)&(args_info->bank_arg), + &(args_info->bank_orig), &(args_info->bank_given), + &(local_args_info.bank_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "bank", '-', + additional_error)) + goto failure; + + } + /* Broker identifier. */ + else if (strcmp (long_options[option_index].name, "broker") == 0) + { + + + if (update_arg( (void *)&(args_info->broker_arg), + &(args_info->broker_orig), &(args_info->broker_given), + &(local_args_info.broker_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "broker", '-', + additional_error)) + goto failure; + + } + /* User name. */ + else if (strcmp (long_options[option_index].name, "user") == 0) + { + + + if (update_arg( (void *)&(args_info->user_arg), + &(args_info->user_orig), &(args_info->user_given), + &(local_args_info.user_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "user", '-', + additional_error)) + goto failure; + + } + /* Password. */ + else if (strcmp (long_options[option_index].name, "pass") == 0) + { + + + if (update_arg( (void *)&(args_info->pass_arg), + &(args_info->pass_orig), &(args_info->pass_given), + &(local_args_info.pass_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "pass", '-', + additional_error)) + goto failure; + + } + /* Account ID. */ + else if (strcmp (long_options[option_index].name, "acct") == 0) + { + + + if (update_arg( (void *)&(args_info->acct_arg), + &(args_info->acct_orig), &(args_info->acct_given), + &(local_args_info.acct_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "acct", '-', + additional_error)) + goto failure; + + } + /* Account Type 1=checking 2=invest 3=ccard. */ + else if (strcmp (long_options[option_index].name, "type") == 0) + { + + + if (update_arg( (void *)&(args_info->type_arg), + &(args_info->type_orig), &(args_info->type_given), + &(local_args_info.type_given), optarg, 0, 0, ARG_INT, + check_ambiguity, override, 0, 0, + "type", '-', + additional_error)) + goto failure; + + } + /* How far back to look from today (in days). */ + else if (strcmp (long_options[option_index].name, "past") == 0) + { + + + if (update_arg( (void *)&(args_info->past_arg), + &(args_info->past_orig), &(args_info->past_given), + &(local_args_info.past_given), optarg, 0, 0, ARG_LONG, + check_ambiguity, override, 0, 0, + "past", '-', + additional_error)) + goto failure; + + } + /* Url to POST the data to (otherwise goes to stdout). */ + else if (strcmp (long_options[option_index].name, "url") == 0) + { + + + if (update_arg( (void *)&(args_info->url_arg), + &(args_info->url_orig), &(args_info->url_given), + &(local_args_info.url_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "url", '-', + additional_error)) + goto failure; + + } + /* Transaction id. */ + else if (strcmp (long_options[option_index].name, "trid") == 0) + { + + + if (update_arg( (void *)&(args_info->trid_arg), + &(args_info->trid_orig), &(args_info->trid_given), + &(local_args_info.trid_given), optarg, 0, 0, ARG_INT, + check_ambiguity, override, 0, 0, + "trid", '-', + additional_error)) + goto failure; + + } + /* List all banks which support online banking. */ + else if (strcmp (long_options[option_index].name, "allsupport") == 0) + { + + if (args_info->command_group_counter && override) + reset_group_command (args_info); + args_info->command_group_counter += 1; + + if (update_arg( 0 , + 0 , &(args_info->allsupport_given), + &(local_args_info.allsupport_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "allsupport", '-', + additional_error)) + goto failure; + + } + + break; + case '?': /* Invalid option. */ + /* `getopt_long' already printed an error message. */ + goto failure; + + default: /* bug: option not considered. */ + fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); + abort (); + } /* switch */ + } /* while */ + + if (args_info->command_group_counter > 1) + { + fprintf (stderr, "%s: %d options of group command were given. At most one is required%s.\n", argv[0], args_info->command_group_counter, (additional_error ? additional_error : "")); + error_occurred = 1; + } + + + + FIX_UNUSED(check_required); + + cmdline_parser_release (&local_args_info); + + if ( error_occurred ) + return (EXIT_FAILURE); + + if (optind < argc) + { + int i = 0 ; + int found_prog_name = 0; + /* whether program name, i.e., argv[0], is in the remaining args + (this may happen with some implementations of getopt, + but surely not with the one included by gengetopt) */ + + i = optind; + while (i < argc) + if (argv[i++] == argv[0]) { + found_prog_name = 1; + break; + } + i = 0; + + args_info->inputs_num = argc - optind - found_prog_name; + args_info->inputs = + (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ; + while (optind < argc) + if (argv[optind++] != argv[0]) + args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind-1]) ; + } + + return 0; + +failure: + + cmdline_parser_release (&local_args_info); + return (EXIT_FAILURE); +} +/* vim: set ft=c noet ts=8 sts=8 sw=8 tw=80 nojs spell : */ diff -Nru libofx-0.10.5/ofxconnect/cmdline.h libofx-0.10.9/ofxconnect/cmdline.h --- libofx-0.10.5/ofxconnect/cmdline.h 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/ofxconnect/cmdline.h 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,244 @@ +/** @file cmdline.h + * @brief The header file for the command line option parser + * generated by GNU Gengetopt version 2.23 + * http://www.gnu.org/software/gengetopt. + * DO NOT modify this file, since it can be overwritten + * @author GNU Gengetopt */ + +#ifndef CMDLINE_H +#define CMDLINE_H + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include /* for FILE */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef CMDLINE_PARSER_PACKAGE +/** @brief the program name (used for printing errors) */ +#define CMDLINE_PARSER_PACKAGE PACKAGE +#endif + +#ifndef CMDLINE_PARSER_PACKAGE_NAME +/** @brief the complete program name (used for help and version) */ +#ifdef PACKAGE_NAME +#define CMDLINE_PARSER_PACKAGE_NAME PACKAGE_NAME +#else +#define CMDLINE_PARSER_PACKAGE_NAME PACKAGE +#endif +#endif + +#ifndef CMDLINE_PARSER_VERSION +/** @brief the program version */ +#define CMDLINE_PARSER_VERSION VERSION +#endif + +/** @brief Where the command line options are stored */ +struct gengetopt_args_info +{ + const char *help_help; /**< @brief Print help and exit help description. */ + const char *version_help; /**< @brief Print version and exit help description. */ + char * fipid_arg; /**< @brief FI partner identifier (looks up fid, org & url from partner server). */ + char * fipid_orig; /**< @brief FI partner identifier (looks up fid, org & url from partner server) original value given at command line. */ + const char *fipid_help; /**< @brief FI partner identifier (looks up fid, org & url from partner server) help description. */ + char * fid_arg; /**< @brief FI identifier. */ + char * fid_orig; /**< @brief FI identifier original value given at command line. */ + const char *fid_help; /**< @brief FI identifier help description. */ + char * org_arg; /**< @brief FI org tag. */ + char * org_orig; /**< @brief FI org tag original value given at command line. */ + const char *org_help; /**< @brief FI org tag help description. */ + char * bank_arg; /**< @brief IBAN bank identifier. */ + char * bank_orig; /**< @brief IBAN bank identifier original value given at command line. */ + const char *bank_help; /**< @brief IBAN bank identifier help description. */ + char * broker_arg; /**< @brief Broker identifier. */ + char * broker_orig; /**< @brief Broker identifier original value given at command line. */ + const char *broker_help; /**< @brief Broker identifier help description. */ + char * user_arg; /**< @brief User name. */ + char * user_orig; /**< @brief User name original value given at command line. */ + const char *user_help; /**< @brief User name help description. */ + char * pass_arg; /**< @brief Password. */ + char * pass_orig; /**< @brief Password original value given at command line. */ + const char *pass_help; /**< @brief Password help description. */ + char * acct_arg; /**< @brief Account ID. */ + char * acct_orig; /**< @brief Account ID original value given at command line. */ + const char *acct_help; /**< @brief Account ID help description. */ + int type_arg; /**< @brief Account Type 1=checking 2=invest 3=ccard. */ + char * type_orig; /**< @brief Account Type 1=checking 2=invest 3=ccard original value given at command line. */ + const char *type_help; /**< @brief Account Type 1=checking 2=invest 3=ccard help description. */ + long past_arg; /**< @brief How far back to look from today (in days). */ + char * past_orig; /**< @brief How far back to look from today (in days) original value given at command line. */ + const char *past_help; /**< @brief How far back to look from today (in days) help description. */ + char * url_arg; /**< @brief Url to POST the data to (otherwise goes to stdout). */ + char * url_orig; /**< @brief Url to POST the data to (otherwise goes to stdout) original value given at command line. */ + const char *url_help; /**< @brief Url to POST the data to (otherwise goes to stdout) help description. */ + int trid_arg; /**< @brief Transaction id. */ + char * trid_orig; /**< @brief Transaction id original value given at command line. */ + const char *trid_help; /**< @brief Transaction id help description. */ + const char *statement_req_help; /**< @brief Request for a statement help description. */ + const char *accountinfo_req_help; /**< @brief Request for a list of accounts help description. */ + const char *payment_req_help; /**< @brief Request to make a payment help description. */ + const char *paymentinquiry_req_help; /**< @brief Request to inquire about the status of a payment help description. */ + const char *bank_list_help; /**< @brief List all known banks help description. */ + const char *bank_fipid_help; /**< @brief List all fipids for a given bank help description. */ + const char *bank_services_help; /**< @brief List supported services for a given fipid help description. */ + const char *allsupport_help; /**< @brief List all banks which support online banking help description. */ + + unsigned int help_given ; /**< @brief Whether help was given. */ + unsigned int version_given ; /**< @brief Whether version was given. */ + unsigned int fipid_given ; /**< @brief Whether fipid was given. */ + unsigned int fid_given ; /**< @brief Whether fid was given. */ + unsigned int org_given ; /**< @brief Whether org was given. */ + unsigned int bank_given ; /**< @brief Whether bank was given. */ + unsigned int broker_given ; /**< @brief Whether broker was given. */ + unsigned int user_given ; /**< @brief Whether user was given. */ + unsigned int pass_given ; /**< @brief Whether pass was given. */ + unsigned int acct_given ; /**< @brief Whether acct was given. */ + unsigned int type_given ; /**< @brief Whether type was given. */ + unsigned int past_given ; /**< @brief Whether past was given. */ + unsigned int url_given ; /**< @brief Whether url was given. */ + unsigned int trid_given ; /**< @brief Whether trid was given. */ + unsigned int statement_req_given ; /**< @brief Whether statement-req was given. */ + unsigned int accountinfo_req_given ; /**< @brief Whether accountinfo-req was given. */ + unsigned int payment_req_given ; /**< @brief Whether payment-req was given. */ + unsigned int paymentinquiry_req_given ; /**< @brief Whether paymentinquiry-req was given. */ + unsigned int bank_list_given ; /**< @brief Whether bank-list was given. */ + unsigned int bank_fipid_given ; /**< @brief Whether bank-fipid was given. */ + unsigned int bank_services_given ; /**< @brief Whether bank-services was given. */ + unsigned int allsupport_given ; /**< @brief Whether allsupport was given. */ + + char **inputs ; /**< @brief unnamed options (options without names) */ + unsigned inputs_num ; /**< @brief unnamed options number */ + int command_group_counter; /**< @brief Counter for group command */ +} ; + +/** @brief The additional parameters to pass to parser functions */ +struct cmdline_parser_params +{ + int override; /**< @brief whether to override possibly already present options (default 0) */ + int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */ + int check_required; /**< @brief whether to check that all required options were provided (default 1) */ + int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */ + int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */ +} ; + +/** @brief the purpose string of the program */ +extern const char *gengetopt_args_info_purpose; +/** @brief the usage string of the program */ +extern const char *gengetopt_args_info_usage; +/** @brief the description string of the program */ +extern const char *gengetopt_args_info_description; +/** @brief all the lines making the help output */ +extern const char *gengetopt_args_info_help[]; + +/** + * The command line parser + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser (int argc, char **argv, + struct gengetopt_args_info *args_info); + +/** + * The command line parser (version with additional parameters - deprecated) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param override whether to override possibly already present options + * @param initialize whether to initialize the option structure my_args_info + * @param check_required whether to check that all required options were provided + * @return 0 if everything went fine, NON 0 if an error took place + * @deprecated use cmdline_parser_ext() instead + */ +int cmdline_parser2 (int argc, char **argv, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); + +/** + * The command line parser (version with additional parameters) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param params additional parameters for the parser + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_ext (int argc, char **argv, + struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params); + +/** + * Save the contents of the option struct into an already open FILE stream. + * @param outfile the stream where to dump options + * @param args_info the option struct to dump + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_dump(FILE *outfile, + struct gengetopt_args_info *args_info); + +/** + * Save the contents of the option struct into a (text) file. + * This file can be read by the config file parser (if generated by gengetopt) + * @param filename the file where to save + * @param args_info the option struct to save + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_file_save(const char *filename, + struct gengetopt_args_info *args_info); + +/** + * Print the help + */ +void cmdline_parser_print_help(void); +/** + * Print the version + */ +void cmdline_parser_print_version(void); + +/** + * Initializes all the fields a cmdline_parser_params structure + * to their default values + * @param params the structure to initialize + */ +void cmdline_parser_params_init(struct cmdline_parser_params *params); + +/** + * Allocates dynamically a cmdline_parser_params structure and initializes + * all its fields to their default values + * @return the created and initialized cmdline_parser_params structure + */ +struct cmdline_parser_params *cmdline_parser_params_create(void); + +/** + * Initializes the passed gengetopt_args_info structure's fields + * (also set default values for options that have a default) + * @param args_info the structure to initialize + */ +void cmdline_parser_init (struct gengetopt_args_info *args_info); +/** + * Deallocates the string fields of the gengetopt_args_info structure + * (but does not deallocate the structure itself) + * @param args_info the structure to deallocate + */ +void cmdline_parser_free (struct gengetopt_args_info *args_info); + +/** + * Checks that all the required options were specified + * @param args_info the structure to check + * @param prog_name the name of the program that will be used to print + * possible errors + * @return + */ +int cmdline_parser_required (struct gengetopt_args_info *args_info, + const char *prog_name); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* CMDLINE_H */ diff -Nru libofx-0.10.5/ofxconnect/.gitignore libofx-0.10.9/ofxconnect/.gitignore --- libofx-0.10.5/ofxconnect/.gitignore 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/ofxconnect/.gitignore 2022-10-03 20:22:59.000000000 +0000 @@ -6,6 +6,4 @@ Makefile Makefile.in ofxconnect -cmdline.c -cmdline.h *.1 diff -Nru libofx-0.10.5/ofxconnect/Makefile.am libofx-0.10.9/ofxconnect/Makefile.am --- libofx-0.10.5/ofxconnect/Makefile.am 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/ofxconnect/Makefile.am 2022-10-03 20:22:59.000000000 +0000 @@ -19,13 +19,13 @@ endif MAINTAINERCLEANFILES = cmdline.c cmdline.h -EXTRA_DIST = cmdline.ggo test-privateserver.sh +EXTRA_DIST = cmdline.ggo test-privateserver.sh CMakeLists.txt # See README.privateserver for details on this server and how to get # the key needed to run this test. TESTS = test-privateserver.sh -ofxconnect.1: ofxconnect$(EXEEXT) $(top_srcdir)/configure.ac +ofxconnect.1: $(top_srcdir)/configure.ac if HAVE_HELP2MAN $(HELP2MAN) -n 'Create a statement request file' -N --output=ofxconnect.1 ./ofxconnect$(EXEEXT) else diff -Nru libofx-0.10.5/ofxconnect/nodeparser.cpp libofx-0.10.9/ofxconnect/nodeparser.cpp --- libofx-0.10.5/ofxconnect/nodeparser.cpp 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/ofxconnect/nodeparser.cpp 2022-10-03 20:22:59.000000000 +0000 @@ -95,13 +95,13 @@ NodeParser result; for (const_iterator iter = begin(); iter != end(); ++iter) { - xmlpp::Node::NodeList list = (*iter)->get_children(); - for (xmlpp::Node::NodeList::const_iterator iter3 = list.begin(); iter3 != list.end(); ++iter3) + xmlpp::Node::NodeList list2 = (*iter)->get_children(); + for (xmlpp::Node::NodeList::const_iterator iter3 = list2.begin(); iter3 != list2.end(); ++iter3) { if ( (*iter3)->get_name() == key ) { - xmlpp::Node::NodeList list = (*iter3)->get_children(); - for (xmlpp::Node::NodeList::const_iterator iter4 = list.begin(); iter4 != list.end(); ++iter4) + xmlpp::Node::NodeList list3 = (*iter3)->get_children(); + for (xmlpp::Node::NodeList::const_iterator iter4 = list3.begin(); iter4 != list3.end(); ++iter4) { const xmlpp::TextNode* nodeText = dynamic_cast(*iter4); if ( nodeText && nodeText->get_content() == value ) diff -Nru libofx-0.10.5/ofxconnect/ofxconnect.cpp libofx-0.10.9/ofxconnect/ofxconnect.cpp --- libofx-0.10.5/ofxconnect/ofxconnect.cpp 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/ofxconnect/ofxconnect.cpp 2022-10-03 20:22:59.000000000 +0000 @@ -307,7 +307,7 @@ char tridstr[33]; memset(tridstr, 0, 33); - bool ok = true; + bool is_trid_given = true; if ( args_info.trid_given ) { @@ -317,10 +317,10 @@ else { std::cerr << "ERROR: --trid is required for a payment inquiry request" << std::endl; - ok = false; + is_trid_given = false; } - if ( ok ) + if ( is_trid_given ) { char* request = libofx_request_payment_status( &fi, tridstr ); @@ -360,7 +360,7 @@ strcpy(payment.datedue, "20060301"); strcpy(payment.memo, "This is a test"); - bool ok = true; + bool is_payment_args_given = true; if ( args_info.bank_given ) { @@ -372,7 +372,7 @@ if ( args_info.type_given && args_info.type_arg == 1 ) { std::cerr << "ERROR: --bank is required for a bank request" << std::endl; - ok = false; + is_payment_args_given = false; } } @@ -386,7 +386,7 @@ if ( args_info.type_given && args_info.type_arg == 2 ) { std::cerr << "ERROR: --broker is required for an investment statement request" << std::endl; - ok = false; + is_payment_args_given = false; } } @@ -398,7 +398,7 @@ else { std::cerr << "ERROR: --acct is required for a statement request" << std::endl; - ok = false; + is_payment_args_given = false; } if ( args_info.type_given ) @@ -423,10 +423,10 @@ else { std::cerr << "ERROR: --type is required for a statement request" << std::endl; - ok = false; + is_payment_args_given = false; } - if ( ok ) + if ( is_payment_args_given ) { char* request = libofx_request_payment( &fi, &account, &payee, &payment ); diff -Nru libofx-0.10.5/ofxconnect/README libofx-0.10.9/ofxconnect/README --- libofx-0.10.5/ofxconnect/README 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/ofxconnect/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -Ofxconnect is a utility to test OFX Direct Connect. And it's a sample so you -can understand how to use it in your own code. - -Direct Connect consists of two separate steps: First, contacting the partner -server to retrieve information about your bank. Second, contacting your bank -to retrieve your accounts and statements. The partner server should be -contacted when the user sets up his accounts. - -Common mistakes with the partner server are to contact it EVERY time you -contact the bank, and contacting it just once to cache the contact -info for all banks. The former is overkill, the latter means users won't -have up-to-date bank contact information. - -Step-by-step guide to using the ofxconnect utility - -1. Retrieve the list of banks - - $ofxconnect -b - -2. Find your bank in the list. Retrieve the FI partner ID's (fipid's) for that bank - - $ofxconnect -f "Wells Fargo" - 101458 - 102078 - 5571 - -3. Retrieve the service capabilities of each fipid to find the one which has the services you want. -Note that all the 6-digit fipids don't seem to work well with libofx right now. - - $ofxconnect -v 5571 - Statements? Yes - Billpay? Yes - Investments? No - -4. Retrieve and view the list of all your accounts - - $ofxconnect -a --fipid=5571 --user=myusername --pass=mypassword accounts.ofx - $ofxdump accounts.ofx 2>/dev/null - -Look for entries like this: - - Account ID: 999888777 00 123456789 - Account name: Bank account 1234567890 - Account type: CHECKING - Bank ID: 999888777 - Branch ID: 00 - Account #: 1234567890 - -5. Retrieve a statement for one of the accounts - - $ofxconnect -s --fipid=5571 --user=myusername --pass=mypassword --bank=xxx --account=xxx --type=x --past=xx statement.ofx - $ofxdump statement.ofx 2>/dev/null - - The --bank and --account parameters should be exactly like the "Bank ID" and "Account #" results from the account request. - The --type is: 1=CHECKING, 2=INVESTMENT, 3=CREDITCARD. Other types are not supported - The --past is how many days previous from today you want. diff -Nru libofx-0.10.5/ofxconnect/README.privateserver libofx-0.10.9/ofxconnect/README.privateserver --- libofx-0.10.5/ofxconnect/README.privateserver 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/ofxconnect/README.privateserver 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -There is an OFX test server which is used by the developers to ensure -that the OFX connection works correctly. The providers of this server -have asked us not to post the connection information publicly. - -Therefore, the test script file which connects to this server is -encrypted using a GnuPG key: OFX Test Server . - -You will need this private key to unlock this file. If you are an -active, contributing member of the open source OFX community, please -e-mail me for this key. Please do not share the key with anyone who does -not fit this description. Please do not post the key on any mailing list -or any other archived forum. If the key does become comprimised, please -e-mail me, or the libofx-devel list and we'll cancel that key and -encrypt it using a new one. - -Thanks - -Ace Jones diff -Nru libofx-0.10.5/ofxdump/CMakeLists.txt libofx-0.10.9/ofxdump/CMakeLists.txt --- libofx-0.10.5/ofxdump/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/ofxdump/CMakeLists.txt 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,66 @@ +# SPDX-FileCopyrightText: 2022 Dawid Wróbel +# SPDX-License-Identifier: GPL-2.0-or-later + +set(ofxdump_SRCS + cmdline.c + ofxdump.cpp +) + +add_executable(ofxdump ${ofxdump_SRCS}) +target_link_libraries(ofxdump libofx) +target_compile_definitions(ofxdump PRIVATE CMDLINE_PARSER_PACKAGE="ofxdump" + CMDLINE_PARSER_PACKAGE_NAME="ofxdump" + CMDLINE_PARSER_VERSION="${LIBOFX_VERSION_RELEASE_STRING}" +) + +if (TARGET getopt) + target_link_libraries(ofxdump getopt) +endif () + +install(TARGETS ofxdump RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + +#################### +### Add tests + +# Just a simple check that we can call the exe +add_test (NAME call-ofxdump COMMAND ofxdump) + +# This is the list of sample files that fail +set (SAMPLE_OFX_FILENAMES_FAILING + failing-ofx-file1.xml + failing-ofx-file2.xml + ofx-2.1.1-sect-13.13.ofx + ofx_sample_files/downcast.ofx + ofx_sample_files/heap-buffer-overflow-1.ofx + ofx_sample_files/heap-buffer-overflow-2.ofx + ofx_sample_files/null-ptr-deref-1.ofx + ofx_sample_files/null-ptr-deref-2.ofx + ofx_sample_files/use-after-free.ofx +) +# This is the list of all sample files (good and fail) +set (SAMPLE_OFX_FILENAMES + another-example.xml + example-listing1.xml + example-listing2.xml + ofx-2.1.1-sect-13.12.ofx + ofx-2.1.1-sect-16.5.3.2.ofx + ofx-2.1.1-sect-16.5.4.2.ofx + ofx-2.1.1-sect-16.5.6.2.ofx + ofx-2.1.1-sect-16.5.6.5.ofx + ofx-2.1.1-sect-8.5.5.ofx + ofx_spec160_stmtrs_example.sgml + ofx_spec201_stmtrs_example.xml + ${SAMPLE_OFX_FILENAMES_FAILING} +) +# Add a test for each file +foreach (fname ${SAMPLE_OFX_FILENAMES}) + set (_testname "test-${fname}") + add_test (NAME ${_testname} COMMAND ofxdump "${CMAKE_SOURCE_DIR}/doc/ofx_sample_files/${fname}") + set_property (TEST ${_testname} PROPERTY ENVIRONMENT "OFX_DTD_PATH=${CMAKE_SOURCE_DIR}/dtd") +endforeach () + +# And for the failing file tests, mark them as failing +foreach (fname ${SAMPLE_OFX_FILENAMES_FAILING}) + set (_testname "test-${fname}") + set_property (TEST ${_testname} PROPERTY WILL_FAIL true) +endforeach () diff -Nru libofx-0.10.5/ofxdump/cmdline.c libofx-0.10.9/ofxdump/cmdline.c --- libofx-0.10.5/ofxdump/cmdline.c 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/ofxdump/cmdline.c 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,690 @@ +/* + File autogenerated by gengetopt version 2.23 + generated with the following command: + gengetopt --unamed-opts -i cmdline.ggo + + The developers of gengetopt consider the fixed text that goes in all + gengetopt output files to be in the public domain: + we make no copyright claims on it. +*/ + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#ifndef FIX_UNUSED +#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ +#endif + +#include + +#include "cmdline.h" + +const char *gengetopt_args_info_purpose = "ofxdump prints to stdout, in human readable form, everything the library \nunderstands about a particular file or response, and sends errors to\nstderr. To know exactly what the library understands about of a particular\nofx response file, just call ofxdump on that file."; + +const char *gengetopt_args_info_usage = "Usage: " CMDLINE_PARSER_PACKAGE " [OPTION]... [FILE]..."; + +const char *gengetopt_args_info_versiontext = ""; + +const char *gengetopt_args_info_description = ""; + +const char *gengetopt_args_info_help[] = { + " -h, --help Print help and exit", + " -V, --version Print version and exit", + " -f, --import-format=STRING Force the file format of the file(s) specified\n (default=`AUTODETECT')", + " --list-import-formats List available import file formats\n 'import-format' command", + " --msg_parser Output file parsing messages (default=off)", + " --msg_debug Output messages meant for debugging\n (default=off)", + " --msg_warning Output warning messages about abnormal conditions\n and unknown constructs (default=on)", + " --msg_error Output error messages (default=on)", + " --msg_info Output informational messages about the progress\n of the library (default=on)", + " --msg_status Output status messages (default=on)", + 0 +}; + +typedef enum {ARG_NO + , ARG_FLAG + , ARG_STRING +} cmdline_parser_arg_type; + +static +void clear_given (struct gengetopt_args_info *args_info); +static +void clear_args (struct gengetopt_args_info *args_info); + +static int +cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error); + + +static char * +gengetopt_strdup (const char *s); + +static +void clear_given (struct gengetopt_args_info *args_info) +{ + args_info->help_given = 0 ; + args_info->version_given = 0 ; + args_info->import_format_given = 0 ; + args_info->list_import_formats_given = 0 ; + args_info->msg_parser_given = 0 ; + args_info->msg_debug_given = 0 ; + args_info->msg_warning_given = 0 ; + args_info->msg_error_given = 0 ; + args_info->msg_info_given = 0 ; + args_info->msg_status_given = 0 ; +} + +static +void clear_args (struct gengetopt_args_info *args_info) +{ + FIX_UNUSED (args_info); + args_info->import_format_arg = gengetopt_strdup ("AUTODETECT"); + args_info->import_format_orig = NULL; + args_info->msg_parser_flag = 0; + args_info->msg_debug_flag = 0; + args_info->msg_warning_flag = 1; + args_info->msg_error_flag = 1; + args_info->msg_info_flag = 1; + args_info->msg_status_flag = 1; + +} + +static +void init_args_info(struct gengetopt_args_info *args_info) +{ + + + args_info->help_help = gengetopt_args_info_help[0] ; + args_info->version_help = gengetopt_args_info_help[1] ; + args_info->import_format_help = gengetopt_args_info_help[2] ; + args_info->list_import_formats_help = gengetopt_args_info_help[3] ; + args_info->msg_parser_help = gengetopt_args_info_help[4] ; + args_info->msg_debug_help = gengetopt_args_info_help[5] ; + args_info->msg_warning_help = gengetopt_args_info_help[6] ; + args_info->msg_error_help = gengetopt_args_info_help[7] ; + args_info->msg_info_help = gengetopt_args_info_help[8] ; + args_info->msg_status_help = gengetopt_args_info_help[9] ; + +} + +void +cmdline_parser_print_version (void) +{ + printf ("%s %s\n", + (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE), + CMDLINE_PARSER_VERSION); + + if (strlen(gengetopt_args_info_versiontext) > 0) + printf("\n%s\n", gengetopt_args_info_versiontext); +} + +static void print_help_common(void) +{ + size_t len_purpose = strlen(gengetopt_args_info_purpose); + size_t len_usage = strlen(gengetopt_args_info_usage); + + if (len_usage > 0) { + printf("%s\n", gengetopt_args_info_usage); + } + if (len_purpose > 0) { + printf("%s\n", gengetopt_args_info_purpose); + } + + if (len_usage || len_purpose) { + printf("\n"); + } + + if (strlen(gengetopt_args_info_description) > 0) { + printf("%s\n\n", gengetopt_args_info_description); + } +} + +void +cmdline_parser_print_help (void) +{ + int i = 0; + print_help_common(); + while (gengetopt_args_info_help[i]) + printf("%s\n", gengetopt_args_info_help[i++]); +} + +void +cmdline_parser_init (struct gengetopt_args_info *args_info) +{ + clear_given (args_info); + clear_args (args_info); + init_args_info (args_info); + + args_info->inputs = 0; + args_info->inputs_num = 0; +} + +void +cmdline_parser_params_init(struct cmdline_parser_params *params) +{ + if (params) + { + params->override = 0; + params->initialize = 1; + params->check_required = 1; + params->check_ambiguity = 0; + params->print_errors = 1; + } +} + +struct cmdline_parser_params * +cmdline_parser_params_create(void) +{ + struct cmdline_parser_params *params = + (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); + cmdline_parser_params_init(params); + return params; +} + +static void +free_string_field (char **s) +{ + if (*s) + { + free (*s); + *s = 0; + } +} + + +static void +cmdline_parser_release (struct gengetopt_args_info *args_info) +{ + unsigned int i; + free_string_field (&(args_info->import_format_arg)); + free_string_field (&(args_info->import_format_orig)); + + + for (i = 0; i < args_info->inputs_num; ++i) + free (args_info->inputs [i]); + + if (args_info->inputs_num) + free (args_info->inputs); + + clear_given (args_info); +} + + +static void +write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) +{ + FIX_UNUSED (values); + if (arg) { + fprintf(outfile, "%s=\"%s\"\n", opt, arg); + } else { + fprintf(outfile, "%s\n", opt); + } +} + + +int +cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) +{ + int i = 0; + + if (!outfile) + { + fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE); + return EXIT_FAILURE; + } + + if (args_info->help_given) + write_into_file(outfile, "help", 0, 0 ); + if (args_info->version_given) + write_into_file(outfile, "version", 0, 0 ); + if (args_info->import_format_given) + write_into_file(outfile, "import-format", args_info->import_format_orig, 0); + if (args_info->list_import_formats_given) + write_into_file(outfile, "list-import-formats", 0, 0 ); + if (args_info->msg_parser_given) + write_into_file(outfile, "msg_parser", 0, 0 ); + if (args_info->msg_debug_given) + write_into_file(outfile, "msg_debug", 0, 0 ); + if (args_info->msg_warning_given) + write_into_file(outfile, "msg_warning", 0, 0 ); + if (args_info->msg_error_given) + write_into_file(outfile, "msg_error", 0, 0 ); + if (args_info->msg_info_given) + write_into_file(outfile, "msg_info", 0, 0 ); + if (args_info->msg_status_given) + write_into_file(outfile, "msg_status", 0, 0 ); + + + i = EXIT_SUCCESS; + return i; +} + +int +cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) +{ + FILE *outfile; + int i = 0; + + outfile = fopen(filename, "w"); + + if (!outfile) + { + fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); + return EXIT_FAILURE; + } + + i = cmdline_parser_dump(outfile, args_info); + fclose (outfile); + + return i; +} + +void +cmdline_parser_free (struct gengetopt_args_info *args_info) +{ + cmdline_parser_release (args_info); +} + +/** @brief replacement of strdup, which is not standard */ +char * +gengetopt_strdup (const char *s) +{ + char *result = 0; + if (!s) + return result; + + result = (char*)malloc(strlen(s) + 1); + if (result == (char*)0) + return (char*)0; + strcpy(result, s); + return result; +} + +int +cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info) +{ + return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); +} + +int +cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params) +{ + int result; + result = cmdline_parser_internal (argc, argv, args_info, params, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) +{ + int result; + struct cmdline_parser_params params; + + params.override = override; + params.initialize = initialize; + params.check_required = check_required; + params.check_ambiguity = 0; + params.print_errors = 1; + + result = cmdline_parser_internal (argc, argv, args_info, ¶ms, 0); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) +{ + FIX_UNUSED (args_info); + FIX_UNUSED (prog_name); + return EXIT_SUCCESS; +} + + +static char *package_name = 0; + +/** + * @brief updates an option + * @param field the generic pointer to the field to update + * @param orig_field the pointer to the orig field + * @param field_given the pointer to the number of occurrence of this option + * @param prev_given the pointer to the number of occurrence already seen + * @param value the argument for this option (if null no arg was specified) + * @param possible_values the possible values for this option (if specified) + * @param default_value the default value (in case the option only accepts fixed values) + * @param arg_type the type of this option + * @param check_ambiguity @see cmdline_parser_params.check_ambiguity + * @param override @see cmdline_parser_params.override + * @param no_free whether to free a possible previous value + * @param multiple_option whether this is a multiple option + * @param long_opt the corresponding long option + * @param short_opt the corresponding short option (or '-' if none) + * @param additional_error possible further error specification + */ +static +int update_arg(void *field, char **orig_field, + unsigned int *field_given, unsigned int *prev_given, + char *value, const char *possible_values[], + const char *default_value, + cmdline_parser_arg_type arg_type, + int check_ambiguity, int override, + int no_free, int multiple_option, + const char *long_opt, char short_opt, + const char *additional_error) +{ + char *stop_char = 0; + const char *val = value; + int found; + char **string_field; + FIX_UNUSED (field); + + stop_char = 0; + found = 0; + + if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) + { + if (short_opt != '-') + fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", + package_name, long_opt, short_opt, + (additional_error ? additional_error : "")); + else + fprintf (stderr, "%s: `--%s' option given more than once%s\n", + package_name, long_opt, + (additional_error ? additional_error : "")); + return 1; /* failure */ + } + + FIX_UNUSED (default_value); + + if (field_given && *field_given && ! override) + return 0; + if (prev_given) + (*prev_given)++; + if (field_given) + (*field_given)++; + if (possible_values) + val = possible_values[found]; + + switch(arg_type) { + case ARG_FLAG: + *((int *)field) = !*((int *)field); + break; + case ARG_STRING: + if (val) { + string_field = (char **)field; + if (!no_free && *string_field) + free (*string_field); /* free previous string */ + *string_field = gengetopt_strdup (val); + } + break; + default: + break; + }; + + FIX_UNUSED(stop_char); + + /* store the original value */ + switch(arg_type) { + case ARG_NO: + case ARG_FLAG: + break; + default: + if (value && orig_field) { + if (no_free) { + *orig_field = value; + } else { + if (*orig_field) + free (*orig_field); /* free previous string */ + *orig_field = gengetopt_strdup (value); + } + } + }; + + return 0; /* OK */ +} + + +int +cmdline_parser_internal ( + int argc, char **argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error) +{ + int c; /* Character of the parsed option. */ + + int error_occurred = 0; + struct gengetopt_args_info local_args_info; + + int override; + int initialize; + int check_required; + int check_ambiguity; + + package_name = argv[0]; + + /* TODO: Why is this here? It is not used anywhere. */ + override = params->override; + FIX_UNUSED(override); + + initialize = params->initialize; + check_required = params->check_required; + + /* TODO: Why is this here? It is not used anywhere. */ + check_ambiguity = params->check_ambiguity; + FIX_UNUSED(check_ambiguity); + + if (initialize) + cmdline_parser_init (args_info); + + cmdline_parser_init (&local_args_info); + + optarg = 0; + optind = 0; + opterr = params->print_errors; + optopt = '?'; + + while (1) + { + int option_index = 0; + + static struct option long_options[] = { + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'V' }, + { "import-format", 1, NULL, 'f' }, + { "list-import-formats", 0, NULL, 0 }, + { "msg_parser", 0, NULL, 0 }, + { "msg_debug", 0, NULL, 0 }, + { "msg_warning", 0, NULL, 0 }, + { "msg_error", 0, NULL, 0 }, + { "msg_info", 0, NULL, 0 }, + { "msg_status", 0, NULL, 0 }, + { 0, 0, 0, 0 } + }; + + c = getopt_long (argc, argv, "hVf:", long_options, &option_index); + + if (c == -1) break; /* Exit from `while (1)' loop. */ + + switch (c) + { + case 'h': /* Print help and exit. */ + cmdline_parser_print_help (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'V': /* Print version and exit. */ + cmdline_parser_print_version (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'f': /* Force the file format of the file(s) specified. */ + + + if (update_arg( (void *)&(args_info->import_format_arg), + &(args_info->import_format_orig), &(args_info->import_format_given), + &(local_args_info.import_format_given), optarg, 0, "AUTODETECT", ARG_STRING, + check_ambiguity, override, 0, 0, + "import-format", 'f', + additional_error)) + goto failure; + + break; + + case 0: /* Long option with no short option */ + /* List available import file formats 'import-format' command. */ + if (strcmp (long_options[option_index].name, "list-import-formats") == 0) + { + + + if (update_arg( 0 , + 0 , &(args_info->list_import_formats_given), + &(local_args_info.list_import_formats_given), optarg, 0, 0, ARG_NO, + check_ambiguity, override, 0, 0, + "list-import-formats", '-', + additional_error)) + goto failure; + + } + /* Output file parsing messages. */ + else if (strcmp (long_options[option_index].name, "msg_parser") == 0) + { + + + if (update_arg((void *)&(args_info->msg_parser_flag), 0, &(args_info->msg_parser_given), + &(local_args_info.msg_parser_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "msg_parser", '-', + additional_error)) + goto failure; + + } + /* Output messages meant for debugging. */ + else if (strcmp (long_options[option_index].name, "msg_debug") == 0) + { + + + if (update_arg((void *)&(args_info->msg_debug_flag), 0, &(args_info->msg_debug_given), + &(local_args_info.msg_debug_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "msg_debug", '-', + additional_error)) + goto failure; + + } + /* Output warning messages about abnormal conditions and unknown constructs. */ + else if (strcmp (long_options[option_index].name, "msg_warning") == 0) + { + + + if (update_arg((void *)&(args_info->msg_warning_flag), 0, &(args_info->msg_warning_given), + &(local_args_info.msg_warning_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "msg_warning", '-', + additional_error)) + goto failure; + + } + /* Output error messages. */ + else if (strcmp (long_options[option_index].name, "msg_error") == 0) + { + + + if (update_arg((void *)&(args_info->msg_error_flag), 0, &(args_info->msg_error_given), + &(local_args_info.msg_error_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "msg_error", '-', + additional_error)) + goto failure; + + } + /* Output informational messages about the progress of the library. */ + else if (strcmp (long_options[option_index].name, "msg_info") == 0) + { + + + if (update_arg((void *)&(args_info->msg_info_flag), 0, &(args_info->msg_info_given), + &(local_args_info.msg_info_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "msg_info", '-', + additional_error)) + goto failure; + + } + /* Output status messages. */ + else if (strcmp (long_options[option_index].name, "msg_status") == 0) + { + + + if (update_arg((void *)&(args_info->msg_status_flag), 0, &(args_info->msg_status_given), + &(local_args_info.msg_status_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "msg_status", '-', + additional_error)) + goto failure; + + } + + break; + case '?': /* Invalid option. */ + /* `getopt_long' already printed an error message. */ + goto failure; + + default: /* bug: option not considered. */ + fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); + abort (); + } /* switch */ + } /* while */ + + + + FIX_UNUSED(check_required); + + cmdline_parser_release (&local_args_info); + + if ( error_occurred ) + return (EXIT_FAILURE); + + if (optind < argc) + { + int i = 0 ; + int found_prog_name = 0; + /* whether program name, i.e., argv[0], is in the remaining args + (this may happen with some implementations of getopt, + but surely not with the one included by gengetopt) */ + + i = optind; + while (i < argc) + if (argv[i++] == argv[0]) { + found_prog_name = 1; + break; + } + i = 0; + + args_info->inputs_num = argc - optind - found_prog_name; + args_info->inputs = + (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ; + while (optind < argc) + if (argv[optind++] != argv[0]) + args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind-1]) ; + } + + return 0; + +failure: + + cmdline_parser_release (&local_args_info); + return (EXIT_FAILURE); +} +/* vim: set ft=c noet ts=8 sts=8 sw=8 tw=80 nojs spell : */ diff -Nru libofx-0.10.5/ofxdump/cmdline.h libofx-0.10.9/ofxdump/cmdline.h --- libofx-0.10.5/ofxdump/cmdline.h 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/ofxdump/cmdline.h 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,203 @@ +/** @file cmdline.h + * @brief The header file for the command line option parser + * generated by GNU Gengetopt version 2.23 + * http://www.gnu.org/software/gengetopt. + * DO NOT modify this file, since it can be overwritten + * @author GNU Gengetopt */ + +#ifndef CMDLINE_H +#define CMDLINE_H + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include /* for FILE */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef CMDLINE_PARSER_PACKAGE +/** @brief the program name (used for printing errors) */ +#define CMDLINE_PARSER_PACKAGE PACKAGE +#endif + +#ifndef CMDLINE_PARSER_PACKAGE_NAME +/** @brief the complete program name (used for help and version) */ +#ifdef PACKAGE_NAME +#define CMDLINE_PARSER_PACKAGE_NAME PACKAGE_NAME +#else +#define CMDLINE_PARSER_PACKAGE_NAME PACKAGE +#endif +#endif + +#ifndef CMDLINE_PARSER_VERSION +/** @brief the program version */ +#define CMDLINE_PARSER_VERSION VERSION +#endif + +/** @brief Where the command line options are stored */ +struct gengetopt_args_info +{ + const char *help_help; /**< @brief Print help and exit help description. */ + const char *version_help; /**< @brief Print version and exit help description. */ + char * import_format_arg; /**< @brief Force the file format of the file(s) specified (default='AUTODETECT'). */ + char * import_format_orig; /**< @brief Force the file format of the file(s) specified original value given at command line. */ + const char *import_format_help; /**< @brief Force the file format of the file(s) specified help description. */ + const char *list_import_formats_help; /**< @brief List available import file formats 'import-format' command help description. */ + int msg_parser_flag; /**< @brief Output file parsing messages (default=off). */ + const char *msg_parser_help; /**< @brief Output file parsing messages help description. */ + int msg_debug_flag; /**< @brief Output messages meant for debugging (default=off). */ + const char *msg_debug_help; /**< @brief Output messages meant for debugging help description. */ + int msg_warning_flag; /**< @brief Output warning messages about abnormal conditions and unknown constructs (default=on). */ + const char *msg_warning_help; /**< @brief Output warning messages about abnormal conditions and unknown constructs help description. */ + int msg_error_flag; /**< @brief Output error messages (default=on). */ + const char *msg_error_help; /**< @brief Output error messages help description. */ + int msg_info_flag; /**< @brief Output informational messages about the progress of the library (default=on). */ + const char *msg_info_help; /**< @brief Output informational messages about the progress of the library help description. */ + int msg_status_flag; /**< @brief Output status messages (default=on). */ + const char *msg_status_help; /**< @brief Output status messages help description. */ + + unsigned int help_given ; /**< @brief Whether help was given. */ + unsigned int version_given ; /**< @brief Whether version was given. */ + unsigned int import_format_given ; /**< @brief Whether import-format was given. */ + unsigned int list_import_formats_given ; /**< @brief Whether list-import-formats was given. */ + unsigned int msg_parser_given ; /**< @brief Whether msg_parser was given. */ + unsigned int msg_debug_given ; /**< @brief Whether msg_debug was given. */ + unsigned int msg_warning_given ; /**< @brief Whether msg_warning was given. */ + unsigned int msg_error_given ; /**< @brief Whether msg_error was given. */ + unsigned int msg_info_given ; /**< @brief Whether msg_info was given. */ + unsigned int msg_status_given ; /**< @brief Whether msg_status was given. */ + + char **inputs ; /**< @brief unnamed options (options without names) */ + unsigned inputs_num ; /**< @brief unnamed options number */ +} ; + +/** @brief The additional parameters to pass to parser functions */ +struct cmdline_parser_params +{ + int override; /**< @brief whether to override possibly already present options (default 0) */ + int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */ + int check_required; /**< @brief whether to check that all required options were provided (default 1) */ + int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */ + int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */ +} ; + +/** @brief the purpose string of the program */ +extern const char *gengetopt_args_info_purpose; +/** @brief the usage string of the program */ +extern const char *gengetopt_args_info_usage; +/** @brief the description string of the program */ +extern const char *gengetopt_args_info_description; +/** @brief all the lines making the help output */ +extern const char *gengetopt_args_info_help[]; + +/** + * The command line parser + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser (int argc, char **argv, + struct gengetopt_args_info *args_info); + +/** + * The command line parser (version with additional parameters - deprecated) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param override whether to override possibly already present options + * @param initialize whether to initialize the option structure my_args_info + * @param check_required whether to check that all required options were provided + * @return 0 if everything went fine, NON 0 if an error took place + * @deprecated use cmdline_parser_ext() instead + */ +int cmdline_parser2 (int argc, char **argv, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); + +/** + * The command line parser (version with additional parameters) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param params additional parameters for the parser + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_ext (int argc, char **argv, + struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params); + +/** + * Save the contents of the option struct into an already open FILE stream. + * @param outfile the stream where to dump options + * @param args_info the option struct to dump + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_dump(FILE *outfile, + struct gengetopt_args_info *args_info); + +/** + * Save the contents of the option struct into a (text) file. + * This file can be read by the config file parser (if generated by gengetopt) + * @param filename the file where to save + * @param args_info the option struct to save + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_file_save(const char *filename, + struct gengetopt_args_info *args_info); + +/** + * Print the help + */ +void cmdline_parser_print_help(void); +/** + * Print the version + */ +void cmdline_parser_print_version(void); + +/** + * Initializes all the fields a cmdline_parser_params structure + * to their default values + * @param params the structure to initialize + */ +void cmdline_parser_params_init(struct cmdline_parser_params *params); + +/** + * Allocates dynamically a cmdline_parser_params structure and initializes + * all its fields to their default values + * @return the created and initialized cmdline_parser_params structure + */ +struct cmdline_parser_params *cmdline_parser_params_create(void); + +/** + * Initializes the passed gengetopt_args_info structure's fields + * (also set default values for options that have a default) + * @param args_info the structure to initialize + */ +void cmdline_parser_init (struct gengetopt_args_info *args_info); +/** + * Deallocates the string fields of the gengetopt_args_info structure + * (but does not deallocate the structure itself) + * @param args_info the structure to deallocate + */ +void cmdline_parser_free (struct gengetopt_args_info *args_info); + +/** + * Checks that all the required options were specified + * @param args_info the structure to check + * @param prog_name the name of the program that will be used to print + * possible errors + * @return + */ +int cmdline_parser_required (struct gengetopt_args_info *args_info, + const char *prog_name); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* CMDLINE_H */ diff -Nru libofx-0.10.5/ofxdump/.gitignore libofx-0.10.9/ofxdump/.gitignore --- libofx-0.10.5/ofxdump/.gitignore 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/ofxdump/.gitignore 2022-10-03 20:22:59.000000000 +0000 @@ -6,6 +6,4 @@ Makefile Makefile.in ofxdump -cmdline.c -cmdline.h *.1 diff -Nru libofx-0.10.5/ofxdump/Makefile.am libofx-0.10.9/ofxdump/Makefile.am --- libofx-0.10.5/ofxdump/Makefile.am 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/ofxdump/Makefile.am 2022-10-03 20:22:59.000000000 +0000 @@ -15,7 +15,7 @@ endif -ofxdump.1: ofxdump$(EXEEXT) $(top_srcdir)/configure.ac +ofxdump.1: $(top_srcdir)/configure.ac if HAVE_HELP2MAN $(HELP2MAN) -n 'Dump content of OFX files as human-readable text' -N --output=ofxdump.1 ./ofxdump$(EXEEXT) else @@ -23,7 +23,7 @@ endif MAINTAINERCLEANFILES = cmdline.c cmdline.h -EXTRA_DIST = cmdline.ggo +EXTRA_DIST = cmdline.ggo CMakeLists.txt # Run all our example files through ofxdump to verify we can parse # them without failure @@ -41,7 +41,14 @@ ../doc/ofx_sample_files/ofx-2.1.1-sect-16.5.6.5.ofx \ ../doc/ofx_sample_files/ofx-2.1.1-sect-8.5.5.ofx \ ../doc/ofx_sample_files/failing-ofx-file1.xml \ - ../doc/ofx_sample_files/failing-ofx-file2.xml + ../doc/ofx_sample_files/failing-ofx-file2.xml \ + ../doc/ofx_sample_files/null-ptr-deref-1.ofx \ + ../doc/ofx_sample_files/null-ptr-deref-2.ofx \ + ../doc/ofx_sample_files/downcast.ofx \ + ../doc/ofx_sample_files/heap-buffer-overflow-1.ofx \ + ../doc/ofx_sample_files/heap-buffer-overflow-2.ofx \ + ../doc/ofx_sample_files/use-after-free.ofx + # To ensure we are not just always green, test that two bogus files # actually fail the ofxdump run. @@ -49,8 +56,14 @@ XFAIL_TESTS = \ ../doc/ofx_sample_files/failing-ofx-file1.xml \ ../doc/ofx_sample_files/failing-ofx-file2.xml \ - ../doc/ofx_sample_files/ofx-2.1.1-sect-13.13.ofx - + ../doc/ofx_sample_files/ofx-2.1.1-sect-13.13.ofx \ + ../doc/ofx_sample_files/null-ptr-deref-1.ofx \ + ../doc/ofx_sample_files/null-ptr-deref-2.ofx \ + ../doc/ofx_sample_files/downcast.ofx \ + ../doc/ofx_sample_files/heap-buffer-overflow-1.ofx \ + ../doc/ofx_sample_files/heap-buffer-overflow-2.ofx \ + ../doc/ofx_sample_files/use-after-free.ofx + TEST_EXTENSIONS = .xml .sgml .ofx OFX_LOG_COMPILER = ./ofxdump # Must set the correct path to the DTD as env variable diff -Nru libofx-0.10.5/README libofx-0.10.9/README --- libofx-0.10.5/README 2022-04-18 20:01:27.000000000 +0000 +++ libofx-0.10.9/README 2022-10-03 20:22:59.000000000 +0000 @@ -1,22 +1,8 @@ Copyright (c) 2002-2010 Benoit Grégoire -This is the LibOFX library. It is a API designed to allow applications to very easily support OFX command responses, usually provided by financial institutions. See http://www.ofx.net/ for details and specification. This project was first started as my end of degree project, with the objective to add OFX support to [GnuCash](https://www.gnucash.org/) If you can read French, the original project presentation is included in the doc directory. I finally decided to make it into a generic library, so all OpenSource financial software can benefit. +# LibOFX +LibOFX library is an API designed to allow applications to very easily support OFX command responses, usually provided by financial institutions. See http://www.ofx.net/ for details and specification. This project was first started as my end of degree project, with the objective to add OFX support to [GnuCash](https://www.gnucash.org/) If you can read French, the original project presentation is included in the doc directory. I finally decided to make it into a generic library, so all OpenSource financial software can benefit. -LibOFX is based on the excellent OpenSP library written by James Clark, and now part of the [OpenJADE](http://openjade.sourceforge.net/) project. OpenSP by itself is not widely distributed. OpenJADE 1.3.1 includes a version on OpenSP that will link, however, it has some major problems with LibOFX and isn't recommended. Since LibOFX uses the generic interface to OpenSP, it should be compatible with all recent versions of OpenSP (It has been developed with OpenSP-1.5pre5). LibOFX is written in C++, but provides a C style interface usable transparently from both C and C++ using a single include file. - -In addition to the library, three utilities are included with libofx - -**ofxdump**:\ -ofxdump prints to stdout, in human-readable form, everything the library understands about a particular OFX response file, and sends errors to stderr. It is a C++ code example and demo of the library (it uses every functions and every structures of LibOFX)\ -usage: `ofxdump` _path_to_ofx_file_`/`_ofx_filename_ - -**ofx2qif**:\ -ofx2qif is a OFX "file" to QIF (Quicken Interchange Format) converter. It was written as a C code example, and as a way for LibOFX to immediately provide something useful, as an incentive for people to try out the library. It is not recommended that financial software use the output of this utility for OFX support. The QIF file format is very primitive, and much information is lost. The utility currently supports every transaction tags of the qif format except the address lines, and supports many of the tags of `!Account`. It should generate QIF files that will import successfully in just about every software with QIF support. -I do not plan on working on this utility much further, but I would be more than happy to accept contributions.\ -usage: `ofx2qif` _path_to_ofx_file_`/`_ofx_filename_ `>` _output_filename_`.qif` - -**ofxconnect**:\ -sample app to demonstrate & test new direct connect API'\s (try "make check" in the ofxconnect folder). Read [ofxdump/README.privateserver](ofxdump/README.privateserver) first. LibOFX strives to achieve the following design goals: @@ -28,9 +14,9 @@ * Banking transactions and statements. * Credit card and statements. * Investment transactions. -* OFX 2.0 +* OFX 2.0 -Future projects for libofx include: +Future projects for LibOFX include: * Header parsing * DTD autodetection * Currency conversion @@ -38,12 +24,247 @@ * QIF export (integrated inside the library) * OFX export -Full documentation of the API and library internals generated using doxygen is available. For a quick start, you should learn all you need to know to get started by reading the libofx.h file in the INC directory, and ofxdump.cpp in the ofxdump directory. +# Additional tools +In addition to the library, three utilities are included with LibOFX: + +## ofxdump +ofxdump prints to stdout, in human-readable form, everything the library understands about a particular OFX response file, and sends errors to stderr. It is a C++ code example and demo of the library (it uses every functions and every structures of LibOFX). + +Usage: `ofxdump _path_to_ofx_file_/_ofx_filename_` + +## ofx2qif +ofx2qif is a OFX "file" to QIF (Quicken Interchange Format) converter. It was written as a C code example, and as a way for LibOFX to immediately provide something useful, as an incentive for people to try out the library. It is not recommended that financial software use the output of this utility for OFX support. The QIF file format is very primitive, and much information is lost. The utility currently supports every transaction tags of the qif format except the address lines, and supports many of the tags of `!Account`. It should generate QIF files that will import successfully in just about every software with QIF support. +I do not plan on working on this utility much further, but I would be more than happy to accept contributions. + +Usage: `ofx2qif _path_to_ofx_file_/_ofx_filename_ > _output_filename_.qif` + +## ofxconnect +ofxconnect is a sample app to demonstrate & test new Direct Connect APIs. +It also serves as an implementation sample, so you can understand how to use it in your own code. + +### The Direct Connect protocol + +Direct Connect consists of two separate steps: First, contacting the partner +server to retrieve information about your bank. Second, contacting your bank +to retrieve your accounts and statements. The partner server should be +contacted when the user sets up his accounts. + +Common mistakes with the partner server are to contact it EVERY time you +contact the bank, and contacting it just once to cache the contact +info for all banks. The former is overkill, the latter means users won't +have up-to-date bank contact information. + +### Usage + +Step-by-step guide to using the ofxconnect utility: + +1. Retrieve the list of banks + + ```shell + $ ofxconnect -b + ``` + +2. Find your bank in the list. Retrieve the FI partner ID's (fipid's) for that bank + + ```shell + $ ofxconnect -f "Wells Fargo" + 101458 + 102078 + 5571 + ``` + +3. Retrieve the service capabilities of each fipid to find the one which has the services you want.\ +Note that all the 6-digit fipids don't seem to work well with LibOFX right now. + + ```shell + $ ofxconnect -v 5571 + Statements? Yes + Billpay? Yes + Investments? No + ``` + +4. Retrieve and view the list of all your accounts + + ```shell + $ ofxconnect -a --fipid=5571 --user=myusername --pass=mypassword accounts.ofx + $ ofxdump accounts.ofx 2>/dev/null + ``` + +5. Look for entries like this: + + ``` + Account ID: 999888777 00 123456789 + Account name: Bank account 1234567890 + Account type: CHECKING + Bank ID: 999888777 + Branch ID: 00 + Account #: 1234567890 + ``` + +6. Retrieve a statement for one of the accounts + + ```shell + $ ofxconnect -s --fipid=5571 --user=myusername --pass=mypassword --bank=xxx --account=xxx --type=x --past=xx statement.ofx + $ ofxdump statement.ofx 2>/dev/null + ```` + + The `--bank` and `--account` parameters should be exactly like the "Bank ID" and "Account #" results from the account request.\ + The `--type` is: `1=CHECKING`, `2=INVESTMENT`, `3=CREDITCARD`. Other types are not supported.\ + The `--past` is how many days previous from today you want. + +### Testing in live environment + +When building using Autotools build system, issuing `make check` in the ofxconnect folder should test against a live test server: + +> There is an OFX test server which is used by the developers to ensure +> that the OFX connection works correctly. The providers of this server +> have asked us not to post the connection information publicly. +> +> Therefore, the test script file which connects to this server is +> encrypted using a GnuPG key: OFX Test Server . +> +> You will need this private key to unlock this file. If you are an +> active, contributing member of the open source OFX community, please +> e-mail me for this key. Please do not share the key with anyone who does +> not fit this description. Please do not post the key on any mailing list +> or any other archived forum. If the key does become comprimised, please +> e-mail me, or the libofx-devel list and we'll cancel that key and +> encrypt it using a new one. +> +> Thanks +> +> Ace Jones + +# Dependencies + +## OpenSP +LibOFX is based on the excellent OpenSP library written by James Clark, and now part of the [OpenJADE](http://openjade.sourceforge.net/) project. OpenSP by itself is not widely distributed. OpenJADE 1.3.1 includes a version on OpenSP that will link, however, it has some major problems with LibOFX and isn't recommended. Since LibOFX uses the generic interface to OpenSP, it should be compatible with all recent versions of OpenSP (It has been developed with OpenSP-1.5pre5). LibOFX is written in C++, but provides a C style interface usable transparently from both C and C++ using a single include file. + +### LibOFX <==> OpenSP compatibility matrix: +| OpenSP version | Status | Comments | +|-----------------------------------------------------|--------------------------------|--------------------------------------------------------------------------------------------| +| 1.3.4 (included in most distro with OpenJADE 1.3.1) | NOT COMPATIBLE | OpenSP doesn't parse OFX files correctly. LibOFX < 0.23 will probably only output garbage. | +| 1.4 | NOT TESTED || +| 1.5pre5 | COMPATIBLE with all versions || +| 1.5pre8 | COMPATIBLE with LibOFX >= 0.23 || +| 1.5 | COMPATIBLE with LibOFX >= 0.23 || + +### Locating the OpenSP library file +The [`FindOpenSP.cmake`](cmake/modules/FindOpenSP.cmake) module attempts to locate the library and its headers on the filesystem. If it fails to do so, or if you want to tell it to use a specific library file instead, you can pass [CMake switches](#cmake-switches) to do so. + +Note that the [upstream CMake](https://gitlab.kitware.com/cmake/cmake/-/blob/master/Modules/FindOpenSP.cmake) ships the [`FindOpenSP.cmake`](cmake/modules/FindOpenSP.cmake) module as of version 3.25, so its copy included with LibOFX sourcecode is used only if your CMake version is older than that. + +### On the SP_MULTI_BYTE +LibOFX must know if OpenSP library was compiled with the `SP_MULTI_BYTE` defined. The `FindOpenSP` module will attempt to detect the `SP_MULTI_BYTE`, based on OpenSP's `config.h`. If, however, you see strings such as `SAEET` or `SAEET▄ù≡ù` instead of `STATEMENT` in ofxdump's output, it means that the library was misconfigured. +In such case you can force LibOFX to override the detected value by setting the `FORCE_OPENSP_MULTIBYTE` [CMake switch](#cmake-switches) to either `ON` or `OFF`. Note that this switch defaults to `AUTO` to use the auto-detected value. + +## Iconv +Used to convert the encoding, not required but very recommended. + +## Libxml++ +Required by the ofxconnect tool. Needs to be compatible with version 2.6 of the ABI, see https://libxmlplusplus.github.io/libxmlplusplus/#abi-versions for details. + +## Libcurl +Required by the ofxconnect tool. + +# Building + +## Using CMake build system + +You can use CMake to build LibOFX. See the `CMakeLists.txt` in root folder for the currently required version. +CMake is designed so that the build process can be done in a separate directory. This is highly recommended for users and required for packagers. +To build LibOFX in the subdirectory `build/`, type: + +```shell +$ cmake -B build -S . # add "-G Ninja" if ninja is installed (optional, see "CMake switches" section below) +$ ccmake -B build -S . # to change the configuration of the build process (optional, see "CMake switches" section below). +``` + +## CMake switches +There are several CMake options available that can be enabled/disabled to change the set of features enabled or the compilation behavior: + + +| Switch | Value | Default | Purpose | +|-------------------------------|:-----------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------:|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `-D BUILD_SHARED_LIBS` | `ON`/`OFF` | `ON` | Whether to build LibOFX dynamically (shared) or statically | +| `-D ENABLE_ICONV` | `ON`/`OFF` | `ON` | Enables ICONV support for encoding conversion | +| `-D ENABLE_OFX2QIF` | `ON`/`OFF` | `ON` | Enables OFX file to QIF (Quicken Interchange Format) file converter | +| `-D ENABLE_OFXDUMP` | `ON`/`OFF` | `ON` | Enables ofxdump utility which prints, in human readable form, everything the library understands about a file | +| `-D ENABLE_OFXCONNECT` | `ON`/`OFF` | `ON` | Enables ofxconnect utility which allows to test OFX Direct Connect | +| `-D FORCE_OPENSP_MULTIBYTE` | `AUTO`/`ON`/`OFF` | `AUTO` | Whether to use the auto-detected value of the `SP_MULTI_BYTE` (`AUTO`), or to override it to `ON` or `OFF`. See [On the SP_MULTI_BYTE](#on-the-spmultibyte) notes. | +| `-D CMAKE_BUILD_TYPE` | Various | `RelWithDebInfo` | Chooses the build type; refer to CMake manual for a list of possible types | +| `-D CMAKE_TOOLCHAIN_FILE` | A path, e.g. `[vcpkg root]/scripts/buildsystems/vcpkg.cmake`, where `[vcpkg root]` is your clone of the vcpkg Git repository. | None | A path to the toolchain file. Implies `ENABLE_VCPKG_INTEGRATION=ON` | +| `-D ENABLE_VCPKG_INTEGRATION` | `ON`/`OFF` | `OFF` | An alternative way to enable vcpkg integration. A attempt will be made to detect the location of the `vcpkg.cmake` toolchain file using `VCPKG_ROOT` environment variable. | +| `-D OpenSP_INCLUDE_DIR` | A path, e.g. `/usr/include/opensp` | Whatever `FindOpenSP.cmake` detects | A path to the OpenSP library includes. Normally `FindOpenSP.cmake` module should locate it, but if it can't or you want to override it, you can use this switch. | +| `-D OpenSP_LIBRARY` | A path, e.g. `/usr/lib/libosp.so.5` | Whatever `FindOpenSP.cmake` detects | Like the `OpenSP_INCLUDE_DIR` above, but for the library file itself. | + +### Vcpkg integration + +vcpkg is a command-line package manager for C++, supported on macOS, Linux and Windows platforms. It is a preferred way of obtaining the dependencies due to its ability to deploy them according to a declarative [vcpkg.json](vcpkg.json) manifest file provided with the source code. This allows to maintain a set of dependencies and their corresponding versions independently for each branch and automatically switching between them as needed. It also guarantees reproducibility of the dev environment and substantially reduces the effort required to set up a working environment. + +Refer to the [Getting Started](https://github.com/microsoft/vcpkg#getting-started) guide on project's website on how to get started if you're not yet familiar with it. + +In order to build LibOFX with it, simply enabling an additional switch in your CMake command should be enough:\ +`-DCMAKE_TOOLCHAIN_FILE=[vcpkg root]/scripts/buildsystems/vcpkg.cmake`, where `[vcpkg root]` is your clone of the vcpkg Git repository. Alternatively, if you have `VCPKG_ROOT` environment variable set-up, you can simply enable `-D ENABLE_VCPKG_INTEGRATION=ON` switch to have it autodetect the location of the vcpkg toolchain file. See notes on the [CMake switches](#cmake-switches) available as well. + +Vcpkg will automatically set-up all the required optional dependencies, per the [CMake switches](#cmake-switches) enabled via the command line. + +## Using classic Autotools build system + +Make sure you have the OpenSP library installed (`libosp.so`) before compiling. You can grab it at http://openjade.sourceforge.net/. The recommended version is OpenSP 1.5. +If you have a version of OpenJade or OpenSP already installed before compiling OpenSP, make sure that you use `./configure --prefix=/usr` to build OpenSP. Otherwise, LibOFX will probably link with the older, incompatible version of OpenSP. + +Then type:\ +1. `./autogen.sh` (for LibOFX cloned from repository)\ +or `./configure` (for a distributed tarball)\ +2. `make`\ +And as root type: +3. `make install` + +# Consuming (using as a dependency in your project) + +LibOFX is distributed with both PkgConfig libofx.pc (materialized from [libofx.pc.in](libofx.pc.in)) and [CMake config-file package](https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html) (materialized from [LibOFXConfig.cmake.in](LibOFXConfig.cmake.in)). If possible, use the latter, as it is more robust +and can automatically locate the OpenSP dependency library via the [`FindOpenSP.cmake`](#locating-the-opensp-library-file). + +A copy of [`FindOpenSP.cmake`](#locating-the-opensp-library-file) module is distributed alongside the CMake config-file package for use in case your CMake version does not ship it. See a note in +[`FindOpenSP.cmake`](#locating-the-opensp-library-file) for details on that. + + +## FAQ/Troubleshooting + +### Q: vcpkg fails to build ofxconnect due to missing Libxml++ + +LibOFX depends on [Libxml++ library that compatible with version 2.6 of its ABI](#libxml), meanwhile vcpkg provides a version compatible with ABI 5.0. Unfortunately, at this point there is no workaround for it if building with vcpkg. + +### Q: Getting "configure: error: unable to link a test program, is OpenSP installed?" + +BE CAREFUL: When you compile OpenSP, by default it will install in /usr/local. On many versions of linux (Most RedHat, All Mandrake up to 8.3) `/usr/local/lib/` is not part of `/etc/ld.so.conf`. In this case LibOFX will either: +1) Fail to link at all +2) Link with `libosp.so.0` (1.3.4, which probably got installed as part of OpenJade) and not work. +Even if you add `/usr/local/lib/` to `/etc/ld.so.conf`, LibOFX will probably still link with OpenSP 1.3.4 at runtime. Symptoms will be complaints of many unclosed statements when running ofxdump on an ofx file. + +I STRONGLY URGE YOU to avoid these problems and compile OpenSP using +`./configure --prefix=/usr` +If you really want to install OpenSP in `/usr/local/lib`, you must add `--with-opensp-libs=/usr/local/lib` to LibOFX's `./configure` or `./autogen.sh` + +### Q: Problems compiling OpenSP 1.4 + +If you are getting errors like: +`../include/Message.h:157: 'class OpenSP::Messenger' is inaccessible nsgmls.cxx:60: within this context)` + +Try to change private to protected in file `OpenSP-1.4/nsgmls/RasEventHandler.h`, on line 105. + +### Q: ofxdump does now work right. It seems some values are cut in half, or one out of two letter is missing. + +See the [On the SP_MULTI_BYTE](#on-the-spmultibyte) notes. + +# API Documentation +Full documentation of the API and library internals generated using doxygen is available. For a quick start, you should learn all you need to know to get started by reading the `libofx.h` file in the INC directory, and `ofxdump.cpp` in the ofxdump directory. -Call for help: +# Get involved! * Please note that despite a very detailed spec, OFX is by nature very hard to test. I only have access to the specifications examples, and -my own bank (Desjardins). But I need people to run as many OFX files from different banks as they can thru libofx, and report the result. -* This is my first attempt at writing an API. I need comments from financial software writers about inc/libofx.h What do YOU need? +my own bank (Desjardins). But I need people to run as many OFX files from different banks as they can thru LibOFX, and report the result. +* This is my first attempt at writing an API. I need comments from financial software writers about `inc/libofx.h` What do YOU need? Benoit Grégoire\ benoitg@coeus.ca diff -Nru libofx-0.10.5/vcpkg.json libofx-0.10.9/vcpkg.json --- libofx-0.10.5/vcpkg.json 1970-01-01 00:00:00.000000000 +0000 +++ libofx-0.10.9/vcpkg.json 2022-10-03 20:22:59.000000000 +0000 @@ -0,0 +1,45 @@ +{ + "name": "libofx", + "version": "0.10.9", + "description": "OFX banking protocol abstraction library", + "homepage": "http://libofx.sourceforge.net", + "dependencies": [ + "libopensp" + ], + "features": { + "iconv": { + "description": "Builds with ICONV support for encoding conversion", + "dependencies": [ + "libiconv" + ] + }, + "ofx2qif": { + "description": "Enables OFX file to QIF (Quicken Interchange Format) file converter" + }, + "ofxconnect": { + "description": "Enables ofxconnect utility which allows to test OFX Direct Connect", + "dependencies": [ + { + "name": "curl", + "features": [ + "ssl" + ] + }, + { + "name": "getopt", + "platform": "windows & !mingw" + }, + "libxmlpp" + ] + }, + "ofxdump": { + "description": "Enables ofxdump utility which prints, in human readable form, everything the library understands about a file", + "dependencies": [ + { + "name": "getopt", + "platform": "windows & !mingw" + } + ] + } + } +}