diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3c5796c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +root = true +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +insert_final_newline = true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d4b1eef --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,98 @@ +name: ci +on: + push: + branches: [ main, master ] + tags: [ "v*" ] + pull_request: + +jobs: + build: + strategy: + fail-fast: false + matrix: + os: [ ubuntu-24.04, windows-latest ] + config: [ Debug, RelWithDebInfo ] + runs-on: ${{ matrix.os }} + env: + VCPKG_DOWNLOADS_DIR: ${{ github.workspace }}\.vcpkg_downloads + VCPKG_DOWNLOADS: ${{ github.workspace }}\.vcpkg_downloads + VCPKG_FTPMIRROR_URL: https://ftpmirror.gnu.org/gnu/{path} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + # ---------- Linux deps ---------- + - name: Install deps (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y \ + ninja-build pkg-config xvfb \ + libgtk-3-dev libglib2.0-dev \ + libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \ + libcurl4-openssl-dev libayatana-appindicator3-dev \ + libgcrypt20-dev + + # ---------- Windows build tooling ---------- + - name: Setup Ninja (Windows) + if: runner.os == 'Windows' + uses: seanmiddleditch/gha-setup-ninja@v4 + + - name: Setup MSVC dev environment (x64) + if: runner.os == 'Windows' + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x64 + + # ---------- Windows deps via vcpkg ---------- + - name: Setup vcpkg (Windows) + if: runner.os == 'Windows' + uses: lukka/run-vcpkg@v11 + with: + vcpkgJsonGlob: 'vcpkg.json' + + + # ---------- Configure ---------- + - name: Configure (Linux Debug) + if: runner.os == 'Linux' && matrix.config == 'Debug' + run: cmake --preset dev -DENABLE_MEGA=OFF + - name: Configure (Linux RelWithDebInfo) + if: runner.os == 'Linux' && matrix.config == 'RelWithDebInfo' + run: cmake --preset rel -DENABLE_MEGA=OFF + - name: Configure (Windows) + if: runner.os == 'Windows' + run: cmake --preset msvc-vcpkg -DCMAKE_BUILD_TYPE=${{ matrix.config }} -DWITH_GUI=OFF -DWITH_TRAY=OFF -DENABLE_MEGA=OFF + + # ---------- Build ---------- + - name: Build (Linux Debug) + if: runner.os == 'Linux' && matrix.config == 'Debug' + run: cmake --build build/dev -- -v + - name: Build (Linux RelWithDebInfo) + if: runner.os == 'Linux' && matrix.config == 'RelWithDebInfo' + run: cmake --build build/rel -- -v + - name: Build (Windows) + if: runner.os == 'Windows' + run: cmake --build --preset msvc-vcpkg --config ${{ matrix.config }} -- -v + + # ---------- Test ---------- + - name: Test (Linux) + if: runner.os == 'Linux' + run: | + if command -v xvfb-run >/dev/null 2>&1; then + xvfb-run -a ctest --test-dir ${{ matrix.config == 'Debug' && 'build/dev' || 'build/rel' }} --output-on-failure -LE net + else + ctest --test-dir ${{ matrix.config == 'Debug' && 'build/dev' || 'build/rel' }} --output-on-failure -LE net + fi + - name: Test (Windows) + if: runner.os == 'Windows' + run: ctest --test-dir build/msvc -C ${{ matrix.config }} --output-on-failure -LE net + + # ---------- Artifacts ---------- + - name: Upload build dir + if: always() + uses: actions/upload-artifact@v4 + with: + name: ${{ runner.os }}-${{ matrix.config }} + path: build/** + if-no-files-found: warn diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4f7bccc --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +build/ +.cache/ +.vscode/ +.idea/ +*.user +*.sln +*.vcxproj +*.vcxproj.filters +*.vcxproj.user +logs/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..918c773 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,617 @@ +cmake_minimum_required(VERSION 3.24) +project(uget VERSION 2.3.0 LANGUAGES C) + +set(CMAKE_VERBOSE_MAKEFILE ON CACHE BOOL "Verbose build" FORCE) + +set(CMAKE_C_STANDARD 17) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS OFF) + +option(UGET_WITH_GUI "Build the GTK front-end" ON) +if(DEFINED WITH_GUI) + set(UGET_WITH_GUI ${WITH_GUI}) +endif() +set_property(CACHE UGET_WITH_GUI PROPERTY VALUE ${UGET_WITH_GUI}) +set(WITH_GUI ${UGET_WITH_GUI}) +option(WITH_TRAY "Build system tray integration (requires GUI)" ON) +option(WITH_OPENSSL "Enable OpenSSL-based crypto/TLS" ON) +option(WITH_GNUTLS "Enable GnuTLS/libgcrypt backend" OFF) +option(WITH_PWMD "Enable libpwmd integration" ON) +option(ENABLE_MEGA "Enable MEGA plugin" ON) +option(ENABLE_SANITIZERS "Enable ASan/UBSan in Debug on non-MSVC builds" OFF) + +if(MSVC) + add_compile_options(/W4 /permissive- /utf-8) +else() + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +if(ENABLE_SANITIZERS AND NOT MSVC) + set(_uget_sanitize_flags -fsanitize=address,undefined) + if(CMAKE_CONFIGURATION_TYPES) + add_compile_options($<$:${_uget_sanitize_flags}>) + add_compile_options($<$:-fno-omit-frame-pointer>) + add_link_options($<$:${_uget_sanitize_flags}>) + if(UNIX AND NOT APPLE) + add_link_options($<$:-Wl,--no-as-needed>) + endif() + else() + string(TOUPPER "${CMAKE_BUILD_TYPE}" _uget_build_type_upper) + if(_uget_build_type_upper STREQUAL "DEBUG") + add_compile_options(${_uget_sanitize_flags} -fno-omit-frame-pointer) + add_link_options(${_uget_sanitize_flags}) + if(UNIX AND NOT APPLE) + add_link_options(-Wl,--no-as-needed) + endif() + endif() + endif() +endif() + +include(GNUInstallDirs) + +set(UG_DATADIR "${CMAKE_INSTALL_FULL_DATADIR}/uget" CACHE STRING + "Path used for UG_DATADIR (where shared data files live)") +include(CheckIncludeFile) +include(CheckSymbolExists) + +# ---- Robust pkg-config discovery (works with vcpkg, MSYS2, Linux) ---- +# Prefer 'pkgconf' on Windows (vcpkg installs it), 'pkg-config' elsewhere. +find_program(PKG_CONFIG_EXECUTABLE NAMES pkgconf pkg-config) +if(PKG_CONFIG_EXECUTABLE) + message(STATUS "Using pkg-config at: ${PKG_CONFIG_EXECUTABLE}") + # Some FindPkgConfig variants also read the env var: + set(ENV{PKG_CONFIG} "${PKG_CONFIG_EXECUTABLE}") +else() + message(STATUS "pkg-config not found on PATH yet; FindPkgConfig may fail unless the toolchain provides it.") +endif() + +find_package(PkgConfig REQUIRED) + +# Feature test macros on non-MSVC to expose POSIX prototypes (getaddrinfo, ftruncate, popen, etc.) +if(NOT MSVC) + add_compile_definitions(_GNU_SOURCE) +endif() + +set(HEADER_NAMES + "sys/types.h" + "sys/select.h" + "sys/socket.h" + "netdb.h" + "arpa/inet.h" + "netinet/in.h" + "sys/time.h" + "unistd.h" + "fcntl.h" + "poll.h" + "sys/stat.h" + "inttypes.h" + "stdint.h" +) +set(HEADER_MACROS + HAVE_SYS_TYPES_H + HAVE_SYS_SELECT_H + HAVE_SYS_SOCKET_H + HAVE_NETDB_H + HAVE_ARPA_INET_H + HAVE_NETINET_IN_H + HAVE_SYS_TIME_H + HAVE_UNISTD_H + HAVE_FCNTL_H + HAVE_POLL_H + HAVE_SYS_STAT_H + HAVE_INTTYPES_H + HAVE_STDINT_H +) + +list(LENGTH HEADER_NAMES _header_count) +if(_header_count GREATER 0) + math(EXPR _header_last "${_header_count} - 1") + foreach(_idx RANGE 0 ${_header_last}) + list(GET HEADER_NAMES ${_idx} _hdr) + list(GET HEADER_MACROS ${_idx} _macro) + check_include_file("${_hdr}" ${_macro}) + endforeach() +endif() + +check_symbol_exists(fileno "stdio.h" HAVE_FILENO) +check_symbol_exists(ftruncate "unistd.h" HAVE_FTRUNCATE) +check_symbol_exists(popen "stdio.h" HAVE_POPEN) +check_symbol_exists(pclose "stdio.h" HAVE_PCLOSE) + +# pkg-config deps +if(NOT UGET_WITH_GUI AND WITH_TRAY) + message(STATUS "UGET_WITH_GUI=OFF -> disabling system tray support") + set(WITH_TRAY OFF CACHE BOOL "" FORCE) +endif() + +set(HAVE_GTK 0) +set(HAVE_GSTREAMER 0) +set(HAVE_GLIB 0) +set(HAVE_CURL 0) + +set(_uget_common_include_dirs) +set(_uget_common_library_dirs) +set(_uget_common_libraries) +set(_uget_common_compile_options) + +pkg_check_modules(GLIB2 QUIET glib-2.0>=2.76 gobject-2.0) +if(NOT GLIB2_FOUND) + find_package(GLIB CONFIG QUIET) + if(GLIB_FOUND) + set(GLIB2_FOUND TRUE) + if(DEFINED GLIB_INCLUDE_DIRS) + set(GLIB2_INCLUDE_DIRS ${GLIB_INCLUDE_DIRS}) + endif() + if(DEFINED GLIB_LIBRARY_DIRS) + set(GLIB2_LIBRARY_DIRS ${GLIB_LIBRARY_DIRS}) + endif() + if(DEFINED GLIB_LIBRARIES) + set(GLIB2_LIBRARIES ${GLIB_LIBRARIES}) + endif() + if(DEFINED GLIB_CFLAGS_OTHER) + set(GLIB2_CFLAGS_OTHER ${GLIB_CFLAGS_OTHER}) + endif() + endif() +endif() + +if(NOT GLIB2_FOUND) + message(FATAL_ERROR "Required GLib not found. Install via vcpkg (manifest) or system packages.") +endif() + +if(NOT DEFINED GLIB2_INCLUDE_DIRS) + set(GLIB2_INCLUDE_DIRS "") +endif() +if(NOT DEFINED GLIB2_LIBRARY_DIRS) + set(GLIB2_LIBRARY_DIRS "") +endif() +if(NOT DEFINED GLIB2_LIBRARIES) + set(GLIB2_LIBRARIES "") +endif() +if(NOT DEFINED GLIB2_CFLAGS_OTHER) + set(GLIB2_CFLAGS_OTHER "") +endif() + +set(GLIB_INCLUDE_DIRS ${GLIB2_INCLUDE_DIRS}) +set(GLIB_LIBRARY_DIRS ${GLIB2_LIBRARY_DIRS}) +set(GLIB_LIBRARIES ${GLIB2_LIBRARIES}) +set(GLIB_CFLAGS_OTHER ${GLIB2_CFLAGS_OTHER}) + +add_compile_definitions(HAVE_GLIB=1) +set(HAVE_GLIB 1) + +list(APPEND _uget_common_include_dirs ${GLIB2_INCLUDE_DIRS}) +list(APPEND _uget_common_library_dirs ${GLIB2_LIBRARY_DIRS}) +list(APPEND _uget_common_libraries ${GLIB2_LIBRARIES}) +list(APPEND _uget_common_compile_options ${GLIB2_CFLAGS_OTHER}) + +pkg_check_modules(GTK3 QUIET gtk+-3.0>=3.24) +pkg_check_modules(GST QUIET gstreamer-1.0 gstreamer-base-1.0) +pkg_check_modules(AYATANA QUIET ayatana-appindicator3-0.1) +pkg_check_modules(APPINDICATOR QUIET appindicator3-0.1) + +if(GTK3_FOUND) + set(HAVE_GTK 1) +endif() +if(GST_FOUND) + set(HAVE_GSTREAMER 1) +endif() + +if(WIN32) + find_package(CURL REQUIRED) + if(TARGET CURL::libcurl) + set(LIBCURL_LIBRARIES CURL::libcurl) + endif() + set(HAVE_CURL 1) +else() + if(PkgConfig_FOUND) + pkg_check_modules(LIBCURL REQUIRED libcurl) + set(HAVE_CURL 1) + else() + message(FATAL_ERROR "libcurl detection on this platform requires pkg-config.") + endif() +endif() + +if(WIN32) + set(UGET_CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIRS}) + set(UGET_CURL_LIBRARY_DIRS "") + set(UGET_CURL_LIBRARIES ${CURL_LIBRARIES}) + set(UGET_CURL_CFLAGS_OTHER "") +else() + set(UGET_CURL_INCLUDE_DIRS ${LIBCURL_INCLUDE_DIRS}) + set(UGET_CURL_LIBRARY_DIRS ${LIBCURL_LIBRARY_DIRS}) + set(UGET_CURL_LIBRARIES ${LIBCURL_LIBRARIES}) + set(UGET_CURL_CFLAGS_OTHER ${LIBCURL_CFLAGS_OTHER}) +endif() + +if(NOT DEFINED CURL_LIBRARIES OR CURL_LIBRARIES STREQUAL "") + set(CURL_LIBRARIES ${UGET_CURL_LIBRARIES}) +endif() +if(NOT DEFINED CURL_INCLUDE_DIRS OR CURL_INCLUDE_DIRS STREQUAL "") + set(CURL_INCLUDE_DIRS ${UGET_CURL_INCLUDE_DIRS}) +endif() + +list(APPEND _uget_common_include_dirs ${UGET_CURL_INCLUDE_DIRS}) +list(APPEND _uget_common_library_dirs ${UGET_CURL_LIBRARY_DIRS}) +list(APPEND _uget_common_libraries ${UGET_CURL_LIBRARIES}) +list(APPEND _uget_common_compile_options ${UGET_CURL_CFLAGS_OTHER}) + +find_package(Threads REQUIRED) + +include(CTest) +if(NOT BUILD_TESTING) + message(STATUS "BUILD_TESTING=OFF: test targets will not be generated") +endif() + +set(HAVE_TRAY 0) +set(HAVE_AYATANA 0) +set(HAVE_APPINDICATOR 0) +set(HAVE_PWMD 0) +set(HAVE_GNUTLS 0) +set(HAVE_OPENSSL 0) +set(HAVE_LIBGCRYPT 0) + +# ---------- TRAY (Ayatana/AppIndicator) ---------- +if(UGET_WITH_GUI AND WITH_TRAY) + if(AYATANA_FOUND) + add_compile_definitions(HAVE_AYATANA=1) + set(HAVE_TRAY 1) + set(HAVE_AYATANA 1) + message(STATUS "Tray: using ayatana-appindicator3") + elseif(APPINDICATOR_FOUND) + add_compile_definitions(HAVE_APPINDICATOR=1) + set(HAVE_TRAY 1) + set(HAVE_APPINDICATOR 1) + message(STATUS "Tray: using appindicator3-0.1 (fallback)") + else() + message(STATUS "Tray requested, but no Ayatana/AppIndicator found -> tray disabled") + set(WITH_TRAY OFF CACHE BOOL "" FORCE) + endif() +elseif(WITH_TRAY) + message(STATUS "WITH_TRAY requested but UGET_WITH_GUI=OFF -> disabling tray support") + set(WITH_TRAY OFF CACHE BOOL "" FORCE) +endif() + +# ---------- PWMD ---------- +if(WITH_PWMD) + if(PkgConfig_FOUND) + pkg_check_modules(PWMD QUIET libpwmd) + if(PWMD_FOUND) + list(APPEND _uget_common_include_dirs ${PWMD_INCLUDE_DIRS}) + list(APPEND _uget_common_library_dirs ${PWMD_LIBRARY_DIRS}) + list(APPEND _uget_common_libraries ${PWMD_LIBRARIES}) + set(HAVE_PWMD 1) + message(STATUS "PWMD: enabled") + else() + message(STATUS "PWMD: not found; disabling") + endif() + else() + message(FATAL_ERROR "WITH_PWMD=ON requires pkg-config.") + endif() +endif() + +# ---------- Crypto/TLS backends ---------- +if(WITH_OPENSSL) + find_package(OpenSSL REQUIRED) + add_compile_definitions(HAVE_OPENSSL=1) + list(APPEND _uget_common_libraries OpenSSL::SSL OpenSSL::Crypto) + set(HAVE_OPENSSL 1) +endif() + +pkg_check_modules(GNUTLS QUIET gnutls) + +set(GCRYPT_FOUND FALSE) +set(_uget_gcrypt_module "") +foreach(_gcrypt_candidate libgcrypt gcrypt) + if(NOT GCRYPT_FOUND) + pkg_check_modules(GCRYPT QUIET ${_gcrypt_candidate}) + if(GCRYPT_FOUND) + set(_uget_gcrypt_module "${_gcrypt_candidate}") + endif() + endif() +endforeach() + +set(HAVE_GNUTLS ${GNUTLS_FOUND}) +set(HAVE_LIBGCRYPT ${GCRYPT_FOUND}) + +if(OPENSSL_FOUND) + set(HAVE_OPENSSL 1) +endif() + +if(WITH_GNUTLS) + if(NOT GNUTLS_FOUND) + message(FATAL_ERROR "WITH_GNUTLS=ON but gnutls was not found") + endif() + if(NOT GCRYPT_FOUND) + message(FATAL_ERROR "WITH_GNUTLS=ON but libgcrypt was not found") + endif() + add_compile_definitions(HAVE_GNUTLS=1 HAVE_LIBGCRYPT=1) + set(HAVE_GNUTLS 1) + set(HAVE_LIBGCRYPT 1) +else() + # Treat GnuTLS as unavailable if the feature is explicitly disabled + set(HAVE_GNUTLS 0) +endif() + +if(HAVE_LIBGCRYPT) + add_compile_definitions(HAVE_LIBGCRYPT=1) + if(_uget_gcrypt_module) + message(STATUS "libgcrypt: enabled via pkg-config module '${_uget_gcrypt_module}'") + endif() +endif() + +# ---- Libraries and executables ---- +set(UGLIB_SOURCES + uglib/UgArray.c + uglib/UgBuffer.c + uglib/UgData.c + uglib/UgEntry.c + uglib/UgFileUtil.c + uglib/UgHtml.c + uglib/UgHtmlEntry.c + uglib/UgHtmlFilter.c + uglib/UgInfo.c + uglib/UgJson-custom.c + uglib/UgJson.c + uglib/UgJsonFile.c + uglib/UgJsonrpc.c + uglib/UgJsonrpcCurl.c + uglib/UgJsonrpcSocket.c + uglib/UgList.c + uglib/UgNode.c + uglib/UgOption.c + uglib/UgRegistry.c + uglib/UgSocket.c + uglib/UgSLink.c + uglib/UgStdio.c + uglib/UgString.c + uglib/UgThread.c + uglib/UgUri.c + uglib/UgUtil.c + uglib/UgValue.c +) + +add_library(uglib STATIC ${UGLIB_SOURCES}) +target_include_directories(uglib + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/uglib + ${CMAKE_BINARY_DIR}/generated) +target_compile_definitions(uglib PUBLIC HAVE_CONFIG_H) +target_link_libraries(uglib PUBLIC Threads::Threads) + +set(uget_core_sources + uget/UgetA2cf.c + uget/UgetApp.c + uget/UgetAria2.c + uget/UgetCurl.c + uget/UgetData.c + uget/UgetEvent.c + uget/UgetFiles.c + uget/UgetHash.c + uget/UgetMedia-youtube.c + uget/UgetMedia.c + uget/UgetNode-compare.c + uget/UgetNode-filter.c + uget/UgetNode.c + uget/UgetOption.c + uget/UgetPlugin.c + uget/UgetPluginAgent.c + uget/UgetPluginAria2.c + uget/UgetPluginCurl.c + uget/UgetPluginEmpty.c + uget/UgetPluginMedia.c + uget/UgetRpc.c + uget/UgetRss.c + uget/UgetSequence.c + uget/UgetSite.c + uget/UgetTask.c +) + +if(HAVE_PWMD) + list(APPEND uget_core_sources uget/pwmd.c) +endif() + +add_library(uget_core STATIC ${uget_core_sources}) +target_include_directories(uget_core + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/uget + ${CMAKE_CURRENT_SOURCE_DIR}/uglib + ${CMAKE_BINARY_DIR}/generated) +target_compile_definitions(uget_core PUBLIC HAVE_CONFIG_H) +target_link_libraries(uget_core PUBLIC uglib Threads::Threads) + +if(HAVE_GNUTLS) + target_include_directories(uget_core PRIVATE ${GNUTLS_INCLUDE_DIRS}) + target_link_libraries(uget_core PUBLIC ${GNUTLS_LIBRARIES}) + target_compile_definitions(uget_core PRIVATE HAVE_GNUTLS=1) +endif() + +if(HAVE_LIBGCRYPT) + target_include_directories(uget_core PRIVATE ${GCRYPT_INCLUDE_DIRS}) + target_link_libraries(uget_core PUBLIC ${GCRYPT_LIBRARIES}) + target_compile_definitions(uget_core PRIVATE HAVE_LIBGCRYPT=1) +endif() + +set(_uget_mega_module "") +if(ENABLE_MEGA) + set(_uget_mega_candidates mega megasdk) + unset(MEGA_FOUND) + unset(MEGA_LIBRARIES) + unset(MEGA_LIBRARY_DIRS) + unset(MEGA_INCLUDE_DIRS) + unset(MEGA_CFLAGS_OTHER) + foreach(_mega_candidate ${_uget_mega_candidates}) + if(NOT MEGA_FOUND) + pkg_check_modules(MEGA QUIET ${_mega_candidate}) + if(MEGA_FOUND) + set(_uget_mega_module "${_mega_candidate}") + endif() + endif() + endforeach() + if(NOT MEGA_FOUND) + list(JOIN _uget_mega_candidates ", " _uget_mega_list) + message(FATAL_ERROR "ENABLE_MEGA=ON but no Mega SDK pkg-config module was found (tried: ${_uget_mega_list})") + endif() + target_sources(uget_core PRIVATE uget/UgetPluginMega.c) + target_include_directories(uget_core PRIVATE ${MEGA_INCLUDE_DIRS}) + if(MEGA_LIBRARY_DIRS) + target_link_directories(uget_core PRIVATE ${MEGA_LIBRARY_DIRS}) + endif() + target_link_libraries(uget_core PRIVATE ${MEGA_LIBRARIES}) + if(MEGA_CFLAGS_OTHER) + target_compile_options(uget_core PRIVATE ${MEGA_CFLAGS_OTHER}) + endif() + target_compile_definitions(uget_core PUBLIC HAVE_MEGA=1) + message(STATUS "Mega: enabled via pkg-config module '${_uget_mega_module}'") +else() + message(STATUS "Mega: disabled (ENABLE_MEGA=OFF)") +endif() + +# --- CLI entrypoint discovery +set(UGET_CLI_CANDIDATES + ${CMAKE_SOURCE_DIR}/uget/cli/uget.c + ${CMAKE_SOURCE_DIR}/uget/uget.c + ${CMAKE_SOURCE_DIR}/uget/main.c + ${CMAKE_SOURCE_DIR}/src/uget.c +) + +set(UGET_CLI_MAIN "") +foreach(_c ${UGET_CLI_CANDIDATES}) + if(EXISTS "${_c}") + set(UGET_CLI_MAIN "${_c}") + break() + endif() +endforeach() + +option(UGET_CLI_STUB "Generate a minimal CLI main() if no real CLI is found" OFF) + +if(UGET_CLI_MAIN) + message(STATUS "uget CLI: using ${UGET_CLI_MAIN}") + add_executable(uget ${UGET_CLI_MAIN}) +elseif(UGET_CLI_STUB) + message(WARNING "uget CLI: real entrypoint not found; generating stub (prints version and exits 0)") + file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/generated) + file(WRITE ${CMAKE_BINARY_DIR}/generated/uget_stub.c +"#include \n" +"int main(int argc, char** argv){\n" +" (void)argc; (void)argv;\n" +" printf(\"uget (stub) built with CMake %s\\n\", \"${CMAKE_VERSION}\");\n" +" return 0;\n" +"}\n") + add_executable(uget ${CMAKE_BINARY_DIR}/generated/uget_stub.c) +else() + message(STATUS "uget CLI: no entrypoint found; skipping CLI build") +endif() + +if(TARGET uget) + target_link_libraries(uget PRIVATE uget_core uglib Threads::Threads ${CURL_LIBRARIES}) + target_include_directories(uget PRIVATE + ${CMAKE_SOURCE_DIR}/uget + ${CMAKE_SOURCE_DIR}/uglib + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_BINARY_DIR}/generated + ${CURL_INCLUDE_DIRS} + ) + target_sources(uget PRIVATE ${CMAKE_SOURCE_DIR}/src/core.c) + target_compile_definitions(uget PRIVATE + $ + ) + install(TARGETS uget RUNTIME DESTINATION bin) +endif() + +if(UGET_WITH_GUI AND GTK3_FOUND) + file(GLOB UGET_GTK_SOURCES CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/ui-gtk/*.c") + if(UGET_GTK_SOURCES) + add_executable(uget-gtk ${UGET_GTK_SOURCES}) + if(WIN32) + set_target_properties(uget-gtk PROPERTIES OUTPUT_NAME "uget") + endif() + target_include_directories(uget-gtk PRIVATE + ${CMAKE_SOURCE_DIR}/uget + ${CMAKE_SOURCE_DIR}/uglib + ${CMAKE_SOURCE_DIR}/ui-gtk + ${GLIB_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS} ${GST_INCLUDE_DIRS} ${AYATANA_INCLUDE_DIRS} + ${CMAKE_BINARY_DIR}/generated) + target_compile_options(uget-gtk PRIVATE + ${GLIB_CFLAGS_OTHER} ${GTK3_CFLAGS_OTHER} ${GST_CFLAGS_OTHER} ${AYATANA_CFLAGS_OTHER}) + target_compile_definitions(uget-gtk PRIVATE HAVE_CONFIG_H UG_DATADIR="${UG_DATADIR}") + target_link_libraries(uget-gtk PRIVATE + uget_core + uglib + Threads::Threads + ${GLIB_LIBRARIES} + ${GTK3_LIBRARIES} + ${GST_LIBRARIES} + ${AYATANA_LIBRARIES}) + if(UNIX AND NOT APPLE) + target_link_libraries(uget-gtk PRIVATE m dl) + target_link_options(uget-gtk PRIVATE -Wl,--as-needed) + endif() + install(TARGETS uget-gtk RUNTIME DESTINATION bin) + message(STATUS "GUI: enabled (gtk+-3.0)") + else() + message(WARNING "UGET_WITH_GUI=ON but no GTK sources were found in ui-gtk/") + message(STATUS "GUI: disabled (gtk+-3.0 not found or UGET_WITH_GUI=OFF)") + endif() +else() + message(STATUS "GUI: disabled (gtk+-3.0 not found or UGET_WITH_GUI=OFF)") +endif() + +set(_uget_targets uglib uget_core) +if(TARGET uget) + list(APPEND _uget_targets uget) +endif() +if(TARGET uget-gtk) + list(APPEND _uget_targets uget-gtk) +endif() + +foreach(_target IN LISTS _uget_targets) + if(TARGET ${_target}) + if(_uget_common_compile_options) + target_compile_options(${_target} PRIVATE ${_uget_common_compile_options}) + endif() + if(_uget_common_include_dirs) + target_include_directories(${_target} PRIVATE ${_uget_common_include_dirs}) + endif() + if(_uget_common_library_dirs) + target_link_directories(${_target} PRIVATE ${_uget_common_library_dirs}) + endif() + endif() +endforeach() + +if(_uget_common_libraries) + if(TARGET uglib) + target_link_libraries(uglib PUBLIC ${_uget_common_libraries}) + endif() + if(TARGET uget_core) + target_link_libraries(uget_core PUBLIC ${_uget_common_libraries}) + endif() +endif() + + +# --- Project-wide compile warnings (already set globally, but ensure targets inherit) --- +foreach(_target IN LISTS _uget_targets) + if(TARGET ${_target}) + if(MSVC) + target_compile_options(${_target} PRIVATE /W4 /permissive- /utf-8) + else() + target_compile_options(${_target} PRIVATE -Wall -Wextra -Wpedantic) + endif() + endif() +endforeach() + +configure_file(${CMAKE_SOURCE_DIR}/cmake/config.h.in + ${CMAKE_BINARY_DIR}/generated/config.h @ONLY) +include_directories(${CMAKE_BINARY_DIR}/generated) + + +if(BUILD_TESTING) + if(UGET_WITH_GUI) + add_subdirectory(tests) + else() + message(STATUS "BUILD_TESTING=ON but UGET_WITH_GUI=OFF -> skipping GLib/GTK tests on this platform") + endif() +endif() + +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/data") + install(DIRECTORY data/ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/uget) +endif() diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..4a3221e --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,28 @@ +{ + "version": 6, + "cmakeMinimumRequired": { "major": 3, "minor": 28 }, + "configurePresets": [ + { "name": "dev", "generator": "Ninja", "binaryDir": "build/dev", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } }, + { "name": "asan", "inherits": "dev", "binaryDir": "build/asan", + "cacheVariables": { "ENABLE_SANITIZERS": true, "CMAKE_BUILD_TYPE": "Debug" } }, + { "name": "rel", "generator": "Ninja", "binaryDir": "build/rel", "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo" } +}, + { "name": "msvc-vcpkg", "generator": "Ninja", "binaryDir": "build/msvc", "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", + "VCPKG_TARGET_TRIPLET": "x64-windows" + } } + ], + "buildPresets": [ + { "name": "dev", "configurePreset": "dev" }, + { "name": "asan", "configurePreset": "asan" }, + { "name": "rel", "configurePreset": "rel" }, + { "name": "msvc-vcpkg", "configurePreset": "msvc-vcpkg" } + ], + "testPresets": [ + { "name": "dev", "configurePreset": "dev" }, + { "name": "asan", "configurePreset": "asan" }, + { "name": "rel", "configurePreset": "rel" }, + { "name": "msvc-vcpkg", "configurePreset": "msvc-vcpkg" } + ] +} diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 0003b59..0000000 --- a/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -# intltool : add "po" in SUBDIRS - -SUBDIRS = \ - uglib \ - uget \ - ui-gtk \ - ui-gtk-1to2 \ - pixmaps \ - sounds \ - tests \ - po \ - doc \ - Windows - -EXTRA_DIST = \ - uget-gtk.desktop \ - .snapcraft.yaml - -appsdir = $(datadir)/applications -apps_DATA = uget-gtk.desktop diff --git a/Windows/Makefile.am b/Windows/Makefile.am deleted file mode 100644 index b8c2588..0000000 --- a/Windows/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -EXTRA_DIST = \ - resources/uget.rc \ - resources/uget-icon.ico \ - msvc/msvc-config.txt \ - msvc/stdint.h \ - msvc/test-json.vcxproj \ - msvc/test-jsonrpc.vcxproj \ - msvc/test-plugin+app.vcxproj \ - msvc/test-uget.vcxproj \ - msvc/test-uglib.vcxproj \ - msvc/uget.sln \ - msvc/uget.vcxproj \ - msvc/uglib.vcxproj \ - msvc/ui-gtk.vcxproj \ - CodeBlocks/mingw-config.txt \ - CodeBlocks/test-json.cbp \ - CodeBlocks/test-jsonrpc.cbp \ - CodeBlocks/test-plugin+app.cbp \ - CodeBlocks/test-uget.cbp \ - CodeBlocks/test-uget-cxx.cbp \ - CodeBlocks/test-uglib.cbp \ - CodeBlocks/test-uglib-cxx.cbp \ - CodeBlocks/uget.cbp \ - CodeBlocks/uglib.cbp \ - CodeBlocks/ui-gtk.cbp \ - CodeBlocks/ui-gtk-1to2.cbp \ - CodeBlocks/uget.workspace - diff --git a/Windows/msvc/test-json.vcxproj b/Windows/msvc/test-json.vcxproj deleted file mode 100644 index 49a1374..0000000 --- a/Windows/msvc/test-json.vcxproj +++ /dev/null @@ -1,103 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {D0C49F36-9ECC-4B87-9360-A7EE570DA73C} - testjson - Win32Proj - - - - Application - Unicode - true - - - Application - Unicode - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\$(ProjectName)\ - true - $(SolutionDir)$(Configuration)\ - $(Configuration)\$(ProjectName)\ - false - - - - Disabled - ..\..\uglib;D:\devpack\gtk3-msvc\lib\glib-2.0\include;D:\devpack\gtk3-msvc\include\glib-2.0;%(AdditionalIncludeDirectories) - WIN32;HAVE_GLIB;inline=__inline;_DEBUG;_CONSOLE;HAVE_GLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - EditAndContinue - - - uglib.lib;glib-2.0.lib;%(AdditionalDependencies) - D:\devpack\gtk3-msvc\lib;Debug;%(AdditionalLibraryDirectories) - true - Console - MachineX86 - - - - - MaxSpeed - true - ..\..\uglib;D:\devpack\gtk3-msvc\lib\glib-2.0\include;D:\devpack\gtk3-msvc\include\glib-2.0;%(AdditionalIncludeDirectories) - WIN32;HAVE_GLIB;inline=__inline;NDEBUG;_CONSOLE;HAVE_GLIB;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - uglib.lib;glib-2.0.lib;%(AdditionalDependencies) - D:\devpack\gtk3-msvc\lib;Release;%(AdditionalLibraryDirectories) - true - Console - true - true - MachineX86 - - - - - - - - {8e8a46b4-6b62-4bd0-bcaf-ba9cf1090dea} - false - - - - - - \ No newline at end of file diff --git a/Windows/msvc/test-jsonrpc.vcxproj b/Windows/msvc/test-jsonrpc.vcxproj deleted file mode 100644 index 8756f52..0000000 --- a/Windows/msvc/test-jsonrpc.vcxproj +++ /dev/null @@ -1,89 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {BE2BF360-69F6-406F-A89D-77B0F9A92C04} - Win32Proj - testjsonrpc - - - - Application - true - Unicode - - - Application - false - Unicode - - - - - - - - - - - - - true - - - false - - - - ..\..\uglib;..\..\uget;D:\devpack\curl-msvc\include;D:\devpack\gtk3-msvc\lib\glib-2.0\include;D:\devpack\gtk3-msvc\include\glib-2.0;%(AdditionalIncludeDirectories) - Level3 - Disabled - WIN32;HAVE_GLIB;inline=__inline;_DEBUG;%(PreprocessorDefinitions) - - - - - uglib.lib;glib-2.0.lib;%(AdditionalDependencies) - D:\devpack\gtk3-msvc\lib;D:\devpack\curl-msvc\lib\Debug;Debug;%(AdditionalLibraryDirectories) - true - uglib.lib;uget.lib;Ws2_32.lib;curllib.lib;glib-2.0.lib;intl.lib;%(AdditionalDependencies) - Console - - - - - ..\..\uglib;..\..\uget;D:\devpack\curl-msvc\include;D:\devpack\gtk3-msvc\lib\glib-2.0\include;D:\devpack\gtk3-msvc\include\glib-2.0;%(AdditionalIncludeDirectories) - Level3 - WIN32;HAVE_GLIB;inline=__inline;NDEBUG;%(PreprocessorDefinitions) - - - - - uglib.lib;glib-2.0.lib;%(AdditionalDependencies) - D:\devpack\gtk3-msvc\lib;D:\devpack\curl-msvc\lib\Release;Release;%(AdditionalLibraryDirectories) - true - uglib.lib;uget.lib;Ws2_32.lib;curllib.lib;glib-2.0.lib;intl.lib;%(AdditionalDependencies) - Console - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Windows/msvc/test-plugin+app.vcxproj b/Windows/msvc/test-plugin+app.vcxproj deleted file mode 100644 index 4b5ce0b..0000000 --- a/Windows/msvc/test-plugin+app.vcxproj +++ /dev/null @@ -1,103 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {CAD0E048-8211-4F6B-9975-215A526AC645} - testjson - Win32Proj - - - - Application - Unicode - true - - - Application - Unicode - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\$(ProjectName)\ - true - $(SolutionDir)$(Configuration)\ - $(Configuration)\$(ProjectName)\ - false - - - - Disabled - ..\..\uglib;..\..\uget;D:\devpack\curl-msvc\include;D:\devpack\gtk3-msvc\lib\glib-2.0\include;D:\devpack\gtk3-msvc\include\glib-2.0;%(AdditionalIncludeDirectories) - WIN32;HAVE_GLIB;inline=__inline;_DEBUG;_CONSOLE;HAVE_GLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - EditAndContinue - - - uglib.lib;uget.lib;Ws2_32.lib;curllib.lib;glib-2.0.lib;intl.lib;%(AdditionalDependencies) - D:\devpack\curl-msvc\lib\Debug;D:\devpack\gtk3-msvc\lib;Debug;%(AdditionalLibraryDirectories) - true - Console - MachineX86 - - - - - MaxSpeed - true - ..\..\uglib;..\..\uget;D:\devpack\curl-msvc\include;D:\devpack\gtk3-msvc\lib\glib-2.0\include;D:\devpack\gtk3-msvc\include\glib-2.0;%(AdditionalIncludeDirectories) - WIN32;HAVE_GLIB;inline=__inline;NDEBUG;_CONSOLE;HAVE_GLIB;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - uglib.lib;uget.lib;Ws2_32.lib;curllib.lib;glib-2.0.lib;intl.lib;%(AdditionalDependencies) - D:\devpack\curl-msvc\lib\Release;D:\devpack\gtk3-msvc\lib;Release;%(AdditionalLibraryDirectories) - true - Console - true - true - MachineX86 - - - - - {8e8a46b4-6b62-4bd0-bcaf-ba9cf1090dea} - false - - - - - - - - - \ No newline at end of file diff --git a/Windows/msvc/test-uget.vcxproj b/Windows/msvc/test-uget.vcxproj deleted file mode 100644 index a46ab9d..0000000 --- a/Windows/msvc/test-uget.vcxproj +++ /dev/null @@ -1,103 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {FFAC27EA-E43A-4A78-924D-41E868A4F27F} - testuget - Win32Proj - - - - Application - Unicode - true - - - Application - Unicode - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\$(ProjectName)\ - true - $(SolutionDir)$(Configuration)\ - $(Configuration)\$(ProjectName)\ - false - - - - Disabled - ..\..\uglib;..\..\uget;D:\devpack\curl-msvc\include;D:\devpack\gtk3-msvc\lib\glib-2.0\include;D:\devpack\gtk3-msvc\include\glib-2.0;%(AdditionalIncludeDirectories) - WIN32;HAVE_GLIB;inline=__inline;_DEBUG;_CONSOLE;HAVE_GLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - EditAndContinue - - - uglib.lib;uget.lib;Ws2_32.lib;curllib.lib;glib-2.0.lib;intl.lib;%(AdditionalDependencies) - D:\devpack\curl-msvc\lib\Debug;D:\devpack\gtk3-msvc\lib;Debug;%(AdditionalLibraryDirectories) - true - Console - MachineX86 - - - - - MaxSpeed - true - ..\..\uglib;..\..\uget;D:\devpack\curl-msvc\include;D:\devpack\gtk3-msvc\lib\glib-2.0\include;D:\devpack\gtk3-msvc\include\glib-2.0;%(AdditionalIncludeDirectories) - WIN32;HAVE_GLIB;inline=__inline;NDEBUG;_CONSOLE;HAVE_GLIB;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - uglib.lib;uget.lib;Ws2_32.lib;curllib.lib;glib-2.0.lib;intl.lib;%(AdditionalDependencies) - D:\devpack\curl-msvc\lib\Release;D:\devpack\gtk3-msvc\lib;Release;%(AdditionalLibraryDirectories) - true - Console - true - true - MachineX86 - - - - - - - - {8e8a46b4-6b62-4bd0-bcaf-ba9cf1090dea} - false - - - - - - \ No newline at end of file diff --git a/Windows/msvc/test-uglib.vcxproj b/Windows/msvc/test-uglib.vcxproj deleted file mode 100644 index 5091680..0000000 --- a/Windows/msvc/test-uglib.vcxproj +++ /dev/null @@ -1,103 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {A5591A27-B27A-4FF2-88E6-E6C534C96E02} - testuglib - Win32Proj - - - - Application - Unicode - true - - - Application - Unicode - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\$(ProjectName)\ - true - $(SolutionDir)$(Configuration)\ - $(Configuration)\$(ProjectName)\ - false - - - - Disabled - ..\..\uglib;D:\devpack\gtk3-msvc\lib\glib-2.0\include;D:\devpack\gtk3-msvc\include\glib-2.0;%(AdditionalIncludeDirectories) - WIN32;HAVE_GLIB;inline=__inline;_DEBUG;_CONSOLE;HAVE_GLIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - EditAndContinue - - - uglib.lib;glib-2.0.lib;%(AdditionalDependencies) - D:\devpack\gtk3-msvc\lib;Debug;%(AdditionalLibraryDirectories) - true - Console - MachineX86 - - - - - MaxSpeed - true - ..\..\uglib;D:\devpack\gtk3-msvc\lib\glib-2.0\include;D:\devpack\gtk3-msvc\include\glib-2.0;%(AdditionalIncludeDirectories) - WIN32;HAVE_GLIB;inline=__inline;NDEBUG;_CONSOLE;HAVE_GLIB;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - uglib.lib;glib-2.0.lib;%(AdditionalDependencies) - D:\devpack\gtk3-msvc\lib;Release;%(AdditionalLibraryDirectories) - true - Console - true - true - MachineX86 - - - - - - - - {8e8a46b4-6b62-4bd0-bcaf-ba9cf1090dea} - false - - - - - - \ No newline at end of file diff --git a/Windows/msvc/uget.sln b/Windows/msvc/uget.sln deleted file mode 100644 index 0c1d6a1..0000000 --- a/Windows/msvc/uget.sln +++ /dev/null @@ -1,79 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uglib", "uglib.vcxproj", "{8E8A46B4-6B62-4BD0-BCAF-BA9CF1090DEA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-json", "test-json.vcxproj", "{D0C49F36-9ECC-4B87-9360-A7EE570DA73C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uget", "uget.vcxproj", "{A98D36E8-7119-4AC4-8820-65B902C6B69E}" - ProjectSection(ProjectDependencies) = postProject - {8E8A46B4-6B62-4BD0-BCAF-BA9CF1090DEA} = {8E8A46B4-6B62-4BD0-BCAF-BA9CF1090DEA} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-plugin+app", "test-plugin+app.vcxproj", "{CAD0E048-8211-4F6B-9975-215A526AC645}" - ProjectSection(ProjectDependencies) = postProject - {A98D36E8-7119-4AC4-8820-65B902C6B69E} = {A98D36E8-7119-4AC4-8820-65B902C6B69E} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ui-gtk", "ui-gtk.vcxproj", "{9D164547-3F37-4C14-BCCE-91EB2F3DC317}" - ProjectSection(ProjectDependencies) = postProject - {8E8A46B4-6B62-4BD0-BCAF-BA9CF1090DEA} = {8E8A46B4-6B62-4BD0-BCAF-BA9CF1090DEA} - {A98D36E8-7119-4AC4-8820-65B902C6B69E} = {A98D36E8-7119-4AC4-8820-65B902C6B69E} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-jsonrpc", "test-jsonrpc.vcxproj", "{BE2BF360-69F6-406F-A89D-77B0F9A92C04}" - ProjectSection(ProjectDependencies) = postProject - {8E8A46B4-6B62-4BD0-BCAF-BA9CF1090DEA} = {8E8A46B4-6B62-4BD0-BCAF-BA9CF1090DEA} - {A98D36E8-7119-4AC4-8820-65B902C6B69E} = {A98D36E8-7119-4AC4-8820-65B902C6B69E} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-uglib", "test-uglib.vcxproj", "{A5591A27-B27A-4FF2-88E6-E6C534C96E02}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test-uget", "test-uget.vcxproj", "{FFAC27EA-E43A-4A78-924D-41E868A4F27F}" - ProjectSection(ProjectDependencies) = postProject - {A98D36E8-7119-4AC4-8820-65B902C6B69E} = {A98D36E8-7119-4AC4-8820-65B902C6B69E} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8E8A46B4-6B62-4BD0-BCAF-BA9CF1090DEA}.Debug|Win32.ActiveCfg = Debug|Win32 - {8E8A46B4-6B62-4BD0-BCAF-BA9CF1090DEA}.Debug|Win32.Build.0 = Debug|Win32 - {8E8A46B4-6B62-4BD0-BCAF-BA9CF1090DEA}.Release|Win32.ActiveCfg = Release|Win32 - {8E8A46B4-6B62-4BD0-BCAF-BA9CF1090DEA}.Release|Win32.Build.0 = Release|Win32 - {D0C49F36-9ECC-4B87-9360-A7EE570DA73C}.Debug|Win32.ActiveCfg = Debug|Win32 - {D0C49F36-9ECC-4B87-9360-A7EE570DA73C}.Debug|Win32.Build.0 = Debug|Win32 - {D0C49F36-9ECC-4B87-9360-A7EE570DA73C}.Release|Win32.ActiveCfg = Release|Win32 - {D0C49F36-9ECC-4B87-9360-A7EE570DA73C}.Release|Win32.Build.0 = Release|Win32 - {A98D36E8-7119-4AC4-8820-65B902C6B69E}.Debug|Win32.ActiveCfg = Debug|Win32 - {A98D36E8-7119-4AC4-8820-65B902C6B69E}.Debug|Win32.Build.0 = Debug|Win32 - {A98D36E8-7119-4AC4-8820-65B902C6B69E}.Release|Win32.ActiveCfg = Release|Win32 - {A98D36E8-7119-4AC4-8820-65B902C6B69E}.Release|Win32.Build.0 = Release|Win32 - {CAD0E048-8211-4F6B-9975-215A526AC645}.Debug|Win32.ActiveCfg = Debug|Win32 - {CAD0E048-8211-4F6B-9975-215A526AC645}.Debug|Win32.Build.0 = Debug|Win32 - {CAD0E048-8211-4F6B-9975-215A526AC645}.Release|Win32.ActiveCfg = Release|Win32 - {CAD0E048-8211-4F6B-9975-215A526AC645}.Release|Win32.Build.0 = Release|Win32 - {9D164547-3F37-4C14-BCCE-91EB2F3DC317}.Debug|Win32.ActiveCfg = Debug|Win32 - {9D164547-3F37-4C14-BCCE-91EB2F3DC317}.Debug|Win32.Build.0 = Debug|Win32 - {9D164547-3F37-4C14-BCCE-91EB2F3DC317}.Release|Win32.ActiveCfg = Release|Win32 - {9D164547-3F37-4C14-BCCE-91EB2F3DC317}.Release|Win32.Build.0 = Release|Win32 - {BE2BF360-69F6-406F-A89D-77B0F9A92C04}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE2BF360-69F6-406F-A89D-77B0F9A92C04}.Debug|Win32.Build.0 = Debug|Win32 - {BE2BF360-69F6-406F-A89D-77B0F9A92C04}.Release|Win32.ActiveCfg = Release|Win32 - {BE2BF360-69F6-406F-A89D-77B0F9A92C04}.Release|Win32.Build.0 = Release|Win32 - {A5591A27-B27A-4FF2-88E6-E6C534C96E02}.Debug|Win32.ActiveCfg = Debug|Win32 - {A5591A27-B27A-4FF2-88E6-E6C534C96E02}.Debug|Win32.Build.0 = Debug|Win32 - {A5591A27-B27A-4FF2-88E6-E6C534C96E02}.Release|Win32.ActiveCfg = Release|Win32 - {A5591A27-B27A-4FF2-88E6-E6C534C96E02}.Release|Win32.Build.0 = Release|Win32 - {FFAC27EA-E43A-4A78-924D-41E868A4F27F}.Debug|Win32.ActiveCfg = Debug|Win32 - {FFAC27EA-E43A-4A78-924D-41E868A4F27F}.Debug|Win32.Build.0 = Debug|Win32 - {FFAC27EA-E43A-4A78-924D-41E868A4F27F}.Release|Win32.ActiveCfg = Release|Win32 - {FFAC27EA-E43A-4A78-924D-41E868A4F27F}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Windows/msvc/uget.vcxproj b/Windows/msvc/uget.vcxproj deleted file mode 100644 index 7e11fa4..0000000 --- a/Windows/msvc/uget.vcxproj +++ /dev/null @@ -1,124 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {A98D36E8-7119-4AC4-8820-65B902C6B69E} - uget - Win32Proj - - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\$(ProjectName)\ - $(SolutionDir)$(Configuration)\ - $(Configuration)\$(ProjectName)\ - - - - Disabled - ..\..\uglib;..\..\uget;D:\devpack\curl-msvc\include;D:\devpack\gtk3-msvc\lib\glib-2.0\include;D:\devpack\gtk3-msvc\include\glib-2.0;D:\devpack\gtk3-msvc\include;%(AdditionalIncludeDirectories) - WIN32;HAVE_GLIB;inline=__inline;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - EditAndContinue - - - - - ..\..\uglib;..\..\uget;D:\devpack\curl-msvc\include;D:\devpack\gtk3-msvc\lib\glib-2.0\include;D:\devpack\gtk3-msvc\include\glib-2.0;D:\devpack\gtk3-msvc\include;%(AdditionalIncludeDirectories) - WIN32;HAVE_GLIB;inline=__inline;NDEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDLL - - - Level3 - ProgramDatabase - - - - - - \ No newline at end of file diff --git a/Windows/msvc/uglib.vcxproj b/Windows/msvc/uglib.vcxproj deleted file mode 100644 index d0a2467..0000000 --- a/Windows/msvc/uglib.vcxproj +++ /dev/null @@ -1,132 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {8E8A46B4-6B62-4BD0-BCAF-BA9CF1090DEA} - uglib - Win32Proj - - - - StaticLibrary - Unicode - true - - - StaticLibrary - Unicode - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(Configuration)\ - $(Configuration)\$(ProjectName)\ - $(SolutionDir)$(Configuration)\ - $(Configuration)\$(ProjectName)\ - - - - Disabled - ..\..\uglib;D:\devpack\curl-msvc\include;D:\devpack\gtk3-msvc\include\glib-2.0;D:\devpack\gtk3-msvc\lib\glib-2.0\include;%(AdditionalIncludeDirectories) - WIN32;HAVE_GLIB;inline=__inline;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - EditAndContinue - - - - - ..\..\uglib;D:\devpack\curl-msvc\include;D:\devpack\gtk3-msvc\include\glib-2.0;D:\devpack\gtk3-msvc\lib\glib-2.0\include;%(AdditionalIncludeDirectories) - WIN32;HAVE_GLIB;inline=__inline;NDEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDLL - - - Level3 - ProgramDatabase - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Windows/msvc/ui-gtk.vcxproj b/Windows/msvc/ui-gtk.vcxproj deleted file mode 100644 index 551e658..0000000 --- a/Windows/msvc/ui-gtk.vcxproj +++ /dev/null @@ -1,155 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - ui-gtk - {9D164547-3F37-4C14-BCCE-91EB2F3DC317} - ugetgtk - Win32Proj - - - - Application - Unicode - true - - - Application - Unicode - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - $(SolutionDir)$(Configuration)\$(ProjectName)\ - $(Configuration)\$(ProjectName)\ - true - $(SolutionDir)$(Configuration)\$(ProjectName)\ - $(Configuration)\$(ProjectName)\ - false - - - - Disabled - ..\..\uglib;..\..\uget;..\..\ui-gtk;D:\devpack\curl-msvc\include;D:\devpack\gtk3-msvc\include;D:\devpack\gtk3-msvc\lib\glib-2.0\include;D:\devpack\gtk3-msvc\include\glib-2.0;D:\devpack\gtk3-msvc\lib\gtk-3.0\include;D:\devpack\gtk3-msvc\include\gtk-3.0;D:\devpack\gtk3-msvc\include\gdk-pixbuf-2.0;D:\devpack\gtk3-msvc\include\pango-1.0;D:\devpack\gtk3-msvc\include\atk-1.0;D:\devpack\gtk3-msvc\include\cairo;%(AdditionalIncludeDirectories) - WIN32;HAVE_GLIB;inline=__inline;_DEBUG;_CONSOLE;DATADIR_WIN_PROG;HAVE_PLUGIN_ARIA2;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - EditAndContinue - - - glib-2.0.lib;gthread-2.0.lib;gmodule-2.0.lib;gobject-2.0.lib;gio-2.0.lib;gtk-win32-3.0.lib;gdk-win32-3.0.lib;gdk_pixbuf-2.0.lib;pango-1.0.lib;pangocairo-1.0.lib;pangowin32-1.0.lib;atk-1.0.lib;intl.lib;cairo.lib;libcurl.lib;Ws2_32.lib;winmm.lib;uget.lib;uglib.lib;%(AdditionalDependencies) - D:\devpack\gtk3-msvc\lib;D:\devpack\curl-msvc;Debug;%(AdditionalLibraryDirectories) - true - Console - MachineX86 - - - - - MaxSpeed - true - ..\..\uglib;..\..\uget;..\..\ui-gtk;D:\devpack\curl-msvc\include;D:\devpack\gtk3-msvc\include;D:\devpack\gtk3-msvc\lib\glib-2.0\include;D:\devpack\gtk3-msvc\include\glib-2.0;D:\devpack\gtk3-msvc\lib\gtk-3.0\include;D:\devpack\gtk3-msvc\include\gtk-3.0;D:\devpack\gtk3-msvc\include\gdk-pixbuf-2.0;D:\devpack\gtk3-msvc\include\pango-1.0;D:\devpack\gtk3-msvc\include\atk-1.0;D:\devpack\gtk3-msvc\include\cairo;%(AdditionalIncludeDirectories) - WIN32;HAVE_GLIB;inline=__inline;NDEBUG;_WINDOWS;DATADIR_WIN_PROG;HAVE_PLUGIN_ARIA2;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glib-2.0.lib;gthread-2.0.lib;gmodule-2.0.lib;gobject-2.0.lib;gio-2.0.lib;gtk-win32-3.0.lib;gdk-win32-3.0.lib;gdk_pixbuf-2.0.lib;pango-1.0.lib;pangocairo-1.0.lib;pangowin32-1.0.lib;atk-1.0.lib;cairo.lib;intl.lib;libcurl.lib;Ws2_32.lib;winmm.lib;uget.lib;uglib.lib;%(AdditionalDependencies) - D:\devpack\gtk3-msvc\lib;D:\devpack\curl-msvc\;Release;%(AdditionalLibraryDirectories) - true - Windows - true - true - MachineX86 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/autogen.sh b/autogen.sh deleted file mode 100644 index c3e671d..0000000 --- a/autogen.sh +++ /dev/null @@ -1,36 +0,0 @@ -if [ ! -f AUTHORS ]; then - touch AUTHORS -fi - -if [ ! -f NEWS ]; then - touch NEWS -fi - -if [ ! -f README ]; then - touch README -fi - -if [ ! -f ChangeLog ]; then - touch ChangeLog -fi - -# autoscan - -## Generate `aclocal.m4' by scanning `configure.ac' or `configure.in' -aclocal - -## --- AC_CONFIG_HEADERS -autoheader - -## --- AC_PROG_INTLTOOL -intltoolize - -## --- AC_PROG_LIBTOOL -# libtoolize --copy - -## --- AM_INIT_AUTOMAKE -automake --add-missing - -autoconf - - diff --git a/cmake/config.h.in b/cmake/config.h.in new file mode 100644 index 0000000..f2d3d19 --- /dev/null +++ b/cmake/config.h.in @@ -0,0 +1,37 @@ +#pragma once +/* Generated by CMake */ + +#cmakedefine01 HAVE_GTK +#cmakedefine01 HAVE_GSTREAMER +#cmakedefine01 HAVE_GLIB +#cmakedefine01 HAVE_CURL + +/* Feature toggles generated by CMake */ +#cmakedefine01 HAVE_TRAY +#cmakedefine01 HAVE_AYATANA +#cmakedefine01 HAVE_APPINDICATOR +#cmakedefine01 HAVE_PWMD +#cmakedefine01 HAVE_GNUTLS +#cmakedefine01 HAVE_OPENSSL +#cmakedefine01 HAVE_LIBGCRYPT + +/* Autoconf-like header availability */ +#cmakedefine01 HAVE_SYS_TYPES_H +#cmakedefine01 HAVE_SYS_SELECT_H +#cmakedefine01 HAVE_SYS_SOCKET_H +#cmakedefine01 HAVE_NETDB_H +#cmakedefine01 HAVE_ARPA_INET_H +#cmakedefine01 HAVE_NETINET_IN_H +#cmakedefine01 HAVE_SYS_TIME_H +#cmakedefine01 HAVE_UNISTD_H +#cmakedefine01 HAVE_FCNTL_H +#cmakedefine01 HAVE_POLL_H +#cmakedefine01 HAVE_SYS_STAT_H +#cmakedefine01 HAVE_INTTYPES_H +#cmakedefine01 HAVE_STDINT_H + +/* Common functions */ +#cmakedefine01 HAVE_FILENO +#cmakedefine01 HAVE_FTRUNCATE +#cmakedefine01 HAVE_POPEN +#cmakedefine01 HAVE_PCLOSE diff --git a/configure.ac b/configure.ac deleted file mode 100644 index 2f7bc5e..0000000 --- a/configure.ac +++ /dev/null @@ -1,265 +0,0 @@ -AC_INIT(uget, 2.2.3) - -## Use automake (add automake to autogen.sh) -AM_INIT_AUTOMAKE - -## --- Use config.h (autogen.sh add autoheader) -AC_CONFIG_HEADERS([config.h]) - -## --- Determine a C compiler to use. -AC_PROG_CC - -## --- Check C compiler -c -o options. -AM_PROG_CC_C_O - -## --- Determine a C++ compiler to use. -# AC_PROG_CXX - -## --- Check for the ar command to use -AM_PROG_AR - -## Use library (static library) -AC_PROG_RANLIB - -## --- Check function posix_fallocate() -AC_CHECK_FUNCS([posix_fallocate]) - -## --- Check function ftruncate() -AC_CHECK_FUNCS([ftruncate]) - -## ---------------------------------------------- -## L10N (add intltoolize to autogen.sh) -AC_PROG_INTLTOOL -## replace ALL_LINGUAS with po/LINGUAS -# ALL_LINGUAS="" -GETTEXT_PACKAGE="$PACKAGE" -AC_SUBST(GETTEXT_PACKAGE) -AM_GLIB_GNU_GETTEXT -AM_GLIB_DEFINE_LOCALEDIR(LOCALEDIR) -## Use AM_GLIB_DEFINE_LOCALEDIR with AC_CONFIG_HEADERS - -## ---------------------------------------------- -## GTK+ -PKG_CHECK_MODULES(GTK, gtk+-3.0 >= 3.4) - -## ---------------- -## glib (add HAVE_GLIB definition to config.h) -PKG_CHECK_EXISTS([glib-2.0], - [have_glib="yes"], - [have_glib="no"]) -if test x$have_glib = xyes ; then - PKG_CHECK_MODULES(GLIB, glib-2.0) - AC_SUBST(GLIB_CFLAGS) - AC_SUBST(GLIB_LIBS) - AC_DEFINE(HAVE_GLIB, 1, [Define to 1 if glib support is required.]) -fi - -## ---------------- -## pthread -AC_CHECK_LIB(pthread, pthread_create,, - [AC_MSG_ERROR([required library pthread missing])]) -PTHREAD_CFLAGS="-pthread" -PTHREAD_LIBS="-pthread" -AC_SUBST(PTHREAD_CFLAGS) -AC_SUBST(PTHREAD_LIBS) - -## ---------------- -## LFS -AC_PATH_PROG(GETCONF, getconf) -if test "x$GETCONF" != "x" ; then - LFS_CFLAGS=`$GETCONF LFS_CFLAGS` - LFS_LDFLAGS=`$GETCONF LFS_LDFLAGS` -fi -AC_SUBST(LFS_CFLAGS) -AC_SUBST(LFS_LDFLAGS) - -## ---------------- -## cURL -AC_PATH_PROG(CURL_CONFIG, curl-config) -if test "x$CURL_CONFIG" = "x" ; then - AC_MSG_ERROR(Unable to find curl-config, please install libcurl) -fi -CURL_CFLAGS=`$CURL_CONFIG --cflags` -CURL_LIBS=`$CURL_CONFIG --libs` -let CURL_VERNUM=0x0`$CURL_CONFIG --vernum` -let CURL_VERMIN=0x071301 # 7.19.1 -if test $CURL_VERNUM -lt $CURL_VERMIN; then - AC_MSG_ERROR(Requires libcurl version >= 7.19.1) -fi -AC_SUBST(CURL_CFLAGS) -AC_SUBST(CURL_LIBS) - -## ---------------- -## GnuTLS -AC_ARG_WITH( - [gnutls], - AC_HELP_STRING([--with-gnutls[=@<:@no/auto/yes@:>@]], [Enable GnuTLS support. (default is auto)]), - [with_gnutls="$withval"], - [with_gnutls="no"] -) -if test "x$with_gnutls" != "xno"; then -# AC_CHECK_HEADER(gcrypt.h, [USE_GNUTLS_GCRYPT=1], [USE_GNUTLS_GCRYPT=0]) -# if test "$USE_GNUTLS_GCRYPT" = "1"; then -# LIBGCRYPT_CFLAGS="" -# AC_SUBST(LIBGCRYPT_CFLAGS) -# fi -# AC_CHECK_HEADER(gcrypt/gcrypt.h, [USE_GNUTLS_GCRYPT=1], [USE_GNUTLS_GCRYPT=0]) -# if test "$USE_GNUTLS_GCRYPT" = "1"; then -# LIBGCRYPT_CFLAGS="" -# AC_SUBST(LIBGCRYPT_CFLAGS, [""]) -# fi -# AC_CHECK_LIB(gcrypt, gcry_control, [USE_GNUTLS_GCRYPT=1], [USE_GNUTLS_GCRYPT=0]) -# if test "$USE_GNUTLS_GCRYPT" = "1"; then -# LIBGCRYPT_LIBS="-lgcrypt" -# AC_SUBST(LIBGCRYPT_LIBS, ["-lgcrypt"]) -# fi - AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config) - if test "x$LIBGCRYPT_CONFIG" = "x" ; then - if test "x$with_gnutls" = "xyes"; then - AC_MSG_ERROR(Unable to find libgcrypt-config, please install libgcrypt) - fi - else - LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags` - LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs` - AC_SUBST(LIBGCRYPT_CFLAGS) - AC_SUBST(LIBGCRYPT_LIBS) - AC_DEFINE(USE_GNUTLS, 1, [Define to 1 if gnutls support is required.]) - fi -fi - -## ---------------- -## OpenSSL -AC_ARG_WITH( - [openssl], - AC_HELP_STRING([--with-openssl[=@<:@no/yes@:>@]], [Enable OpenSSL support.]), - [with_openssl="$withval"], - [with_openssl="yes"] -) -if test "x$LIBGCRYPT_CONFIG" = "x" ; then - if test "x$with_openssl" = "xyes"; then - PKG_CHECK_MODULES(LIBCRYPTO, libcrypto) - AC_SUBST(LIBCRYPTO_CFLAGS) - AC_SUBST(LIBCRYPTO_LIBS) - AC_DEFINE(USE_OPENSSL, 1, [Define to 1 if openssl support is required.]) - fi -fi - -## ---------------- -## libnotify -AC_ARG_ENABLE( - [notify], - AC_HELP_STRING([--disable-notify], [Disable libnotify support.]), - [enable_notify="$enableval"], - [enable_notify="yes"] -) -if test "x$enable_notify" = "xyes"; then - PKG_CHECK_MODULES(LIBNOTIFY, libnotify) - AC_DEFINE(HAVE_LIBNOTIFY, 1, [Define to 1 if libnotify support is required.]) - # for ArchLinux - AC_SUBST(LIBNOTIFY_CFLAGS) - AC_SUBST(LIBNOTIFY_LIBS) -fi - -## ---------------- -## appindicator -AC_ARG_ENABLE( - [appindicator], - AS_HELP_STRING([--enable-appindicator[=@<:@no/auto/yes@:>@]],[Build support for application indicators.]), - [enable_appindicator=$enableval], - [enable_appindicator="auto"] -) -if test x$enable_appindicator = xauto ; then - PKG_CHECK_EXISTS([appindicator3-0.1], - [enable_appindicator="yes"], - [enable_appindicator="no"]) -fi -if test x$enable_appindicator = xyes ; then - PKG_CHECK_MODULES(APP_INDICATOR, appindicator3-0.1) - AC_SUBST(APP_INDICATOR_CFLAGS) - AC_SUBST(APP_INDICATOR_LIBS) - AC_DEFINE(HAVE_APP_INDICATOR, 1, [Have AppIndicator]) -fi - -## ---------------- -## gstreamer -AC_ARG_ENABLE( - [gstreamer], - AC_HELP_STRING([--disable-gstreamer], [Disable GStreamer audio support.]), - [enable_gstreamer="$enableval"], - [enable_gstreamer="yes"] -) -if test "x$enable_gstreamer" = "xyes"; then - PKG_CHECK_EXISTS([gstreamer-1.0], - [enable_gstreamer1="yes"], - [enable_gstreamer1="no"]) -fi -if test "x$enable_gstreamer1" = "xyes"; then - PKG_CHECK_MODULES(GSTREAMER, gstreamer-1.0) - AC_DEFINE(HAVE_GSTREAMER, 1, [Define to 1 if gstreamer support is required.]) - # for ArchLinux - AC_SUBST(GSTREAMER_CFLAGS) - AC_SUBST(GSTREAMER_LIBS) -elif test "x$enable_gstreamer" = "xyes"; then - PKG_CHECK_MODULES(GSTREAMER, gstreamer-0.10) - AC_DEFINE(HAVE_GSTREAMER, 1, [Define to 1 if gstreamer support is required.]) - # for ArchLinux - AC_SUBST(GSTREAMER_CFLAGS) - AC_SUBST(GSTREAMER_LIBS) -fi - -## ----------------- -## libpwmd -AC_ARG_ENABLE( - [pwmd], - AC_HELP_STRING([--enable-pwmd], [Enable pwmd support.]), - [enable_pwmd="$enableval"], - [enable_pwmd="no"] -) -if test "x$enable_pwmd" = "xyes"; then - PKG_CHECK_MODULES(LIBPWMD, [libpwmd-8.0 >= 8.3.0]) - AC_DEFINE(HAVE_LIBPWMD, 1, [Define to 1 if libpwmd support is required.]) -fi -AM_CONDITIONAL([WITH_LIBPWMD], [test "x$enable_pwmd" = "xyes"]) - -## ----------------- -## RSS Notify -AC_ARG_ENABLE( - [rss-notify], - AC_HELP_STRING([--disable-rss-notify], [Disable RSS Notify.]), - [enable_rss_notify="$enableval"], - [enable_rss_notify="yes"] -) -if test "x$enable_rss_notify" = "xyes"; then - AC_DEFINE(HAVE_RSS_NOTIFY, 1, [Define to 1 to enable RSS Notify.]) -fi - -## ----------------- -## UNIX Domain Socket -AC_ARG_ENABLE( - [unix-socket], - AC_HELP_STRING([--enable-unix-socket], [Enable UNIX Domain Socket.]), - [enable_unix_socket="$enableval"], - [enable_unix_socket="no"] -) -if test "x$enable_unix_socket" = "xyes"; then - AC_DEFINE(USE_UNIX_DOMAIN_SOCKET, 1, [Define to 1 to use UNIX Domain Socket.]) -fi - -## ---------------------------------------------- -## output -AC_CONFIG_FILES([ - Makefile - doc/Makefile - tests/Makefile - uget/Makefile - uglib/Makefile - ui-gtk/Makefile - ui-gtk-1to2/Makefile - pixmaps/Makefile - sounds/Makefile - po/Makefile.in - Windows/Makefile -]) - -AC_OUTPUT - diff --git a/doc/Makefile.am b/doc/Makefile.am deleted file mode 100644 index 1c3a899..0000000 --- a/doc/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ -EXTRA_DIST = \ - uget.txt \ - folders.txt \ - JSON-RPC_interface.txt \ - To_build_uGet_in_MinGW.txt - diff --git a/doc/To_build_uGet_in_MinGW.txt b/doc/To_build_uGet_in_MinGW.txt deleted file mode 100644 index a628847..0000000 --- a/doc/To_build_uGet_in_MinGW.txt +++ /dev/null @@ -1,20 +0,0 @@ -To build uGet in MinGW environment - -# ------------ Install packages -------------- -# toolchain -pacman -S mingw-w64-i686-binutils mingw-w64-i686-gcc mingw-w64-i686-gdb - -# make and Autotools -pacman -S make pkgconfig autoconf automake libtool intltool - -# gtk familiy -pacman -S mingw-w64-i686-gtk3 - -# curl -pacman -S mingw-w64-i686-curl - -# ------------ Build uGet -------------- -. autogen.sh -./configure --disable-notify --disable-gstreamer _WINDOWS=1 NDEBUG=1 -make - diff --git a/docs/BUILDING.md b/docs/BUILDING.md new file mode 100644 index 0000000..5e4735b --- /dev/null +++ b/docs/BUILDING.md @@ -0,0 +1,57 @@ +# Building uGet with CMake + +uGet now uses a single CMake-based build across platforms. You will need **CMake +3.24 or newer** plus a C and C++ toolchain that can compile GTK-based +applications. + +## Linux and other Unix-like platforms + +```sh +cmake --preset dev +cmake --build build/dev +ctest --test-dir build/dev --output-on-failure +``` + +Install the GTK 3, GLib, GStreamer and libcurl development packages from your +distribution. The configure step will fail if these packages are missing while +`WITH_GUI` is enabled (the default). For headless or minimal builds you can pass +`-DWITH_GUI=OFF` to skip those requirements. + +Other useful presets: + +- `cmake --preset asan` – Debug build with AddressSanitizer and + UndefinedBehaviorSanitizer enabled (requires clang or gcc with sanitizer + support). +- `cmake --preset rel` – RelWithDebInfo configuration suitable for + release/packaging validation. + +The presets drive dependency discovery via `pkg-config`. Optional components +(such as Ayatana/AppIndicator tray icons, OpenSSL, libpwmd and GnuTLS) are +picked up automatically when their development packages are available. If a +library is missing the feature falls back gracefully or is disabled without +failing the configuration. You can also toggle features explicitly with +`-DWITH_TRAY=OFF`, `-DWITH_OPENSSL=OFF`, `-DWITH_PWMD=OFF`, or +`-DWITH_GNUTLS=ON` when running `cmake`. + +## Windows (MSVC + vcpkg) + +Install Visual Studio 2022 with the "Desktop development with C++" workload and +set up [vcpkg](https://github.com/microsoft/vcpkg). With `VCPKG_ROOT` pointing +at your vcpkg checkout, run the Windows preset: + +```powershell +cmake --preset msvc-vcpkg +cmake --build build\msvc --config Debug +ctest --test-dir build\msvc -C Debug --output-on-failure +``` + +The vcpkg manifest (vcpkg.json) pulls in gtk3, glib, gstreamer, curl and +openssl. Tray integration will automatically use Ayatana/AppIndicator when those +libraries are available in vcpkg; otherwise the build continues without tray +support. Additional options described above work on Windows as well. + +For release-like builds use the RelWithDebInfo configuration: + +```powershell +cmake --build build\msvc --config RelWithDebInfo +``` diff --git a/docs/BUILD_WINDOWS.md b/docs/BUILD_WINDOWS.md new file mode 100644 index 0000000..1121f1e --- /dev/null +++ b/docs/BUILD_WINDOWS.md @@ -0,0 +1,29 @@ +# Building on Windows (MSVC + vcpkg, x64) + +> Requires CMake 3.24 or newer. + +## Prereqs +- Visual Studio 2022 (Desktop development with C++) +- vcpkg (https://github.com/microsoft/vcpkg) and set `VCPKG_ROOT` + +## One-time setup +```powershell +# In an x64 Native Tools for VS 2022 shell: +git clone https://github.com/microsoft/vcpkg %USERPROFILE%\vcpkg +setx VCPKG_ROOT %USERPROFILE%\vcpkg +``` + +## Configure, build, test +```powershell +cmake --preset msvc-vcpkg +cmake --build build\msvc --config Debug +ctest --test-dir build\msvc -C Debug --output-on-failure +``` + +## Notes +- Dependencies come from vcpkg.json (gtk3, glib, gstreamer, curl, openssl). +- Tray support (Ayatana/AppIndicator) may be unavailable on Windows: the build will continue without it. +- Optional components such as OpenSSL, libpwmd or GnuTLS follow the same + autodetection as on Linux; toggle them manually by passing + `-DWITH_OPENSSL=OFF`, `-DWITH_PWMD=OFF`, or `-DWITH_GNUTLS=ON` to `cmake`. +- Use RelWithDebInfo for release-like builds: `cmake -S . -B build\msvc -DCMAKE_BUILD_TYPE=RelWithDebInfo --preset msvc-vcpkg` diff --git a/docs/DEVELOPER.md b/docs/DEVELOPER.md new file mode 100644 index 0000000..8b79dfa --- /dev/null +++ b/docs/DEVELOPER.md @@ -0,0 +1,16 @@ +# Build Presets + +Use CMake presets to configure common build types: + +- `cmake --preset dev` for a standard Debug build. +- `cmake --preset asan` for a Debug build with AddressSanitizer/UndefinedBehaviorSanitizer enabled (Unix-like platforms). +- `cmake --preset rel` for a RelWithDebInfo build. +- `cmake --preset msvc-vcpkg` for the Visual Studio + vcpkg toolchain on Windows. + +When debugging sanitizer builds you can enable stricter behavior with: + +```sh +export ASAN_OPTIONS=halt_on_error=1 +``` + +Set the variable before running the instrumented binary to stop immediately on the first sanitizer report. diff --git a/include/core.h b/include/core.h new file mode 100644 index 0000000..cd1f3ec --- /dev/null +++ b/include/core.h @@ -0,0 +1,3 @@ +#pragma once + +int core_dummy(void); diff --git a/pixmaps/Makefile.am b/pixmaps/Makefile.am deleted file mode 100644 index 0074c7c..0000000 --- a/pixmaps/Makefile.am +++ /dev/null @@ -1,48 +0,0 @@ -# icons installing path: -# $(datadir)/icons/hicolor/16x16/apps/uget-icon.png -# $(datadir)/icons/hicolor/22x22/apps/uget-icon.png -# $(datadir)/icons/hicolor/24x24/apps/uget-icon.png -# $(datadir)/icons/hicolor/32x32/apps/uget-icon.png -# $(datadir)/icons/hicolor/48x48/apps/uget-icon.png -# $(datadir)/icons/hicolor/64x64/apps/uget-icon.png -# $(datadir)/icons/hicolor/96x96/apps/uget-icon.png -# $(datadir)/icons/hicolor/128x128/apps/uget-icon.png -# $(datadir)/icons/hicolor/scalable/apps/uget-icon.svg -# -iconsdir = $(datadir) -nobase_dist_icons_DATA = \ - icons/hicolor/16x16/apps/uget-icon.png \ - icons/hicolor/22x22/apps/uget-icon.png \ - icons/hicolor/24x24/apps/uget-icon.png \ - icons/hicolor/32x32/apps/uget-icon.png \ - icons/hicolor/48x48/apps/uget-icon.png \ - icons/hicolor/64x64/apps/uget-icon.png \ - icons/hicolor/96x96/apps/uget-icon.png \ - icons/hicolor/128x128/apps/uget-icon.png \ - icons/hicolor/scalable/apps/uget-icon.svg \ - icons/hicolor/16x16/apps/uget-tray-default.png \ - icons/hicolor/22x22/apps/uget-tray-default.png \ - icons/hicolor/24x24/apps/uget-tray-default.png \ - icons/hicolor/32x32/apps/uget-tray-default.png \ - icons/hicolor/48x48/apps/uget-tray-default.png \ - icons/hicolor/16x16/apps/uget-tray-downloading.png \ - icons/hicolor/22x22/apps/uget-tray-downloading.png \ - icons/hicolor/24x24/apps/uget-tray-downloading.png \ - icons/hicolor/32x32/apps/uget-tray-downloading.png \ - icons/hicolor/48x48/apps/uget-tray-downloading.png \ - icons/hicolor/16x16/apps/uget-tray-error.png \ - icons/hicolor/22x22/apps/uget-tray-error.png \ - icons/hicolor/24x24/apps/uget-tray-error.png \ - icons/hicolor/32x32/apps/uget-tray-error.png \ - icons/hicolor/48x48/apps/uget-tray-error.png - - -# pixmaps -# -ugetpixmapdir = $(datadir)/pixmaps/uget -dist_ugetpixmap_DATA = logo.png - -# icons/hicolor/index.theme is needed by gtk_icon_theme_append_search_path() -# -EXTRA_DIST = icons/hicolor/index.theme - diff --git a/sounds/Makefile.am b/sounds/Makefile.am deleted file mode 100644 index 657412b..0000000 --- a/sounds/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ -soundsdir = $(datadir)/sounds/uget - -sounds_DATA = notification.wav - -EXTRA_DIST = $(sounds_DATA) - diff --git a/src/core.c b/src/core.c new file mode 100644 index 0000000..5dbba08 --- /dev/null +++ b/src/core.c @@ -0,0 +1,7 @@ +#include "config.h" +#include "core.h" + +int core_dummy(void) +{ + return 0; +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..0ad38c3 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,91 @@ +cmake_minimum_required(VERSION 3.10) +cmake_policy(SET CMP0079 NEW) + +find_package(PkgConfig REQUIRED) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) + +if(NOT UGET_WITH_GUI) + message(STATUS "tests/: UGET_WITH_GUI=OFF -> not building legacy GLib/GTK tests") + return() +endif() + +add_library(uglib_alias ALIAS uglib) +add_library(uget_core_alias ALIAS uget_core) + +set(_uget_has_mega FALSE) +if(HAVE_LIBGCRYPT AND (HAVE_OPENSSL OR HAVE_GNUTLS)) + set(_uget_has_mega TRUE) +else() + message(STATUS "Skipping test_plugin_app (Mega plug-in not available)") +endif() + +function(add_uget_test target) + set(options) + set(oneValueArgs LABELS WORKING_DIRECTORY) + set(multiValueArgs SOURCES LIBS) + cmake_parse_arguments(TEST "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT TEST_SOURCES) + message(FATAL_ERROR "add_uget_test(${target}) requires SOURCES") + endif() + + add_executable(${target} ${TEST_SOURCES}) + target_link_libraries(${target} PRIVATE PkgConfig::GLIB ${TEST_LIBS}) + target_compile_definitions(${target} PRIVATE HAVE_CONFIG_H) + + add_test(NAME ${target} COMMAND $) + + if(TEST_LABELS) + set(_labels "${TEST_LABELS}") + else() + set(_labels "unit") + endif() + if(TEST_WORKING_DIRECTORY) + set(_work_dir "${TEST_WORKING_DIRECTORY}") + else() + set(_work_dir "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + set_tests_properties(${target} PROPERTIES + LABELS "${_labels}" + WORKING_DIRECTORY "${_work_dir}" + TIMEOUT 60) +endfunction() + +add_uget_test(test_json + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test-json.c + LIBS uglib_alias +) + +add_uget_test(test_info + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test-info.c + LIBS uglib_alias +) + +add_uget_test(test_uglib + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test-uglib.c + LIBS uglib_alias +) + +add_uget_test(test_uget + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test-uget.c + LIBS uget_core_alias uglib_alias + LABELS "unit;net" +) + +add_uget_test(test_jsonrpc + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test-jsonrpc.c + LIBS uget_core_alias uglib_alias + LABELS "unit;net" +) + +if(TEST test_http) + set_tests_properties(test_http PROPERTIES LABELS "unit;net" TIMEOUT 60) +endif() + +if(_uget_has_mega) + add_uget_test(test_plugin_app + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test-plugin+app.c + LIBS uget_core_alias uglib_alias + LABELS "unit;net" + ) +endif() diff --git a/tests/Makefile.am b/tests/Makefile.am deleted file mode 100644 index c0f9de0..0000000 --- a/tests/Makefile.am +++ /dev/null @@ -1,50 +0,0 @@ -noinst_PROGRAMS = \ - test-json test-jsonrpc test-plugin+app test-info \ - test-uglib test-uget -# test-uglib-cxx test-uget-cxx -TESTS_LIBS = @PTHREAD_LIBS@ @CURL_LIBS@ @GLIB_LIBS@ - -if WITH_LIBPWMD -TESTS_LIBS += @LIBPWMD_LIBS@ -endif - -# set the include path found by configure -AM_CPPFLAGS = -I$(top_srcdir)/uglib -I$(top_srcdir)/uget -AM_CFLAGS = @PTHREAD_CFLAGS@ @LFS_CFLAGS@ @CURL_CFLAGS@ @GLIB_CFLAGS@ -AM_LDFLAGS = @LFS_LDFLAGS@ - -# test_json_CPPFLAGS = -I$(top_srcdir)/uglib -test_json_LDADD = $(top_builddir)/uglib/libuglib.a $(TESTS_LIBS) -test_json_SOURCES = test-json.c - -# test_jsonrpc_CPPFLAGS = -I$(top_srcdir)/uglib -I$(top_srcdir)/uget -test_jsonrpc_LDADD = $(top_builddir)/uget/libuget.a $(top_builddir)/uglib/libuglib.a $(TESTS_LIBS) -test_jsonrpc_SOURCES = test-jsonrpc.c - -test_plugin_app_CPPFLAGS = -I$(top_srcdir)/uglib -I$(top_srcdir)/uget @LIBGCRYPT_CFLAGS@ @LIBCRYPTO_CFLAGS@ -test_plugin_app_LDADD = $(top_builddir)/uget/libuget.a $(top_builddir)/uglib/libuglib.a $(TESTS_LIBS) @LIBGCRYPT_LIBS@ @LIBCRYPTO_LIBS@ -test_plugin_app_SOURCES = test-plugin+app.c - -# test_info_CPPFLAGS = -I$(top_srcdir)/uglib -test_info_LDADD = $(top_builddir)/uglib/libuglib.a $(TESTS_LIBS) -test_info_SOURCES = test-info.c - -# test_uglib_CPPFLAGS = -I$(top_srcdir)/uglib -test_uglib_LDADD = $(top_builddir)/uglib/libuglib.a $(TESTS_LIBS) -test_uglib_SOURCES = test-uglib.c - -# test_uget_CPPFLAGS = -I$(top_srcdir)/uglib -I$(top_srcdir)/uget -test_uget_LDADD = $(top_builddir)/uget/libuget.a $(top_builddir)/uglib/libuglib.a $(TESTS_LIBS) -test_uget_SOURCES = test-uget.c - -## test C++ standard-layout -#test_uglib_cxx_CPPFLAGS = -I$(top_srcdir)/uglib -#test_uglib_cxx_CXXFLAGS = -std=c++11 -#test_uglib_cxx_LDADD = $(top_builddir)/uglib/libuglib.a $(TESTS_LIBS) -#test_uglib_cxx_SOURCES = test-uglib-cxx.cxx - -## test_uget_cxx_CPPFLAGS = -I$(top_srcdir)/uglib -I$(top_srcdir)/uget -#test_uget_cxx_CXXFLAGS = -std=c++11 -#test_uget_cxx_LDADD = $(top_builddir)/uget/libuget.a $(top_builddir)/uglib/libuglib.a $(TESTS_LIBS) -#test_uget_cxx_SOURCES = test-uget-cxx.cxx - diff --git a/tests/test-json.c b/tests/test-json.c index 250a11c..bf418e6 100644 --- a/tests/test-json.c +++ b/tests/test-json.c @@ -261,9 +261,34 @@ SampleJs* sample_js_new (void) void sample_js_free (SampleJs* samplejs) { + int index; + + if (samplejs == NULL) + return; + + ug_free (samplejs->name); + samplejs->name = NULL; + + ug_free (samplejs->info.ftp.user); + samplejs->info.ftp.user = NULL; + ug_free (samplejs->info.ftp.password); + samplejs->info.ftp.password = NULL; + + ug_free (samplejs->info.http.user_agent); + samplejs->info.http.user_agent = NULL; + ug_free (samplejs->info.http.referrer); + samplejs->info.http.referrer = NULL; + + for (index = 0; index < samplejs->info.sarray.length; index++) + ug_free (samplejs->info.sarray.at[index]); ug_array_clear (&samplejs->info.sarray); + ug_array_clear (&samplejs->info.iarray); + + for (index = 0; index < samplejs->info.oarray.length; index++) + worked_id_final (&samplejs->info.oarray.at[index]); ug_array_clear (&samplejs->info.oarray); + free (samplejs); } @@ -508,6 +533,7 @@ void sample_js_to_file (SampleJs* samplejs, const char* filename) ug_json_end_write (&json); ug_json_final (&json); + ug_buffer_clear (&buffer, 1); fclose (file); } @@ -844,6 +870,8 @@ void test_array (void) "array.length = '%d'\n" "array.allocated = '%d'\n", array.at, array.length, array.allocated); + + ug_array_clear (&array); } // ---------------------------------------------------------------------------- diff --git a/tests/test-jsonrpc.c b/tests/test-jsonrpc.c index 674db50..b6dcc68 100644 --- a/tests/test-jsonrpc.c +++ b/tests/test-jsonrpc.c @@ -35,6 +35,7 @@ */ #include +#include #include #include #include @@ -55,10 +56,17 @@ #define ug_sleep(millisecond) usleep (millisecond * 1000) #endif +static void +free_rpc_array_container (UgJsonrpcArray* array) +{ + ug_jsonrpc_array_free (array); +} + static void socket_receiver (UgSocketServer* server, SOCKET client_fd, void* data) { - char buf[5]; + (void)data; + char buf[5]; ug_socket_server_ref (server); @@ -166,6 +174,7 @@ void print_rpc_object (UgJsonrpcObject* jobj) ug_buffer_write_char (&buffer, '\0'); puts (buffer.beg); + ug_buffer_clear (&buffer, 1); } void test_rpc_parser (void) @@ -198,8 +207,7 @@ void test_rpc_parser (void) parse_rpc_object (jobj, json_string3); print_rpc_object (jobj); - ug_jsonrpc_array_clear (jarray, 1); - free (jarray); + free_rpc_array_container (jarray); } void test_rpc_curl_packet (UgJsonrpcCurl* jrcurl) @@ -257,8 +265,7 @@ void test_jsonrpc_curl (void) ug_jsonrpc_curl_final (jrcurl); free (jrcurl); - ug_jsonrpc_array_clear (jarray, 1); - free (jarray); + free_rpc_array_container (jarray); } // ---------------------------------------------------------------------------- @@ -266,8 +273,10 @@ void test_jsonrpc_curl (void) static void jsonrpc_accepted (UgJsonrpc* jrpc, void* data, void* data2) { - UgJsonrpcObject* request; - UgJsonrpcObject* response; + (void)data; + (void)data2; + UgJsonrpcObject* request; + UgJsonrpcObject* response; int result; request = ug_jsonrpc_object_new (); @@ -419,8 +428,8 @@ void test_uget_aria2 (void) test_uget_aria2_rpc_object (uaria2); // uget_aria2_shutdown (uaria2); - uget_aria2_stop_thread (uaria2); - uget_aria2_unref (uaria2); + uget_aria2_stop_thread (uaria2); + uget_aria2_free (uaria2); ug_sleep (2000); } diff --git a/tests/test-plugin+app.c b/tests/test-plugin+app.c index 0a57c0a..68774fe 100644 --- a/tests/test-plugin+app.c +++ b/tests/test-plugin+app.c @@ -34,368 +34,384 @@ * */ -#include +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include -#include #include +#include +#include #include #include -#include +#include #if defined _WIN32 || defined _WIN64 #include -#define ug_sleep Sleep +#define ug_sleep Sleep #else -#include // usleep() -#define ug_sleep(millisecond) usleep (millisecond * 1000) +#include // usleep() +#define ug_sleep(millisecond) usleep(millisecond * 1000) #endif // _WIN32 || _WIN64 // ---------------------------------------------------------------------------- // test_download -void download_by_plugin(UgInfo* info, const UgetPluginInfo* pinfo) -{ - UgetCommon* common; - UgetFiles* files; - UgetFile* file1; - UgetPlugin* plugin; - UgetEvent* events; - UgetEvent* cur; - UgetEvent* next; - UgetProgress* progress; - int index; - int speed_limit[2]; - char* string[5]; - - speed_limit[0] = 1000000; - speed_limit[1] = 1000000; - - plugin = uget_plugin_new(pinfo); - uget_plugin_accept(plugin, info); - uget_plugin_ctrl(plugin, UGET_PLUGIN_CTRL_SPEED, speed_limit); - if (uget_plugin_start(plugin) == FALSE) { - uget_plugin_unref(plugin); - puts("plug-in failed to start."); - return; - } - - while (uget_plugin_sync(plugin, info)) { - ug_sleep(1000); - // event - events = uget_plugin_pop(plugin); - for (cur = events; cur; cur = next) { - next = cur->next; - printf ("\n" "Event type: %d - %s\n", cur->type, cur->string); - uget_event_free(cur); - } - // progress - progress = ug_info_get(info, UgetProgressInfo); - if (progress == NULL) - continue; - string[0] = ug_str_from_int_unit(progress->complete, NULL); - string[1] = ug_str_from_int_unit(progress->total, NULL); - string[2] = ug_str_from_int_unit(progress->uploaded, NULL); - string[3] = ug_str_from_int_unit(progress->download_speed, "/s"); - string[4] = ug_str_from_int_unit(progress->upload_speed, "/s"); - printf("\r" "DL: %s / %s, %d%%, %s | UL: %s, %s" " ", - string[0], string[1], progress->percent, - string[3], string[2], string[4]); - for (index = 0; index < 5; index++) - ug_free(string[index]); - } - // these data may changed, print them. - common = ug_info_get(info, UgetCommonInfo); - printf("\n" - "common->name : %s\n" - "common->uri : %s\n" - "common->file : %s\n", - common->name, common->uri, common->file); - // print children - files = ug_info_realloc(info, UgetFilesInfo); - for (file1 = (UgetFile*)files->list.head; file1; file1 = file1->next) - printf("file name : %s\n", file1->path); - - uget_plugin_unref(plugin); +void download_by_plugin(UgInfo *info, const UgetPluginInfo *pinfo) { + UgetCommon *common; + UgetFiles *files; + UgetFile *file1; + UgetPlugin *plugin; + UgetEvent *events; + UgetEvent *cur; + UgetEvent *next; + UgetProgress *progress; + int index; + int speed_limit[2]; + char *string[5]; + + speed_limit[0] = 1000000; + speed_limit[1] = 1000000; + + plugin = uget_plugin_new(pinfo); + uget_plugin_accept(plugin, info); + uget_plugin_ctrl(plugin, UGET_PLUGIN_CTRL_SPEED, speed_limit); + if (uget_plugin_start(plugin) == FALSE) { + uget_plugin_unref(plugin); + puts("plug-in failed to start."); + return; + } + + while (uget_plugin_sync(plugin, info)) { + ug_sleep(1000); + // event + events = uget_plugin_pop(plugin); + for (cur = events; cur; cur = next) { + next = cur->next; + printf("\n" + "Event type: %d - %s\n", + cur->type, cur->string); + uget_event_free(cur); + } + // progress + progress = ug_info_get(info, UgetProgressInfo); + if (progress == NULL) + continue; + string[0] = ug_str_from_int_unit(progress->complete, NULL); + string[1] = ug_str_from_int_unit(progress->total, NULL); + string[2] = ug_str_from_int_unit(progress->uploaded, NULL); + string[3] = ug_str_from_int_unit(progress->download_speed, "/s"); + string[4] = ug_str_from_int_unit(progress->upload_speed, "/s"); + printf("\r" + "DL: %s / %s, %d%%, %s | UL: %s, %s" + " ", + string[0], string[1], progress->percent, string[3], string[2], + string[4]); + for (index = 0; index < 5; index++) + ug_free(string[index]); + } + // these data may changed, print them. + common = ug_info_get(info, UgetCommonInfo); + printf("\n" + "common->name : %s\n" + "common->uri : %s\n" + "common->file : %s\n", + common->name, common->uri, common->file); + // print children + files = ug_info_realloc(info, UgetFilesInfo); + for (file1 = (UgetFile *)files->list.head; file1; file1 = file1->next) + printf("file name : %s\n", file1->path); + + uget_plugin_unref(plugin); } -void test_download(void) -{ - UgetCommon* common; - UgetHttp* http; - UgInfo* info; - char* referrer; - char* uri; - char* mirrors; - - uri = "https://mega.nz/#F!i5FXiSoD!TObpvqxETCq8TbEhFevzpg"; -// uri = "https://mega.nz/#!MSpjBRhZ!nZBsUQCAnf71842wXuals_ftSkga3fIQypzBsKEZbmk"; -// uri = "https://www.youtube.com/watch?v=y2004Xaz2HU"; -// uri = "http://download.tuxfamily.org/notepadplus/6.5.3/npp.6.5.3.Installer.exe"; -// uri = "http://ftp.gimp.org/pub/gimp/v2.8/windows/gimp-2.8.10-setup.exe"; -// mirrors = "ftp://195.220.108.108/linux/fedora/linux/updates/19/x86_64/kernel-3.11.2-201.fc19.x86_64.rpm"; - mirrors = NULL; - -// referrer = "http://code.google.com/p/tortoisegit/wiki/Download?tm=2"; - referrer = NULL; - - info = ug_info_new(8, 0); - // commom options - common = ug_info_realloc(info, UgetCommonInfo); - common->uri = ug_strdup(uri); - if (mirrors) - common->mirrors = ug_strdup(mirrors); -// common->folder = ug_strdup ("D:\\Downloads"); -// common->max_connections = 2; - common->debug_level = 1; - common->retry_limit = 1; - common->connect_timeout = 30; - - // http options - http = ug_info_realloc(info, UgetHttpInfo); - if (referrer) - http->referrer = ug_strdup(referrer); +void test_download(void) { + UgetCommon *common; + UgetHttp *http; + UgInfo *info; + char *referrer; + char *uri; + char *mirrors; + + uri = "https://mega.nz/#F!i5FXiSoD!TObpvqxETCq8TbEhFevzpg"; + // uri = + //"https://mega.nz/#!MSpjBRhZ!nZBsUQCAnf71842wXuals_ftSkga3fIQypzBsKEZbmk"; + // uri = "https://www.youtube.com/watch?v=y2004Xaz2HU"; + // uri = + //"http://download.tuxfamily.org/notepadplus/6.5.3/npp.6.5.3.Installer.exe"; + // uri = "http://ftp.gimp.org/pub/gimp/v2.8/windows/gimp-2.8.10-setup.exe"; + // mirrors = + //"ftp://195.220.108.108/linux/fedora/linux/updates/19/x86_64/kernel-3.11.2-201.fc19.x86_64.rpm"; + mirrors = NULL; + + // referrer = "http://code.google.com/p/tortoisegit/wiki/Download?tm=2"; + referrer = NULL; + + info = ug_info_new(8, 0); + // commom options + common = ug_info_realloc(info, UgetCommonInfo); + common->uri = ug_strdup(uri); + if (mirrors) + common->mirrors = ug_strdup(mirrors); + // common->folder = ug_strdup ("D:\\Downloads"); + // common->max_connections = 2; + common->debug_level = 1; + common->retry_limit = 1; + common->connect_timeout = 30; + + // http options + http = ug_info_realloc(info, UgetHttpInfo); + if (referrer) + http->referrer = ug_strdup(referrer); // download_by_plugin(info, UgetPluginCurlInfo); // download_by_plugin(info, UgetPluginAria2Info); // download_by_plugin(info, UgetPluginMediaInfo); - download_by_plugin(info, UgetPluginMegaInfo); - ug_info_unref(info); +#ifdef HAVE_MEGA + download_by_plugin(info, UgetPluginMegaInfo); +#endif + + ug_info_unref(info); } // ---------------------------------------------------------------------------- // test_plugin -void test_setup_plugin_aria2 (void) -{ - const UgetPluginInfo* pinfo; +void test_setup_plugin_aria2(void) { + const UgetPluginInfo *pinfo; - pinfo = UgetPluginAria2Info; - uget_plugin_global_set(pinfo, UGET_PLUGIN_GLOBAL_INIT, (void*) TRUE); - uget_plugin_global_set(pinfo, UGET_PLUGIN_ARIA2_GLOBAL_URI, - "http://localhost/jsonrpc"); + pinfo = UgetPluginAria2Info; + uget_plugin_global_set(pinfo, UGET_PLUGIN_GLOBAL_INIT, (void *)TRUE); + uget_plugin_global_set(pinfo, UGET_PLUGIN_ARIA2_GLOBAL_URI, + "http://localhost/jsonrpc"); #if defined _WIN32 || defined _WIN64 - uget_plugin_global_set(pinfo, UGET_PLUGIN_ARIA2_GLOBAL_PATH, - "C:\\Program Files\\uGet\\bin\\aria2c.exe"); + uget_plugin_global_set(pinfo, UGET_PLUGIN_ARIA2_GLOBAL_PATH, + "C:\\Program Files\\uGet\\bin\\aria2c.exe"); #endif - uget_plugin_global_set(pinfo, UGET_PLUGIN_ARIA2_GLOBAL_ARGUMENT, - "--enable-rpc=true -D --check-certificate=false"); - uget_plugin_global_set(pinfo, UGET_PLUGIN_ARIA2_GLOBAL_LAUNCH, (void*) TRUE); - uget_plugin_global_set(pinfo, UGET_PLUGIN_ARIA2_GLOBAL_SHUTDOWN, (void*) TRUE); - ug_sleep (1000); - uget_plugin_global_set(pinfo, UGET_PLUGIN_GLOBAL_INIT, (void*) FALSE); - ug_sleep (1000); + uget_plugin_global_set(pinfo, UGET_PLUGIN_ARIA2_GLOBAL_ARGUMENT, + "--enable-rpc=true -D --check-certificate=false"); + uget_plugin_global_set(pinfo, UGET_PLUGIN_ARIA2_GLOBAL_LAUNCH, (void *)TRUE); + uget_plugin_global_set(pinfo, UGET_PLUGIN_ARIA2_GLOBAL_SHUTDOWN, + (void *)TRUE); + ug_sleep(1000); + uget_plugin_global_set(pinfo, UGET_PLUGIN_GLOBAL_INIT, (void *)FALSE); + ug_sleep(1000); } // ---------------------------------------------------------------------------- // test_task -void print_speed_limit (UgetNode** dnode, int count) -{ - int total[2] = {0,0}; - UgetRelation* relation; - - for (count = 0; count < 7; count++) { - relation = ug_info_get (dnode[count]->info, UgetRelationInfo); - if (relation->task) { - printf ("limit D: %d, U: %d | speed D: %d, U: %d\n", - relation->task->limit[0], - relation->task->limit[1], - relation->task->speed[0], - relation->task->speed[1]); - total[0] += relation->task->limit[0]; - total[1] += relation->task->limit[1]; - } - } - - printf ("total limit D: %d, U: %d\n", - total[0], - total[1]); +void print_speed_limit(UgetNode **dnode, int count) { + int total[2] = {0, 0}; + UgetRelation *relation; + + for (count = 0; count < 7; count++) { + relation = ug_info_get(dnode[count]->info, UgetRelationInfo); + if (relation->task) { + printf("limit D: %d, U: %d | speed D: %d, U: %d\n", + relation->task->limit[0], relation->task->limit[1], + relation->task->speed[0], relation->task->speed[1]); + total[0] += relation->task->limit[0]; + total[1] += relation->task->limit[1]; + } + } + + printf("total limit D: %d, U: %d\n", total[0], total[1]); } -void test_task (void) -{ - UgetTask* task; - UgetNode* dnode[7]; - UgetRelation* relation; - int count; - - task = calloc (1, sizeof (UgetTask)); - uget_task_init (task); - - // task speed control ------------------- - for (count = 0; count < 7; count++) { - dnode[count] = uget_node_new (NULL); - relation = ug_info_realloc (dnode[count]->info, UgetRelationInfo); - uget_task_add (task, dnode[count], UgetPluginEmptyInfo); - if (relation->task) { - relation->task->limit[0] = 2000; - relation->task->limit[1] = 1500; - relation->task->speed[0] = 2000 - count * 200; - relation->task->speed[1] = 1500 - count * 200; - } - } - if (relation->task) { - relation->task->limit[0] = 0; - relation->task->limit[1] = 0; - } - - uget_task_set_speed (task, 12000, 8000); - print_speed_limit(dnode, 7); - puts ("---"); - uget_task_adjust_speed (task); - print_speed_limit(dnode, 7); - - uget_task_remove_all (task); - uget_task_final (task); - free (task); - - for (count = 0; count < 7; count++) - uget_node_free (dnode[count]); +void test_task(void) { + UgetTask *task; + UgetNode *dnode[7]; + UgetRelation *relation; + int count; + + task = calloc(1, sizeof(UgetTask)); + uget_task_init(task); + + // task speed control ------------------- + for (count = 0; count < 7; count++) { + dnode[count] = uget_node_new(NULL); + relation = ug_info_realloc(dnode[count]->info, UgetRelationInfo); + uget_task_add(task, dnode[count], UgetPluginEmptyInfo); + if (relation->task) { + relation->task->limit[0] = 2000; + relation->task->limit[1] = 1500; + relation->task->speed[0] = 2000 - count * 200; + relation->task->speed[1] = 1500 - count * 200; + } + } + if (relation->task) { + relation->task->limit[0] = 0; + relation->task->limit[1] = 0; + } + + uget_task_set_speed(task, 12000, 8000); + print_speed_limit(dnode, 7); + puts("---"); + uget_task_adjust_speed(task); + print_speed_limit(dnode, 7); + + uget_task_remove_all(task); + uget_task_final(task); + free(task); + + for (count = 0; count < 7; count++) + uget_node_free(dnode[count]); } // ---------------------------------------------------------------------------- // test_app -void setup_app (UgetApp* app) -{ - UgetNode* cnode; - UgetCategory* category; - UgetCommon* common; - - cnode = uget_node_new (NULL); - category = ug_info_realloc (cnode->info, UgetCategoryInfo); - *(char**)ug_array_alloc (&category->schemes, 1) = ug_strdup ("http"); - *(char**)ug_array_alloc (&category->schemes, 1) = ug_strdup ("https"); - *(char**)ug_array_alloc (&category->schemes, 1) = ug_strdup ("ftp"); - common = ug_info_realloc (cnode->info, UgetCommonInfo); - common->name = ug_strdup ("Home Category"); - common->max_connections = 2; - uget_app_add_category (app, cnode, TRUE); - - uget_app_add_plugin (app, UgetPluginAria2Info); - uget_app_add_plugin (app, UgetPluginCurlInfo); - uget_app_clear_plugins (app); - uget_app_set_default_plugin (app, UgetPluginCurlInfo); -} - -void start_app (UgetApp* app) -{ - UgetNode* dnode; - UgetCommon* common; - char* string[2]; - - dnode = uget_node_new (NULL); - common = ug_info_realloc (dnode->info, UgetCommonInfo); - common->name = ug_strdup ("Download"); - common->uri = ug_strdup ("http://www.utorrent.com/scripts/dl.php?track=stable&build=29812&client=utorrent"); - common->folder = ug_strdup ("D:\\Downloads"); - common->debug_level = 1; -// common->keeping.enable = TRUE; -// common->keeping.uri = TRUE; -// common->keeping.folder = TRUE; -// common->keeping.debug_level = TRUE; - - uget_app_add_download (app, dnode, NULL, FALSE); - puts ("uget_app_grow()"); - while (uget_app_grow (app, FALSE)) { - ug_sleep (1000); - string[0] = ug_str_from_int_unit (app->task.speed.download, "/s"); - string[1] = ug_str_from_int_unit (app->task.speed.upload, "/s"); - printf ("\r" "DL: %s | UL %s" " ", string[0], string[1]); - ug_free (string[0]); - ug_free (string[1]); - } - puts ("uget_app_grow() return 0"); - - puts ("call uget_app_grow() again"); - uget_app_grow (app, FALSE); +void setup_app(UgetApp *app) { + UgetNode *cnode; + UgetCategory *category; + UgetCommon *common; + + cnode = uget_node_new(NULL); + category = ug_info_realloc(cnode->info, UgetCategoryInfo); + *(char **)ug_array_alloc(&category->schemes, 1) = ug_strdup("http"); + *(char **)ug_array_alloc(&category->schemes, 1) = ug_strdup("https"); + *(char **)ug_array_alloc(&category->schemes, 1) = ug_strdup("ftp"); + common = ug_info_realloc(cnode->info, UgetCommonInfo); + common->name = ug_strdup("Home Category"); + common->max_connections = 2; + uget_app_add_category(app, cnode, TRUE); + + uget_app_add_plugin(app, UgetPluginAria2Info); + uget_app_add_plugin(app, UgetPluginCurlInfo); + uget_app_clear_plugins(app); + uget_app_set_default_plugin(app, UgetPluginCurlInfo); } -void close_app (UgetApp* app) -{ - uget_app_clear_plugins (app); +void start_app(UgetApp *app) { + UgetNode *dnode; + UgetCommon *common; + char *string[2]; + + dnode = uget_node_new(NULL); + common = ug_info_realloc(dnode->info, UgetCommonInfo); + common->name = ug_strdup("Download"); + common->uri = ug_strdup("http://www.utorrent.com/scripts/" + "dl.php?track=stable&build=29812&client=utorrent"); + common->folder = ug_strdup("D:\\Downloads"); + common->debug_level = 1; + // common->keeping.enable = TRUE; + // common->keeping.uri = TRUE; + // common->keeping.folder = TRUE; + // common->keeping.debug_level = TRUE; + + uget_app_add_download(app, dnode, NULL, FALSE); + puts("uget_app_grow()"); + while (uget_app_grow(app, FALSE)) { + ug_sleep(1000); + string[0] = ug_str_from_int_unit(app->task.speed.download, "/s"); + string[1] = ug_str_from_int_unit(app->task.speed.upload, "/s"); + printf("\r" + "DL: %s | UL %s" + " ", + string[0], string[1]); + ug_free(string[0]); + ug_free(string[1]); + } + puts("uget_app_grow() return 0"); + + puts("call uget_app_grow() again"); + uget_app_grow(app, FALSE); } -void test_app_node (UgetApp* app) -{ - UgetNode* dnode[7]; - UgetNode* cnode; - UgetCommon* common; - int count; - - for (count = 0; count < 7; count++) { - dnode[count] = uget_node_new (NULL); - common = ug_info_realloc (dnode[count]->info, UgetCommonInfo); - common->uri = ug_strdup ("ftp://127.0.0.1/"); - common->folder = ug_strdup ("D:\\Downloads"); - common->keeping.enable = TRUE; - common->keeping.uri = FALSE; - common->keeping.folder = FALSE; - uget_app_add_download (app, dnode[count], NULL, TRUE); - } - - uget_app_move_download (app, dnode[5], NULL); - uget_app_delete_download (app, dnode[2], TRUE); - uget_app_delete_download (app, dnode[4], FALSE); - uget_app_delete_download (app, dnode[6], FALSE); - - cnode = app->real.children; - if (cnode) - printf ("%d\n", cnode->n_children); - - cnode = app->split.children; - if (cnode) - printf ("%d\n", cnode->n_children); - - cnode = app->mix.children; - if (cnode) - printf ("%d\n", cnode->n_children); - - cnode = app->mix_split.children; - if (cnode) - printf ("%d\n", cnode->n_children); +void close_app(UgetApp *app) { uget_app_clear_plugins(app); } + +void test_app_node(UgetApp *app) { + UgetNode *dnode[7]; + UgetNode *cnode; + UgetCommon *common; + int count; + + for (count = 0; count < 7; count++) { + dnode[count] = uget_node_new(NULL); + common = ug_info_realloc(dnode[count]->info, UgetCommonInfo); + common->uri = ug_strdup("ftp://127.0.0.1/"); + common->folder = ug_strdup("D:\\Downloads"); + common->keeping.enable = TRUE; + common->keeping.uri = FALSE; + common->keeping.folder = FALSE; + uget_app_add_download(app, dnode[count], NULL, TRUE); + } + + uget_app_move_download(app, dnode[5], NULL); + uget_app_delete_download(app, dnode[2], TRUE); + uget_app_delete_download(app, dnode[4], FALSE); + uget_app_delete_download(app, dnode[6], FALSE); + + cnode = app->real.children; + if (cnode) + printf("%d\n", cnode->n_children); + + cnode = app->split.children; + if (cnode) + printf("%d\n", cnode->n_children); + + cnode = app->mix.children; + if (cnode) + printf("%d\n", cnode->n_children); + + cnode = app->mix_split.children; + if (cnode) + printf("%d\n", cnode->n_children); } -void test_app (void) -{ - UgetApp* app; - - app = calloc (1, sizeof (UgetApp)); - uget_app_init (app); - setup_app (app); - start_app (app); -// test_app_node (app); - uget_app_save_categories (app, NULL); -// uget_app_load_categories (app, NULL); - uget_app_final (app); - free (app); +void test_app(void) { + UgetApp *app; + + app = calloc(1, sizeof(UgetApp)); + uget_app_init(app); + setup_app(app); + start_app(app); + // test_app_node (app); + uget_app_save_categories(app, NULL); + // uget_app_load_categories (app, NULL); + uget_app_final(app); + free(app); } // ---------------------------------------------------------------------------- // main -int main (void) -{ - // initialize plug-in - uget_plugin_global_set(UgetPluginCurlInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) TRUE); - uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_GLOBAL_INIT, (void*) TRUE); - uget_plugin_global_set(UgetPluginMediaInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) TRUE); - uget_plugin_global_set(UgetPluginMegaInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) TRUE); -// test_setup_plugin_aria2(); - - test_download(); -// test_task(); -// test_app(); - -// uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_ARIA2_GLOBAL_SHUTDOWN_NOW, (void*) TRUE); - // finalize plug-in - uget_plugin_global_set(UgetPluginCurlInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) FALSE); - uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_GLOBAL_INIT, (void*) FALSE); - uget_plugin_global_set(UgetPluginMediaInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) FALSE); - uget_plugin_global_set(UgetPluginMegaInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) FALSE); - ug_sleep(1000); - - return 0; -} +int main(void) { + // initialize plug-in + uget_plugin_global_set(UgetPluginCurlInfo, UGET_PLUGIN_GLOBAL_INIT, + (void *)TRUE); + uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_GLOBAL_INIT, + (void *)TRUE); + uget_plugin_global_set(UgetPluginMediaInfo, UGET_PLUGIN_GLOBAL_INIT, + (void *)TRUE); +#ifdef HAVE_MEGA + uget_plugin_global_set(UgetPluginMegaInfo, UGET_PLUGIN_GLOBAL_INIT, + (void *)TRUE); +#endif + // test_setup_plugin_aria2(); + + test_download(); + // test_task(); + // test_app(); + + // uget_plugin_global_set(UgetPluginAria2Info, + //UGET_PLUGIN_ARIA2_GLOBAL_SHUTDOWN_NOW, (void*) TRUE); + // finalize plug-in + uget_plugin_global_set(UgetPluginCurlInfo, UGET_PLUGIN_GLOBAL_INIT, + (void *)FALSE); + uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_GLOBAL_INIT, + (void *)FALSE); + uget_plugin_global_set(UgetPluginMediaInfo, UGET_PLUGIN_GLOBAL_INIT, + (void *)FALSE); +#ifdef HAVE_MEGA + uget_plugin_global_set(UgetPluginMegaInfo, UGET_PLUGIN_GLOBAL_INIT, + (void *)FALSE); +#endif + + ug_sleep(1000); + + return 0; +} diff --git a/tests/test-uglib.c b/tests/test-uglib.c index 598999b..e51df6e 100644 --- a/tests/test-uglib.c +++ b/tests/test-uglib.c @@ -129,7 +129,7 @@ void test_uri (void) // ---------------------------------------------------------------------------- // test UgList -static UgLink link[4]; +static UgLink ug_links[4]; void test_list (void) { @@ -138,16 +138,16 @@ void test_list (void) uintptr_t index; ug_list_init (&list); - for (index = 0; index < 4; index++) - link[index].data = (void*) index; + for (index = 0; index < 4; index++) + ug_links[index].data = (void*) index; - ug_list_append (&list, link + 0); - ug_list_append (&list, link + 1); - ug_list_append (&list, link + 2); - ug_list_append (&list, link + 3); + ug_list_append (&list, ug_links + 0); + ug_list_append (&list, ug_links + 1); + ug_list_append (&list, ug_links + 2); + ug_list_append (&list, ug_links + 3); - ug_list_remove (&list, link + 2); - ug_list_insert (&list, link + 3, link + 2); + ug_list_remove (&list, ug_links + 2); + ug_list_insert (&list, ug_links + 3, ug_links + 2); for (temp = list.head; temp; temp = temp->next) { printf ("%d, %p, %p\n", @@ -371,7 +371,7 @@ int print_option_callback (UgOption* option, void test_option (void) { UgOption option; - struct Opt dest; + struct Opt dest = {0}; ug_option_init (&option); // ug_option_set_parser (&option, print_option_callback, NULL, NULL); @@ -379,6 +379,8 @@ void test_option (void) ug_option_parse (&option, "--category-index=1", -1); ug_option_parse (&option, "-cn=hhk", -1); ug_option_final (&option); + + ug_free (dest.name); } void test_cmd_arg (void) @@ -446,6 +448,8 @@ void test_html (void) ug_html_parse (uhtml, "< p attr1=\"value1\" attr2=val2/> < &xxxxx; ", -1); ug_html_end_parse (uhtml); puts("\n"); + + ug_html_free (uhtml); } void test_unicode (void) diff --git a/uget/Android.mk b/uget/Android.mk deleted file mode 100644 index d824c76..0000000 --- a/uget/Android.mk +++ /dev/null @@ -1,37 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := libuget -LOCAL_CPPFLAGS += -DNDEBUG -## -DNO_RETRY_IF_CONNECT_FAILED - -LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/../uglib $(LOCAL_PATH)/../curl/include $(LOCAL_PATH)/../openssl/include -LOCAL_SRC_FILES := \ - UgetSequence.c \ - UgetRpc.c \ - UgetOption.c \ - UgetData.c \ - UgetFiles.c \ - UgetNode.c \ - UgetNode-compare.c \ - UgetNode-filter.c \ - UgetTask.c \ - UgetHash.c \ - UgetSite.c \ - UgetApp.c \ - UgetEvent.c \ - UgetPlugin.c \ - UgetA2cf.c \ - UgetCurl.c \ - UgetAria2.c \ - UgetMedia.c \ - UgetMedia-youtube.c \ - UgetPluginCurl.c \ - UgetPluginAria2.c \ - UgetPluginMedia.c \ - UgetPluginAgent.c \ - UgetPluginMega.c - -include $(BUILD_STATIC_LIBRARY) - diff --git a/uget/Makefile.am b/uget/Makefile.am deleted file mode 100644 index 669af9e..0000000 --- a/uget/Makefile.am +++ /dev/null @@ -1,74 +0,0 @@ -## To enable LFS (Large File Support) in 32bit platform -## add `getconf LFS_CFLAGS` to CFLAGS -## add `getconf LFS_LDFLAGS` to LDFLAGS - -## static library --- - -# lib_LIBRARIES = libuget.a -noinst_LIBRARIES = libuget.a - -libuget_a_CPPFLAGS = -I$(top_srcdir)/uglib -I$(top_srcdir)/uget -libuget_a_CFLAGS = @PTHREAD_CFLAGS@ @GLIB_CFLAGS@ - -libuget_a_SOURCES = \ - UgetSequence.c \ - UgetRss.c \ - UgetRpc.c \ - UgetOption.c \ - UgetData.c \ - UgetFiles.c \ - UgetNode.c \ - UgetNode-compare.c \ - UgetNode-filter.c \ - UgetTask.c \ - UgetHash.c \ - UgetSite.c \ - UgetApp.c \ - UgetEvent.c \ - UgetPlugin.c \ - UgetA2cf.c \ - UgetCurl.c \ - UgetAria2.c \ - UgetMedia.c \ - UgetMedia-youtube.c \ - UgetPluginCurl.c \ - UgetPluginAria2.c \ - UgetPluginMedia.c \ - UgetPluginAgent.c \ - UgetPluginMega.c \ - UgetPluginEmpty.c - -noinst_HEADERS = \ - UgetSequence.h \ - UgetRss.h \ - UgetRpc.h \ - UgetOption.h \ - UgetData.h \ - UgetFiles.h \ - UgetNode.h \ - UgetTask.h \ - UgetHash.h \ - UgetSite.h \ - UgetApp.h \ - UgetEvent.h \ - UgetPlugin.h \ - UgetA2cf.h \ - UgetCurl.h \ - UgetAria2.h \ - UgetMedia.h \ - UgetPluginCurl.h \ - UgetPluginAria2.h \ - UgetPluginMedia.h \ - UgetPluginAgent.h \ - UgetPluginMega.h \ - UgetPluginEmpty.h - -if WITH_LIBPWMD -libuget_a_CFLAGS += @LIBPWMD_CFLAGS@ -libuget_a_SOURCES += pwmd.c -noinst_HEADERS += pwmd.h -endif - -EXTRA_DIST = \ - Android.mk \ - CMakeLists.txt diff --git a/uget/UgetAria2.c b/uget/UgetAria2.c index ba36a0e..af048ab 100644 --- a/uget/UgetAria2.c +++ b/uget/UgetAria2.c @@ -34,6 +34,8 @@ * */ +#include + #include #include #include @@ -72,8 +74,7 @@ struct UgetAria2Thread { - UgThread thread; - UgetAria2* uaria2; + UgetAria2* uaria2; UgJsonrpcArray queuing; UgJsonrpcArray request; UgJsonrpcArray response; @@ -81,27 +82,24 @@ struct UgetAria2Thread int finalized; }; -static UgThreadResult uget_aria2_thread (UgetAria2Thread* uathread); +static gpointer uget_aria2_thread (gpointer data); static UgetAria2Thread* uget_aria2_thread_new (UgetAria2* uaria2) { - UgetAria2Thread* uat; - UgThread thread; + UgetAria2Thread* uat; - uat = ug_malloc (sizeof (UgetAria2Thread)); - uat->uaria2 = uaria2; - ug_jsonrpc_array_init (&uat->queuing, 16); - ug_jsonrpc_array_init (&uat->request, 16); - ug_jsonrpc_array_init (&uat->response, 16); - ug_jsonrpc_curl_init (&uat->json); - ug_jsonrpc_curl_set_url (&uat->json, uaria2->uri); - uat->finalized = FALSE; + uat = ug_malloc (sizeof (UgetAria2Thread)); + uat->uaria2 = uaria2; + ug_jsonrpc_array_init (&uat->queuing, 16); + ug_jsonrpc_array_init (&uat->request, 16); + ug_jsonrpc_array_init (&uat->response, 16); + ug_jsonrpc_curl_init (&uat->json); + ug_jsonrpc_curl_set_url (&uat->json, uaria2->uri); + uat->finalized = FALSE; - uget_aria2_ref (uaria2); - ug_thread_create (&thread, (UgThreadFunc) uget_aria2_thread, uat); - ug_thread_unjoin (&thread); + uget_aria2_ref (uaria2); - return uat; + return uat; } static void uget_aria2_thread_free (UgetAria2Thread* uat) @@ -285,23 +283,26 @@ static void recycle_speed_request (UgetAria2* uaria2, UgJsonrpcObject* jreq) uget_aria2_recycle (uaria2, jres); } -static UgThreadResult uget_aria2_thread (UgetAria2Thread* uathread) +static gpointer uget_aria2_thread (gpointer data) { - UgetAria2* uaria2; - UgJsonrpcObject* jreq = NULL; - UgJsonrpcObject* jobj = NULL; - UgJsonrpcObject* jreq_shutdown = NULL; - int counts; + UgetAria2Thread* uathread = data; + UgetAria2* uaria2; + UgJsonrpcObject* jreq = NULL; + UgJsonrpcObject* jobj = NULL; + UgJsonrpcObject* jreq_shutdown = NULL; + int counts; uaria2 = uathread->uaria2; // temp.index = ug_jsonrpc_array_find_ptr (uaria2); - for (counts = 0; ; counts++) { - // finalize - if (uathread->finalized == TRUE) { - // shutdown request - if (uaria2->shutdown && jreq_shutdown == NULL) { - jreq_shutdown = uget_aria2_alloc (uaria2, TRUE, TRUE); + for (counts = 0; ; counts++) { + if (g_atomic_int_get (&uaria2->stop)) + uathread->finalized = TRUE; + // finalize + if (uathread->finalized == TRUE) { + // shutdown request + if (uaria2->shutdown && jreq_shutdown == NULL) { + jreq_shutdown = uget_aria2_alloc (uaria2, TRUE, TRUE); jreq_shutdown->method_static = "aria2.shutdown"; uget_aria2_request (uaria2, jreq_shutdown); } @@ -329,11 +330,19 @@ static UgThreadResult uget_aria2_thread (UgetAria2Thread* uathread) } // get requests from queue - if (uget_aria2_thread_queuing (uathread) == 0) { - // default: sleep 0.5 second - ug_sleep (uaria2->polling_interval); - continue; - } + if (uget_aria2_thread_queuing (uathread) == 0) { + g_mutex_lock (&uaria2->thread_lock); + if (!g_atomic_int_get (&uaria2->stop) && + uathread->finalized == FALSE) { + gint64 end_time = g_get_monotonic_time () + + (gint64) uaria2->polling_interval * G_TIME_SPAN_MILLISECOND; + g_cond_wait_until (&uaria2->thread_cond, + &uaria2->thread_lock, + end_time); + } + g_mutex_unlock (&uaria2->thread_lock); + continue; + } // send requests & get responses uget_aria2_thread_request (uathread); @@ -357,9 +366,13 @@ static UgThreadResult uget_aria2_thread (UgetAria2Thread* uathread) uget_aria2_recycle (uaria2, jobj); } - uget_aria2_thread_free (uathread); - uget_aria2_unref (uaria2); - return UG_THREAD_RESULT; + g_mutex_lock (&uaria2->thread_lock); + uaria2->worker = NULL; + g_mutex_unlock (&uaria2->thread_lock); + + uget_aria2_thread_free (uathread); + uget_aria2_unref (uaria2); + return NULL; } // ---------------------------------------------------------------------------- @@ -377,20 +390,23 @@ UgetAria2* uget_aria2_new (void) #endif // _WIN32 || _WIN64 curl_global_init (CURL_GLOBAL_ALL); - uaria2 = ug_malloc0 (sizeof (UgetAria2)); - uaria2->ref_count = 1; - uaria2->batch_len = RPC_BATCH_LEN; - uaria2->polling_interval = RPC_INTERVAL; - uaria2->speed_required = FALSE; - uaria2->limit_required = FALSE; - uaria2->uri = ug_strdup (RPC_URI); - uaria2->path = ug_strdup (ARIA2_PATH); - uaria2->args = ug_strdup (ARIA2_ARGS); - ug_mutex_init (&uaria2->mutex); - ug_mutex_init (&uaria2->completed_mutex); - - ug_jsonrpc_array_init (&uaria2->queuing, 16); - ug_jsonrpc_array_init (&uaria2->recycled, 16); + uaria2 = ug_malloc0 (sizeof (UgetAria2)); + uaria2->ref_count = 1; + uaria2->batch_len = RPC_BATCH_LEN; + uaria2->polling_interval = RPC_INTERVAL; + uaria2->speed_required = FALSE; + uaria2->limit_required = FALSE; + uaria2->uri = ug_strdup (RPC_URI); + uaria2->path = ug_strdup (ARIA2_PATH); + uaria2->args = ug_strdup (ARIA2_ARGS); + ug_mutex_init (&uaria2->mutex); + ug_mutex_init (&uaria2->completed_mutex); + g_mutex_init (&uaria2->thread_lock); + g_cond_init (&uaria2->thread_cond); + g_atomic_int_set (&uaria2->stop, 0); + + ug_jsonrpc_array_init (&uaria2->queuing, 16); + ug_jsonrpc_array_init (&uaria2->recycled, 16); ug_slinks_init (&uaria2->requested, 16); ug_slinks_init (&uaria2->responsed, 16); uaria2->completed_changed = 0; @@ -433,43 +449,132 @@ void uget_aria2_ref (UgetAria2* uaria2) uaria2->ref_count++; } -void uget_aria2_unref (UgetAria2* uaria2) +static void +uget_aria2_dispose (UgetAria2* uaria2) { - if (--uaria2->ref_count == 0) { - ug_jsonrpc_array_clear (&uaria2->queuing, TRUE); - ug_jsonrpc_array_clear (&uaria2->recycled, TRUE); - ug_slinks_foreach (&uaria2->requested, (void*)ug_jsonrpc_object_free, NULL); - ug_slinks_foreach (&uaria2->responsed, (void*)ug_jsonrpc_object_free, NULL); - ug_slinks_final (&uaria2->requested); - ug_slinks_final (&uaria2->responsed); + int index; - ug_value_foreach (&uaria2->status_keys, ug_value_set_string, NULL); - ug_value_clear (&uaria2->status_keys); + if (uaria2 == NULL) + return; - ug_mutex_clear (&uaria2->completed_mutex); - ug_mutex_clear (&uaria2->mutex); - ug_free (uaria2->uri); - ug_free (uaria2->path); - ug_free (uaria2->args); - ug_free (uaria2); + uget_aria2_stop_thread (uaria2); - curl_global_cleanup (); + ug_mutex_lock (&uaria2->mutex); + for (index = 0; index < uaria2->queuing.length; index++) + if (uaria2->queuing.at[index]) + ug_jsonrpc_object_free (uaria2->queuing.at[index]); + ug_jsonrpc_array_clear (&uaria2->queuing, 0); + + for (index = 0; index < uaria2->recycled.length; index++) + if (uaria2->recycled.at[index]) + ug_jsonrpc_object_free (uaria2->recycled.at[index]); + ug_jsonrpc_array_clear (&uaria2->recycled, 0); + ug_mutex_unlock (&uaria2->mutex); + + ug_slinks_foreach (&uaria2->requested, (void*)ug_jsonrpc_object_free, NULL); + ug_slinks_foreach (&uaria2->responsed, (void*)ug_jsonrpc_object_free, NULL); + ug_slinks_final (&uaria2->requested); + ug_slinks_final (&uaria2->responsed); + + ug_value_foreach (&uaria2->status_keys, ug_value_set_string, NULL); + ug_value_clear (&uaria2->status_keys); + + ug_mutex_clear (&uaria2->completed_mutex); + ug_mutex_clear (&uaria2->mutex); + g_cond_clear (&uaria2->thread_cond); + g_mutex_clear (&uaria2->thread_lock); + + ug_free (uaria2->token); + ug_free (uaria2->uri); + ug_free (uaria2->path); + ug_free (uaria2->args); + ug_free (uaria2); + + curl_global_cleanup (); #if defined _WIN32 || defined _WIN64 - WSACleanup (); + WSACleanup (); #endif // _WIN32 || _WIN64 - } +} + +void uget_aria2_unref (UgetAria2* uaria2) +{ + if (uaria2 == NULL) + return; + + if (--uaria2->ref_count == 0) + uget_aria2_dispose (uaria2); +} + +void uget_aria2_free (UgetAria2* uaria2) +{ + if (uaria2 == NULL) + return; + + uaria2->ref_count = 1; + uget_aria2_unref (uaria2); } void uget_aria2_start_thread (UgetAria2* uaria2) { - if (uaria2->thread == NULL) - uaria2->thread = uget_aria2_thread_new (uaria2); + UgetAria2Thread* worker; + + if (uaria2 == NULL) + return; + + g_mutex_lock (&uaria2->thread_lock); + if (uaria2->thread != NULL) { + g_mutex_unlock (&uaria2->thread_lock); + return; + } + + if (uaria2->worker == NULL) + uaria2->worker = uget_aria2_thread_new (uaria2); + + g_atomic_int_set (&uaria2->stop, 0); + worker = uaria2->worker; + uaria2->thread = g_thread_new ("uget-aria2", uget_aria2_thread, worker); + + if (uaria2->thread == NULL) { + uaria2->worker = NULL; + g_mutex_unlock (&uaria2->thread_lock); + if (worker) { + uget_aria2_thread_free (worker); + uget_aria2_unref (uaria2); + } + return; + } + + g_mutex_unlock (&uaria2->thread_lock); } void uget_aria2_stop_thread (UgetAria2* uaria2) { - uaria2->thread->finalized = TRUE; - uaria2->thread = NULL; + GThread* thread; + + if (uaria2 == NULL) + return; + + g_mutex_lock (&uaria2->thread_lock); + if (uaria2->thread == NULL && uaria2->worker == NULL) { + g_mutex_unlock (&uaria2->thread_lock); + return; + } + + g_atomic_int_set (&uaria2->stop, 1); + if (uaria2->worker) + uaria2->worker->finalized = TRUE; + g_cond_broadcast (&uaria2->thread_cond); + + thread = uaria2->thread; + uaria2->thread = NULL; + g_mutex_unlock (&uaria2->thread_lock); + + if (thread && thread != g_thread_self()) + g_thread_join (thread); + + g_mutex_lock (&uaria2->thread_lock); + uaria2->worker = NULL; + g_mutex_unlock (&uaria2->thread_lock); } void uget_aria2_set_uri (UgetAria2* uaria2, const char* uri) @@ -711,9 +816,13 @@ UgJsonrpcObject* uget_aria2_alloc (UgetAria2* uaria2, int is_request, int has_r void uget_aria2_request (UgetAria2* uaria2, UgJsonrpcObject* request) { - ug_mutex_lock (&uaria2->mutex); - *(UgJsonrpcObject**)ug_array_alloc (&uaria2->queuing, 1) = request; - ug_mutex_unlock (&uaria2->mutex); + ug_mutex_lock (&uaria2->mutex); + *(UgJsonrpcObject**)ug_array_alloc (&uaria2->queuing, 1) = request; + ug_mutex_unlock (&uaria2->mutex); + + g_mutex_lock (&uaria2->thread_lock); + g_cond_signal (&uaria2->thread_cond); + g_mutex_unlock (&uaria2->thread_lock); } UgJsonrpcObject* uget_aria2_respond (UgetAria2* uaria2, UgJsonrpcObject* request) diff --git a/uget/UgetAria2.h b/uget/UgetAria2.h index e7f6832..fac5e80 100644 --- a/uget/UgetAria2.h +++ b/uget/UgetAria2.h @@ -37,6 +37,8 @@ #ifndef UGET_ARIA2_H #define UGET_ARIA2_H +#include + #include #include #include @@ -59,8 +61,13 @@ struct UgetAria2 { int ref_count; - UgMutex mutex; - UgetAria2Thread* thread; + UgMutex mutex; + UgetAria2Thread* worker; + + GThread* thread; + GMutex thread_lock; + GCond thread_cond; + volatile gint stop; // request -> global thread -> requested + responsed // @@ -112,6 +119,7 @@ struct UgetAria2 UgetAria2* uget_aria2_new (void); void uget_aria2_ref (UgetAria2* ua2); void uget_aria2_unref (UgetAria2* ua2); +void uget_aria2_free (UgetAria2* ua2); void uget_aria2_start_thread (UgetAria2* uaria2); void uget_aria2_stop_thread (UgetAria2* uaria2); diff --git a/uglib/Android.mk b/uglib/Android.mk deleted file mode 100644 index 996910f..0000000 --- a/uglib/Android.mk +++ /dev/null @@ -1,37 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := libuglib -LOCAL_CPPFLAGS := -DNDEBUG -LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/../curl/include -LOCAL_SRC_FILES := \ - UgStdio.c \ - UgString.c \ - UgThread.c \ - UgSocket.c \ - UgUtil.c \ - UgFileUtil.c \ - UgArray.c \ - UgList.c \ - UgSLink.c \ - UgOption.c \ - UgUri.c \ - UgNode.c \ - UgData.c \ - UgInfo.c \ - UgRegistry.c \ - UgValue.c \ - UgEntry.c \ - UgBuffer.c \ - UgJson.c \ - UgJson-custom.c \ - UgJsonFile.c \ - UgJsonrpc.c \ - UgJsonrpcSocket.c \ - UgJsonrpcCurl.c \ - UgHtml.c \ - UgHtmlEntry.c \ - UgHtmlFilter.c - -include $(BUILD_STATIC_LIBRARY) diff --git a/uglib/Makefile.am b/uglib/Makefile.am deleted file mode 100644 index ec902e8..0000000 --- a/uglib/Makefile.am +++ /dev/null @@ -1,76 +0,0 @@ -## To enable LFS (Large File Support) in 32bit platform -## add `getconf LFS_CFLAGS` to CFLAGS -## add `getconf LFS_LDFLAGS` to LDFLAGS - -AUTOMAKE_OPTIONS = no-dependencies - -## static library --- - -# lib_LIBRARIES = libuglib.a -noinst_LIBRARIES = libuglib.a - -libuglib_a_CPPFLAGS = -I$(top_srcdir)/uglib -libuglib_a_CFLAGS = @PTHREAD_CFLAGS@ @LFS_CFLAGS@ @CURL_CFLAGS@ @GLIB_CFLAGS@ - -libuglib_a_SOURCES = \ - UgStdio.c \ - UgString.c \ - UgThread.c \ - UgSocket.c \ - UgUtil.c \ - UgFileUtil.c \ - UgArray.c \ - UgList.c \ - UgSLink.c \ - UgOption.c \ - UgUri.c \ - UgNode.c \ - UgData.c \ - UgInfo.c \ - UgRegistry.c \ - UgValue.c \ - UgEntry.c \ - UgBuffer.c \ - UgJson.c \ - UgJson-custom.c \ - UgJsonFile.c \ - UgJsonrpc.c \ - UgJsonrpcSocket.c \ - UgJsonrpcCurl.c \ - UgHtml.c \ - UgHtmlEntry.c \ - UgHtmlFilter.c - -noinst_HEADERS = \ - UgDefine.h \ - UgStdio.h \ - UgString.h \ - UgThread.h \ - UgSocket.h \ - UgUtil.h \ - UgFileUtil.h \ - UgArray.h \ - UgList.h \ - UgSLink.h \ - UgOption.h \ - UgUri.h \ - UgNode.h \ - UgData.h \ - UgInfo.h \ - UgRegistry.h \ - UgValue.h \ - UgEntry.h \ - UgBuffer.h \ - UgJson.h \ - UgJson-custom.h \ - UgJsonFile.h \ - UgJsonrpc.h \ - UgJsonrpcSocket.h \ - UgJsonrpcCurl.h \ - UgHtml.h \ - UgHtmlEntry.h \ - UgHtmlFilter.h - -EXTRA_DIST = \ - Android.mk \ - CMakeLists.txt diff --git a/uglib/UgJson-custom.c b/uglib/UgJson-custom.c index 5392d3f..bbeb68c 100644 --- a/uglib/UgJson-custom.c +++ b/uglib/UgJson-custom.c @@ -36,273 +36,256 @@ #if defined(_MSC_VER) #define _CRT_SECURE_NO_WARNINGS -#define strtoll _strtoi64 -#define snprintf _snprintf +#if _MSC_VER < 1800 +#define strtoll _strtoi64 +#endif +#if _MSC_VER < 1900 +#define snprintf _snprintf +#endif #endif -#include // time_t -#include // INT_MIN, INT_MAX, UINT_MAX +#include +#include // INT_MIN, INT_MAX, UINT_MAX #include -#include #include -#include +#include +#include // time_t // ---------------------------------------------------------------------------- -UgJsonError ug_json_parse_int_string(UgJson* json, - const char* name, const char* value, - void* dest, void* data) -{ -// if (json->type >= UG_JSON_OBJECT) { -// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); -// return UG_JSON_ERROR_TYPE_NOT_MATCH; -// } - - if (json->type == UG_JSON_STRING || json->type == UG_JSON_NUMBER) - *(int*) dest = strtol(value, NULL, 10); - else - return UG_JSON_ERROR_TYPE_NOT_MATCH; - return UG_JSON_ERROR_NONE; +UgJsonError ug_json_parse_int_string(UgJson *json, const char *name, + const char *value, void *dest, + void *data) { + // if (json->type >= UG_JSON_OBJECT) { + // ug_json_push(json, ug_json_parse_unknown, NULL, NULL); + // return UG_JSON_ERROR_TYPE_NOT_MATCH; + // } + + if (json->type == UG_JSON_STRING || json->type == UG_JSON_NUMBER) + *(int *)dest = strtol(value, NULL, 10); + else + return UG_JSON_ERROR_TYPE_NOT_MATCH; + return UG_JSON_ERROR_NONE; } -UgJsonError ug_json_parse_uint_string(UgJson* json, - const char* name, const char* value, - void* dest, void* data) -{ -// if (json->type >= UG_JSON_OBJECT) { -// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); -// return UG_JSON_ERROR_TYPE_NOT_MATCH; -// } - - if (json->type == UG_JSON_STRING || json->type == UG_JSON_NUMBER) - *(unsigned int*) dest = strtoul(value, NULL, 10); - else - return UG_JSON_ERROR_TYPE_NOT_MATCH; - return UG_JSON_ERROR_NONE; +UgJsonError ug_json_parse_uint_string(UgJson *json, const char *name, + const char *value, void *dest, + void *data) { + // if (json->type >= UG_JSON_OBJECT) { + // ug_json_push(json, ug_json_parse_unknown, NULL, NULL); + // return UG_JSON_ERROR_TYPE_NOT_MATCH; + // } + + if (json->type == UG_JSON_STRING || json->type == UG_JSON_NUMBER) + *(unsigned int *)dest = strtoul(value, NULL, 10); + else + return UG_JSON_ERROR_TYPE_NOT_MATCH; + return UG_JSON_ERROR_NONE; } -UgJsonError ug_json_parse_int64_string(UgJson* json, - const char* name, const char* value, - void* dest, void* data) -{ -// if (json->type >= UG_JSON_OBJECT) { -// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); -// return UG_JSON_ERROR_TYPE_NOT_MATCH; -// } - - if (json->type == UG_JSON_STRING || json->type == UG_JSON_NUMBER) - *(int64_t*) dest = strtoll(value, NULL, 10); - else - return UG_JSON_ERROR_TYPE_NOT_MATCH; - return UG_JSON_ERROR_NONE; +UgJsonError ug_json_parse_int64_string(UgJson *json, const char *name, + const char *value, void *dest, + void *data) { + // if (json->type >= UG_JSON_OBJECT) { + // ug_json_push(json, ug_json_parse_unknown, NULL, NULL); + // return UG_JSON_ERROR_TYPE_NOT_MATCH; + // } + + if (json->type == UG_JSON_STRING || json->type == UG_JSON_NUMBER) + *(int64_t *)dest = strtoll(value, NULL, 10); + else + return UG_JSON_ERROR_TYPE_NOT_MATCH; + return UG_JSON_ERROR_NONE; } -UgJsonError ug_json_parse_double_string(UgJson* json, - const char* name, const char* value, - void* dest, void* data) -{ -// if (json->type >= UG_JSON_OBJECT) { -// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); -// return UG_JSON_ERROR_TYPE_NOT_MATCH; -// } - - if (json->type == UG_JSON_STRING || json->type == UG_JSON_NUMBER) - *(double*) dest = strtod(value, NULL); - else - return UG_JSON_ERROR_TYPE_NOT_MATCH; - return UG_JSON_ERROR_NONE; +UgJsonError ug_json_parse_double_string(UgJson *json, const char *name, + const char *value, void *dest, + void *data) { + // if (json->type >= UG_JSON_OBJECT) { + // ug_json_push(json, ug_json_parse_unknown, NULL, NULL); + // return UG_JSON_ERROR_TYPE_NOT_MATCH; + // } + + if (json->type == UG_JSON_STRING || json->type == UG_JSON_NUMBER) + *(double *)dest = strtod(value, NULL); + else + return UG_JSON_ERROR_TYPE_NOT_MATCH; + return UG_JSON_ERROR_NONE; } -void ug_json_write_int_string(UgJson* json, int* value) -{ - int len; - char* buf; +void ug_json_write_int_string(UgJson *json, int *value) { + int len; + char *buf; - len = snprintf(NULL, 0, "%d", *value) + 1; - buf = ug_malloc(len); - snprintf(buf, len, "%d", *value); - ug_json_write_string(json, buf); - ug_free(buf); + len = snprintf(NULL, 0, "%d", *value) + 1; + buf = ug_malloc(len); + snprintf(buf, len, "%d", *value); + ug_json_write_string(json, buf); + ug_free(buf); } -void ug_json_write_uint_string(UgJson* json, unsigned int* value) -{ - int len; - char* buf; +void ug_json_write_uint_string(UgJson *json, unsigned int *value) { + int len; + char *buf; - len = snprintf(NULL, 0, "%u", *value) + 1; - buf = ug_malloc(len); - snprintf(buf, len, "%u", *value); - ug_json_write_string(json, buf); - ug_free(buf); + len = snprintf(NULL, 0, "%u", *value) + 1; + buf = ug_malloc(len); + snprintf(buf, len, "%u", *value); + ug_json_write_string(json, buf); + ug_free(buf); } -void ug_json_write_int64_string(UgJson* json, int64_t* value) -{ - int len; - char* buf; +void ug_json_write_int64_string(UgJson *json, int64_t *value) { + int len; + char *buf; -#if defined (_MSC_VER) || defined (__MINGW32__) - len = snprintf(NULL, 0, "%I64d", *value) + 1; - buf = ug_malloc(len); - snprintf(buf, len, "%I64d", *value); +#if defined(_MSC_VER) || defined(__MINGW32__) + len = snprintf(NULL, 0, "%I64d", *value) + 1; + buf = ug_malloc(len); + snprintf(buf, len, "%I64d", *value); #else - len = snprintf(NULL, 0, "%lld", (long long) *value) + 1; - buf = ug_malloc(len); - snprintf(buf, len, "%lld", (long long) *value); + len = snprintf(NULL, 0, "%lld", (long long)*value) + 1; + buf = ug_malloc(len); + snprintf(buf, len, "%lld", (long long)*value); #endif - ug_json_write_string(json, buf); - ug_free(buf); + ug_json_write_string(json, buf); + ug_free(buf); } -void ug_json_write_double_string(UgJson* json, double* value) -{ - int len; - char* buf; +void ug_json_write_double_string(UgJson *json, double *value) { + int len; + char *buf; - len = snprintf(NULL, 0, "%f", *value) + 1; - buf = ug_malloc(len); - snprintf(buf, len, "%f", *value); - ug_json_write_string(json, buf); - ug_free(buf); + len = snprintf(NULL, 0, "%f", *value) + 1; + buf = ug_malloc(len); + snprintf(buf, len, "%f", *value); + ug_json_write_string(json, buf); + ug_free(buf); } // ---------------------------------------------------------------------------- // parse and write JSON number for C types - uint8_t, int16_t, and int32_t -UgJsonError ug_json_parse_uint8(UgJson* json, - const char* name, const char* value, - void* dest, void* data) -{ -// if (json->type >= UG_JSON_OBJECT) { -// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); -// return UG_JSON_ERROR_TYPE_NOT_MATCH; -// } - - if (json->type != UG_JSON_NUMBER) - return UG_JSON_ERROR_TYPE_NOT_MATCH; - *(uint8_t*) dest = strtol(value, NULL, 10); - return UG_JSON_ERROR_NONE; +UgJsonError ug_json_parse_uint8(UgJson *json, const char *name, + const char *value, void *dest, void *data) { + // if (json->type >= UG_JSON_OBJECT) { + // ug_json_push(json, ug_json_parse_unknown, NULL, NULL); + // return UG_JSON_ERROR_TYPE_NOT_MATCH; + // } + + if (json->type != UG_JSON_NUMBER) + return UG_JSON_ERROR_TYPE_NOT_MATCH; + *(uint8_t *)dest = strtol(value, NULL, 10); + return UG_JSON_ERROR_NONE; } -UgJsonError ug_json_parse_int16(UgJson* json, - const char* name, const char* value, - void* dest, void* data) -{ -// if (json->type >= UG_JSON_OBJECT) { -// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); -// return UG_JSON_ERROR_TYPE_NOT_MATCH; -// } - - if (json->type != UG_JSON_NUMBER) - return UG_JSON_ERROR_TYPE_NOT_MATCH; - *(int16_t*) dest = strtol(value, NULL, 10); - return UG_JSON_ERROR_NONE; +UgJsonError ug_json_parse_int16(UgJson *json, const char *name, + const char *value, void *dest, void *data) { + // if (json->type >= UG_JSON_OBJECT) { + // ug_json_push(json, ug_json_parse_unknown, NULL, NULL); + // return UG_JSON_ERROR_TYPE_NOT_MATCH; + // } + + if (json->type != UG_JSON_NUMBER) + return UG_JSON_ERROR_TYPE_NOT_MATCH; + *(int16_t *)dest = strtol(value, NULL, 10); + return UG_JSON_ERROR_NONE; } -UgJsonError ug_json_parse_int32(UgJson* json, - const char* name, const char* value, - void* dest, void* data) -{ -// if (json->type >= UG_JSON_OBJECT) { -// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); -// return UG_JSON_ERROR_TYPE_NOT_MATCH; -// } - - if (json->type != UG_JSON_NUMBER) - return UG_JSON_ERROR_TYPE_NOT_MATCH; - *(int32_t*) dest = strtol(value, NULL, 10); - return UG_JSON_ERROR_NONE; +UgJsonError ug_json_parse_int32(UgJson *json, const char *name, + const char *value, void *dest, void *data) { + // if (json->type >= UG_JSON_OBJECT) { + // ug_json_push(json, ug_json_parse_unknown, NULL, NULL); + // return UG_JSON_ERROR_TYPE_NOT_MATCH; + // } + + if (json->type != UG_JSON_NUMBER) + return UG_JSON_ERROR_TYPE_NOT_MATCH; + *(int32_t *)dest = strtol(value, NULL, 10); + return UG_JSON_ERROR_NONE; } -void ug_json_write_uint8(UgJson* json, uint8_t* value) -{ - ug_json_write_int(json, *(uint8_t*)value); +void ug_json_write_uint8(UgJson *json, uint8_t *value) { + ug_json_write_int(json, *(uint8_t *)value); } -void ug_json_write_int16(UgJson* json, int16_t* value) -{ - ug_json_write_int(json, *(int16_t*)value); +void ug_json_write_int16(UgJson *json, int16_t *value) { + ug_json_write_int(json, *(int16_t *)value); } -void ug_json_write_int32(UgJson* json, int32_t* value) -{ - ug_json_write_int(json, *(int32_t*)value); +void ug_json_write_int32(UgJson *json, int32_t *value) { + ug_json_write_int(json, *(int32_t *)value); } // ---------------------------------------------------------------------------- // parse string "true" and "false" to integer (boolean). // write integer (boolean) to string "true" and "false". -UgJsonError ug_json_parse_bool_string(UgJson* json, - const char* name, const char* value, - void* dest, void* data) -{ -// if (json->type >= UG_JSON_OBJECT) { -// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); -// return UG_JSON_ERROR_TYPE_NOT_MATCH; -// } - - switch (json->type) { - case UG_JSON_TRUE: - *(int*) dest = TRUE; - break; - - case UG_JSON_FALSE: - *(int*) dest = FALSE; - break; - -// case UG_JSON_NUMBER: -// if (strtol(value, NULL, 10) == 0) -// *(int*) dest = FALSE; -// else -// *(int*) dest = TRUE; -// break; - - case UG_JSON_STRING: - if (strcmp(value, "true") == 0) - *(int*) dest = TRUE; - else if (strcmp(value, "false") == 0) - *(int*) dest = FALSE; - break; - - default: - return UG_JSON_ERROR_TYPE_NOT_MATCH; - } - return UG_JSON_ERROR_NONE; +UgJsonError ug_json_parse_bool_string(UgJson *json, const char *name, + const char *value, void *dest, + void *data) { + // if (json->type >= UG_JSON_OBJECT) { + // ug_json_push(json, ug_json_parse_unknown, NULL, NULL); + // return UG_JSON_ERROR_TYPE_NOT_MATCH; + // } + + switch (json->type) { + case UG_JSON_TRUE: + *(int *)dest = TRUE; + break; + + case UG_JSON_FALSE: + *(int *)dest = FALSE; + break; + + // case UG_JSON_NUMBER: + // if (strtol(value, NULL, 10) == 0) + // *(int*) dest = FALSE; + // else + // *(int*) dest = TRUE; + // break; + + case UG_JSON_STRING: + if (strcmp(value, "true") == 0) + *(int *)dest = TRUE; + else if (strcmp(value, "false") == 0) + *(int *)dest = FALSE; + break; + + default: + return UG_JSON_ERROR_TYPE_NOT_MATCH; + } + return UG_JSON_ERROR_NONE; } -void ug_json_write_bool_string(UgJson* json, int* value) -{ - if (*value == FALSE) - ug_json_write_string(json, "false"); - else - ug_json_write_string(json, "true"); +void ug_json_write_bool_string(UgJson *json, int *value) { + if (*value == FALSE) + ug_json_write_string(json, "false"); + else + ug_json_write_string(json, "true"); } // ---------------------------------------------------------------------------- // UgJsonParseFunc and UgJsonWriteFunc for time_t -UgJsonError ug_json_parse_time_t(UgJson* json, - const char* name, const char* value, - void* dest, void* none) -{ +UgJsonError ug_json_parse_time_t(UgJson *json, const char *name, + const char *value, void *dest, void *none) { #if 1 - if (json->type != UG_JSON_NUMBER) - return UG_JSON_ERROR_TYPE_NOT_MATCH; - *(time_t*) dest = strtoll(value, NULL, 10); - return UG_JSON_ERROR_NONE; + if (json->type != UG_JSON_NUMBER) + return UG_JSON_ERROR_TYPE_NOT_MATCH; + *(time_t *)dest = strtoll(value, NULL, 10); + return UG_JSON_ERROR_NONE; #else - struct tm timem; + struct tm timem; - timem.tm_year = year - 1900; - timem.tm_mon = month - 1; - timem.tm_mday = day; - timem.tm_hour = hour; - timem.tm_min = minute; - timem.tm_sec) = second; - timem.tm_isdst = 0; - *(time_t*) dest = mktime(timem); + timem.tm_year = year - 1900; + timem.tm_mon = month - 1; + timem.tm_mday = day; + timem.tm_hour = hour; + timem.tm_min = minute; + timem.tm_sec) = second; + timem.tm_isdst = 0; + *(time_t *)dest = mktime(timem); // if (json->type >= UG_JSON_OBJECT) { // ug_json_push(json, ug_json_parse_unknown, NULL, NULL); @@ -311,26 +294,21 @@ UgJsonError ug_json_parse_time_t(UgJson* json, #endif } -void ug_json_write_time_t(UgJson* json, void* data) -{ +void ug_json_write_time_t(UgJson *json, void *data) { #if 1 - ug_json_write_int64(json, *(time_t*) data); + ug_json_write_int64(json, *(time_t *)data); #else - struct tm* timem; - char* timestr; - - timem = gmtime((time_t*) dest); // localtime((time_t*) dest); - timestr = ug_malloc(32); - // output format : "2013-02-05 21:25:15" - snprintf(timestr, 32, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", - timem->tm_year + 1900, - timem->tm_mon + 1, - timem->tm_mday, - timem->tm_hour, - timem->tm_min, - timem->tm_sec); - ug_json_write_string(json, timestr); - ug_free(timestr); + struct tm *timem; + char *timestr; + + timem = gmtime((time_t *)dest); // localtime((time_t*) dest); + timestr = ug_malloc(32); + // output format : "2013-02-05 21:25:15" + snprintf(timestr, 32, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", timem->tm_year + 1900, + timem->tm_mon + 1, timem->tm_mday, timem->tm_hour, timem->tm_min, + timem->tm_sec); + ug_json_write_string(json, timestr); + ug_free(timestr); #endif } @@ -343,135 +321,131 @@ void ug_json_write_time_t(UgJson* json, void* data) // ug_json_end_parse(json); enum { - PARSER_STACK_BASE, // 0 - PARSER_STACK_TYPE, // 1 - PARSER_STACK_DATA2, // 2 - PARSER_STACK_DATA1, // 3 - PARSER_STACK_FUNC, // 4 - PARSER_STACK_UNIT = PARSER_STACK_FUNC, // equal with STACK_MULTIPLY_VALUE + PARSER_STACK_BASE, // 0 + PARSER_STACK_TYPE, // 1 + PARSER_STACK_DATA2, // 2 + PARSER_STACK_DATA1, // 3 + PARSER_STACK_FUNC, // 4 + PARSER_STACK_UNIT = PARSER_STACK_FUNC, // equal with STACK_MULTIPLY_VALUE }; // static function -static void ug_json_call_parser_value(UgJson* json, UgValue* uvalue, const char* value) -{ - UgJsonParseFunc parser; - void** stack; - char error; - int stackLen; - - // get parser and data from stack - if (json->stack.length && json->type < UG_JSON_N_TYPE) { - stackLen = json->stack.length; - stack = json->stack.at + json->stack.length; - parser = *(stack - PARSER_STACK_FUNC); - error = parser(json, - uvalue->name, - value, - *(stack - PARSER_STACK_DATA1), - *(stack - PARSER_STACK_DATA2)); - if (error) - json->error = error; - // It must push parser when getting UG_JSON_OBJECT or UG_JSON_ARRAY. - // If callback function does NOT push any parser, push default one. - if (json->type >= UG_JSON_OBJECT && stackLen == json->stack.length) - ug_json_push(json, ug_json_parse_unknown, NULL, NULL); - } - - // reset state - json->type = 0; // UG_JSON_VALUE - // reset buffer - json->buf.at[0] = 0; - json->buf.length = 1; +static void ug_json_call_parser_value(UgJson *json, UgValue *uvalue, + const char *value) { + UgJsonParseFunc parser; + void **stack; + char error; + int stackLen; + + // get parser and data from stack + if (json->stack.length && json->type < UG_JSON_N_TYPE) { + stackLen = json->stack.length; + stack = json->stack.at + json->stack.length; + parser = *(stack - PARSER_STACK_FUNC); + error = parser(json, uvalue->name, value, *(stack - PARSER_STACK_DATA1), + *(stack - PARSER_STACK_DATA2)); + if (error) + json->error = error; + // It must push parser when getting UG_JSON_OBJECT or UG_JSON_ARRAY. + // If callback function does NOT push any parser, push default one. + if (json->type >= UG_JSON_OBJECT && stackLen == json->stack.length) + ug_json_push(json, ug_json_parse_unknown, NULL, NULL); + } + + // reset state + json->type = 0; // UG_JSON_VALUE + // reset buffer + json->buf.at[0] = 0; + json->buf.length = 1; } -void ug_json_parse_by_value(UgJson* json, UgValue* value) -{ - UgValue* end; - - switch (value->type) { - case UG_VALUE_NONE: - default: - // skip this value - break; - - case UG_VALUE_OBJECT: - json->type = UG_JSON_OBJECT; - ug_json_call_parser_value(json, value, NULL); - json->scope = UG_JSON_OBJECT; - end = value->c.object->at + value->c.object->length; - for (value = value->c.object->at; value < end; value++) - ug_json_parse_by_value(json, value); - ug_json_pop(json); - break; - - case UG_VALUE_ARRAY: - json->type = UG_JSON_ARRAY; - ug_json_call_parser_value(json, value, NULL); - json->scope = UG_JSON_ARRAY; - end = value->c.array->at + value->c.array->length; - for (value = value->c.array->at; value < end; value++) - ug_json_parse_by_value(json, value); - ug_json_pop(json); - break; - - case UG_VALUE_BOOL: - if (value->c.boolean == FALSE) { - json->type = UG_JSON_FALSE; - ug_json_call_parser_value(json, value, "false"); - } - else { - json->type = UG_JSON_TRUE; - ug_json_call_parser_value(json, value, "true"); - } - break; - - case UG_VALUE_INT: - json->type = UG_JSON_NUMBER; - snprintf(json->buf.at, json->buf.allocated, "%d", value->c.integer); - ug_json_call_parser_value(json, value, json->buf.at); - break; - - case UG_VALUE_UINT: - json->type = UG_JSON_NUMBER; - snprintf(json->buf.at, json->buf.allocated, "%u", value->c.uinteger); - ug_json_call_parser_value(json, value, json->buf.at); - break; - - case UG_VALUE_INT64: - json->type = UG_JSON_NUMBER; -#if defined (_MSC_VER) || defined (__MINGW32__) - snprintf(json->buf.at, json->buf.allocated, "%I64d", value->c.integer64); +void ug_json_parse_by_value(UgJson *json, UgValue *value) { + UgValue *end; + + switch (value->type) { + case UG_VALUE_NONE: + default: + // skip this value + break; + + case UG_VALUE_OBJECT: + json->type = UG_JSON_OBJECT; + ug_json_call_parser_value(json, value, NULL); + json->scope = UG_JSON_OBJECT; + end = value->c.object->at + value->c.object->length; + for (value = value->c.object->at; value < end; value++) + ug_json_parse_by_value(json, value); + ug_json_pop(json); + break; + + case UG_VALUE_ARRAY: + json->type = UG_JSON_ARRAY; + ug_json_call_parser_value(json, value, NULL); + json->scope = UG_JSON_ARRAY; + end = value->c.array->at + value->c.array->length; + for (value = value->c.array->at; value < end; value++) + ug_json_parse_by_value(json, value); + ug_json_pop(json); + break; + + case UG_VALUE_BOOL: + if (value->c.boolean == FALSE) { + json->type = UG_JSON_FALSE; + ug_json_call_parser_value(json, value, "false"); + } else { + json->type = UG_JSON_TRUE; + ug_json_call_parser_value(json, value, "true"); + } + break; + + case UG_VALUE_INT: + json->type = UG_JSON_NUMBER; + snprintf(json->buf.at, json->buf.allocated, "%d", value->c.integer); + ug_json_call_parser_value(json, value, json->buf.at); + break; + + case UG_VALUE_UINT: + json->type = UG_JSON_NUMBER; + snprintf(json->buf.at, json->buf.allocated, "%u", value->c.uinteger); + ug_json_call_parser_value(json, value, json->buf.at); + break; + + case UG_VALUE_INT64: + json->type = UG_JSON_NUMBER; +#if defined(_MSC_VER) || defined(__MINGW32__) + snprintf(json->buf.at, json->buf.allocated, "%I64d", value->c.integer64); #else - snprintf(json->buf.at, json->buf.allocated, "%lld", (long long int) value->c.integer64); + snprintf(json->buf.at, json->buf.allocated, "%lld", + (long long int)value->c.integer64); #endif - ug_json_call_parser_value(json, value, json->buf.at); - break; + ug_json_call_parser_value(json, value, json->buf.at); + break; - case UG_VALUE_UINT64: - json->type = UG_JSON_NUMBER; -#if defined (_MSC_VER) || defined (__MINGW32__) - snprintf(json->buf.at, json->buf.allocated, "%I64u", value->c.uinteger64); + case UG_VALUE_UINT64: + json->type = UG_JSON_NUMBER; +#if defined(_MSC_VER) || defined(__MINGW32__) + snprintf(json->buf.at, json->buf.allocated, "%I64u", value->c.uinteger64); #else - snprintf(json->buf.at, json->buf.allocated, "%llu", (long long int) value->c.uinteger64 ); + snprintf(json->buf.at, json->buf.allocated, "%llu", + (long long int)value->c.uinteger64); #endif - ug_json_call_parser_value(json, value, json->buf.at); - break; - - case UG_VALUE_DOUBLE: - json->type = UG_JSON_NUMBER; - snprintf(json->buf.at, json->buf.allocated, "%f", value->c.fraction); - ug_json_call_parser_value(json, value, json->buf.at); - break; - - case UG_VALUE_STRING: - if (value->c.string == NULL) { - json->type = UG_JSON_NULL; - ug_json_call_parser_value(json, value, NULL); - } - else { - json->type = UG_JSON_STRING; - ug_json_call_parser_value(json, value, value->c.string); - } - break; - } + ug_json_call_parser_value(json, value, json->buf.at); + break; + + case UG_VALUE_DOUBLE: + json->type = UG_JSON_NUMBER; + snprintf(json->buf.at, json->buf.allocated, "%f", value->c.fraction); + ug_json_call_parser_value(json, value, json->buf.at); + break; + + case UG_VALUE_STRING: + if (value->c.string == NULL) { + json->type = UG_JSON_NULL; + ug_json_call_parser_value(json, value, NULL); + } else { + json->type = UG_JSON_STRING; + ug_json_call_parser_value(json, value, value->c.string); + } + break; + } } diff --git a/uglib/UgJsonrpc.c b/uglib/UgJsonrpc.c index 4805248..cd14624 100644 --- a/uglib/UgJsonrpc.c +++ b/uglib/UgJsonrpc.c @@ -430,7 +430,22 @@ int ug_jsonrpc_call_batch(UgJsonrpc* jrpc, jrpc->error = n; // parser --- end --- - return 0; // no error + return 0; // no error +} + +void ug_jsonrpc_array_free (UgJsonrpcArray* array) +{ + if (array == NULL) + return; + + for (int index = 0; index < array->length; ++index) { + UgJsonrpcObject* object = array->at[index]; + if (object) + ug_jsonrpc_object_free (object); + } + + ug_array_clear (array); + ug_free (array); } // ------------------------------------ diff --git a/uglib/UgJsonrpc.h b/uglib/UgJsonrpc.h index 24fbca5..a2ffb82 100644 --- a/uglib/UgJsonrpc.h +++ b/uglib/UgJsonrpc.h @@ -123,11 +123,14 @@ void ug_json_write_rpc_object(UgJson* json, UgJsonrpcObject* jrobj); //void ug_jsonrpc_array_init(UgJsonrpcArray* joarray, int allocated_len); #define ug_jsonrpc_array_init(array, allocated_len) \ - ug_array_init(array, sizeof(UgJsonrpcObject*), allocated_len) + ug_array_init(array, sizeof(UgJsonrpcObject*), allocated_len) // param free_objects: TRUE or FALSE void ug_jsonrpc_array_clear(UgJsonrpcArray* joarray, int free_objects); +// Free a batch returned by ug_jsonrpc_call_batch (frees elements + container). +void ug_jsonrpc_array_free (UgJsonrpcArray* array); + UgJsonrpcObject* ug_jsonrpc_array_find(UgJsonrpcArray* joarray, UgValue* id, int* index); UgJsonrpcObject* ug_jsonrpc_array_alloc(UgJsonrpcArray* joarray); diff --git a/uglib/UgStdio.h b/uglib/UgStdio.h index 9b2707e..bde3358 100644 --- a/uglib/UgStdio.h +++ b/uglib/UgStdio.h @@ -50,9 +50,11 @@ #ifdef _MSC_VER #define _CRT_SECURE_NO_WARNINGS +#if _MSC_VER < 1900 #ifndef snprintf #define snprintf _snprintf #endif // snprintf +#endif // _MSC_VER < 1900 #endif // _MSC_VER #ifdef HAVE_GLIB @@ -70,6 +72,10 @@ #include // for O_* flags //#include #include // for S_* mode +#ifdef HAVE_CONFIG_H +#include +#endif + #include #ifdef __cplusplus diff --git a/ui-gtk-1to2/Makefile.am b/ui-gtk-1to2/Makefile.am deleted file mode 100644 index f3da88a..0000000 --- a/ui-gtk-1to2/Makefile.am +++ /dev/null @@ -1,40 +0,0 @@ -AUTOMAKE_OPTIONS = subdir-objects no-dependencies - -bin_PROGRAMS = uget-gtk-1to2 - -uget_gtk_1to2_CPPFLAGS = \ - -DDATADIR='"$(datadir)"' \ - -I$(top_srcdir)/ui-gtk \ - -I$(top_srcdir)/uget \ - -I$(top_srcdir)/uglib - -uget_gtk_1to2_CFLAGS = \ - @GTK_CFLAGS@ - -uget_gtk_1to2_LDADD = \ - $(top_builddir)/uget/libuget.a \ - $(top_builddir)/uglib/libuglib.a \ - @GTK_LIBS@ - -uget_gtk_1to2_SOURCES = \ - UgCategory.c \ - UgData1.c \ - UgData-download.c \ - UgDataset.c \ - UgMarkup.c \ - UgRegistry1.c \ - UgSetting.c \ - Ugtk1to2.c \ - ../ui-gtk/UgtkSetting.c \ - main.c - -noinst_HEADERS = \ - UgCategory.h \ - UgData1.h \ - UgData-download.h \ - UgDataset.h \ - UgMarkup.h \ - UgRegistry1.h \ - UgSetting.h \ - Ugtk1to2.h \ - ../ui-gtk/UgtkSetting.h diff --git a/ui-gtk/Makefile.am b/ui-gtk/Makefile.am deleted file mode 100644 index 8446a34..0000000 --- a/ui-gtk/Makefile.am +++ /dev/null @@ -1,62 +0,0 @@ -bin_PROGRAMS = uget-gtk - -uget_gtk_CPPFLAGS = \ - -DUG_DATADIR='"$(datadir)"' \ - -I$(top_srcdir)/ui-gtk \ - -I$(top_srcdir)/uget \ - -I$(top_srcdir)/uglib - -uget_gtk_CFLAGS = \ - @PTHREAD_CFLAGS@ \ - @LFS_CFLAGS@ \ - @CURL_CFLAGS@ \ - @LIBGCRYPT_CFLAGS@ \ - @LIBCRYPTO_CFLAGS@ \ - @GTK_CFLAGS@ \ - @LIBNOTIFY_CFLAGS@ \ - @APP_INDICATOR_CFLAGS@ \ - @GSTREAMER_CFLAGS@ \ - @LIBPWMD_CFLAGS@ - -uget_gtk_LDFLAGS = @LFS_LDFLAGS@ - -uget_gtk_LDADD = \ - $(top_builddir)/uget/libuget.a \ - $(top_builddir)/uglib/libuglib.a \ - @PTHREAD_LIBS@ \ - @CURL_LIBS@ \ - @LIBGCRYPT_LIBS@ \ - @LIBCRYPTO_LIBS@ \ - @GTK_LIBS@ \ - @LIBNOTIFY_LIBS@ \ - @APP_INDICATOR_LIBS@ \ - @GSTREAMER_LIBS@ \ - @LIBPWMD_LIBS@ - -uget_gtk_SOURCES = \ - UgtkUtil.c UgtkConfig.c UgtkSetting.c \ - UgtkNodeList.c UgtkNodeTree.c UgtkNodeView.c \ - UgtkTraveler.c UgtkSummary.c \ - UgtkTrayIcon.c UgtkBanner.c \ - UgtkSequence.c UgtkSelector.c \ - UgtkProxyForm.c UgtkDownloadForm.c UgtkCategoryForm.c \ - UgtkNodeDialog.c UgtkBatchDialog.c \ - UgtkScheduleForm.c UgtkSettingForm.c UgtkSettingDialog.c \ - UgtkConfirmDialog.c UgtkAboutDialog.c \ - UgtkMenubar.c UgtkMenubar-ui.c \ - UgtkApp.c UgtkApp-ui.c UgtkApp-callback.c \ - UgtkApp-timeout.c UgtkApp-main.c - -noinst_HEADERS = \ - UgtkUtil.h UgtkConfig.h UgtkSetting.h \ - UgtkNodeList.h UgtkNodeTree.h UgtkNodeView.h \ - UgtkTraveler.h UgtkSummary.h \ - UgtkTrayIcon.h UgtkBanner.h \ - UgtkSequence.h UgtkSelector.h \ - UgtkProxyForm.h UgtkDownloadForm.h UgtkCategoryForm.h \ - UgtkNodeDialog.h UgtkBatchDialog.h \ - UgtkScheduleForm.h UgtkSettingForm.h UgtkSettingDialog.h \ - UgtkConfirmDialog.h UgtkAboutDialog.h \ - UgtkMenubar.h \ - UgtkApp.h - diff --git a/ui-gtk/UgtkApp.c b/ui-gtk/UgtkApp.c index a4a88f4..4a1b9a0 100644 --- a/ui-gtk/UgtkApp.c +++ b/ui-gtk/UgtkApp.c @@ -73,8 +73,10 @@ void ugtk_app_init (UgtkApp* app, UgetRpc* rpc) // plug-in initialize uget_plugin_global_set(UgetPluginCurlInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) TRUE); uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_GLOBAL_INIT, (void*) TRUE); - uget_plugin_global_set(UgetPluginMediaInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) TRUE); - uget_plugin_global_set(UgetPluginMegaInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) TRUE); + uget_plugin_global_set(UgetPluginMediaInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) TRUE); +#ifdef HAVE_MEGA + uget_plugin_global_set(UgetPluginMegaInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) TRUE); +#endif // apply UgtkSetting ugtk_app_set_plugin_setting (app, &app->setting); ugtk_app_set_window_setting (app, &app->setting); @@ -125,8 +127,10 @@ void ugtk_app_final (UgtkApp* app) (void*)(intptr_t) shutdown_now); uget_plugin_global_set(UgetPluginCurlInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) FALSE); uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_GLOBAL_INIT, (void*) FALSE); - uget_plugin_global_set(UgetPluginMediaInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) FALSE); - uget_plugin_global_set(UgetPluginMegaInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) FALSE); + uget_plugin_global_set(UgetPluginMediaInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) FALSE); +#ifdef HAVE_MEGA + uget_plugin_global_set(UgetPluginMegaInfo, UGET_PLUGIN_GLOBAL_INIT, (void*) FALSE); +#endif } void ugtk_app_save (UgtkApp* app) @@ -529,7 +533,9 @@ void ugtk_app_set_plugin_setting (UgtkApp* app, UgtkSetting* setting) uget_plugin_global_set(UgetPluginMediaInfo, UGET_PLUGIN_MEDIA_GLOBAL_TYPE, (void*)(intptr_t) setting->media.type); // set MEGA plug-in - uget_app_add_plugin ((UgetApp*) app, UgetPluginMegaInfo); +#ifdef HAVE_MEGA + uget_app_add_plugin ((UgetApp*) app, UgetPluginMegaInfo); +#endif // set aria2 plug-in if (setting->plugin_order >= UGTK_PLUGIN_ORDER_ARIA2) { uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_ARIA2_GLOBAL_URI, diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 0000000..be17ac6 --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,20 @@ +{ + "name": "uget", + "version-string": "dev", + "builtin-baseline": "594ad8871e1e8e45f8e626c015fd611163430207", + "dependencies": [ + "curl", + "glib", + "gtk", + { + "name": "libgcrypt", + "platform": "!windows | mingw" + }, + { + "name": "libgpg-error", + "platform": "!windows | mingw" + }, + "openssl", + "pkgconf" + ] +} \ No newline at end of file