diff -Nru uget-2.2.0/aclocal.m4 uget-2.2.2/aclocal.m4 --- uget-2.2.0/aclocal.m4 2018-01-08 00:05:08.000000000 +0000 +++ uget-2.2.2/aclocal.m4 2019-05-19 16:51:31.000000000 +0000 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15.1 -*- Autoconf -*- +# generated automatically by aclocal 1.16.1 -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -47,7 +47,10 @@ # # Modified to require ngettext # Matthias Clasen 08/06/2004 -# + +# Increment this whenever this file is changed. +#serial 1 + # We need this here as well, since someone might use autoconf-2.5x # to configure GLib then an older version to configure a package # using AM_GLIB_GNU_GETTEXT @@ -1071,7 +1074,7 @@ [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) ])dnl PKG_HAVE_DEFINE_WITH_MODULES -# Copyright (C) 2002-2017 Free Software Foundation, Inc. +# Copyright (C) 2002-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1083,10 +1086,10 @@ # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.15' +[am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15.1], [], +m4_if([$1], [1.16.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -1102,12 +1105,12 @@ # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15.1])dnl +[AM_AUTOMAKE_VERSION([1.16.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) -# Copyright (C) 2011-2017 Free Software Foundation, Inc. +# Copyright (C) 2011-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1169,7 +1172,7 @@ # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1221,7 +1224,7 @@ # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1252,7 +1255,7 @@ Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1443,13 +1446,12 @@ # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. - # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], @@ -1457,49 +1459,41 @@ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE([$CONFIG_FILES], + [*\'*], [eval set x "$CONFIG_FILES"], + [*], [set x $CONFIG_FILES]) shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME(["$am_mf"])` + am_filepart=`AS_BASENAME(["$am_mf"])` + AM_RUN_LOG([cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles]) || am_rc=$? done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. Try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi + AS_UNSET([am_dirpart]) + AS_UNSET([am_filepart]) + AS_UNSET([am_mf]) + AS_UNSET([am_rc]) + rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS @@ -1508,18 +1502,17 @@ # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) + [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1606,8 +1599,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. @@ -1674,7 +1667,7 @@ Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -1716,7 +1709,7 @@ done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1737,7 +1730,7 @@ fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2017 Free Software Foundation, Inc. +# Copyright (C) 2003-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1758,7 +1751,7 @@ # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1766,49 +1759,42 @@ # AM_MAKE_INCLUDE() # ----------------- -# Check to see how make treats includes. +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' +[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) + AS_CASE([$?:`cat confinc.out 2>/dev/null`], + ['0:this is the am__doit target'], + [AS_CASE([$s], + [BSD], [am__include='.include' am__quote='"'], + [am__include='include' am__quote=''])]) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT([${_am_result}]) +AC_SUBST([am__include])]) +AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1847,7 +1833,7 @@ # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1876,7 +1862,7 @@ AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1923,7 +1909,7 @@ # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1942,7 +1928,7 @@ # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2023,7 +2009,7 @@ rm -f conftest.file ]) -# Copyright (C) 2009-2017 Free Software Foundation, Inc. +# Copyright (C) 2009-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2083,7 +2069,7 @@ _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2111,7 +2097,7 @@ INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2017 Free Software Foundation, Inc. +# Copyright (C) 2006-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2130,7 +2116,7 @@ # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2017 Free Software Foundation, Inc. +# Copyright (C) 2004-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru uget-2.2.0/ar-lib uget-2.2.2/ar-lib --- uget-2.2.0/ar-lib 2017-08-15 07:25:07.000000000 +0000 +++ uget-2.2.2/ar-lib 2018-02-26 20:38:27.000000000 +0000 @@ -4,7 +4,7 @@ me=ar-lib scriptversion=2012-03-01.08; # UTC -# Copyright (C) 2010-2017 Free Software Foundation, Inc. +# Copyright (C) 2010-2018 Free Software Foundation, Inc. # Written by Peter Rosin . # # This program is free software; you can redistribute it and/or modify @@ -18,7 +18,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a diff -Nru uget-2.2.0/compile uget-2.2.2/compile --- uget-2.2.0/compile 2017-08-15 07:25:07.000000000 +0000 +++ uget-2.2.2/compile 2018-03-08 20:15:51.000000000 +0000 @@ -1,9 +1,9 @@ #! /bin/sh # Wrapper for compilers which do not understand '-c -o'. -scriptversion=2016-01-11.22; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -340,7 +340,7 @@ # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" diff -Nru uget-2.2.0/configure uget-2.2.2/configure --- uget-2.2.0/configure 2018-01-08 00:05:11.000000000 +0000 +++ uget-2.2.2/configure 2019-05-19 16:51:35.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for uget 2.2.0. +# Generated by GNU Autoconf 2.69 for uget 2.2.2. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ # Identity of this package. PACKAGE_NAME='uget' PACKAGE_TARNAME='uget' -PACKAGE_VERSION='2.2.0' -PACKAGE_STRING='uget 2.2.0' +PACKAGE_VERSION='2.2.2' +PACKAGE_STRING='uget 2.2.2' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -714,7 +714,6 @@ AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE -am__quote am__include DEPDIR OBJEXT @@ -788,7 +787,8 @@ PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR -SHELL' +SHELL +am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking @@ -1370,7 +1370,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures uget 2.2.0 to adapt to many kinds of systems. +\`configure' configures uget 2.2.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1436,7 +1436,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of uget 2.2.0:";; + short | recursive ) echo "Configuration of uget 2.2.2:";; esac cat <<\_ACEOF @@ -1571,7 +1571,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -uget configure 2.2.0 +uget configure 2.2.2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1936,7 +1936,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by uget $as_me 2.2.0, which was +It was created by uget $as_me 2.2.2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2286,7 +2286,7 @@ ## Use automake (add automake to autogen.sh) -am__api_version='1.15' +am__api_version='1.16' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do @@ -2801,7 +2801,7 @@ # Define the identity of the package. PACKAGE='uget' - VERSION='2.2.0' + VERSION='2.2.2' cat >>confdefs.h <<_ACEOF @@ -2831,8 +2831,8 @@ # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The @@ -2883,7 +2883,7 @@ Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -3751,45 +3751,45 @@ ac_config_commands="$ac_config_commands depfiles" - -am_make=${MAKE-make} -cat > confinc << 'END' +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +$as_echo "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : @@ -7138,12 +7138,12 @@ pkg_cv_LIBPWMD_CFLAGS="$LIBPWMD_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpwmd-8.0 >= 8.0.0\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libpwmd-8.0 >= 8.0.0") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpwmd-8.0 >= 8.3.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libpwmd-8.0 >= 8.3.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_LIBPWMD_CFLAGS=`$PKG_CONFIG --cflags "libpwmd-8.0 >= 8.0.0" 2>/dev/null` + pkg_cv_LIBPWMD_CFLAGS=`$PKG_CONFIG --cflags "libpwmd-8.0 >= 8.3.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -7155,12 +7155,12 @@ pkg_cv_LIBPWMD_LIBS="$LIBPWMD_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpwmd-8.0 >= 8.0.0\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libpwmd-8.0 >= 8.0.0") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpwmd-8.0 >= 8.3.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libpwmd-8.0 >= 8.3.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_LIBPWMD_LIBS=`$PKG_CONFIG --libs "libpwmd-8.0 >= 8.0.0" 2>/dev/null` + pkg_cv_LIBPWMD_LIBS=`$PKG_CONFIG --libs "libpwmd-8.0 >= 8.3.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -7181,14 +7181,14 @@ _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - LIBPWMD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libpwmd-8.0 >= 8.0.0" 2>&1` + LIBPWMD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libpwmd-8.0 >= 8.3.0" 2>&1` else - LIBPWMD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libpwmd-8.0 >= 8.0.0" 2>&1` + LIBPWMD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libpwmd-8.0 >= 8.3.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$LIBPWMD_PKG_ERRORS" >&5 - as_fn_error $? "Package requirements (libpwmd-8.0 >= 8.0.0) were not met: + as_fn_error $? "Package requirements (libpwmd-8.0 >= 8.3.0) were not met: $LIBPWMD_PKG_ERRORS @@ -7808,7 +7808,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by uget $as_me 2.2.0, which was +This file was extended by uget $as_me 2.2.2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -7874,7 +7874,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -uget config.status 2.2.0 +uget config.status 2.2.2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -7993,7 +7993,7 @@ # # INIT-COMMANDS # -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" _ACEOF @@ -8618,29 +8618,35 @@ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -8658,53 +8664,48 @@ q } s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } - /^X\(\/\/\)$/{ + /^X\/\(\/\/\)$/{ s//\1/ q } - /^X\(\/\).*/{ + /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? done + if test $am_rc -ne 0; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. Try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk } ;; "default-1":C) case "$CONFIG_FILES" in *po/Makefile.in*) diff -Nru uget-2.2.0/configure.ac uget-2.2.2/configure.ac --- uget-2.2.0/configure.ac 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/configure.ac 2019-05-19 16:50:00.000000000 +0000 @@ -1,4 +1,4 @@ -AC_INIT(uget, 2.2.0) +AC_INIT(uget, 2.2.2) ## Use automake (add automake to autogen.sh) AM_INIT_AUTOMAKE @@ -216,7 +216,7 @@ [enable_pwmd="no"] ) if test "x$enable_pwmd" = "xyes"; then - PKG_CHECK_MODULES(LIBPWMD, [libpwmd-8.0 >= 8.0.0]) + 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"]) diff -Nru uget-2.2.0/debian/changelog uget-2.2.2/debian/changelog --- uget-2.2.0/debian/changelog 2018-02-28 08:54:02.000000000 +0000 +++ uget-2.2.2/debian/changelog 2019-11-17 19:07:37.000000000 +0000 @@ -1,8 +1,33 @@ -uget (2.2.0-1build1) bionic; urgency=medium +uget (2.2.2-1ppa1~bionic1) bionic; urgency=medium - * No-change rebuild against libcurl4 + * Automated backport upload; no source changes. - -- Steve Langasek Wed, 28 Feb 2018 08:54:02 +0000 + -- Alexander Pozdnyakov Sun, 17 Nov 2019 22:07:37 +0300 + +uget (2.2.2-1) unstable; urgency=medium + + * New upstream release + + -- Alexander Pozdnyakov Tue, 11 Jun 2019 21:03:20 +0300 + +uget (2.2.1-1+nmu2) unstable; urgency=medium + + * Rebuild + + -- Alexander Pozdnyakov Fri, 21 Dec 2018 22:01:26 +0300 + +uget (2.2.1-1+nmu1) unstable; urgency=medium + + * Non-maintainer upload. + * Backports from Sid + + -- Alexander Pozdnyakov Sun, 06 May 2018 21:46:04 +0300 + +uget (2.2.1-1) unstable; urgency=medium + + * New upstream release + + -- Elías Alejandro Año Mendoza Fri, 16 Mar 2018 13:10:09 -0300 uget (2.2.0-1) unstable; urgency=medium diff -Nru uget-2.2.0/debian/compat uget-2.2.2/debian/compat --- uget-2.2.0/debian/compat 2018-01-16 14:59:02.000000000 +0000 +++ uget-2.2.2/debian/compat 2019-06-11 18:03:20.000000000 +0000 @@ -1 +1 @@ -11 +9 diff -Nru uget-2.2.0/debian/control uget-2.2.2/debian/control --- uget-2.2.0/debian/control 2018-02-28 08:54:02.000000000 +0000 +++ uget-2.2.2/debian/control 2019-06-11 18:03:20.000000000 +0000 @@ -1,19 +1,16 @@ Source: uget Section: net Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Elías Alejandro Año Mendoza -Build-Depends: debhelper (>= 11), +Maintainer: Alexander Pozdnyakov +Build-Depends: debhelper (>= 9), intltool, libnotify-dev, libgstreamer1.0-dev, libgtk-3-dev, libssl-dev, libcurl4-openssl-dev -Standards-Version: 4.1.3 +Standards-Version: 4.3.0 Homepage: http://urlget.sourceforge.net/ -Vcs-Git: https://anonscm.debian.org/git/collab-maint/uget.git -Vcs-Browser: https://anonscm.debian.org/gitweb/?p=collab-maint/uget.git Package: uget Architecture: any diff -Nru uget-2.2.0/depcomp uget-2.2.2/depcomp --- uget-2.2.0/depcomp 2017-08-15 07:25:07.000000000 +0000 +++ uget-2.2.2/depcomp 2018-03-08 20:15:51.000000000 +0000 @@ -1,9 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2016-01-11.22; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -783,7 +783,7 @@ # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" diff -Nru uget-2.2.0/doc/Makefile.in uget-2.2.2/doc/Makefile.in --- uget-2.2.0/doc/Makefile.in 2018-01-08 00:05:58.000000000 +0000 +++ uget-2.2.2/doc/Makefile.in 2019-05-19 16:51:34.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -291,8 +291,8 @@ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -310,7 +310,10 @@ cscope cscopelist: -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ diff -Nru uget-2.2.0/doc/uget.txt uget-2.2.2/doc/uget.txt --- uget-2.2.0/doc/uget.txt 2017-11-16 13:26:18.000000000 +0000 +++ uget-2.2.2/doc/uget.txt 2019-05-19 16:49:05.000000000 +0000 @@ -1,48 +1,47 @@ UgNode | - `- UgetNode (Root, Category, Download, File) + `-- UgetNode (Root, Category, Download, File) ------------------------------------------------------------------------------- UgetNode Tree chart: - Root -+- Category1 -+- Download1 (URI) -+- File - | | | - | | `- cookie or post file (attachment) - | | - | +- Download2 (URI) -+- File1 - | | (torrent path) | - | | +- File2 - | | | - | | `- torrent file (attachment) - | | - | +- Download3 (URI) -+- File - | (metalink path) | - | `- metalink file (attachment) - `-- Category2 + Root --+-- Category1 --+-- Download1 (URI) + | | + | | + | | + | `-- Download2 (URI) + | (torrent path) + | + | + `-- Category2 --+-- Download3 (URI) + | (metalink path) + | + | + `-- Download4 (URI) ------------------------------------------------------------------------------- UgetNode Tree chart for "All Category" Real node and Fake node: - Real Fake L1 Fake L2 + Real Fake L1 Fake L2 - Category0 -+ - Category1 -+--> all ------+--> all active - Category2 -+ +--> all queuing - +--> all finished - +--> all recycled + Category0 --+ + Category1 --+--> all ------+--> all active + Category2 --+ +--> all queuing + +--> all finished + `--> all recycled ------------------------------------------------------------------------------- UgetNode Tree chart for "All Status" Real node and Fake node: - Real Fake + Real Fake - Category -+--> active - +--> queuing - +--> finished - +--> recycled - | - `--> sorted + Category --+--> active + +--> queuing + +--> finished + +--> recycled + | + `--> sorted ------------------------------------------------------------------------------- @@ -50,30 +49,30 @@ Category-Home.json { - "name": "Home", "info": { "category": {}, - "common": {}, + "common": { + "name": "Home" + }, "proxy": {}, "http": {}, "ftp": {} }, "children": [ { - "name": "download-file1", - "info": { - "common": {}, - "proxy": {}, - "http": {}, - "ftp": {} - }, - "children": [ - ] - }, - { - "name": "download-file2", "info": { - "common": {}, + "common": { + "name": "download-file1", + "file": "download-file1.torrent" + }, + "files": { + "collection" : [ + { + "name": "download-file1.zip", + "type": 0 + } + ] + } "proxy": {}, "http": {}, "ftp": {} @@ -82,9 +81,11 @@ ] }, { - "name": "download-file3", "info": { - "common": {}, + "common": { + "name": "download-file3", + "file": "download-file3.7z" + }, "proxy": {}, "http": {}, "ftp": {} diff -Nru uget-2.2.0/install-sh uget-2.2.2/install-sh --- uget-2.2.0/install-sh 2017-08-15 07:25:07.000000000 +0000 +++ uget-2.2.2/install-sh 2018-03-11 21:18:51.000000000 +0000 @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2016-01-11.22; # UTC +scriptversion=2018-03-11.20; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -271,15 +271,18 @@ fi dst=$dst_arg - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. + # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst - dst=$dstdir/`basename "$src"` + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac dstdir_status=0 else dstdir=`dirname "$dst"` @@ -288,6 +291,11 @@ fi fi + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + obsolete_mkdir_used=false if test $dstdir_status != 0; then @@ -324,34 +332,43 @@ # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) + # Note that $RANDOM variable is not portable (e.g. dash); Use it + # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p' feature. if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi - rmdir "$tmpdir/d" "$tmpdir" + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac;; @@ -427,8 +444,8 @@ else # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 @@ -493,7 +510,7 @@ done # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" diff -Nru uget-2.2.0/Makefile.in uget-2.2.2/Makefile.in --- uget-2.2.0/Makefile.in 2018-01-08 00:05:58.000000000 +0000 +++ uget-2.2.2/Makefile.in 2019-05-19 16:51:33.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -164,7 +164,7 @@ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - cscope distdir dist dist-all distcheck + cscope distdir distdir-am dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, @@ -423,8 +423,8 @@ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -578,7 +578,10 @@ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ diff -Nru uget-2.2.0/missing uget-2.2.2/missing --- uget-2.2.0/missing 2017-08-15 07:25:07.000000000 +0000 +++ uget-2.2.2/missing 2018-03-08 20:15:51.000000000 +0000 @@ -1,9 +1,9 @@ #! /bin/sh # Common wrapper for a few potentially missing GNU programs. -scriptversion=2016-01-11.22; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -101,9 +101,9 @@ exit $st fi -perl_URL=http://www.perl.org/ -flex_URL=http://flex.sourceforge.net/ -gnu_software_URL=http://www.gnu.org/software +perl_URL=https://www.perl.org/ +flex_URL=https://github.com/westes/flex +gnu_software_URL=https://www.gnu.org/software program_details () { @@ -207,7 +207,7 @@ exit $st # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" diff -Nru uget-2.2.0/pixmaps/Makefile.in uget-2.2.2/pixmaps/Makefile.in --- uget-2.2.0/pixmaps/Makefile.in 2018-01-08 00:05:58.000000000 +0000 +++ uget-2.2.2/pixmaps/Makefile.in 2019-05-19 16:51:34.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -364,8 +364,8 @@ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -428,7 +428,10 @@ cscope cscopelist: -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ diff -Nru uget-2.2.0/po/ar.po uget-2.2.2/po/ar.po --- uget-2.2.0/po/ar.po 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/po/ar.po 2019-05-19 16:49:05.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # ABDULSALAM Arromaih , 2016 # ahmad , 2013 @@ -343,7 +343,7 @@ msgstr "حدث خطأ" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "حدث خطأ أثناء التنزيل." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/be.po uget-2.2.2/po/be.po --- uget-2.2.0/po/be.po 2017-11-16 13:26:19.000000000 +0000 +++ uget-2.2.2/po/be.po 2019-05-19 16:49:05.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Mihail Varantsou , 2011 msgid "" @@ -338,7 +338,7 @@ msgstr "Узнікла памылка" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Падчас сцягвання ўзнікла памылка." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/bg.po uget-2.2.2/po/bg.po --- uget-2.2.0/po/bg.po 2017-11-16 13:26:18.000000000 +0000 +++ uget-2.2.2/po/bg.po 2019-05-19 16:49:05.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Atanas Kovachki , 2014 msgid "" @@ -338,7 +338,7 @@ msgstr "" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "" #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/bn_BD.po uget-2.2.2/po/bn_BD.po --- uget-2.2.0/po/bn_BD.po 2017-11-16 13:26:19.000000000 +0000 +++ uget-2.2.2/po/bn_BD.po 2019-05-19 16:49:05.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Nazir Ahmed Sabbir , 2015 # Reazul Iqbal , 2015,2017 @@ -340,7 +340,7 @@ msgstr "" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "" #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/ca.po uget-2.2.2/po/ca.po --- uget-2.2.0/po/ca.po 2017-11-16 13:26:19.000000000 +0000 +++ uget-2.2.2/po/ca.po 2019-05-19 16:49:05.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # dsabadell , 2015 msgid "" @@ -338,7 +338,7 @@ msgstr "S'ha produït un error" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "S'ha produït un error mentre descarregava." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/cs.po uget-2.2.2/po/cs.po --- uget-2.2.0/po/cs.po 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/po/cs.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Alois Nešpor , 2014 # Radoslav Klein , 2017 @@ -342,7 +342,7 @@ msgstr "Vyskytla se chyba" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Vyskytla se chyba během stahování." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/da.po uget-2.2.2/po/da.po --- uget-2.2.0/po/da.po 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/po/da.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Filip Kemuel Dam Bartholdy , 2013,2016 # scootergrisen, 2017 @@ -339,7 +339,7 @@ msgstr "Der opstod fejl" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Der opstod fejl under download." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/de.po uget-2.2.2/po/de.po --- uget-2.2.0/po/de.po 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/po/de.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Michael Tunnell , 2013 # Tobias Bannert , 2016-2017 @@ -339,7 +339,7 @@ msgstr "Fehler aufgetreten" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Es ist ein Fehler beim Herunterladen aufgetreten." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/es.po uget-2.2.2/po/es.po --- uget-2.2.0/po/es.po 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/po/es.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Alejo_K , 2015 # Alejo_K , 2016 @@ -341,7 +341,7 @@ msgstr "Se ha producido un error" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Se ha producido un error al descargar." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/fa.po uget-2.2.2/po/fa.po --- uget-2.2.0/po/fa.po 2017-11-16 13:26:18.000000000 +0000 +++ uget-2.2.2/po/fa.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Ali 4129 , 2016 # amin hosseinzadeh fardnia , 2015 @@ -342,7 +342,7 @@ msgstr "ارور رخ داد" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "هنگام دانلود ارور رخ داد." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/fr.po uget-2.2.2/po/fr.po --- uget-2.2.0/po/fr.po 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/po/fr.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Nicolas Cuffia , 2016 # Patrice LACOUTURE , 2017 @@ -340,7 +340,7 @@ msgstr "Une erreur est survenue" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Une erreur est survenue lors du téléchargement." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/he.po uget-2.2.2/po/he.po --- uget-2.2.0/po/he.po 2017-11-16 13:26:19.000000000 +0000 +++ uget-2.2.2/po/he.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Arthur Zamarin , 2014 msgid "" @@ -338,7 +338,7 @@ msgstr "" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "" #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/hr.po uget-2.2.2/po/hr.po --- uget-2.2.0/po/hr.po 2017-11-16 13:26:19.000000000 +0000 +++ uget-2.2.2/po/hr.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # gogo , 2015 msgid "" @@ -338,7 +338,7 @@ msgstr "Nastala je greška" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Nastala je greška pri preuzimanju." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/hu.po uget-2.2.2/po/hu.po --- uget-2.2.0/po/hu.po 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/po/hu.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,15 +1,15 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: -# Balzamon, 2016-2017 +# Balzamon, 2016-2018 msgid "" msgstr "" "Project-Id-Version: uGet\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-06-03 03:10+0800\n" -"PO-Revision-Date: 2017-10-11 14:43+0000\n" +"PO-Revision-Date: 2018-02-06 10:03+0000\n" "Last-Translator: Balzamon\n" "Language-Team: Hungarian (http://www.transifex.com/uget/uget/language/hu/)\n" "MIME-Version: 1.0\n" @@ -136,7 +136,7 @@ #. UGET_EVENT_ERROR_UNSUPPORTED_FILE #: ../../po/../uget/UgetEvent.c:93 msgid "post file not found." -msgstr "" +msgstr "post fájl nem található" #. UGET_EVENT_ERROR_POST_FILE_NOT_FOUND #: ../../po/../uget/UgetEvent.c:94 @@ -149,11 +149,11 @@ #: ../../po/../uget/UgetMedia-youtube.c:288 msgid "Error occurred during getting video info." -msgstr "" +msgstr "Hiba történt a video info beszerzésekor." #: ../../po/../uget/UgetMedia-youtube.c:534 msgid "Error occurred during getting video web page." -msgstr "" +msgstr "Hiba történt a videó weboldalának betöltésekor." #: ../../po/../uget/UgetMedia-youtube.c:606 msgid "No video_id found in URL of YouTube." @@ -289,7 +289,7 @@ #: ../../po/../uget/UgetPluginMedia.c:489 msgid "Failed to get media link." -msgstr "" +msgstr "A media link nem nyitható meg." #: ../../po/../uget/UgetPluginMedia.c:505 msgid "No matched media." @@ -338,7 +338,7 @@ msgstr "Hiba történt" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Hiba történt a letöltéskor." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/id.po uget-2.2.2/po/id.po --- uget-2.2.0/po/id.po 2017-11-16 13:26:19.000000000 +0000 +++ uget-2.2.2/po/id.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # benny , 2013 # Hasan Al Banna, 2014 @@ -345,7 +345,7 @@ msgstr "Galat Terjadi" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Galat Terjadi ketika sedang mengunduh." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/it.po uget-2.2.2/po/it.po --- uget-2.2.0/po/it.po 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/po/it.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,18 +1,19 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # bovirus , 2013 # Giuseppe Pignataro (Fasbyte01) , 2017 +# Martino Mensio , 2018 # tomberry , 2015 msgid "" msgstr "" "Project-Id-Version: uGet\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-06-03 03:10+0800\n" -"PO-Revision-Date: 2017-09-22 23:51+0000\n" -"Last-Translator: Giuseppe Pignataro (Fasbyte01) \n" +"PO-Revision-Date: 2018-01-15 22:05+0000\n" +"Last-Translator: Martino Mensio \n" "Language-Team: Italian (http://www.transifex.com/uget/uget/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -28,7 +29,7 @@ "While attempting an SSH connection to %s there was a problem verifying it's hostkey against the known and trusted hosts file because it's hostkey was not found.\n" "\n" "Would you like to treat this connection as trusted for this and future connections by adding %s's hostkey to the known hosts file?" -msgstr "" +msgstr "Demone di gestione delle password: uget\n\nNel tentativo di connessione SSH a %s c'è stato un problema nella verifica della chiave del rispettivo host considerando il file degli host conosciuti e fidati perché la sua chiave host non è stata trovata.\n\nVuoi considerare questa connessione come fidata per questa e le future connessioni aggiungendo la chiave host di %s al file di host conosciuti?" #: ../../po/../uget/UgetApp.c:103 msgid "All Category" @@ -340,7 +341,7 @@ msgstr "Si è verificato un errroe" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Errore durante il download." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 @@ -537,7 +538,7 @@ #: ../../po/../ui-gtk/UgtkApp.c:1600 msgid "Plain text file" -msgstr "" +msgstr "File di solo testo" #: ../../po/../ui-gtk/UgtkApp.c:1612 msgid "Export URLs to text file" @@ -649,7 +650,7 @@ #: ../../po/../ui-gtk/UgtkConfirmDialog.c:70 msgid "Are you sure you want to delete files?" -msgstr "Confermi la cancellazione deii file?" +msgstr "Confermi la cancellazione dei file?" #: ../../po/../ui-gtk/UgtkConfirmDialog.c:74 msgid "Really delete category?" diff -Nru uget-2.2.0/po/ja.po uget-2.2.2/po/ja.po --- uget-2.2.0/po/ja.po 2017-11-16 13:26:19.000000000 +0000 +++ uget-2.2.2/po/ja.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Naofumi , 2017 msgid "" @@ -338,7 +338,7 @@ msgstr "エラーが発生しました" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "ダウンロード中にエラーが発生しました。" #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/ka_GE.po uget-2.2.2/po/ka_GE.po --- uget-2.2.0/po/ka_GE.po 2017-11-16 13:26:18.000000000 +0000 +++ uget-2.2.2/po/ka_GE.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Giorgi Maghlakelidze , 2013 msgid "" @@ -338,7 +338,7 @@ msgstr "" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "" #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/kk.po uget-2.2.2/po/kk.po --- uget-2.2.0/po/kk.po 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/po/kk.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Baurzhan Muftakhidinov , 2016 msgid "" @@ -338,7 +338,7 @@ msgstr "Қате орын алды" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Жүктеп алу қатесі." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/ku.po uget-2.2.2/po/ku.po --- uget-2.2.0/po/ku.po 2017-11-16 13:26:18.000000000 +0000 +++ uget-2.2.2/po/ku.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Haval Abdulkarim , 2015 # muhamad osman muhamad , 2014 @@ -339,7 +339,7 @@ msgstr "" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "" #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/lt.po uget-2.2.2/po/lt.po --- uget-2.2.0/po/lt.po 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/po/lt.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Moo, 2017 msgid "" @@ -338,7 +338,7 @@ msgstr "Įvyko klaida" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Atsiunčiant, įvyko klaida." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/or_IN.po uget-2.2.2/po/or_IN.po --- uget-2.2.0/po/or_IN.po 2017-11-16 13:26:20.000000000 +0000 +++ uget-2.2.2/po/or_IN.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: msgid "" msgstr "" @@ -337,7 +337,7 @@ msgstr "" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "" #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/pl.po uget-2.2.2/po/pl.po --- uget-2.2.0/po/pl.po 2017-11-16 13:26:20.000000000 +0000 +++ uget-2.2.2/po/pl.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Artur Frącek , 2013 # div off , 2016-2017 @@ -342,7 +342,7 @@ msgstr "Wystąpił błąd." #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Wystąpił błąd podczas pobierania." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/pt_BR.po uget-2.2.2/po/pt_BR.po --- uget-2.2.0/po/pt_BR.po 2017-11-16 13:26:19.000000000 +0000 +++ uget-2.2.2/po/pt_BR.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # carlo giusepe tadei valente sasaki , 2014,2016 # Rafael Fontenelle , 2013 @@ -339,7 +339,7 @@ msgstr "Ocorreu um erro" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Ocorreu um erro ao baixar." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/ro.po uget-2.2.2/po/ro.po --- uget-2.2.0/po/ro.po 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/po/ro.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Nicolae Crefelean, 2017 # Remus-Gabriel Chelu , 2016 @@ -339,7 +339,7 @@ msgstr "" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "" #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/ru.po uget-2.2.2/po/ru.po --- uget-2.2.0/po/ru.po 2017-11-16 13:26:19.000000000 +0000 +++ uget-2.2.2/po/ru.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Anton Shcherbina , 2016 # Paul Zercy , 2013 @@ -342,7 +342,7 @@ msgstr "Произошла ошибка" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Произошла ошибка при загрузке." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/sk_SK.po uget-2.2.2/po/sk_SK.po --- uget-2.2.0/po/sk_SK.po 2017-11-16 13:26:19.000000000 +0000 +++ uget-2.2.2/po/sk_SK.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # pyler , 2014 msgid "" @@ -338,7 +338,7 @@ msgstr "Vyskytla sa chyba" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Vyskytla sa chyba pri sťahovaní." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/sr@latin.po uget-2.2.2/po/sr@latin.po --- uget-2.2.0/po/sr@latin.po 2017-11-16 13:26:20.000000000 +0000 +++ uget-2.2.2/po/sr@latin.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # markosm , 2014 msgid "" @@ -338,7 +338,7 @@ msgstr "Dogodila se greška" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Dogodila se greška kod preuzimanja." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/sr.po uget-2.2.2/po/sr.po --- uget-2.2.0/po/sr.po 2017-11-16 13:26:19.000000000 +0000 +++ uget-2.2.2/po/sr.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # markosm , 2016 # markosm , 2014 @@ -339,7 +339,7 @@ msgstr "Догодила се грешка" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Догодила се грешка код преузимања." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/sv.po uget-2.2.2/po/sv.po --- uget-2.2.0/po/sv.po 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/po/sv.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Patrik Nilsson , 2017 msgid "" @@ -338,7 +338,7 @@ msgstr "Fel uppstod" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Fel uppstod under nedladdning." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/tr.po uget-2.2.2/po/tr.po --- uget-2.2.0/po/tr.po 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/po/tr.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Emin Tufan , 2016-2017 # yakup , 2013 @@ -339,7 +339,7 @@ msgstr "Hata Oluştu" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "İndirilirken hata oluştu." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/uk.po uget-2.2.2/po/uk.po --- uget-2.2.0/po/uk.po 2017-11-16 13:26:19.000000000 +0000 +++ uget-2.2.2/po/uk.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Oleh, 2014 # Serhij Dubyk , 2011 @@ -340,7 +340,7 @@ msgstr "Сталася помилка" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Сталася помилка при завантаженні." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/uz@Latn.po uget-2.2.2/po/uz@Latn.po --- uget-2.2.0/po/uz@Latn.po 2017-11-16 13:26:19.000000000 +0000 +++ uget-2.2.2/po/uz@Latn.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Akmal , 2015 msgid "" @@ -338,7 +338,7 @@ msgstr "Xatolik yuz berdi" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Yuklab olinayotganda xatolik yuz berdi." #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/vi.po uget-2.2.2/po/vi.po --- uget-2.2.0/po/vi.po 2017-11-16 13:26:18.000000000 +0000 +++ uget-2.2.2/po/vi.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,7 +1,7 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Tran Thai Hoa , 2015 msgid "" @@ -338,7 +338,7 @@ msgstr "Xảy ra lỗi" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "Lỗi trong khi tải" #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 diff -Nru uget-2.2.0/po/zh_CN.po uget-2.2.2/po/zh_CN.po --- uget-2.2.0/po/zh_CN.po 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/po/zh_CN.po 2019-05-19 16:49:06.000000000 +0000 @@ -1,8 +1,9 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: +# Demon Smith , 2018 # Dz Chen , 2015-2017 # jiajinming , 2014 # Tommy He , 2014 @@ -11,8 +12,8 @@ "Project-Id-Version: uGet\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-06-03 03:10+0800\n" -"PO-Revision-Date: 2017-12-22 19:28+0000\n" -"Last-Translator: Dz Chen \n" +"PO-Revision-Date: 2018-02-24 10:55+0000\n" +"Last-Translator: Demon Smith \n" "Language-Team: Chinese (China) (http://www.transifex.com/uget/uget/language/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -340,7 +341,7 @@ msgstr "发生错误" #: ../../po/../ui-gtk/UgtkApp-timeout.c:781 -msgid "Error Occurred when downloading." +msgid "Error Occurred during downloading." msgstr "下载时发生错误。" #: ../../po/../ui-gtk/UgtkApp-timeout.c:782 @@ -512,7 +513,7 @@ #. add link #: ../../po/../ui-gtk/UgtkApp.c:1485 msgid "Link " -msgstr "连结 " +msgstr "链接 " #. add image #: ../../po/../ui-gtk/UgtkApp.c:1490 @@ -674,6 +675,10 @@ msgid "Mirrors:" msgstr "镜像:" +#: ../ui-gtk/UgtkDownloadForm.c:141 +msgid "Leave blank to use default filename ..." +msgstr "留空以使用默认文件名 ..." + #. File - label #: ../../po/../ui-gtk/UgtkDownloadForm.c:146 #: ../../po/../ui-gtk/UgtkProxyForm.c:393 @@ -1005,7 +1010,7 @@ #. Download Columns - Elapsed #: ../../po/../ui-gtk/UgtkMenubar-ui.c:396 msgid "_Elapsed" -msgstr "已完成(_E)" +msgstr "已用时间(_E)" #. Download Columns - Left #: ../../po/../ui-gtk/UgtkMenubar-ui.c:401 @@ -1409,7 +1414,7 @@ #. radio "From" #: ../../po/../ui-gtk/UgtkSequence.c:85 msgid "_From:" -msgstr "从(_F):" +msgstr "来源(_F):" #. label "To" #: ../../po/../ui-gtk/UgtkSequence.c:108 @@ -1440,7 +1445,7 @@ #: ../../po/../ui-gtk/UgtkSequence.c:196 msgid "No character in 'From' or 'To' entry." -msgstr "'从'和'到'输入框为空。" +msgstr "'来源'和'到'输入框为空。" #: ../../po/../ui-gtk/UgtkSequence.c:311 msgid "Preview" diff -Nru uget-2.2.0/po/zh_TW.po uget-2.2.2/po/zh_TW.po --- uget-2.2.0/po/zh_TW.po 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/po/zh_TW.po 2019-05-19 16:49:06.000000000 +0000 @@ -347,8 +347,8 @@ msgstr "發生錯誤" #: ../ui-gtk/UgtkApp-timeout.c:780 -msgid "Error Occurred when downloading." -msgstr "下載時發生錯誤。" +msgid "Error Occurred during downloading." +msgstr "下載期間發生錯誤。" #: ../ui-gtk/UgtkApp-timeout.c:781 msgid "Download Starting" @@ -676,6 +676,10 @@ msgid "Mirrors:" msgstr "鏡像:" +#: ../ui-gtk/UgtkDownloadForm.c:141 +msgid "Leave blank to use default filename ..." +msgstr "保持空白以使用預設檔名 ..." + #. File - label #: ../ui-gtk/UgtkDownloadForm.c:146 ../ui-gtk/UgtkProxyForm.c:393 msgid "File:" diff -Nru uget-2.2.0/README uget-2.2.2/README --- uget-2.2.0/README 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/README 2019-05-19 16:50:00.000000000 +0000 @@ -1,3 +1,15 @@ +uGet 2.2.2: (2019-05-20) +1. use quicksort to sort downloads. +2. backup torrent and metalink files. +3. curl plug-in: handle duplicate files with double extensions. + +uGet 2.2.1: (2018-03-08) +1. reduce memory usage. +2. mega plug-in: completed size should not be '-1' if file size > 2G on a 32-bit system. +3. adjust speed limit independently without enabling global speed limit. +4. Fix: Can't get 1080p video from YouTube. +5. update translation files. + uGet 2.2.0: (2018-01-06) 1. mega plug-in: create new plug-in for MEGA site. 2. all plug-in: avoid crash if plug-in failed to start. diff -Nru uget-2.2.0/sounds/Makefile.in uget-2.2.2/sounds/Makefile.in --- uget-2.2.0/sounds/Makefile.in 2018-01-08 00:05:58.000000000 +0000 +++ uget-2.2.2/sounds/Makefile.in 2019-05-19 16:51:34.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -318,8 +318,8 @@ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -358,7 +358,10 @@ cscope cscopelist: -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ diff -Nru uget-2.2.0/tests/Makefile.in uget-2.2.2/tests/Makefile.in --- uget-2.2.0/tests/Makefile.in 2018-01-08 00:05:58.000000000 +0000 +++ uget-2.2.2/tests/Makefile.in 2019-05-19 16:51:34.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -142,7 +142,11 @@ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/test-info.Po \ + ./$(DEPDIR)/test-json.Po ./$(DEPDIR)/test-jsonrpc.Po \ + ./$(DEPDIR)/test-uget.Po ./$(DEPDIR)/test-uglib.Po \ + ./$(DEPDIR)/test_plugin_app-test-plugin+app.Po am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -391,8 +395,8 @@ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -437,12 +441,18 @@ distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-info.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-json.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-jsonrpc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-uget.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-uglib.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_plugin_app-test-plugin+app.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-info.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-json.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-jsonrpc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-uget.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-uglib.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_plugin_app-test-plugin+app.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -524,7 +534,10 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -593,7 +606,12 @@ clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/test-info.Po + -rm -f ./$(DEPDIR)/test-json.Po + -rm -f ./$(DEPDIR)/test-jsonrpc.Po + -rm -f ./$(DEPDIR)/test-uget.Po + -rm -f ./$(DEPDIR)/test-uglib.Po + -rm -f ./$(DEPDIR)/test_plugin_app-test-plugin+app.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -639,7 +657,12 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/test-info.Po + -rm -f ./$(DEPDIR)/test-json.Po + -rm -f ./$(DEPDIR)/test-jsonrpc.Po + -rm -f ./$(DEPDIR)/test-uget.Po + -rm -f ./$(DEPDIR)/test-uglib.Po + -rm -f ./$(DEPDIR)/test_plugin_app-test-plugin+app.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -659,18 +682,18 @@ .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \ - distclean-compile distclean-generic distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-noinstPROGRAMS cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am .PRECIOUS: Makefile diff -Nru uget-2.2.0/tests/test-info.c uget-2.2.2/tests/test-info.c --- uget-2.2.0/tests/test-info.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/tests/test-info.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -53,23 +53,23 @@ const UgEntry Test1Entry[] = { - {"type", offsetof (Test1, type), UG_ENTRY_INT, NULL, NULL}, + {"type", offsetof(Test1, type), UG_ENTRY_INT, NULL, NULL}, {NULL} }; -void test1_init (Test1* t1); +void test1_init(Test1* t1); const UgDataInfo Test1Info = { "Test1", - sizeof (Test1), - Test1Entry, // UgEntry + sizeof(Test1), (UgInitFunc) test1_init, (UgFinalFunc) NULL, - (UgAssignFunc) NULL + (UgAssignFunc) NULL, + Test1Entry, // UgEntry }; -void test1_init (Test1* t1) +void test1_init(Test1* t1) { t1->info = &Test1Info; t1->type = 1; @@ -88,23 +88,23 @@ const UgEntry Test2Entry[] = { - {"type", offsetof (Test2, type), UG_ENTRY_INT, NULL, NULL}, + {"type", offsetof(Test2, type), UG_ENTRY_INT, NULL, NULL}, {NULL} }; -void test2_init (Test2* t2); +void test2_init(Test2* t2); const UgDataInfo Test2Info = { "Test2", - sizeof (Test2), - Test2Entry, // UgEntry + sizeof(Test2), (UgInitFunc) test2_init, (UgFinalFunc) NULL, - (UgAssignFunc) NULL + (UgAssignFunc) NULL, + Test2Entry, // UgEntry }; -void test2_init (Test2* t2) +void test2_init(Test2* t2) { t2->info = &Test2Info; t2->type = 2; @@ -123,23 +123,23 @@ const UgEntry Test3Entry[] = { - {"type", offsetof (Test3, type), UG_ENTRY_INT, NULL, NULL}, + {"type", offsetof(Test3, type), UG_ENTRY_INT, NULL, NULL}, {NULL} }; -void test3_init (Test3* t3); +void test3_init(Test3* t3); const UgDataInfo Test3Info = { "Test3", - sizeof (Test3), - Test3Entry, // UgEntry + sizeof(Test3), (UgInitFunc) test3_init, (UgFinalFunc) NULL, - (UgAssignFunc) NULL + (UgAssignFunc) NULL, + Test3Entry, // UgEntry }; -void test3_init (Test3* t3) +void test3_init(Test3* t3) { t3->info = &Test3Info; t3->type = 3; @@ -154,20 +154,20 @@ {NULL} }; -void test_info (UgInfo* info) +void test_info(UgInfo* info) { void* data; - puts ("\n--- test_info:"); - data = ug_info_realloc (info, &Test2Info); - printf ("ug_info_realloc (Test2Info) : %d\n", ((Test2*)data)->type); - data = ug_info_realloc (info, &Test1Info); - printf ("ug_info_realloc (Test1Info) : %d\n", ((Test1*)data)->type); - data = ug_info_realloc (info, &Test3Info); - printf ("ug_info_realloc (Test3Info) : %d\n", ((Test3*)data)->type); + puts("\n--- test_info:"); + data = ug_info_realloc(info, &Test2Info); + printf("ug_info_realloc (Test2Info) : %d\n", ((Test2*)data)->type); + data = ug_info_realloc(info, &Test1Info); + printf("ug_info_realloc (Test1Info) : %d\n", ((Test1*)data)->type); + data = ug_info_realloc(info, &Test3Info); + printf("ug_info_realloc (Test3Info) : %d\n", ((Test3*)data)->type); } -void parse_info (UgInfo* info) +void parse_info(UgInfo* info) { int code; UgJson json; @@ -187,107 +187,107 @@ }; // UgRegistry is used by ug_json_parse_info() and ug_json_parse_info_entry() - ug_registry_init (®istry); - ug_registry_add (®istry, &Test2Info); - ug_registry_add (®istry, &Test3Info); - ug_registry_add (®istry, &Test1Info); -// ug_registry_sort (®istry); + ug_registry_init(®istry); + ug_registry_add(®istry, &Test2Info); + ug_registry_add(®istry, &Test3Info); + ug_registry_add(®istry, &Test1Info); +// ug_registry_sort(®istry); // ug_json_parse_info() must use default UgInfoKeys. - ug_info_set_registry (®istry); + ug_info_set_registry(®istry); - ug_json_init (&json); - ug_json_begin_parse (&json); + ug_json_init(&json); + ug_json_begin_parse(&json); #if 1 // method 1: use UgEntry to parse start of object - ug_json_push (&json, ug_json_parse_entry, info, InfoCustomEntry); + ug_json_push(&json, ug_json_parse_entry, info, InfoCustomEntry); #else // method 2: push ug_json_parse_info() to parse start of object - ug_json_push (&json, ug_json_parse_info, info, ®istry); + ug_json_push(&json, ug_json_parse_info, info, ®istry); #endif - code = ug_json_parse (&json, json_string, -1); - ug_json_end_parse (&json); - ug_json_final (&json); - printf ("ug_json_parse response %d\n", code); + code = ug_json_parse(&json, json_string, -1); + ug_json_end_parse(&json); + ug_json_final(&json); + printf("ug_json_parse response %d\n", code); - ug_info_set_registry (NULL); - ug_registry_final (®istry); + ug_info_set_registry(NULL); + ug_registry_final(®istry); } -void dump_info (UgInfo* info) +void dump_info(UgInfo* info) { UgPair* cur; UgPair* end; for (cur = info->at, end = info->at + info->length; cur < end; cur++) { if (cur->key == NULL) { - puts ("NULL"); + puts("NULL"); continue; } - printf ("%s", ((UgDataInfo*)cur->key)->name); + printf("%s", ((UgDataInfo*)cur->key)->name); if (cur->data) - printf (" : %d", ((Test1*)cur->data)->type); - puts (""); + printf(" : %d", ((Test1*)cur->data)->type); + puts(""); } } // UgBufferFunc -static int buffer_to_file (UgBuffer* buffer) +static int buffer_to_file(UgBuffer* buffer) { FILE* file = buffer->data; - printf ("write %d bytes to file\n", ug_buffer_length (buffer)); - fwrite (buffer->beg, 1, ug_buffer_length(buffer), file); + printf("write %d bytes to file\n", ug_buffer_length(buffer)); + fwrite(buffer->beg, 1, ug_buffer_length(buffer), file); buffer->cur = buffer->beg; return 0; } -void write_info_to_file (UgInfo* info, char* filename) +void write_info_to_file(UgInfo* info, char* filename) { UgJson json; FILE* file; UgBuffer buffer; - file = fopen (filename, "w"); - ug_buffer_init (&buffer, 128); + file = fopen(filename, "w"); + ug_buffer_init(&buffer, 128); buffer.more = buffer_to_file; buffer.data = file; - ug_json_init (&json); - ug_json_begin_write (&json, UG_JSON_FORMAT_INDENT, &buffer); + ug_json_init(&json); + ug_json_begin_write(&json, UG_JSON_FORMAT_INDENT, &buffer); #if 1 // method 1: use UgEntry to write start of object - ug_json_write_entry (&json, info, InfoCustomEntry); + ug_json_write_entry(&json, info, InfoCustomEntry); #else // method 2: call ug_json_write_object_head() to write start of object - ug_json_write_object_head (&json); - ug_json_write_info (&json, info); - ug_json_write_object_tail (&json); + ug_json_write_object_head(&json); + ug_json_write_info(&json, info); + ug_json_write_object_tail(&json); #endif - ug_json_end_write (&json); - ug_json_final (&json); + ug_json_end_write(&json); + ug_json_final(&json); - ug_buffer_clear (&buffer, 1); - fclose (file); + ug_buffer_clear(&buffer, 1); + fclose(file); } // ---------------------------------------------------------------------------- // main -int main (void) +int main(void) { UgInfo info; - puts ("\n--- test UgInfo functions:"); - ug_info_init (&info, 8, 2); + puts("\n--- test UgInfo functions:"); + ug_info_init(&info, 8, 2); #if 0 - test_info (&info); + test_info(&info); #else - parse_info (&info); + parse_info(&info); #endif - dump_info (&info); - write_info_to_file (&info, "test-info.json"); - ug_info_final (&info); + dump_info(&info); + write_info_to_file(&info, "test-info.json"); + ug_info_final(&info); return 0; } diff -Nru uget-2.2.0/tests/test-json.c uget-2.2.2/tests/test-json.c --- uget-2.2.0/tests/test-json.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/tests/test-json.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/tests/test-jsonrpc.c uget-2.2.2/tests/test-jsonrpc.c --- uget-2.2.0/tests/test-jsonrpc.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/tests/test-jsonrpc.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/tests/test-plugin+app.c uget-2.2.2/tests/test-plugin+app.c --- uget-2.2.0/tests/test-plugin+app.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/tests/test-plugin+app.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -52,73 +52,84 @@ #endif // _WIN32 || _WIN64 // ---------------------------------------------------------------------------- -// test_node +// test_download -void download_node (UgetNode* node, const UgetPluginInfo* info) +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 integer[2]; + int index; + int speed_limit[2]; char* string[5]; - plugin = uget_plugin_new (info); -// integer[0] = 1000000; -// integer[1] = 1000000; -// uget_plugin_ctrl (plugin, UGET_PLUGIN_CTRL_SPEED, integer); + speed_limit[0] = 1000000; + speed_limit[1] = 1000000; - uget_plugin_start (plugin, node); - while (uget_plugin_sync (plugin)) { - ug_sleep (1000); + 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); + 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); + uget_event_free(cur); } // progress - progress = ug_info_get (&node->info, UgetProgressInfo); + 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 (integer[0] = 0; integer[0] < 5; integer[0]++) - ug_free (string[integer[0]]); + 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 (&node->info, UgetCommonInfo); - printf ("\n" - "node->name : %s\n" - "common->uri : %s\n" - "common->file : %s\n", - node->name, common->uri, common->file); + 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 - for (node = node->children; node; node = node->next) - printf ("child node name : %s\n", node->name); + 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); + uget_plugin_unref(plugin); } -void test_node_download (void) +void test_download(void) { UgetCommon* common; UgetHttp* http; - UgetNode* node; + UgInfo* info; char* referrer; char* uri; char* mirrors; - uri = "https://mega.nz/#!MSpjBRhZ!nZBsUQCAnf71842wXuals_ftSkga3fIQypzBsKEZbmk"; + 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"; @@ -128,12 +139,12 @@ // referrer = "http://code.google.com/p/tortoisegit/wiki/Download?tm=2"; referrer = NULL; - node = uget_node_new (NULL); + info = ug_info_new(8, 0); // commom options - common = ug_info_realloc (&node->info, UgetCommonInfo); - common->uri = ug_strdup (uri); + common = ug_info_realloc(info, UgetCommonInfo); + common->uri = ug_strdup(uri); if (mirrors) - common->mirrors = ug_strdup (mirrors); + common->mirrors = ug_strdup(mirrors); // common->folder = ug_strdup ("D:\\Downloads"); // common->max_connections = 2; common->debug_level = 1; @@ -141,15 +152,15 @@ common->connect_timeout = 30; // http options - http = ug_info_realloc (&node->info, UgetHttpInfo); + http = ug_info_realloc(info, UgetHttpInfo); if (referrer) - http->referrer = ug_strdup (referrer); + http->referrer = ug_strdup(referrer); -// download_node (node, UgetPluginCurlInfo); -// download_node (node, UgetPluginAria2Info); -// download_node (node, UgetPluginMediaInfo); - download_node (node, UgetPluginMegaInfo); - uget_node_unref (node); +// download_by_plugin(info, UgetPluginCurlInfo); +// download_by_plugin(info, UgetPluginAria2Info); +// download_by_plugin(info, UgetPluginMediaInfo); + download_by_plugin(info, UgetPluginMegaInfo); + ug_info_unref(info); } // ---------------------------------------------------------------------------- @@ -160,39 +171,41 @@ const UgetPluginInfo* pinfo; pinfo = UgetPluginAria2Info; - uget_plugin_set (pinfo, UGET_PLUGIN_INIT, (void*) TRUE); - uget_plugin_set (pinfo, UGET_PLUGIN_ARIA2_URI, + 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_set (pinfo, UGET_PLUGIN_ARIA2_PATH, + uget_plugin_global_set(pinfo, UGET_PLUGIN_ARIA2_GLOBAL_PATH, "C:\\Program Files\\uGet\\bin\\aria2c.exe"); #endif - uget_plugin_set (pinfo, UGET_PLUGIN_ARIA2_ARGUMENT, + uget_plugin_global_set(pinfo, UGET_PLUGIN_ARIA2_GLOBAL_ARGUMENT, "--enable-rpc=true -D --check-certificate=false"); - uget_plugin_set (pinfo, UGET_PLUGIN_ARIA2_LAUNCH, (void*) TRUE); - uget_plugin_set (pinfo, UGET_PLUGIN_ARIA2_SHUTDOWN, (void*) TRUE); + 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_set (pinfo, UGET_PLUGIN_INIT, (void*) FALSE); + uget_plugin_global_set(pinfo, UGET_PLUGIN_GLOBAL_INIT, (void*) FALSE); ug_sleep (1000); } // ---------------------------------------------------------------------------- // test_task -void print_node_speed_limit (UgetNode** dnode, int count) +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); - 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]; + 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", @@ -213,28 +226,32 @@ // task speed control ------------------- for (count = 0; count < 7; count++) { dnode[count] = uget_node_new (NULL); - relation = ug_info_realloc (&dnode[count]->info, UgetRelationInfo); - relation->task.limit[0] = 2000; - relation->task.limit[1] = 1500; - relation->task.speed[0] = 2000 - count * 200; - relation->task.speed[1] = 1500 - count * 200; + 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; } - relation->task.limit[0] = 0; - relation->task.limit[1] = 0; uget_task_set_speed (task, 12000, 8000); - print_node_speed_limit(dnode, 7); + print_speed_limit(dnode, 7); puts ("---"); uget_task_adjust_speed (task); - print_node_speed_limit(dnode, 7); + print_speed_limit(dnode, 7); uget_task_remove_all (task); uget_task_final (task); free (task); for (count = 0; count < 7; count++) - uget_node_unref (dnode[count]); + uget_node_free (dnode[count]); } // ---------------------------------------------------------------------------- @@ -247,12 +264,12 @@ UgetCommon* common; cnode = uget_node_new (NULL); - cnode->name = ug_strdup ("Home Category"); - category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + 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 = ug_info_realloc (cnode->info, UgetCommonInfo); + common->name = ug_strdup ("Home Category"); common->max_connections = 2; uget_app_add_category (app, cnode, TRUE); @@ -269,8 +286,8 @@ char* string[2]; dnode = uget_node_new (NULL); - dnode->name = ug_strdup ("Download"); - common = ug_info_realloc (&dnode->info, UgetCommonInfo); + 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; @@ -309,7 +326,7 @@ for (count = 0; count < 7; count++) { dnode[count] = uget_node_new (NULL); - common = ug_info_realloc (&dnode[count]->info, UgetCommonInfo); + 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; @@ -361,22 +378,22 @@ int main (void) { // initialize plug-in - uget_plugin_set (UgetPluginCurlInfo, UGET_PLUGIN_INIT, (void*) TRUE); - uget_plugin_set (UgetPluginAria2Info, UGET_PLUGIN_INIT, (void*) TRUE); - uget_plugin_set (UgetPluginMediaInfo, UGET_PLUGIN_INIT, (void*) TRUE); - uget_plugin_set (UgetPluginMegaInfo, UGET_PLUGIN_INIT, (void*) TRUE); -// test_setup_plugin_aria2 (); - - test_node_download (); -// test_task (); -// test_app (); + 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_set (UgetPluginAria2Info, UGET_PLUGIN_ARIA2_SHUTDOWN_NOW, (void*) TRUE); +// uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_ARIA2_GLOBAL_SHUTDOWN_NOW, (void*) TRUE); // finalize plug-in - uget_plugin_set (UgetPluginCurlInfo, UGET_PLUGIN_INIT, (void*) FALSE); - uget_plugin_set (UgetPluginAria2Info, UGET_PLUGIN_INIT, (void*) FALSE); - uget_plugin_set (UgetPluginMediaInfo, UGET_PLUGIN_INIT, (void*) FALSE); - uget_plugin_set (UgetPluginMegaInfo, UGET_PLUGIN_INIT, (void*) FALSE); + 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; diff -Nru uget-2.2.0/tests/test-uget.c uget-2.2.2/tests/test-uget.c --- uget-2.2.0/tests/test-uget.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/tests/test-uget.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -38,6 +38,11 @@ #include #include #include + +#include +#include +#include +#include //#include #include @@ -62,18 +67,14 @@ UgetNode* newtwo; newone = uget_node_new (NULL); - newone->type = 1; uget_node_append (parent, newone); newtwo = uget_node_new (NULL); - newtwo->type = 2; uget_node_append (parent, newtwo); parent = newtwo; newone = uget_node_new (NULL); - newone->type = 3; uget_node_append (parent, newone); newtwo = uget_node_new (NULL); - newtwo->type = 4; uget_node_append (parent, newtwo); } @@ -134,7 +135,7 @@ print_fake_path (node); - uget_node_unref (node); + uget_node_free (node); } void parse_node (UgetNode* parent) @@ -459,20 +460,102 @@ uget_sequence_get_list (&useq, "http://sample/*-*-*.mp4", &list); for (link = list.head; link; link = link->next) puts (link->data); - ug_list_foreach_link (&list, (UgForeachFunc)ug_free, NULL); - ug_list_clear (&list, FALSE); + uget_sequence_clear_result(&list); puts (" --- preview ---"); uget_sequence_get_preview (&useq, "http://sample/*-*.mp4", &list); for (link = list.head; link; link = link->next) puts (link->data); - ug_list_foreach_link (&list, (UgForeachFunc)ug_free, NULL); - ug_list_clear (&list, FALSE); + uget_sequence_clear_result(&list); uget_sequence_final (&useq); } // ---------------------------------------------------------------------------- +// UgetFiles + +void test_files_json(UgetFiles* files) +{ + UgJson json; + UgBuffer buffer; + UgJsonError code; + UgetFiles* files2; + + ug_json_init(&json); + ug_buffer_init(&buffer, 4096); + + // write + ug_json_begin_write(&json, UG_JSON_FORMAT_INDENT, &buffer); + ug_json_write_object_head(&json); + ug_json_write_entry(&json, files, files->info->entry); + ug_json_write_object_tail(&json); + ug_json_end_write(&json); + ug_buffer_write_char(&buffer, '\0'); + puts("\n--- print files ---"); + puts(buffer.beg); + + files2 = ug_data_new(UgetFilesInfo); + // parse + ug_json_begin_parse(&json); + ug_json_push(&json, ug_json_parse_entry, files2, (void*)files2->info->entry); + ug_json_push(&json, ug_json_parse_object, NULL, NULL); + code = ug_json_parse(&json, buffer.beg, -1); + ug_json_end_parse(&json); + printf("\n" "parse return %d\n", code); + + // write + buffer.cur = buffer.beg; + ug_json_begin_write(&json, UG_JSON_FORMAT_INDENT, &buffer); + ug_json_write_entry(&json, files2, files2->info->entry); + ug_json_end_write(&json); + ug_buffer_write_char(&buffer, '\0'); + puts("\n--- print files2 ---"); + puts(buffer.beg); + + ug_data_free(files2); + + ug_buffer_clear(&buffer, TRUE); + ug_json_final(&json); +} + +void test_files(void) +{ + UgetFiles* files; + UgetFiles* src; + UgetFile* element; + + files = ug_data_new(UgetFilesInfo); + src = ug_data_new(UgetFilesInfo); + + element = uget_files_realloc(files, "0.mp4"); + element = uget_files_realloc(files, "1.mp4"); + element = uget_files_realloc(files, "2.mp4"); + element = uget_files_realloc(files, "xyz.mp4"); + + test_files_json(files); + + element = uget_files_realloc(src, "0.mp4"); + element = uget_files_realloc(src, "1.mp4"); + element = uget_files_realloc(src, "2.mp4"); + element = uget_files_realloc(src, "3.mp4"); + + element = uget_files_realloc(src, "foo.mp4"); + element = uget_files_realloc(src, "xxx.apk"); + + uget_files_sync(files, src); + test_files_json(files); + + element->state |= UGET_FILE_STATE_DELETED; + src->sync_count++; + + uget_files_sync(files, src); + test_files_json(files); + + ug_data_free(files); + ug_data_free(src); +} + +// ---------------------------------------------------------------------------- // main int main (void) @@ -484,7 +567,8 @@ // test_uget_curl (); // test_uget_rss (); // test_media (); - test_seq (); +// test_seq (); + test_files(); return 0; } diff -Nru uget-2.2.0/tests/test-uglib.c uget-2.2.2/tests/test-uglib.c --- uget-2.2.0/tests/test-uglib.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/tests/test-uglib.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -305,7 +305,7 @@ printf ("%.*s\n", len, base64); puts (base64); - orig = ug_base64_decode(base64, len, NULL); + orig = (char*) ug_base64_decode(base64, len, NULL); printf ("%.*s\n", len, orig); ug_free (base64); diff -Nru uget-2.2.0/uget/Android.mk uget-2.2.2/uget/Android.mk --- uget-2.2.0/uget/Android.mk 2018-01-06 06:32:35.000000000 +0000 +++ uget-2.2.2/uget/Android.mk 2019-05-19 16:49:06.000000000 +0000 @@ -12,8 +12,10 @@ UgetRpc.c \ UgetOption.c \ UgetData.c \ + UgetFiles.c \ UgetNode.c \ UgetNode-compare.c \ + UgetNode-filter.c \ UgetTask.c \ UgetHash.c \ UgetSite.c \ diff -Nru uget-2.2.0/uget/CMakeLists.txt uget-2.2.2/uget/CMakeLists.txt --- uget-2.2.0/uget/CMakeLists.txt 2018-01-06 06:32:35.000000000 +0000 +++ uget-2.2.2/uget/CMakeLists.txt 2019-05-19 16:49:06.000000000 +0000 @@ -18,8 +18,10 @@ UgetRpc.c UgetOption.c UgetData.c + UgetFiles.c UgetNode.c UgetNode-compare.c + UgetNode-filter.c UgetTask.c UgetHash.c UgetSite.c diff -Nru uget-2.2.0/uget/Makefile.am uget-2.2.2/uget/Makefile.am --- uget-2.2.0/uget/Makefile.am 2018-01-06 06:32:35.000000000 +0000 +++ uget-2.2.2/uget/Makefile.am 2019-05-19 16:49:06.000000000 +0000 @@ -16,8 +16,10 @@ UgetRpc.c \ UgetOption.c \ UgetData.c \ + UgetFiles.c \ UgetNode.c \ UgetNode-compare.c \ + UgetNode-filter.c \ UgetTask.c \ UgetHash.c \ UgetSite.c \ @@ -42,6 +44,7 @@ UgetRpc.h \ UgetOption.h \ UgetData.h \ + UgetFiles.h \ UgetNode.h \ UgetTask.h \ UgetHash.h \ diff -Nru uget-2.2.0/uget/Makefile.in uget-2.2.2/uget/Makefile.in --- uget-2.2.0/uget/Makefile.in 2018-01-08 00:05:58.000000000 +0000 +++ uget-2.2.2/uget/Makefile.in 2019-05-19 16:51:34.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,18 +110,19 @@ libuget_a_AR = $(AR) $(ARFLAGS) libuget_a_LIBADD = am__libuget_a_SOURCES_DIST = UgetSequence.c UgetRss.c UgetRpc.c \ - UgetOption.c UgetData.c UgetNode.c UgetNode-compare.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 pwmd.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 pwmd.c @WITH_LIBPWMD_TRUE@am__objects_1 = libuget_a-pwmd.$(OBJEXT) am_libuget_a_OBJECTS = libuget_a-UgetSequence.$(OBJEXT) \ libuget_a-UgetRss.$(OBJEXT) libuget_a-UgetRpc.$(OBJEXT) \ libuget_a-UgetOption.$(OBJEXT) libuget_a-UgetData.$(OBJEXT) \ - libuget_a-UgetNode.$(OBJEXT) \ + libuget_a-UgetFiles.$(OBJEXT) libuget_a-UgetNode.$(OBJEXT) \ libuget_a-UgetNode-compare.$(OBJEXT) \ + libuget_a-UgetNode-filter.$(OBJEXT) \ libuget_a-UgetTask.$(OBJEXT) libuget_a-UgetHash.$(OBJEXT) \ libuget_a-UgetSite.$(OBJEXT) libuget_a-UgetApp.$(OBJEXT) \ libuget_a-UgetEvent.$(OBJEXT) libuget_a-UgetPlugin.$(OBJEXT) \ @@ -149,7 +150,34 @@ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/libuget_a-UgetA2cf.Po \ + ./$(DEPDIR)/libuget_a-UgetApp.Po \ + ./$(DEPDIR)/libuget_a-UgetAria2.Po \ + ./$(DEPDIR)/libuget_a-UgetCurl.Po \ + ./$(DEPDIR)/libuget_a-UgetData.Po \ + ./$(DEPDIR)/libuget_a-UgetEvent.Po \ + ./$(DEPDIR)/libuget_a-UgetFiles.Po \ + ./$(DEPDIR)/libuget_a-UgetHash.Po \ + ./$(DEPDIR)/libuget_a-UgetMedia-youtube.Po \ + ./$(DEPDIR)/libuget_a-UgetMedia.Po \ + ./$(DEPDIR)/libuget_a-UgetNode-compare.Po \ + ./$(DEPDIR)/libuget_a-UgetNode-filter.Po \ + ./$(DEPDIR)/libuget_a-UgetNode.Po \ + ./$(DEPDIR)/libuget_a-UgetOption.Po \ + ./$(DEPDIR)/libuget_a-UgetPlugin.Po \ + ./$(DEPDIR)/libuget_a-UgetPluginAgent.Po \ + ./$(DEPDIR)/libuget_a-UgetPluginAria2.Po \ + ./$(DEPDIR)/libuget_a-UgetPluginCurl.Po \ + ./$(DEPDIR)/libuget_a-UgetPluginEmpty.Po \ + ./$(DEPDIR)/libuget_a-UgetPluginMedia.Po \ + ./$(DEPDIR)/libuget_a-UgetPluginMega.Po \ + ./$(DEPDIR)/libuget_a-UgetRpc.Po \ + ./$(DEPDIR)/libuget_a-UgetRss.Po \ + ./$(DEPDIR)/libuget_a-UgetSequence.Po \ + ./$(DEPDIR)/libuget_a-UgetSite.Po \ + ./$(DEPDIR)/libuget_a-UgetTask.Po \ + ./$(DEPDIR)/libuget_a-pwmd.Po am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -175,9 +203,9 @@ *) (install-info --version) >/dev/null 2>&1;; \ esac am__noinst_HEADERS_DIST = UgetSequence.h UgetRss.h UgetRpc.h \ - UgetOption.h UgetData.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 \ + 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 pwmd.h HEADERS = $(noinst_HEADERS) @@ -356,18 +384,18 @@ libuget_a_CPPFLAGS = -I$(top_srcdir)/uglib -I$(top_srcdir)/uget libuget_a_CFLAGS = @PTHREAD_CFLAGS@ @GLIB_CFLAGS@ $(am__append_1) libuget_a_SOURCES = UgetSequence.c UgetRss.c UgetRpc.c UgetOption.c \ - UgetData.c UgetNode.c UgetNode-compare.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 \ - $(am__append_2) + 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 $(am__append_2) noinst_HEADERS = UgetSequence.h UgetRss.h UgetRpc.h UgetOption.h \ - UgetData.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 $(am__append_3) + 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 $(am__append_3) EXTRA_DIST = \ Android.mk \ CMakeLists.txt @@ -393,8 +421,8 @@ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -420,31 +448,39 @@ distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetA2cf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetApp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetAria2.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetCurl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetData.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetEvent.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetHash.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetMedia-youtube.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetMedia.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetNode-compare.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetNode.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetOption.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetPlugin.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetPluginAgent.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetPluginAria2.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetPluginCurl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetPluginEmpty.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetPluginMedia.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetPluginMega.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetRpc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetRss.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetSequence.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetSite.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetTask.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-pwmd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetA2cf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetApp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetAria2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetCurl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetData.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetEvent.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetFiles.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetHash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetMedia-youtube.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetMedia.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetNode-compare.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetNode-filter.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetNode.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetOption.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetPlugin.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetPluginAgent.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetPluginAria2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetPluginCurl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetPluginEmpty.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetPluginMedia.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetPluginMega.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetRpc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetRss.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetSequence.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetSite.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-UgetTask.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuget_a-pwmd.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -530,6 +566,20 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuget_a_CPPFLAGS) $(CPPFLAGS) $(libuget_a_CFLAGS) $(CFLAGS) -c -o libuget_a-UgetData.obj `if test -f 'UgetData.c'; then $(CYGPATH_W) 'UgetData.c'; else $(CYGPATH_W) '$(srcdir)/UgetData.c'; fi` +libuget_a-UgetFiles.o: UgetFiles.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuget_a_CPPFLAGS) $(CPPFLAGS) $(libuget_a_CFLAGS) $(CFLAGS) -MT libuget_a-UgetFiles.o -MD -MP -MF $(DEPDIR)/libuget_a-UgetFiles.Tpo -c -o libuget_a-UgetFiles.o `test -f 'UgetFiles.c' || echo '$(srcdir)/'`UgetFiles.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuget_a-UgetFiles.Tpo $(DEPDIR)/libuget_a-UgetFiles.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgetFiles.c' object='libuget_a-UgetFiles.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuget_a_CPPFLAGS) $(CPPFLAGS) $(libuget_a_CFLAGS) $(CFLAGS) -c -o libuget_a-UgetFiles.o `test -f 'UgetFiles.c' || echo '$(srcdir)/'`UgetFiles.c + +libuget_a-UgetFiles.obj: UgetFiles.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuget_a_CPPFLAGS) $(CPPFLAGS) $(libuget_a_CFLAGS) $(CFLAGS) -MT libuget_a-UgetFiles.obj -MD -MP -MF $(DEPDIR)/libuget_a-UgetFiles.Tpo -c -o libuget_a-UgetFiles.obj `if test -f 'UgetFiles.c'; then $(CYGPATH_W) 'UgetFiles.c'; else $(CYGPATH_W) '$(srcdir)/UgetFiles.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuget_a-UgetFiles.Tpo $(DEPDIR)/libuget_a-UgetFiles.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgetFiles.c' object='libuget_a-UgetFiles.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuget_a_CPPFLAGS) $(CPPFLAGS) $(libuget_a_CFLAGS) $(CFLAGS) -c -o libuget_a-UgetFiles.obj `if test -f 'UgetFiles.c'; then $(CYGPATH_W) 'UgetFiles.c'; else $(CYGPATH_W) '$(srcdir)/UgetFiles.c'; fi` + libuget_a-UgetNode.o: UgetNode.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuget_a_CPPFLAGS) $(CPPFLAGS) $(libuget_a_CFLAGS) $(CFLAGS) -MT libuget_a-UgetNode.o -MD -MP -MF $(DEPDIR)/libuget_a-UgetNode.Tpo -c -o libuget_a-UgetNode.o `test -f 'UgetNode.c' || echo '$(srcdir)/'`UgetNode.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuget_a-UgetNode.Tpo $(DEPDIR)/libuget_a-UgetNode.Po @@ -558,6 +608,20 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuget_a_CPPFLAGS) $(CPPFLAGS) $(libuget_a_CFLAGS) $(CFLAGS) -c -o libuget_a-UgetNode-compare.obj `if test -f 'UgetNode-compare.c'; then $(CYGPATH_W) 'UgetNode-compare.c'; else $(CYGPATH_W) '$(srcdir)/UgetNode-compare.c'; fi` +libuget_a-UgetNode-filter.o: UgetNode-filter.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuget_a_CPPFLAGS) $(CPPFLAGS) $(libuget_a_CFLAGS) $(CFLAGS) -MT libuget_a-UgetNode-filter.o -MD -MP -MF $(DEPDIR)/libuget_a-UgetNode-filter.Tpo -c -o libuget_a-UgetNode-filter.o `test -f 'UgetNode-filter.c' || echo '$(srcdir)/'`UgetNode-filter.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuget_a-UgetNode-filter.Tpo $(DEPDIR)/libuget_a-UgetNode-filter.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgetNode-filter.c' object='libuget_a-UgetNode-filter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuget_a_CPPFLAGS) $(CPPFLAGS) $(libuget_a_CFLAGS) $(CFLAGS) -c -o libuget_a-UgetNode-filter.o `test -f 'UgetNode-filter.c' || echo '$(srcdir)/'`UgetNode-filter.c + +libuget_a-UgetNode-filter.obj: UgetNode-filter.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuget_a_CPPFLAGS) $(CPPFLAGS) $(libuget_a_CFLAGS) $(CFLAGS) -MT libuget_a-UgetNode-filter.obj -MD -MP -MF $(DEPDIR)/libuget_a-UgetNode-filter.Tpo -c -o libuget_a-UgetNode-filter.obj `if test -f 'UgetNode-filter.c'; then $(CYGPATH_W) 'UgetNode-filter.c'; else $(CYGPATH_W) '$(srcdir)/UgetNode-filter.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuget_a-UgetNode-filter.Tpo $(DEPDIR)/libuget_a-UgetNode-filter.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgetNode-filter.c' object='libuget_a-UgetNode-filter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuget_a_CPPFLAGS) $(CPPFLAGS) $(libuget_a_CFLAGS) $(CFLAGS) -c -o libuget_a-UgetNode-filter.obj `if test -f 'UgetNode-filter.c'; then $(CYGPATH_W) 'UgetNode-filter.c'; else $(CYGPATH_W) '$(srcdir)/UgetNode-filter.c'; fi` + libuget_a-UgetTask.o: UgetTask.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuget_a_CPPFLAGS) $(CPPFLAGS) $(libuget_a_CFLAGS) $(CFLAGS) -MT libuget_a-UgetTask.o -MD -MP -MF $(DEPDIR)/libuget_a-UgetTask.Tpo -c -o libuget_a-UgetTask.o `test -f 'UgetTask.c' || echo '$(srcdir)/'`UgetTask.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuget_a-UgetTask.Tpo $(DEPDIR)/libuget_a-UgetTask.Po @@ -862,7 +926,10 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -931,7 +998,33 @@ clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/libuget_a-UgetA2cf.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetApp.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetAria2.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetCurl.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetData.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetEvent.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetFiles.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetHash.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetMedia-youtube.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetMedia.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetNode-compare.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetNode-filter.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetNode.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetOption.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetPlugin.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetPluginAgent.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetPluginAria2.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetPluginCurl.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetPluginEmpty.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetPluginMedia.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetPluginMega.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetRpc.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetRss.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetSequence.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetSite.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetTask.Po + -rm -f ./$(DEPDIR)/libuget_a-pwmd.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -977,7 +1070,33 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/libuget_a-UgetA2cf.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetApp.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetAria2.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetCurl.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetData.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetEvent.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetFiles.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetHash.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetMedia-youtube.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetMedia.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetNode-compare.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetNode-filter.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetNode.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetOption.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetPlugin.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetPluginAgent.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetPluginAria2.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetPluginCurl.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetPluginEmpty.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetPluginMedia.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetPluginMega.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetRpc.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetRss.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetSequence.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetSite.Po + -rm -f ./$(DEPDIR)/libuget_a-UgetTask.Po + -rm -f ./$(DEPDIR)/libuget_a-pwmd.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -997,18 +1116,18 @@ .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ - distclean-compile distclean-generic distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-noinstLIBRARIES cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am .PRECIOUS: Makefile diff -Nru uget-2.2.0/uget/pwmd.c uget-2.2.2/uget/pwmd.c --- uget-2.2.0/uget/pwmd.c 2017-11-16 13:26:18.000000000 +0000 +++ uget-2.2.2/uget/pwmd.c 2019-05-19 16:49:07.000000000 +0000 @@ -24,110 +24,220 @@ #include #include "pwmd.h" -gpg_error_t ug_set_pwmd_proxy_options(struct pwmd_proxy_s *pwmd, - UgetProxy *proxy) +static gpg_error_t alloc_result(const char* s, size_t len, char** result) { - gpg_error_t rc; - pwm_t *pwm = NULL; - gchar *result; - gchar *path = NULL; - gint i; - gchar **args = NULL; - - pwmd->port = 80; - - if (proxy->pwmd.element) { - pwmd->path = path = g_strdup_printf("%s\t", proxy->pwmd.element); - - for (i = 0; path[i]; i++) { - if (path[i] == '^') - path[i] = '\t'; - } - } - - pwmd_init(); - rc = pwmd_new("uget", &pwm); - if (rc) - goto fail; - - rc = pwmd_setopt (pwm, PWMD_OPTION_SOCKET_TIMEOUT, 120); - - if (!rc && proxy->pwmd.socket_args && *proxy->pwmd.socket_args) - args = g_strsplit (proxy->pwmd.socket_args, ",", 0); - - if (!rc) - rc = pwmd_connect(pwm, proxy->pwmd.socket, - g_strv_length (args) > 0 ? args[0] : NULL, - g_strv_length (args) > 1 ? args[1] : NULL, - g_strv_length (args) > 2 ? args[2] : NULL, - g_strv_length (args) > 3 ? args[3] : NULL, - g_strv_length (args) > 4 ? args[4] : NULL, - g_strv_length (args) > 5 ? args[5] : NULL, - g_strv_length (args) > 6 ? args[6] : NULL, - g_strv_length (args) > 7 ? args[7] : NULL - ); - if (rc) - goto fail; - - rc = pwmd_setopt(pwm, PWMD_OPTION_PINENTRY_DESC, NULL); - if (!rc) - rc = pwmd_command(pwm, NULL, NULL, NULL, NULL, - "OPTION lock-timeout=100"); - if (rc) - goto fail; - - rc = pwmd_open(pwm, proxy->pwmd.file, NULL, NULL); - if (rc) - goto fail; - - rc = pwmd_command(pwm, &result, NULL, NULL, NULL, "GET %stype", - path ? path : ""); - if (rc) - goto fail; - - pwmd->type = result; - rc = pwmd_command(pwm, &result, NULL, NULL, NULL, "GET %shostname", - path ? path : ""); - if (rc) - goto fail; - - pwmd->hostname = result; - rc = pwmd_command(pwm, &result, NULL, NULL, NULL, "GET %sport", - path ? path : ""); - if (rc && gpg_err_code (rc) != GPG_ERR_ELEMENT_NOT_FOUND) - goto fail; - - pwmd->port = atoi(result); - pwmd_free(result); - rc = pwmd_command(pwm, &result, NULL, NULL, NULL, "GET %susername", - path ? path : ""); - if (rc && gpg_err_code (rc) != GPG_ERR_ELEMENT_NOT_FOUND - && gpg_err_code (rc) != GPG_ERR_NO_DATA) - goto fail; - - if (!rc) - pwmd->username = result; - rc = pwmd_command(pwm, &result, NULL, NULL, NULL, "GET %spassword", - path ? path : ""); - - if (rc && gpg_err_code (rc) != GPG_ERR_ELEMENT_NOT_FOUND - && gpg_err_code (rc) != GPG_ERR_NO_DATA) - goto fail; - if (!rc) - pwmd->password = result; - - rc = 0; + char *b; + + if (!len) { + *result = NULL; + return 0; + } + + b = pwmd_malloc(len+1); + if (!b) + return GPG_ERR_ENOMEM; + + memcpy(b, s, len); + b[len] = 0; + *result = b; + return 0; +} + +static int failure(const char* root, const char* id, gpg_error_t rc, + int required) +{ + if (!rc) + return 0; + + if (gpg_err_code (rc) == GPG_ERR_ELEMENT_NOT_FOUND + || gpg_err_code (rc) == GPG_ERR_NO_DATA) { + if (!required) + return 0; + + fprintf(stderr, "pwmd: ERR(%u): %s%s%s: %s\n", rc, + root ? root : "", root ? "^": "", id, + gpg_strerror (rc)); + } + + return 1; +} + +gpg_error_t ug_set_pwmd_proxy_options(struct pwmd_proxy_s* pwmd, + UgetProxy* proxy) +{ + char *bulk = NULL; + const gchar *bresult = NULL; + gchar *result = NULL; + size_t brlen, len; + size_t offset = 0; + char *str; + gpg_error_t rcs[4] = { 0 }; + gpg_error_t rc, brc; + pwm_t *pwm = NULL; + gchar *path = NULL; + const gchar *root = proxy->pwmd.element; + gint i; + gchar **args = NULL; + + pwmd->port = 80; + + if (proxy->pwmd.element) { + pwmd->path = path = g_strdup_printf("%s\t", proxy->pwmd.element); + + for (i = 0; path[i]; i++) { + if (path[i] == '^') + path[i] = '\t'; + } + } + + pwmd_init(); + rc = pwmd_new("uget", &pwm); + if (rc) + goto fail; + + rc = pwmd_setopt(pwm, PWMD_OPTION_SOCKET_TIMEOUT, 120); + + if (!rc && proxy->pwmd.socket_args && *proxy->pwmd.socket_args) + args = g_strsplit(proxy->pwmd.socket_args, ",", 0); + + if (!rc) + rc = pwmd_connect(pwm, proxy->pwmd.socket, + g_strv_length (args) > 0 ? args[0] : NULL, + g_strv_length (args) > 1 ? args[1] : NULL, + g_strv_length (args) > 2 ? args[2] : NULL, + g_strv_length (args) > 3 ? args[3] : NULL, + g_strv_length (args) > 4 ? args[4] : NULL, + g_strv_length (args) > 5 ? args[5] : NULL, + g_strv_length (args) > 6 ? args[6] : NULL, + g_strv_length (args) > 7 ? args[7] : NULL + ); + if (rc) + goto fail; + + rc = pwmd_setopt(pwm, PWMD_OPTION_PINENTRY_DESC, NULL); + if (!rc) + rc = pwmd_setopt(pwm, PWMD_OPTION_LOCK_TIMEOUT, 100); + if (rc) + goto fail; + + rc = pwmd_open(pwm, proxy->pwmd.file, NULL, NULL); + if (rc) + goto fail; + + rc = pwmd_bulk_append(&bulk, "NOP", 3, "NOP", NULL, 0, &offset); + if (rc) + goto fail; + + rcs[0] = 0; + rcs[1] = GPG_ERR_MISSING_ERRNO; + str = pwmd_strdup_printf("%stype", path); + rc = pwmd_bulk_append_rc(&bulk, rcs, "TYPE", 4, "GET", str, + strlen (str), &offset); + pwmd_free(str); + if (rc) + goto fail; + + rcs[0] = 0; + rcs[1] = GPG_ERR_MISSING_ERRNO; + str = pwmd_strdup_printf("%shostname", path); + rc = pwmd_bulk_append_rc(&bulk, rcs, "HOST", 4, "GET", str, + strlen (str), &offset); + pwmd_free(str); + if (rc) + goto fail; + + rcs[0] = 0; + rcs[1] = gpg_err_make (GPG_ERR_SOURCE_USER_1, GPG_ERR_ELEMENT_NOT_FOUND); + rcs[2] = GPG_ERR_MISSING_ERRNO; + str = pwmd_strdup_printf("%sport", path); + rc = pwmd_bulk_append_rc(&bulk, rcs, "PORT", 4, "GET", str, + strlen (str), &offset); + pwmd_free(str); + if (rc) + goto fail; + + rcs[0] = 0; + rcs[1] = gpg_err_make (GPG_ERR_SOURCE_USER_1, GPG_ERR_ELEMENT_NOT_FOUND); + rcs[2] = gpg_err_make (GPG_ERR_SOURCE_USER_1, GPG_ERR_NO_DATA); + rcs[3] = GPG_ERR_MISSING_ERRNO; + str = pwmd_strdup_printf("%susername", path); + rc = pwmd_bulk_append_rc(&bulk, rcs, "USER", 4, "GET", str, + strlen (str), &offset); + pwmd_free(str); + if (rc) + goto fail; + + rcs[0] = 0; + rcs[1] = gpg_err_make (GPG_ERR_SOURCE_USER_1, GPG_ERR_ELEMENT_NOT_FOUND); + rcs[2] = gpg_err_make (GPG_ERR_SOURCE_USER_1, GPG_ERR_NO_DATA); + rcs[3] = GPG_ERR_MISSING_ERRNO; + str = pwmd_strdup_printf("%spassword", path); + rc = pwmd_bulk_append_rc(&bulk, rcs, "PASS", 4, "GET", str, + strlen (str), &offset); + pwmd_free(str); + if (rc) + goto fail; + + rc = pwmd_bulk_finalize(&bulk); + if (!rc) + rc = pwmd_bulk(pwm, &result, &len, NULL, NULL, bulk, strlen (bulk)); + if (rc) + goto fail; + + offset = 0; + rc = pwmd_bulk_result(result, len, "TYPE", 4, &offset, &bresult, + &brlen, &brc); + if (failure(root, "type", rc ? rc : brc, 1)) + goto fail; + else if(brlen) + alloc_result (bresult, brlen, &pwmd->type); + + rc = pwmd_bulk_result(result, len, "HOST", 4, &offset, &bresult, + &brlen, &brc); + if (failure(root, "hostname", rc ? rc : brc, 1)) + goto fail; + else if (brlen) + alloc_result(bresult, brlen, &pwmd->hostname); + + rc = pwmd_bulk_result(result, len, "PORT", 4, &offset, &bresult, + &brlen, &brc); + if (failure(root, "port", rc ? rc : brc, 0)) + goto fail; + else if (brlen) { + char *p; + + alloc_result(bresult, brlen, &p); + pwmd->port = atoi(p); + pwmd_free(p); + } + + rc = pwmd_bulk_result(result, len, "USER", 4, &offset, &bresult, + &brlen, &brc); + if (failure(root, "username", rc ? rc : brc, 0)) + goto fail; + else if (brlen) + alloc_result(bresult, brlen, &pwmd->username); + + rc = pwmd_bulk_result(result, len, "PASS", 4, &offset, &bresult, + &brlen, &brc); + if (failure(root, "password", rc ? rc : brc, 0)) + goto fail; + else if (brlen) + alloc_result(bresult, brlen, &pwmd->password); + + brc = 0; fail: - if (args) - g_strfreev (args); + if (args) + g_strfreev(args); - if (pwm) - pwmd_close(pwm); - return rc; + pwmd_free(result); + pwmd_free(bulk); + pwmd_close(pwm); + return rc ? rc : brc; } -void ug_close_pwmd(struct pwmd_proxy_s *pwmd) +void ug_close_pwmd(struct pwmd_proxy_s* pwmd) { pwmd_free(pwmd->type); pwmd_free(pwmd->hostname); diff -Nru uget-2.2.0/uget/pwmd.h uget-2.2.2/uget/pwmd.h --- uget-2.2.0/uget/pwmd.h 2017-11-16 13:26:18.000000000 +0000 +++ uget-2.2.2/uget/pwmd.h 2019-05-19 16:49:07.000000000 +0000 @@ -22,15 +22,15 @@ #include "UgetData.h" struct pwmd_proxy_s { - gchar *hostname; - gchar *username; - gchar *password; - gchar *type; - gchar *path; + gchar* hostname; + gchar* username; + gchar* password; + gchar* type; + gchar* path; gint port; }; -gpg_error_t ug_set_pwmd_proxy_options(struct pwmd_proxy_s *, UgetProxy *); -void ug_close_pwmd(struct pwmd_proxy_s *); +gpg_error_t ug_set_pwmd_proxy_options(struct pwmd_proxy_s*, UgetProxy*); +void ug_close_pwmd(struct pwmd_proxy_s*); #endif diff -Nru uget-2.2.0/uget/UgetA2cf.c uget-2.2.2/uget/UgetA2cf.c --- uget-2.2.0/uget/UgetA2cf.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetA2cf.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2011-2018 by C.H. Huang + * Copyright (C) 2011-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -40,6 +40,8 @@ #include #include +#define INFO_HASH_LEN_MAX 8192 + enum { ENDIAN_UNKNOWN, ENDIAN_BE, @@ -136,7 +138,7 @@ // ---------------------------------------------------------------------------- -#define A2CF_LAST_PIECE_LEN(a2cf) ((a2cf)->total_size & ((a2cf)->piece_len-1)) +#define A2CF_LAST_PIECE_LEN(a2cf) ((a2cf)->total_size % (a2cf)->piece_len) static UgetA2cfPiece* a2cf_piece_new (uint32_t length) { @@ -356,21 +358,29 @@ FILE* file; uint32_t index; uint32_t n_pieces; + uint32_t bitfield_len; init_endian_type (); file = ug_fopen (filename, "rb"); if (file == NULL) return FALSE; + // version ug_fread (file, (char*)&a2cf->ver, 2); ug_fread (file, (char*)&a2cf->ext, 4); a2cf->ver = uint16_from_be (a2cf->ver); a2cf->ext = uint32_from_be (a2cf->ext); + // check file version - uGet only support version 1 + if (a2cf->ver != 1) + goto failed; + // info hash a2cf->info_hash_len = 0; ug_fread (file, (char*)&a2cf->info_hash_len, 4); a2cf->info_hash_len = uint32_from_be (a2cf->info_hash_len); - if (a2cf->info_hash_len == 0) + if (a2cf->info_hash_len > INFO_HASH_LEN_MAX) + goto failed; + else if (a2cf->info_hash_len == 0) a2cf->info_hash = NULL; else { a2cf->info_hash = ug_malloc (a2cf->info_hash_len); @@ -383,33 +393,34 @@ a2cf->piece_len = uint32_from_be (a2cf->piece_len); a2cf->total_len = uint64_from_be (a2cf->total_len); a2cf->upload_len = uint64_from_be (a2cf->upload_len); - // bit field - if (ug_fread (file, (char*)&a2cf->bitfield_len, 4) != 4) { - fclose (file); - return FALSE; - } + + // bitfield + if (ug_fread (file, (char*)&a2cf->bitfield_len, 4) != 4) + goto failed; a2cf->bitfield_len = uint32_from_be (a2cf->bitfield_len); - if (a2cf->bitfield_len == 0) { + // check bitfield_len + bitfield_len = (uint32_t)(a2cf->total_len / (8 * a2cf->piece_len)); + bitfield_len += (uint32_t)(a2cf->total_len % (8 * a2cf->piece_len)) ? 1 : 0; + if (a2cf->bitfield_len == 0 || a2cf->bitfield_len != bitfield_len) { a2cf->bitfield = NULL; - return FALSE; + goto failed; } else { a2cf->bitfield = ug_malloc (a2cf->bitfield_len); if (ug_fread (file, a2cf->bitfield, a2cf->bitfield_len) != a2cf->bitfield_len) - { - fclose (file); - return FALSE; - } + goto failed; } + // The number of in-flight pieces. n_pieces = 0; ug_fread (file, (char*)&n_pieces, 4); n_pieces = uint32_from_be (n_pieces); - // piece.index_end + // piece.index_end - calculate number of the last piece a2cf->piece.index_end = (uint32_t) (a2cf->total_len / a2cf->piece_len) + - ( (a2cf->total_len & (a2cf->piece_len-1)) ? 1 : 0 ); - // load pieces + ( (a2cf->total_len % a2cf->piece_len) ? 1 : 0 ); + + // load in-flight pieces for (index = 0; index < n_pieces; index++) { piece = a2cf_piece_new (a2cf->piece_len); if (a2cf_piece_read (piece, file) == FALSE) { @@ -421,6 +432,10 @@ fclose (file); return TRUE; + +failed: + fclose(file); + return FALSE; } int uget_a2cf_save (UgetA2cf* a2cf, const char* filename) @@ -491,7 +506,7 @@ return FALSE; index = (uint32_t) (beg[0] / a2cf->piece_len); - piece_beg = (uint32_t) (beg[0] & (a2cf->piece_len-1)); + piece_beg = (uint32_t) (beg[0] % a2cf->piece_len); // find begin for (; index < a2cf->piece.index_end; index++) { @@ -517,6 +532,7 @@ } } beg[0] = (uint64_t)index * a2cf->piece_len + piece_beg; + // if current piece is the last piece if (index == a2cf->piece.index_end - 1) { end[0] = a2cf->total_len; return TRUE; @@ -595,8 +611,8 @@ index_beg = (uint32_t) (beg / a2cf->piece_len); index_end = (uint32_t) (end / a2cf->piece_len); - piece_beg = beg & (a2cf->piece_len-1); - piece_end = end & (a2cf->piece_len-1); + piece_beg = (uint32_t) (beg % a2cf->piece_len); + piece_end = (uint32_t) (end % a2cf->piece_len); // first piece or only 1 piece if (index_beg == index_end) { @@ -646,7 +662,7 @@ for (index = 0; index < a2cf->piece.index_end; index++) { if (test_bit (a2cf->bitfield, index) == TRUE) { if (index == a2cf->piece.index_end - 1) { - last_piece_len = a2cf->total_len & (a2cf->piece_len-1); + last_piece_len = a2cf->total_len % a2cf->piece_len; if (last_piece_len) { completed += last_piece_len; break; @@ -704,7 +720,7 @@ piece = a2cf_piece_new (a2cf->piece_len); piece->index = piece_index; if (piece_index == a2cf->piece.index_end - 1) - a2cf_piece_truncate (piece, a2cf->total_len & (a2cf->piece_len-1)); + a2cf_piece_truncate (piece, a2cf->total_len % a2cf->piece_len); uget_a2cf_insert (a2cf, piece); } return piece; diff -Nru uget-2.2.0/uget/UgetA2cf.h uget-2.2.2/uget/UgetA2cf.h --- uget-2.2.0/uget/UgetA2cf.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetA2cf.h 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2011-2018 by C.H. Huang + * Copyright (C) 2011-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uget/UgetApp.c uget-2.2.2/uget/UgetApp.c --- uget-2.2.0/uget/UgetApp.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetApp.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -61,35 +61,59 @@ #define _(x) x #endif -static struct UgetNodeNotification notification_real = - {NULL, NULL, NULL, NULL, - (UgCompareFunc) NULL, FALSE, - NULL}; -static struct UgetNodeNotification notification_split = - {uget_node_create_split, NULL, NULL, NULL, - (UgCompareFunc) NULL, FALSE, - NULL}; -static struct UgetNodeNotification notification_sorted = - {uget_node_create_sorted, NULL, NULL, NULL, - (UgCompareFunc) NULL, FALSE, - NULL}; -static struct UgetNodeNotification notification_sorted_split = - {uget_node_create_split, NULL, NULL, NULL, - (UgCompareFunc) NULL, FALSE, - NULL}; -static struct UgetNodeNotification notification_mix = - {uget_node_create_mix, NULL, NULL, NULL, - (UgCompareFunc) NULL, FALSE, - NULL}; -static struct UgetNodeNotification notification_mix_split = - {uget_node_create_mix_split, NULL, NULL, NULL, - (UgCompareFunc) NULL, FALSE, - NULL}; +static struct UgetNodeControl control_real = +{ +// NULL, // struct UgetNodeControl* children; + &uget_node_default_notifier, // struct UgetNodeNotifier* notifier; + {NULL, FALSE}, // struct UgetNodeSort sort; + NULL, // UgetNodeFunc filter; +}; + +static struct UgetNodeControl control_split = +{ +// NULL, // struct UgetNodeControl* children; + &uget_node_default_notifier, // struct UgetNodeNotifier* notifier; + {NULL, FALSE}, // struct UgetNodeSort sort; + uget_node_filter_split, // UgetNodeFunc filter; +}; + +static struct UgetNodeControl control_sorted = +{ +// NULL, // struct UgetNodeControl* children; + &uget_node_default_notifier, // struct UgetNodeNotifier* notifier; + {NULL, FALSE}, // struct UgetNodeSort sort; + uget_node_filter_sorted, // UgetNodeFunc filter; +}; + +static struct UgetNodeControl control_sorted_split = +{ +// NULL, // struct UgetNodeControl* children; + &uget_node_default_notifier, // struct UgetNodeNotifier* notifier; + {NULL, FALSE}, // struct UgetNodeSort sort; + uget_node_filter_split, // UgetNodeFunc filter; +}; + +static struct UgetNodeControl control_mix = +{ +// NULL, // struct UgetNodeControl* children; + &uget_node_default_notifier, // struct UgetNodeNotifier* notifier; + {NULL, FALSE}, // struct UgetNodeSort sort; + uget_node_filter_mix, // UgetNodeFunc filter; +}; + +static struct UgetNodeControl control_mix_split = +{ +// NULL, // struct UgetNodeControl* children; + &uget_node_default_notifier, // struct UgetNodeNotifier* notifier; + {NULL, FALSE}, // struct UgetNodeSort sort; + uget_node_filter_mix_split, // UgetNodeFunc filter; +}; void uget_app_init (UgetApp* app) { - UgetNode* node; + UgetCommon* common; + UgetNode* node; // real and virtual root nodes uget_node_init (&app->real, NULL); @@ -98,19 +122,22 @@ uget_node_init (&app->sorted_split, &app->sorted); uget_node_init (&app->mix, &app->real); uget_node_init (&app->mix_split, &app->mix); - app->real.notification = ¬ification_real; - app->split.notification = ¬ification_split; - app->sorted.notification = ¬ification_sorted; - app->sorted_split.notification = ¬ification_sorted_split; - app->mix.notification = ¬ification_mix; - app->mix_split.notification = ¬ification_mix_split; + app->real.control = &control_real; + app->split.control = &control_split; + app->sorted.control = &control_sorted; + app->sorted_split.control = &control_sorted_split; + app->mix.control = &control_mix; + app->mix_split.control = &control_mix_split; // add virtual category - "All Category" node = uget_node_new (NULL); - node->name = ug_strdup (_("All Category")); + common = ug_info_realloc(node->info, UgetCommonInfo); + common->name = ug_strdup (_("All Category")); uget_node_append (&app->mix, node); uget_task_init (&app->task); ug_array_init (&app->nodes, sizeof (void*), 32); + app->uri_hash = NULL; + app->config_dir = NULL; // plug-in registry app->plugin_default = NULL; @@ -118,6 +145,7 @@ // info registry ug_registry_init (&app->infos); ug_registry_add (&app->infos, UgetCommonInfo); + ug_registry_add (&app->infos, UgetFilesInfo); ug_registry_add (&app->infos, UgetProgressInfo); ug_registry_add (&app->infos, UgetProxyInfo); ug_registry_add (&app->infos, UgetHttpInfo); @@ -127,25 +155,33 @@ ug_registry_add (&app->infos, UgetCategoryInfo); ug_registry_sort (&app->infos); ug_info_set_registry (&app->infos); + // counter + app->n_error = 0; + app->n_moved = 0; + app->n_deleted = 0; + app->n_completed = 0; } void uget_app_final (UgetApp* app) { ug_array_clear (&app->nodes); uget_task_final (&app->task); - uget_app_clear_plugins (app); + uget_app_clear_plugins (app); // clear app->plugins - uget_node_unref_children (&app->mix_split); - uget_node_unref_children (&app->mix); - uget_node_unref_children (&app->sorted); - uget_node_unref_children (&app->split); - uget_node_unref_children (&app->real); + uget_node_clear_children (&app->mix_split); + uget_node_clear_children (&app->mix); + uget_node_clear_children (&app->sorted_split); + uget_node_clear_children (&app->sorted); + uget_node_clear_children (&app->split); + uget_node_clear_children (&app->real); ug_registry_final (&app->plugins); ug_registry_final (&app->infos); uget_uri_hash_free (app->uri_hash); app->uri_hash = NULL; + ug_free(app->config_dir); + app->config_dir = NULL; } static UgArrayPtr* uget_app_store_nodes (UgetApp* app, UgetNode* parent) @@ -158,7 +194,7 @@ // array->length = 0; ug_array_alloc (array, parent->n_children); for (index = 0, dnode = parent->children; dnode; dnode = dnode->next) - array->at[index++] = dnode->data; + array->at[index++] = dnode->base; return array; } @@ -170,6 +206,7 @@ static int uget_app_activate (UgetApp* app, UgetNode* cnode, UgetCategory* category) { + UgetRelation* relation; UgetNode* dnode; UgetNode* sibling; UgetLog* log; @@ -183,12 +220,13 @@ for (index = 0; index < array->length; index++) { dnode = array->at[index]; uget_node_updated (dnode); - if (dnode->state & UGET_STATE_ACTIVE) { + relation = ug_info_realloc(dnode->info, UgetRelationInfo); + if (relation->group & UGET_GROUP_ACTIVE) { // remove node and insert it again to sort node - if (app->mix.notification->compare) { + if (app->mix.control->sort.compare) { sibling = dnode->next; uget_node_remove (cnode, dnode); - uget_node_unref_fake (dnode); + uget_node_clear_fake (dnode); uget_node_insert (cnode, sibling, dnode); app->n_moved++; } @@ -197,19 +235,19 @@ uget_task_remove (&app->task, dnode); uget_node_remove (cnode, dnode); - uget_node_unref_fake (dnode); - if (dnode->state & UGET_STATE_COMPLETED) { - dnode->state |= UGET_STATE_FINISHED; + uget_node_clear_fake (dnode); + if (relation->group & UGET_GROUP_COMPLETED) { + relation->group |= UGET_GROUP_FINISHED; sibling = category->finished->children; // completed time - log = ug_info_realloc (&dnode->info, UgetLogInfo); + log = ug_info_realloc (dnode->info, UgetLogInfo); log->completed_time = time(NULL); // get current time app->n_completed++; } else { - dnode->state |= UGET_STATE_QUEUING; + relation->group |= UGET_GROUP_QUEUING; sibling = category->queuing->children; - if (dnode->state & UGET_STATE_ERROR) + if (relation->group & UGET_GROUP_ERROR) app->n_error++; } @@ -231,6 +269,7 @@ static void uget_app_queuing (UgetApp* app, UgetNode* cnode, UgetCategory* category) { + UgetRelation* relation; UgetNode* dnode; UgArrayPtr* array; int index; @@ -243,7 +282,8 @@ dnode = array->at[index]; if (category->active->n_children >= category->active_limit) break; - if (dnode->state & UGET_STATE_INACTIVE) + relation = ug_info_realloc(dnode->info, UgetRelationInfo); + if (relation->group & UGET_GROUP_INACTIVE) continue; uget_app_activate_download (app, dnode); app->n_moved++; @@ -257,37 +297,56 @@ { UgetCategory* category; UgetNode* cnode; - UgetNode* dnode; int n_active = 0; // dispatch plug-in event, calc speed uget_task_dispatch (&app->task); // active, queuing, finished, recycled for (cnode = app->real.children; cnode; cnode = cnode->next) { - category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + category = ug_info_realloc (cnode->info, UgetCategoryInfo); if (category == NULL) continue; uget_app_activate (app, cnode, category); if (no_queuing == FALSE) uget_app_queuing (app, cnode, category); + n_active += category->active->n_children; + } + return n_active; +} + +int uget_app_trim(UgetApp* app, UgArrayPtr* deleted_nodes) +{ + UgetCategory* category; + UgetNode* cnode; + UgetNode* dnode; + int n_deleted_prev = app->n_deleted; + + for (cnode = app->real.children; cnode; cnode = cnode->next) { + category = ug_info_realloc(cnode->info, UgetCategoryInfo); + if (category == NULL) + continue; while (category->finished->n_children > category->finished_limit) { dnode = category->finished->last->real; - uget_uri_hash_remove_download (app->uri_hash, dnode); - uget_node_remove (cnode, dnode); - uget_node_unref (dnode); + uget_uri_hash_remove_download(app->uri_hash, dnode->info); + uget_node_remove(cnode, dnode); + uget_node_free(dnode); app->n_deleted++; + // add deleted nodes to array + if (deleted_nodes) + *(void**)ug_array_alloc(deleted_nodes, 1) = dnode; } while (category->recycled->n_children > category->recycled_limit) { dnode = category->recycled->last->real; - uget_uri_hash_remove_download (app->uri_hash, dnode); - uget_node_remove (cnode, dnode); - uget_node_unref (dnode); + uget_uri_hash_remove_download(app->uri_hash, dnode->info); + uget_node_remove(cnode, dnode); + uget_node_free(dnode); app->n_deleted++; + // add deleted nodes to array + if (deleted_nodes) + *(void**)ug_array_alloc(deleted_nodes, 1) = dnode; } - n_active += category->active->n_children; } - - return n_active; + return app->n_deleted - n_deleted_prev; } void uget_app_set_config_dir (UgetApp* app, const char* dir) @@ -302,12 +361,12 @@ UgetNode* real; node = app->mix.children; - if (app->mix.notification->reversed != reversed) { - app->mix.notification->reversed = reversed; - app->mix_split.notification->reversed = reversed; - app->sorted.notification->reversed = reversed; - app->sorted_split.notification->reversed = reversed; - if (app->mix.notification->compare == compare && compare) { + if (app->mix.control->sort.reverse != reversed) { + app->mix.control->sort.reverse = reversed; + app->mix_split.control->sort.reverse = reversed; + app->sorted.control->sort.reverse = reversed; + app->sorted_split.control->sort.reverse = reversed; + if (app->mix.control->sort.compare == compare && compare) { // reverse first category in app->mix ug_node_reverse ((UgNode*) node); // reverse each category in app->mix_split @@ -323,11 +382,11 @@ } } - if (app->mix.notification->compare != compare) { - app->mix.notification->compare = compare; - app->mix_split.notification->compare = compare; - app->sorted.notification->compare = compare; - app->sorted_split.notification->compare = compare; + if (app->mix.control->sort.compare != compare) { + app->mix.control->sort.compare = compare; + app->mix_split.control->sort.compare = compare; + app->sorted.control->sort.compare = compare; + app->sorted_split.control->sort.compare = compare; if (compare == NULL) { // reorder first category in app->mix for (real = app->real.last; real; real = real->prev) @@ -366,35 +425,10 @@ UgetNodeFunc removed, UgNotifyFunc updated) { - notification_real.inserted = inserted; - notification_real.removed = removed; - notification_real.updated = updated; - notification_real.data = data; - - notification_split.inserted = inserted; - notification_split.removed = removed; - notification_split.updated = updated; - notification_split.data = data; - - notification_sorted.inserted = inserted; - notification_sorted.removed = removed; - notification_sorted.updated = updated; - notification_sorted.data = data; - - notification_sorted_split.inserted = inserted; - notification_sorted_split.removed = removed; - notification_sorted_split.updated = updated; - notification_sorted_split.data = data; - - notification_mix.inserted = inserted; - notification_mix.removed = removed; - notification_mix.updated = updated; - notification_mix.data = data; - - notification_mix_split.inserted = inserted; - notification_mix_split.removed = removed; - notification_mix_split.updated = updated; - notification_mix_split.data = data; + uget_node_default_notifier.inserted = inserted; + uget_node_default_notifier.removed = removed; + uget_node_default_notifier.updated = updated; + uget_node_default_notifier.data = data; } void uget_app_add_category (UgetApp* app, UgetNode* cnode, int save_file) @@ -404,25 +438,24 @@ char* path_base; char* path; - cnode->type = UGET_NODE_CATEGORY; uget_node_append (&app->real, cnode); uget_uri_hash_add_category (app->uri_hash, cnode); - category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + category = ug_info_realloc (cnode->info, UgetCategoryInfo); for (node = cnode->fake; node; node = node->peer) { - switch (node->state) { - case UGET_STATE_ACTIVE: + switch (uget_node_get_group(node)) { + case UGET_GROUP_ACTIVE: category->active = node; break; - case UGET_STATE_QUEUING: + case UGET_GROUP_QUEUING: category->queuing = node; break; - case UGET_STATE_FINISHED: + case UGET_GROUP_FINISHED: category->finished = node; break; - case UGET_STATE_RECYCLED: + case UGET_GROUP_RECYCLED: category->recycled = node; break; @@ -506,7 +539,7 @@ uget_app_stop_category (app, cnode); uget_uri_hash_remove_category (app->uri_hash, cnode); uget_node_remove (&app->real, cnode); - uget_node_unref (cnode); + uget_node_free (cnode); if (app->config_dir == NULL) path_base = ug_strdup ("category"); @@ -544,7 +577,7 @@ UgArrayPtr* array; int index; - category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + category = ug_info_realloc (cnode->info, UgetCategoryInfo); // Because uget_app_queue_download() will change node linking, // program must store active nodes to array before calling uget_app_queue_download() @@ -566,7 +599,7 @@ UgArrayPtr* array; int index; - category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + category = ug_info_realloc (cnode->info, UgetCategoryInfo); // Because uget_app_queue_download() will change node linking, // program must store active nodes to array before calling uget_app_queue_download() @@ -600,7 +633,7 @@ UgArrayPtr* array; int index; - category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + category = ug_info_realloc (cnode->info, UgetCategoryInfo); // Because uget_app_queue_download() will change node linking, // program must store active nodes to array before calling uget_app_queue_download() @@ -652,7 +685,7 @@ matched.count = 0; for (cnode = app->real.children; cnode; cnode = cnode->next) { - category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + category = ug_info_realloc (cnode->info, UgetCategoryInfo); if (category == NULL) continue; // null-terminated @@ -690,58 +723,75 @@ UgetCommon* common; dnode = uget_node_new (NULL); - common = ug_info_realloc (&dnode->info, UgetCommonInfo); + common = ug_info_realloc (dnode->info, UgetCommonInfo); common->uri = ug_strdup (uri); return uget_app_add_download (app, dnode, cnode, apply); } int uget_app_add_download (UgetApp* app, UgetNode* dnode, UgetNode* cnode, int apply) { + UgetRelation* relation; + UgetRelation* relation_c; UgetNode* sibling; UgetLog* log; - UgUri uuri; + UgUri* uuri; + char* fattch; int value; struct { UgetCommon* common; UgetCategory* category; } temp; - temp.common = ug_info_realloc (&dnode->info, UgetCommonInfo); + temp.common = ug_info_realloc (dnode->info, UgetCommonInfo); // replace invalid characters \/:*?"<>| by _ in filename. if (temp.common->file) ug_str_replace_chars (temp.common->file, "\\/:*?\"<>|", '_'); // decode name, filename, and category if (temp.common->uri) { - ug_uri_init (&uuri, temp.common->uri); - // assign node name if it's name is NULL - if (dnode->name == NULL) { + uuri = ug_malloc(sizeof (UgUri)); + ug_uri_init(uuri, temp.common->uri); + // set UgetCommon::name if it's name is NULL + if (temp.common->name == NULL) { if (temp.common->file) - dnode->name = ug_strdup (temp.common->file); + temp.common->name = ug_strdup(temp.common->file); else - uget_node_set_name_by_uri (dnode, &uuri); + temp.common->name = uget_name_from_uri(uuri); + } + // backup file + if (ug_uri_is_file(uuri)) { + fattch = uget_app_save_attachment(app, dnode->info, + temp.common->uri + uuri->path, NULL); + if (fattch) { + // uuri will failure + ug_free(temp.common->uri); + temp.common->uri = fattch; + } } + ug_free(uuri); + // if (cnode == NULL) - cnode = uget_app_match_category (app, &uuri, temp.common->file); + cnode = uget_app_match_category (app, uuri, temp.common->file); } if (cnode == NULL) cnode = app->real.children; if (cnode) { - dnode->type = UGET_NODE_DOWNLOAD; - dnode->state &= UGET_STATE_CATEGORY | UGET_STATE_PAUSED; - dnode->state |= UGET_STATE_QUEUING; - log = ug_info_realloc (&dnode->info, UgetLogInfo); + relation = ug_info_realloc(dnode->info, UgetRelationInfo); + relation->group &= UGET_GROUP_MAJOR | UGET_GROUP_PAUSED; + relation->group |= UGET_GROUP_QUEUING; + log = ug_info_realloc (dnode->info, UgetLogInfo); log->added_time = time (NULL); // get current time if (apply) { value = temp.common->keeping.enable; temp.common->keeping.enable = TRUE; temp.common->keeping.uri = TRUE; - ug_info_assign (&dnode->info, &cnode->info, UgetCategoryInfo); + ug_info_assign (dnode->info, cnode->info, UgetCategoryInfo); temp.common->keeping.enable = value; - if (cnode->state & UGET_STATE_PAUSED) - dnode->state |= UGET_STATE_PAUSED; + relation_c = ug_info_realloc(cnode->info, UgetRelationInfo); + if (relation_c->group & UGET_GROUP_PAUSED) + relation->group |= UGET_GROUP_PAUSED; } - temp.category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + temp.category = ug_info_realloc (cnode->info, UgetCategoryInfo); // try to insert download before finished and recycled sibling = temp.category->finished->children; if (sibling == NULL) @@ -750,7 +800,7 @@ if (sibling) sibling = sibling->real; uget_node_insert (cnode, sibling, dnode); - uget_uri_hash_add_download (app->uri_hash, dnode); + uget_uri_hash_add_download(app->uri_hash, dnode->info); return TRUE; } return FALSE; @@ -777,13 +827,15 @@ { UgetNode* sibling; UgetCategory* category; + UgetRelation* relation; if (dnode->parent == cnode) return FALSE; - category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + category = ug_info_realloc(cnode->info, UgetCategoryInfo); + relation = ug_info_realloc(dnode->info, UgetRelationInfo); - switch (dnode->state & UGET_STATE_CATEGORY) { - case UGET_STATE_ACTIVE: + switch (relation->group & UGET_GROUP_MAJOR) { + case UGET_GROUP_ACTIVE: sibling = category->queuing->children; if (sibling == NULL) sibling = category->finished->children; @@ -792,14 +844,14 @@ break; default: - case UGET_STATE_QUEUING: - case UGET_STATE_FINISHED: + case UGET_GROUP_QUEUING: + case UGET_GROUP_FINISHED: sibling = category->finished->children; if (sibling == NULL) sibling = category->recycled->children; break; - case UGET_STATE_RECYCLED: + case UGET_GROUP_RECYCLED: sibling = category->recycled->children; break; } @@ -807,96 +859,75 @@ sibling = sibling->real; uget_node_remove (dnode->parent, dnode); - uget_node_unref_fake (dnode); + uget_node_clear_fake (dnode); uget_node_insert (cnode, sibling, dnode); return TRUE; } -static int delete_dnode_files (UgetNode* dnode, int has_aria2_file) +// used by uget_app_delete_download() +static int delete_files(UgetFiles* files, int has_temp_file) { - UgetNode* fnode; // filenode - UgetNode* fnode_next; - int error; - int error_count = 0; - - if (has_aria2_file == TRUE) { - // move first aria2 to tail - for (fnode = dnode->children; fnode; fnode = fnode_next) { - fnode_next = fnode->next; - if (strstr (fnode->name, ".aria2")) { - uget_node_move (dnode, NULL, fnode); - break; - } - } - } - - for (fnode = dnode->children; fnode; fnode = fnode_next) { - fnode_next = fnode->next; + UgetFile* file1; + int n_error; - if (fnode->name == NULL) { - uget_node_remove (dnode, fnode); + for (n_error = 0, file1 = (UgetFile*)files->list.head; file1; file1 = file1->next) { + if (file1->state & UGET_FILE_STATE_DELETED) continue; - } - if (ug_file_is_exist (fnode->name) == FALSE) { - uget_node_remove (dnode, fnode); - continue; - } - error = ug_remove (fnode->name); - if (error != 0) - error_count++; - else if (error_count == 0 || strstr (fnode->name, ".aria2") == NULL) - uget_node_remove (dnode, fnode); + if (ug_file_is_exist(file1->path) == FALSE) + file1->state |= UGET_FILE_STATE_DELETED; + else if (ug_remove(file1->path) != 0) + n_error++; + else if (file1->type != UGET_FILE_TEMPORARY) + file1->state |= UGET_FILE_STATE_DELETED; } - if (dnode->children == NULL) - return TRUE; - else - return FALSE; + return (n_error == 0) ? TRUE : FALSE; } -static UG_THREAD_RETURN_TYPE delete_file_thread (UgetNode* dnode) +// used by uget_app_delete_download() +static UgThreadResult delete_files_thread(UgetFiles* files) { int count; #ifdef USE__ANDROID__SAF - if (delete_dnode_files (dnode, TRUE) == FALSE) + if (delete_files(files, TRUE) == FALSE) #endif for (count = 0; count < 3; count++) { - ug_sleep (2 * 1000); // sleep 2 seconds - delete_dnode_files (dnode, FALSE); - if (dnode->children == NULL) + ug_sleep(2 * 1000); // sleep 2 seconds + if (delete_files(files, FALSE)) break; } - uget_node_unref (dnode); - return UG_THREAD_RETURN_VALUE; + ug_data_free(files); + return UG_THREAD_RESULT; } int uget_app_delete_download (UgetApp* app, UgetNode* dnode, int delete_file) { - UgetNode* cnode; UgThread thread; + UgetFiles* files; int is_active; - cnode = dnode->parent; - is_active = uget_task_remove (&app->task, dnode); - uget_node_remove (cnode, dnode); - uget_node_unref_fake (dnode); - uget_uri_hash_remove_download (app->uri_hash, dnode); - - if (delete_file == TRUE) { + is_active = uget_task_remove(&app->task, dnode); #ifdef USE__ANDROID__SAF - is_active = TRUE; // delete files in thread if program use Android SAF + is_active = TRUE; // delete files in thread if program use Android SAF #endif - if (is_active == TRUE || delete_dnode_files (dnode, TRUE) == FALSE) { - ug_thread_create (&thread, (UgThreadFunc) delete_file_thread, dnode); - ug_thread_unjoin (&thread); + uget_uri_hash_remove_download(app->uri_hash, dnode->info); + files = ug_info_set(dnode->info, UgetFilesInfo, NULL); + uget_node_free(dnode); + + if (delete_file == TRUE && files) { + if (is_active == TRUE || delete_files(files, TRUE) == FALSE) { + // delete files and free 'files' in thread + ug_thread_create(&thread, (UgThreadFunc) delete_files_thread, files); + ug_thread_unjoin(&thread); return FALSE; } } - uget_node_unref (dnode); + if (files) + ug_data_free(files); return TRUE; } @@ -905,24 +936,26 @@ UgetNode* cnode; UgetNode* sibling; UgetCategory* category; + UgetRelation* relation; cnode = dnode->parent; uget_task_remove (&app->task, dnode); uget_node_remove (cnode, dnode); - if (dnode->state & UGET_STATE_RECYCLED) { - uget_node_unref (dnode); + relation = ug_info_realloc(dnode->info, UgetRelationInfo); + if (relation->group & UGET_GROUP_RECYCLED) { + uget_node_free (dnode); return FALSE; } else { - dnode->state &= ~UGET_STATE_CATEGORY; - dnode->state |= UGET_STATE_RECYCLED; - uget_node_unref_fake (dnode); - category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + relation->group &= ~UGET_GROUP_MAJOR; + relation->group |= UGET_GROUP_RECYCLED; + uget_node_clear_fake (dnode); + category = ug_info_realloc (cnode->info, UgetCategoryInfo); // try to insert download before recycled sibling = category->recycled->children; if (sibling) - sibling = sibling->data; + sibling = sibling->base; uget_node_insert (cnode, sibling, dnode); return TRUE; } @@ -932,6 +965,7 @@ { UgetLog* log; UgetCommon* common; + UgetRelation* relation; UgetNode* cnode; UgetNode* sibling; union { @@ -939,18 +973,19 @@ UgetPluginInfo* pinfo; } temp; - if (dnode->state & UGET_STATE_ACTIVE) + relation = ug_info_realloc(dnode->info, UgetRelationInfo); + if (relation->group & UGET_GROUP_ACTIVE) return FALSE; - common = ug_info_get (&dnode->info, UgetCommonInfo); + common = ug_info_get (dnode->info, UgetCommonInfo); if (common == NULL || common->uri == NULL) return FALSE; // match plug-in - log = ug_info_realloc (&dnode->info, UgetLogInfo); + log = ug_info_realloc (dnode->info, UgetLogInfo); temp.pinfo = uget_app_match_plugin (app, common->uri, NULL); if (temp.pinfo == NULL) { // no plug-in support uget_app_queue_download (app, dnode); - dnode->state |= UGET_STATE_ERROR; + relation->group |= UGET_GROUP_ERROR; ug_list_prepend (&log->messages, (UgLink*) uget_event_new_error ( UGET_EVENT_ERROR_UNSUPPORTED_SCHEME, NULL)); @@ -970,15 +1005,15 @@ if (uget_task_add (&app->task, dnode, temp.pinfo) == FALSE) { // plug-in start failed. uget_app_queue_download (app, dnode); - dnode->state |= UGET_STATE_ERROR; + relation->group |= UGET_GROUP_ERROR; uget_node_updated (dnode); return FALSE; } // change node state and move node position uget_node_remove (cnode, dnode); - uget_node_unref_fake (dnode); - dnode->state = UGET_STATE_ACTIVE; - temp.category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + uget_node_clear_fake (dnode); + relation->group = UGET_GROUP_ACTIVE; + temp.category = ug_info_realloc (cnode->info, UgetCategoryInfo); // try to insert download before queuing, finished, and recycled sibling = temp.category->queuing->children; if (sibling == NULL) @@ -996,23 +1031,25 @@ { #if 0 UgetCategory* category; + UgetRelation* relation; UgetNode* sibling; UgetNode* cnode; UgetNode* fake; - if (dnode->state & UGET_STATE_UNRUNNABLE) + relation = ug_info_realloc(dnode->info, UgetRelationInfo); + if (relation->group & UGET_GROUP_UNRUNNABLE) return FALSE; uget_task_remove (&app->task, dnode); - dnode->state |= UGET_STATE_PAUSED; + relation->group |= UGET_GROUP_PAUSED; cnode = dnode->parent; - category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + category = ug_info_realloc (cnode->info, UgetCategoryInfo); for (fake = dnode->fake; fake; fake = fake->peer) { if (fake->parent == category->active) { uget_node_remove (cnode, dnode); - uget_node_unref_fake (dnode); + uget_node_clear_fake (dnode); - dnode->state |= UGET_STATE_QUEUING; + relation->group |= UGET_GROUP_QUEUING; // try to insert download before queuing, finished, and recycled sibling = category->queuing->children; if (sibling == NULL) @@ -1027,17 +1064,18 @@ } } #else - if (dnode->state & UGET_STATE_ACTIVE) { + UgetRelation* relation; + + relation = ug_info_realloc(dnode->info, UgetRelationInfo); + if (relation->group & UGET_GROUP_ACTIVE) { // uget_task_remove (&app->task, dnode); - UgetRelation* relation; - relation = ug_info_get (&dnode->info, UgetRelationInfo); - if (relation && relation->task.plugin) - uget_plugin_stop (relation->task.plugin); - dnode->state &= ~UGET_STATE_ACTIVE; + if (relation && relation->task) + uget_plugin_stop (relation->task->plugin); + relation->group &= ~UGET_GROUP_ACTIVE; } - else if (dnode->state & UGET_STATE_UNRUNNABLE) + else if (relation->group & UGET_GROUP_UNRUNNABLE) return FALSE; - dnode->state |= UGET_STATE_PAUSED; + relation->group |= UGET_GROUP_PAUSED; #endif return TRUE; } @@ -1047,24 +1085,26 @@ UgetNode* cnode; UgetNode* sibling; UgetCategory* category; + UgetRelation* relation; - if ((dnode->state & UGET_STATE_ACTIVE) == 0 && - (dnode->state & UGET_STATE_UNRUNNABLE) == 0) + relation = ug_info_realloc(dnode->info, UgetRelationInfo); + if ((relation->group & UGET_GROUP_ACTIVE) == 0 && + (relation->group & UGET_GROUP_UNRUNNABLE) == 0) return FALSE; - if (dnode->state & UGET_STATE_QUEUING) - dnode->state = UGET_STATE_QUEUING; + if (relation->group & UGET_GROUP_QUEUING) + relation->group = UGET_GROUP_QUEUING; else { cnode = dnode->parent; uget_node_remove (cnode, dnode); - uget_node_unref_fake (dnode); + uget_node_clear_fake (dnode); // --- decide sibling position & insert before it --- // if current download is in active, insert it before queuing, // otherwise insert it before finished and recycled. - category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + category = ug_info_realloc (cnode->info, UgetCategoryInfo); sibling = NULL; - if (dnode->state & UGET_STATE_ACTIVE) { + if (relation->group & UGET_GROUP_ACTIVE) { uget_task_remove (&app->task, dnode); sibling = category->queuing->children; } @@ -1075,7 +1115,7 @@ // get real sibling if (sibling) sibling = sibling->real; - dnode->state = UGET_STATE_QUEUING; + relation->group = UGET_GROUP_QUEUING; uget_node_insert (cnode, sibling, dnode); } return TRUE; @@ -1086,21 +1126,19 @@ UgetCommon* common; UgetNode* sibling; UgetNode* cnode = NULL; - UgUri uuri; - common = ug_info_realloc (&dnode->info, UgetCommonInfo); + common = ug_info_realloc(dnode->info, UgetCommonInfo); if (common->file) { - if (dnode->name && strcmp (common->file, dnode->name) == 0) + if (common->name && strcmp(common->file, common->name) == 0) return; - ug_free (dnode->name); - dnode->name = ug_strdup (common->file); + ug_free(common->name); + common->name = ug_strdup(common->file); cnode = dnode->parent; } else if (common->uri) { - if (dnode->name && strcmp (common->uri, dnode->name) == 0) + if (common->name && strcmp(common->uri, common->name) == 0) return; - ug_uri_init (&uuri, common->uri); - uget_node_set_name_by_uri (dnode, &uuri); + common->name = uget_name_from_uri_str(common->uri); cnode = dnode->parent; } @@ -1108,9 +1146,9 @@ if (cnode) { // cnode = dnode->parent; sibling = dnode->next; - uget_node_remove (cnode, dnode); - uget_node_unref_fake (dnode); - uget_node_insert (cnode, sibling, dnode); + uget_node_remove(cnode, dnode); + uget_node_clear_fake(dnode); + uget_node_insert(cnode, sibling, dnode); } } @@ -1125,10 +1163,112 @@ uget_uri_hash_add_category (app->uri_hash, cnode); } +char* uget_app_save_attachment(UgetApp* app, UgInfo* info, + const char* src_path, const char* rename) +{ + char* dest_path; + int count; + UgetFile* file1; + UgetFiles* files; + + if (rename == NULL) { + rename = strrchr(src_path, UG_DIR_SEPARATOR); +#if defined _WIN32 || defined _WIN64 + if (rename == NULL) + rename = strrchr(src_path, '/'); +#endif + if (rename == NULL) + rename = src_path; + else + rename++; + } + + dest_path = ug_strdup_printf( + "%s" UG_DIR_SEPARATOR_S "attachment" UG_DIR_SEPARATOR_S "%s", + app->config_dir, rename); + + for (count = 0; ug_file_is_exist(dest_path); count++) { + ug_free(dest_path); + dest_path = ug_strdup_printf( + "%s" UG_DIR_SEPARATOR_S "attachment" UG_DIR_SEPARATOR_S "%d) %s", + app->config_dir, count, rename); + } + + if (ug_file_copy(src_path, dest_path) == -1) { + ug_free(dest_path); + return NULL; + } + // add new path to UgetFiles + files = ug_info_realloc(info, UgetFilesInfo); + file1 = uget_files_realloc(files, dest_path); + file1->type = UGET_FILE_ATTACHMENT; + + return dest_path; +} + +/* +void uget_app_store_attachment(UgetApp* app, UgInfo* info) +{ + int num; + char* fname; + char* fattch; + UgUri* uuri; + union { + UgetHttp* http; + UgetCommon* common; + } tmp; + + tmp.common = ug_info_get(info, UgetCommonInfo); + if (tmp.common && tmp.common->uri) { + uuri = ug_malloc(sizeof(UgUri)); + ug_uri_init(uuri, tmp.common->uri); + if (ug_uri_is_file(uuri)) { + fattch = uget_app_save_attachment(app, info, + tmp.common->uri + uuri->path, NULL); + if (fattch) { + ug_free(tmp.common->uri); + tmp.common->uri = fattch; + } + } + ug_free(uuri); + } + + srand((unsigned int) time(NULL)); + num = rand(); + + tmp.http = ug_info_get(info, UgetHttpInfo); + // backup cookie file + if (tmp.http && tmp.http->cookie_file) { + fname = ug_strdup_printf("%X.cookie", num); + fattch = uget_app_save_attachment(app, info, + tmp.http->cookie_file, fname); + ug_free(fname); + if (fattch) { + ug_free(tmp.http->cookie_file); + tmp.http->cookie_file = fattch; + } + } + + // backup post file + if (tmp.http && tmp.http->post_file) { + fname = ug_strdup_printf("%X.post", num); + fattch = uget_app_save_attachment(app, info, + tmp.http->post_file, fname); + ug_free(fname); + if (fattch) { + ug_free(tmp.http->post_file); + tmp.http->post_file = fattch; + } + } +} + */ + void uget_app_clear_attachment (UgetApp* app) { UgetNode* dnode; UgetHttp* http; + UgetFiles* files; + UgetFile* file1; UgDir* dir; void* hash; const char* name; @@ -1138,12 +1278,20 @@ hash = uget_uri_hash_new (); // add attachment for (dnode = app->mix.children->children; dnode; dnode = dnode->next) { - if ((http = ug_info_get (&dnode->data->info, UgetHttpInfo)) == NULL) - continue; - if (http->cookie_file) - uget_uri_hash_add (hash, http->cookie_file); - if (http->post_file) - uget_uri_hash_add (hash, http->post_file); + // UgetFiles + if ((files = ug_info_get(dnode->info, UgetFilesInfo)) != NULL ) { + for (file1 = (UgetFile*)files->list.head; file1; file1 = file1->next) { + if (file1->type == UGET_FILE_ATTACHMENT) + uget_uri_hash_add(hash, file1->path); + } + } + // UgetHttp + if ((http = ug_info_get(dnode->info, UgetHttpInfo)) != NULL) { + if (http->cookie_file) + uget_uri_hash_add(hash, http->cookie_file); + if (http->post_file) + uget_uri_hash_add(hash, http->post_file); + } } folder = ug_build_filename (app->config_dir, "attachment", NULL); @@ -1185,7 +1333,8 @@ pend = app->plugins.at + app->plugins.length; for (pair = app->plugins.at; pair < pend; pair++) { if (pair->data) { - uget_plugin_set (pair->data, UGET_PLUGIN_INIT, (void*) FALSE); + uget_plugin_global_set(pair->data, UGET_PLUGIN_GLOBAL_INIT, + (void*) FALSE); pair->data = NULL; } } @@ -1198,9 +1347,9 @@ pair = ug_registry_find (&app->plugins, pinfo->name, NULL); if (pair == NULL || pair->data == NULL) - uget_plugin_set (pinfo, UGET_PLUGIN_INIT, (void*) TRUE); + uget_plugin_global_set(pinfo, UGET_PLUGIN_GLOBAL_INIT, (void*) TRUE); if (pair == NULL) - ug_registry_add (&app->plugins, (const UgDataInfo*)pinfo); + ug_registry_add (&app->plugins, (const UgTypeInfo*)pinfo); } void uget_app_remove_plugin (UgetApp* app, const UgetPluginInfo* pinfo) @@ -1209,7 +1358,7 @@ pair = ug_registry_find (&app->plugins, pinfo->name, NULL); if (pair && pair->data) { - uget_plugin_set (pair->data, UGET_PLUGIN_INIT, (void*) FALSE); + uget_plugin_global_set(pair->data, UGET_PLUGIN_GLOBAL_INIT, (void*) FALSE); pair->data = NULL; } } @@ -1283,6 +1432,17 @@ // ---------------------------------------------------------------------------- // save/load categories +// convert old format to new +static void remove_file_node(UgetNode* cnode) +{ + UgetNode* dnode; + + for (dnode = cnode->children; dnode; dnode = dnode->next) { + while (dnode->children) + uget_node_free(dnode->children); + } +} + int uget_app_save_category (UgetApp* app, UgetNode* cnode, const char* filename, void* jsonfile) { int fd; @@ -1367,10 +1527,12 @@ uget_node_make_fake (cnode); // move all downloads from active to queuing in this category uget_app_stop_category (app, cnode); + // convert old format to new + remove_file_node(cnode); return cnode; } else { - uget_node_unref (cnode); + uget_node_free (cnode); return NULL; } } @@ -1477,7 +1639,7 @@ UgetFtp* ftp; } temp; - temp.common = ug_info_realloc (&node->info, UgetCommonInfo); + temp.common = ug_info_realloc (node->info, UgetCommonInfo); if (temp.common) { temp.common->keeping.enable = enable; if (enable) { @@ -1515,7 +1677,7 @@ } } - temp.proxy = ug_info_get (&node->info, UgetProxyInfo); + temp.proxy = ug_info_get (node->info, UgetProxyInfo); if (temp.proxy) { temp.proxy->keeping.enable = enable; if (enable) { @@ -1532,7 +1694,7 @@ } } - temp.http = ug_info_get (&node->info, UgetHttpInfo); + temp.http = ug_info_get (node->info, UgetHttpInfo); if (temp.http) { temp.http->keeping.enable = enable; if (enable) { @@ -1557,7 +1719,7 @@ } } - temp.ftp = ug_info_get (&node->info, UgetFtpInfo); + temp.ftp = ug_info_get (node->info, UgetFtpInfo); if (temp.ftp) { temp.ftp->keeping.enable = enable; if (enable) { diff -Nru uget-2.2.0/uget/UgetApp.h uget-2.2.2/uget/UgetApp.h --- uget-2.2.0/uget/UgetApp.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetApp.h 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -75,30 +75,37 @@ struct UgetApp { UGET_APP_MEMBERS; -// UgetNode real; // real root node for real nodes -// UgetNode split; // virtual root -// UgetNode sorted; // virtual root -// UgetNode sorted_split; // virtual root -// UgetNode mix; // virtual root -// UgetNode mix_split; // virtual root -// UgRegistry infos; -// UgRegistry plugins; -// UgetPluginInfo* plugin; -// UgetTask task; -// UgArrayPtr nodes; -// void* uri_hash; -// char* config_dir; -// int n_error; // these n_xxxx increase by uget_app_grow() -// int n_moved; -// int n_deleted; -// int n_completed; +/* // ------ UgetApp members ------ + UgetNode real; // real root node for real nodes + UgetNode split; // virtual root + UgetNode sorted; // virtual root + UgetNode sorted_split; // virtual root + UgetNode mix; // virtual root + UgetNode mix_split; // virtual root + UgRegistry infos; + UgRegistry plugins; + UgetPluginInfo* plugin_default; + UgetTask task; + UgArrayPtr nodes; + void* uri_hash; + char* config_dir; + int n_error; // uget_app_grow() will count these value: + int n_moved; // n_error, n_moved, n_deleted, and + int n_deleted; // n_completed + int n_completed; // + */ }; void uget_app_init (UgetApp* app); void uget_app_final (UgetApp* app); -// uget_app_grow() return number of active download +// uget_app_grow() activate queue download +// return number of active download int uget_app_grow (UgetApp* app, int no_queuing); +// uget_app_trim() remove finished/recycled download that over capacity +// return number of trimmed download +int uget_app_trim (UgetApp* app, UgArrayPtr* deleted_nodes); + void uget_app_set_config_dir (UgetApp* app, const char* dir); void uget_app_set_sorting (UgetApp* app, UgCompareFunc func, int reversed); void uget_app_set_notification (UgetApp* app, void* data, @@ -130,9 +137,12 @@ #ifdef NO_URI_HASH #define uget_app_use_uri_hash(app) +#define uget_app_save_attachment(app, info, file, rename) #define uget_app_clear_attachment(app) #else void uget_app_use_uri_hash (UgetApp* app); +char* uget_app_save_attachment(UgetApp* app, UgInfo* info, + const char* file, const char* rename); void uget_app_clear_attachment (UgetApp* app); #endif @@ -176,10 +186,95 @@ namespace Uget { +// This one is for derived use only. No data members here. +// Your derived struct/class must be C++11 standard-layout struct AppMethod { + inline void init(void) + { uget_app_init((UgetApp*)this); } + inline void final(void) + { uget_app_final((UgetApp*)this); } + + inline void grow(int noQueuing) + { uget_app_grow((UgetApp*)this, noQueuing); } + inline void trim(UgArrayPtr* deleted_nodes = NULL) + { uget_app_trim((UgetApp*)this, deleted_nodes); } + + inline void setConfigDir(const char* dir) + { uget_app_set_config_dir((UgetApp*)this, dir); } + inline void setSorting(UgCompareFunc func, int reversed) + { uget_app_set_sorting((UgetApp*)this, func, reversed); } + inline void setNotification(void* data, UgetNodeFunc inserted, UgetNodeFunc removed, UgNotifyFunc updated) + { uget_app_set_notification((UgetApp*)this, data, inserted, removed, updated); } + + inline void addCategory(UgetNode* cnode, int saveFile) + { uget_app_add_category((UgetApp*)this, cnode, saveFile); } + inline void moveCategory(UgetNode* cnode, UgetNode* position) + { uget_app_move_category((UgetApp*)this, cnode, position); } + inline void deleteCategory(UgetNode* cnode) + { uget_app_delete_category((UgetApp*)this, cnode); } + inline void stopCategory(UgetNode* cnode) + { uget_app_stop_category((UgetApp*)this, cnode); } + inline void pauseCategory(UgetNode* cnode) + { uget_app_pause_category((UgetApp*)this, cnode); } + inline void resumeCategory(UgetNode* cnode) + { uget_app_resume_category((UgetApp*)this, cnode); } + inline UgetNode* matchCategory(UgUri* uuri, const char* file) + { return uget_app_match_category((UgetApp*)this, uuri, file); } + + inline int addDownload(const char* uri, UgetNode* cnode, int apply) + { return uget_app_add_download_uri((UgetApp*)this, uri, cnode, apply); } + inline int addDownload(UgetNode* dnode, UgetNode* cnode, int apply) + { return uget_app_add_download((UgetApp*)this, dnode, cnode, apply); } + inline int moveDownload(UgetNode* dnode, UgetNode* dnode_position) + { return uget_app_move_download((UgetApp*)this, dnode, dnode_position); } + inline int moveDownloadTo(UgetNode* dnode, UgetNode* cnode) + { return uget_app_move_download_to((UgetApp*)this, dnode, cnode); } + inline int deleteDownload(UgetNode* dnode, int deleteFile) + { return uget_app_delete_download((UgetApp*)this, dnode, deleteFile); } + inline int recycleDownload(UgetNode* dnode) + { return uget_app_recycle_download((UgetApp*)this, dnode); } + inline int activateDownload(UgetNode* dnode) + { return uget_app_activate_download((UgetApp*)this, dnode); } + inline int pauseDownload(UgetNode* dnode) + { return uget_app_pause_download((UgetApp*)this, dnode); } + inline int queueDownload(UgetNode* dnode) + { return uget_app_queue_download((UgetApp*)this, dnode); } + inline void resetDownloadName(UgetNode* dnode) + { uget_app_reset_download_name((UgetApp*)this, dnode); } + + inline void useUriHash(void) + { uget_app_use_uri_hash((UgetApp*)this); } + inline void clearAttachment(void) + { uget_app_clear_attachment((UgetApp*)this); } + + inline void clearPlugins(void) + { uget_app_clear_plugins((UgetApp*)this); } + inline void addPlugin(const UgetPluginInfo* pinfo) + { uget_app_add_plugin((UgetApp*)this, pinfo); } + inline void removePlugin(const UgetPluginInfo* pinfo) + { uget_app_remove_plugin((UgetApp*)this, pinfo); } + inline int findPlugin(const char* name, const UgetPluginInfo** pinfo) + { return uget_app_find_plugin((UgetApp*)this, name, pinfo); } + inline void setDefaultPlugin(const UgetPluginInfo* pinfo) + { return uget_app_set_default_plugin((UgetApp*)this, pinfo); } + inline UgetPluginInfo* matchPlugin(const char* uri, const UgetPluginInfo* exclude) + { return uget_app_match_plugin((UgetApp*)this, uri, exclude); } + + inline int saveCategory(UgetNode* cnode, const char* filename, void* jsonfile) + { return uget_app_save_category((UgetApp*)this, cnode, filename, jsonfile); } + inline UgetNode* loadCategory(const char* filename, void* jsonfile) + { return uget_app_load_category((UgetApp*)this, filename, jsonfile); } + // return number of category save/load + inline int saveCategories(const char* folder) + { return uget_app_save_categories((UgetApp*)this, folder); } + inline int loadCategories(const char* folder) + { return uget_app_load_categories((UgetApp*)this, folder); } }; +// This one is for directly use only. You can NOT derived it. +struct App : AppMethod, UgetApp {}; + }; // namespace Uget #endif // __cplusplus diff -Nru uget-2.2.0/uget/UgetAria2.c uget-2.2.2/uget/UgetAria2.c --- uget-2.2.0/uget/UgetAria2.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetAria2.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2011-2018 by C.H. Huang + * Copyright (C) 2011-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -81,7 +81,7 @@ int finalized; }; -static UG_THREAD_RETURN_TYPE uget_aria2_thread (UgetAria2Thread* uathread); +static UgThreadResult uget_aria2_thread (UgetAria2Thread* uathread); static UgetAria2Thread* uget_aria2_thread_new (UgetAria2* uaria2) { @@ -285,7 +285,7 @@ uget_aria2_recycle (uaria2, jres); } -static UG_THREAD_RETURN_TYPE uget_aria2_thread (UgetAria2Thread* uathread) +static UgThreadResult uget_aria2_thread (UgetAria2Thread* uathread) { UgetAria2* uaria2; UgJsonrpcObject* jreq = NULL; @@ -359,7 +359,7 @@ uget_aria2_thread_free (uathread); uget_aria2_unref (uaria2); - return UG_THREAD_RETURN_VALUE; + return UG_THREAD_RESULT; } // ---------------------------------------------------------------------------- @@ -546,7 +546,7 @@ char cmd[1]; } Aria2LaunchData; -static UG_THREAD_RETURN_TYPE aria2_launch_thread (Aria2LaunchData* uald) +static UgThreadResult aria2_launch_thread (Aria2LaunchData* uald) { int result; @@ -556,7 +556,7 @@ else uald->uaria2->launched = TRUE; ug_free (uald); - return UG_THREAD_RETURN_VALUE; + return UG_THREAD_RESULT; } int uget_aria2_launch (UgetAria2* uaria2) diff -Nru uget-2.2.0/uget/UgetAria2.h uget-2.2.2/uget/UgetAria2.h --- uget-2.2.0/uget/UgetAria2.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetAria2.h 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2011-2018 by C.H. Huang + * Copyright (C) 2011-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uget/UgetCurl.c uget-2.2.2/uget/UgetCurl.c --- uget-2.2.0/uget/UgetCurl.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetCurl.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -104,7 +104,7 @@ ug_free (ugcurl); } -static UG_THREAD_RETURN_TYPE uget_curl_thread (UgetCurl* ugcurl) +static UgThreadResult uget_curl_thread (UgetCurl* ugcurl) { char* tempstr; CURLcode code; @@ -237,7 +237,7 @@ if (ugcurl->state == UGET_CURL_ERROR) ugcurl->test_ok = FALSE; ugcurl->stopped = TRUE; - return UG_THREAD_RETURN_VALUE; + return UG_THREAD_RESULT; } void uget_curl_run (UgetCurl* ugcurl, int joinable) @@ -940,7 +940,6 @@ ugcurl->state = UGET_CURL_ERROR; gchar *e = ug_strdup_printf("Pwmd ERR %u: %s", rc, gpg_strerror(rc)); ugcurl->event = uget_event_new_error (UGET_EVENT_ERROR_CUSTOM, e); - fprintf(stderr, "%s\n", e); g_free(e); return FALSE; } diff -Nru uget-2.2.0/uget/UgetCurl.h uget-2.2.2/uget/UgetCurl.h --- uget-2.2.0/uget/UgetCurl.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetCurl.h 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uget/UgetData.c uget-2.2.2/uget/UgetData.c --- uget-2.2.0/uget/UgetData.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetData.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -37,48 +37,49 @@ #include #include #include +#include #include #include // ---------------------------------------------------------------------------- // UgetCommon -static void uget_common_init (UgetCommon* common); -static void uget_common_final (UgetCommon* common); -static int uget_common_assign (UgetCommon* common, UgetCommon* src); +static void uget_common_init(UgetCommon* common); +static void uget_common_final(UgetCommon* common); +static int uget_common_assign(UgetCommon* common, UgetCommon* src); static const UgEntry UgetCommonEntry[] = { -// {"name", offsetof (UgetCommon, name), UG_ENTRY_STRING, -// UG_ENTRY_SKIP_IF_NULL, NULL}, - {"uri", offsetof (UgetCommon, uri), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"mirrors", offsetof (UgetCommon, mirrors), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"file", offsetof (UgetCommon, file), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"folder", offsetof (UgetCommon, folder), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"user", offsetof (UgetCommon, user), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"password", offsetof (UgetCommon, password), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"connect-timeout", offsetof (UgetCommon, connect_timeout), + {"name", offsetof(UgetCommon, name), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"uri", offsetof(UgetCommon, uri), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"mirrors", offsetof(UgetCommon, mirrors), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"file", offsetof(UgetCommon, file), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"folder", offsetof(UgetCommon, folder), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"user", offsetof(UgetCommon, user), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"password", offsetof(UgetCommon, password), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"connect-timeout", offsetof(UgetCommon, connect_timeout), UG_ENTRY_UINT, NULL, NULL}, - {"transmit-timeout", offsetof (UgetCommon, transmit_timeout), + {"transmit-timeout", offsetof(UgetCommon, transmit_timeout), UG_ENTRY_UINT, NULL, NULL}, - {"retry-delay", offsetof (UgetCommon, retry_delay), + {"retry-delay", offsetof(UgetCommon, retry_delay), UG_ENTRY_INT, NULL, NULL}, - {"retry-limit", offsetof (UgetCommon, retry_limit), + {"retry-limit", offsetof(UgetCommon, retry_limit), UG_ENTRY_INT, NULL, NULL}, - {"retry-count", offsetof (UgetCommon, retry_count), + {"retry-count", offsetof(UgetCommon, retry_count), UG_ENTRY_INT, NULL, NULL}, - {"max-connections", offsetof (UgetCommon, max_connections), + {"max-connections", offsetof(UgetCommon, max_connections), UG_ENTRY_UINT, NULL, NULL}, - {"max-upload-speed", offsetof (UgetCommon, max_upload_speed), + {"max-upload-speed", offsetof(UgetCommon, max_upload_speed), UG_ENTRY_INT, NULL, NULL}, - {"max-download-speed", offsetof (UgetCommon, max_download_speed), + {"max-download-speed", offsetof(UgetCommon, max_download_speed), UG_ENTRY_INT, NULL, NULL}, - {"timestamp", offsetof (UgetCommon, timestamp), + {"timestamp", offsetof(UgetCommon, timestamp), UG_ENTRY_INT, NULL, NULL}, {NULL} // null-terminated }; @@ -86,16 +87,16 @@ static const UgDataInfo UgetCommonInfoStatic = { "common", // name - sizeof (UgetCommon), // size - UgetCommonEntry, + sizeof(UgetCommon), // size (UgInitFunc) uget_common_init, (UgFinalFunc) uget_common_final, (UgAssignFunc) uget_common_assign, + UgetCommonEntry, }; // extern const UgDataInfo* UgetCommonInfo = &UgetCommonInfoStatic; -static void uget_common_init (UgetCommon* common) +static void uget_common_init(UgetCommon* common) { common->connect_timeout = 15; common->transmit_timeout = 30; @@ -108,51 +109,54 @@ #endif } -static void uget_common_final (UgetCommon* common) +static void uget_common_final(UgetCommon* common) { -// ug_free (common->name); - ug_free (common->uri); - ug_free (common->mirrors); - ug_free (common->file); - ug_free (common->folder); - ug_free (common->user); - ug_free (common->password); -} - -static int uget_common_assign (UgetCommon* common, UgetCommon* src) -{ -// if (common->keeping.enable == FALSE || common->keeping.name == FALSE) { -// ug_free (common->name); -// common->name = (src->name) ? ug_strdup (src->name) : NULL; -// } + ug_free(common->name); + ug_free(common->uri); + ug_free(common->mirrors); + ug_free(common->file); + ug_free(common->folder); + ug_free(common->user); + ug_free(common->password); +} + +static int uget_common_assign(UgetCommon* common, UgetCommon* src) +{ +#if 0 + // Program can NOT copy UgetCommon::name to other one. + if (common->keeping.enable == FALSE || common->keeping.name == FALSE) { + ug_free(common->name); + common->name = (src->name) ? ug_strdup(src->name) : NULL; + } +#endif if (common->keeping.enable == FALSE || common->keeping.uri == FALSE) { - ug_free (common->uri); - common->uri = (src->uri) ? ug_strdup (src->uri) : NULL; + ug_free(common->uri); + common->uri = (src->uri) ? ug_strdup(src->uri) : NULL; common->keeping.uri = src->keeping.uri; } if (common->keeping.enable == FALSE || common->keeping.mirrors == FALSE) { - ug_free (common->mirrors); - common->mirrors = (src->mirrors) ? ug_strdup (src->mirrors) : NULL; + ug_free(common->mirrors); + common->mirrors = (src->mirrors) ? ug_strdup(src->mirrors) : NULL; common->keeping.mirrors = src->keeping.mirrors; } if (common->keeping.enable == FALSE || common->keeping.file == FALSE) { - ug_free (common->file); - common->file = (src->file) ? ug_strdup (src->file) : NULL; + ug_free(common->file); + common->file = (src->file) ? ug_strdup(src->file) : NULL; common->keeping.file = src->keeping.file; } if (common->keeping.enable == FALSE || common->keeping.folder == FALSE) { - ug_free (common->folder); - common->folder = (src->folder) ? ug_strdup (src->folder) : NULL; + ug_free(common->folder); + common->folder = (src->folder) ? ug_strdup(src->folder) : NULL; common->keeping.folder = src->keeping.folder; } if (common->keeping.enable == FALSE || common->keeping.user == FALSE) { - ug_free (common->user); - common->user = (src->user) ? ug_strdup (src->user) : NULL; + ug_free(common->user); + common->user = (src->user) ? ug_strdup(src->user) : NULL; common->keeping.user = src->keeping.user; } if (common->keeping.enable == FALSE || common->keeping.password == FALSE) { - ug_free (common->password); - common->password = (src->password) ? ug_strdup (src->password) : NULL; + ug_free(common->password); + common->password = (src->password) ? ug_strdup(src->password) : NULL; common->keeping.password = src->keeping.password; } // timeout @@ -204,28 +208,65 @@ return TRUE; } +// helper functions +char* uget_name_from_uri_str(const char* uri) +{ + UgUri uuri; + + ug_uri_init(&uuri, uri); + return uget_name_from_uri(&uuri); +} + +char* uget_name_from_uri(UgUri* uuri) +{ + const char* filename; + char* name = NULL; + int length; + + if (uuri->scheme_len == 6 && strncmp(uuri->uri, "magnet", 6) == 0) { + length = 0; + filename = strstr(uuri->uri + uuri->file, "dn="); + if (filename) { + filename = filename + 3; + length = strcspn(filename, "&"); + name = ug_malloc(length + 1); + ug_decode_uri(filename, length, name); + if (ug_utf8_get_invalid(name, NULL) != -1) + name = ug_strndup(filename, length); + } + } + if (name == NULL) { + length = ug_uri_file(uuri, &filename); + if (length == 0) + name = ug_strdup(uuri->uri); + else + name = ug_uri_get_file(uuri); + } + return name; +} + // ---------------------------------------------------------------------------- // UgetProgress static const UgEntry UgetProgressEntry[] = { - {"complete", offsetof (UgetProgress, complete), UG_ENTRY_INT64, NULL, NULL}, - {"total", offsetof (UgetProgress, total), UG_ENTRY_INT64, NULL, NULL}, - {"elapsed", offsetof (UgetProgress, elapsed), UG_ENTRY_INT64, NULL, NULL}, - {"uploaded", offsetof (UgetProgress, uploaded), UG_ENTRY_INT64, NULL, NULL}, - {"percent", offsetof (UgetProgress, percent), UG_ENTRY_INT, NULL, NULL}, -// {"ratio", offsetof (UgetProgress, ratio), UG_ENTRY_DOUBLE, NULL, NULL}, + {"complete", offsetof(UgetProgress, complete), UG_ENTRY_INT64, NULL, NULL}, + {"total", offsetof(UgetProgress, total), UG_ENTRY_INT64, NULL, NULL}, + {"elapsed", offsetof(UgetProgress, elapsed), UG_ENTRY_INT64, NULL, NULL}, + {"uploaded", offsetof(UgetProgress, uploaded), UG_ENTRY_INT64, NULL, NULL}, + {"percent", offsetof(UgetProgress, percent), UG_ENTRY_INT, NULL, NULL}, +// {"ratio", offsetof(UgetProgress, ratio), UG_ENTRY_DOUBLE, NULL, NULL}, {NULL} // null-terminated }; static const UgDataInfo UgetProgressInfoStatic = { "progress", // name - sizeof (UgetProgress), // size - UgetProgressEntry, + sizeof(UgetProgress), // size (UgInitFunc) NULL, (UgFinalFunc) NULL, (UgAssignFunc) NULL, + UgetProgressEntry, }; // extern const UgDataInfo* UgetProgressInfo = &UgetProgressInfoStatic; @@ -239,31 +280,31 @@ #ifdef HAVE_LIBPWMD static const UgEntry UgetProxyPwmdEntry[] = { - {"socket", offsetof (struct UgetProxyPwmd, socket), + {"socket", offsetof(struct UgetProxyPwmd, socket), UG_ENTRY_STRING, NULL, NULL}, - {"socket-args", offsetof (struct UgetProxyPwmd, socket_args), + {"socket-args", offsetof(struct UgetProxyPwmd, socket_args), UG_ENTRY_STRING, NULL, NULL}, - {"file", offsetof (struct UgetProxyPwmd, file), + {"file", offsetof(struct UgetProxyPwmd, file), UG_ENTRY_STRING, NULL, NULL}, - {"element", offsetof (struct UgetProxyPwmd, element), + {"element", offsetof(struct UgetProxyPwmd, element), UG_ENTRY_STRING, NULL, NULL}, }; #endif // End of HAVE_LIBPWMD static const UgEntry UgetProxyEntry[] = { - {"host", offsetof (UgetProxy, host), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"port", offsetof (UgetProxy, port), UG_ENTRY_UINT, + {"host", offsetof(UgetProxy, host), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"port", offsetof(UgetProxy, port), UG_ENTRY_UINT, NULL, NULL}, - {"type", offsetof (UgetProxy, type), UG_ENTRY_UINT, + {"type", offsetof(UgetProxy, type), UG_ENTRY_UINT, NULL, NULL}, - {"user", offsetof (UgetProxy, user), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"password", offsetof (UgetProxy, password), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, + {"user", offsetof(UgetProxy, user), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"password", offsetof(UgetProxy, password), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, #ifdef HAVE_LIBPWMD - {"pwmd", offsetof (UgetProxy, pwmd), + {"pwmd", offsetof(UgetProxy, pwmd), UG_ENTRY_OBJECT, (void*) UgetProxyPwmdEntry, NULL}, #endif {NULL}, // null-terminated @@ -272,35 +313,34 @@ static const UgDataInfo UgetProxyInfoStatic = { "proxy", // name - sizeof (UgetProxy), // size - UgetProxyEntry, // entry - + sizeof(UgetProxy), // size (UgInitFunc) NULL, (UgFinalFunc) uget_proxy_final, (UgAssignFunc) uget_proxy_assign, + UgetProxyEntry, // entry }; // extern const UgDataInfo* UgetProxyInfo = &UgetProxyInfoStatic; -static void uget_proxy_final (UgetProxy* proxy) +static void uget_proxy_final(UgetProxy* proxy) { - ug_free (proxy->host); - ug_free (proxy->user); - ug_free (proxy->password); + ug_free(proxy->host); + ug_free(proxy->user); + ug_free(proxy->password); #ifdef HAVE_LIBPWMD - ug_free (proxy->pwmd.socket); - ug_free (proxy->pwmd.socket_args); - ug_free (proxy->pwmd.file); - ug_free (proxy->pwmd.element); + ug_free(proxy->pwmd.socket); + ug_free(proxy->pwmd.socket_args); + ug_free(proxy->pwmd.file); + ug_free(proxy->pwmd.element); #endif // HAVE_LIBPWMD } -static int uget_proxy_assign (UgetProxy* proxy, UgetProxy* src) +static int uget_proxy_assign(UgetProxy* proxy, UgetProxy* src) { if (proxy->keeping.enable == FALSE || proxy->keeping.host == FALSE) { - ug_free (proxy->host); - proxy->host = (src->host) ? ug_strdup (src->host) : NULL; + ug_free(proxy->host); + proxy->host = (src->host) ? ug_strdup(src->host) : NULL; proxy->keeping.host = src->keeping.host; } if (proxy->keeping.enable == FALSE || proxy->keeping.port == FALSE) { @@ -313,35 +353,35 @@ } if (proxy->keeping.enable == FALSE || proxy->keeping.user == FALSE) { - ug_free (proxy->user); - proxy->user = (src->user) ? ug_strdup (src->user) : NULL; + ug_free(proxy->user); + proxy->user = (src->user) ? ug_strdup(src->user) : NULL; proxy->keeping.user = src->keeping.user; } if (proxy->keeping.enable == FALSE || proxy->keeping.password == FALSE) { - ug_free (proxy->password); - proxy->password = (src->password) ? ug_strdup (src->password) : NULL; + ug_free(proxy->password); + proxy->password = (src->password) ? ug_strdup(src->password) : NULL; proxy->keeping.password = src->keeping.password; } #ifdef HAVE_LIBPWMD if (proxy->keeping.enable == FALSE || proxy->pwmd.keeping.socket == FALSE) { - ug_free (proxy->pwmd.socket); - proxy->pwmd.socket = (src->pwmd.socket) ? ug_strdup (src->pwmd.socket) : NULL; + ug_free(proxy->pwmd.socket); + proxy->pwmd.socket = (src->pwmd.socket) ? ug_strdup(src->pwmd.socket) : NULL; proxy->pwmd.keeping.socket = src->pwmd.keeping.socket; } if (proxy->keeping.enable == FALSE || proxy->pwmd.keeping.socket_args == FALSE) { - ug_free (proxy->pwmd.socket_args); - proxy->pwmd.socket_args = (src->pwmd.socket_args) ? ug_strdup (src->pwmd.socket_args) : NULL; + ug_free(proxy->pwmd.socket_args); + proxy->pwmd.socket_args = (src->pwmd.socket_args) ? ug_strdup(src->pwmd.socket_args) : NULL; proxy->pwmd.keeping.socket_args = src->pwmd.keeping.socket_args; } if (proxy->keeping.enable == FALSE || proxy->pwmd.keeping.file == FALSE) { - ug_free (proxy->pwmd.file); - proxy->pwmd.file = (src->pwmd.file) ? ug_strdup (src->pwmd.file) : NULL; + ug_free(proxy->pwmd.file); + proxy->pwmd.file = (src->pwmd.file) ? ug_strdup(src->pwmd.file) : NULL; proxy->pwmd.keeping.file = src->pwmd.keeping.file; } if (proxy->keeping.enable == FALSE || proxy->pwmd.keeping.element == FALSE) { - ug_free (proxy->pwmd.element); - proxy->pwmd.element = (src->pwmd.element) ? ug_strdup (src->pwmd.element) : NULL; + ug_free(proxy->pwmd.element); + proxy->pwmd.element = (src->pwmd.element) ? ug_strdup(src->pwmd.element) : NULL; proxy->pwmd.keeping.element = src->pwmd.keeping.element; } #endif // HAVE_LIBPWMD @@ -361,23 +401,23 @@ static const UgEntry UgetHttpEntry[] = { - {"user", offsetof (UgetHttp, user), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"password", offsetof (UgetHttp, password), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"referrer", offsetof (UgetHttp, referrer), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"user-agent", offsetof (UgetHttp, user_agent), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"post-data", offsetof (UgetHttp, post_data), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"post-file", offsetof (UgetHttp, post_file), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"cookie-data", offsetof (UgetHttp, cookie_data), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"cookie-file", offsetof (UgetHttp, cookie_file), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"redirection-limit", offsetof (UgetHttp, redirection_limit),UG_ENTRY_UINT, + {"user", offsetof(UgetHttp, user), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"password", offsetof(UgetHttp, password), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"referrer", offsetof(UgetHttp, referrer), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"user-agent", offsetof(UgetHttp, user_agent), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"post-data", offsetof(UgetHttp, post_data), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"post-file", offsetof(UgetHttp, post_file), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"cookie-data", offsetof(UgetHttp, cookie_data), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"cookie-file", offsetof(UgetHttp, cookie_file), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"redirection-limit", offsetof(UgetHttp, redirection_limit),UG_ENTRY_UINT, NULL, NULL}, {NULL}, // null-terminated }; @@ -385,73 +425,72 @@ static const UgDataInfo UgetHttpInfoStatic = { "http", // name - sizeof (UgetHttp), // size - UgetHttpEntry, // entry - + sizeof(UgetHttp), // size (UgInitFunc) uget_http_init, (UgFinalFunc) uget_http_final, (UgAssignFunc) uget_http_assign, + UgetHttpEntry, // entry }; // extern const UgDataInfo* UgetHttpInfo = &UgetHttpInfoStatic; -static void uget_http_init (UgetHttp* http) +static void uget_http_init(UgetHttp* http) { http->redirection_limit = 30; } -static void uget_http_final (UgetHttp* http) +static void uget_http_final(UgetHttp* http) { - ug_free (http->user); - ug_free (http->password); - ug_free (http->referrer); - ug_free (http->user_agent); - ug_free (http->post_data); - ug_free (http->post_file); - ug_free (http->cookie_data); - ug_free (http->cookie_file); + ug_free(http->user); + ug_free(http->password); + ug_free(http->referrer); + ug_free(http->user_agent); + ug_free(http->post_data); + ug_free(http->post_file); + ug_free(http->cookie_data); + ug_free(http->cookie_file); } -static int uget_http_assign (UgetHttp* http, UgetHttp* src) +static int uget_http_assign(UgetHttp* http, UgetHttp* src) { if (http->keeping.enable == FALSE || http->keeping.user == FALSE) { - ug_free (http->user); - http->user = (src->user) ? ug_strdup (src->user) : NULL; + ug_free(http->user); + http->user = (src->user) ? ug_strdup(src->user) : NULL; http->keeping.user = src->keeping.user; } if (http->keeping.enable == FALSE || http->keeping.password == FALSE) { - ug_free (http->password); - http->password = (src->password) ? ug_strdup (src->password) : NULL; + ug_free(http->password); + http->password = (src->password) ? ug_strdup(src->password) : NULL; http->keeping.password = src->keeping.password; } if (http->keeping.enable == FALSE || http->keeping.referrer == FALSE) { - ug_free (http->referrer); - http->referrer = (src->referrer) ? ug_strdup (src->referrer) : NULL; + ug_free(http->referrer); + http->referrer = (src->referrer) ? ug_strdup(src->referrer) : NULL; http->keeping.referrer = src->keeping.referrer; } if (http->keeping.enable == FALSE || http->keeping.user_agent == FALSE) { - ug_free (http->user_agent); - http->user_agent = (src->user_agent) ? ug_strdup (src->user_agent) : NULL; + ug_free(http->user_agent); + http->user_agent = (src->user_agent) ? ug_strdup(src->user_agent) : NULL; http->keeping.user_agent = src->keeping.user_agent; } if (http->keeping.enable == FALSE || http->keeping.post_data == FALSE) { - ug_free (http->post_data); - http->post_data = (src->post_data) ? ug_strdup (src->post_data) : NULL; + ug_free(http->post_data); + http->post_data = (src->post_data) ? ug_strdup(src->post_data) : NULL; http->keeping.post_data = src->keeping.post_data; } if (http->keeping.enable == FALSE || http->keeping.post_file == FALSE) { - ug_free (http->post_file); - http->post_file = (src->post_file) ? ug_strdup (src->post_file) : NULL; + ug_free(http->post_file); + http->post_file = (src->post_file) ? ug_strdup(src->post_file) : NULL; http->keeping.post_file = src->keeping.post_file; } if (http->keeping.enable == FALSE || http->keeping.cookie_data == FALSE) { ug_free (http->cookie_data); - http->cookie_data = (src->cookie_data) ? ug_strdup (src->cookie_data) : NULL; + http->cookie_data = (src->cookie_data) ? ug_strdup(src->cookie_data) : NULL; http->keeping.cookie_data = src->keeping.cookie_data; } if (http->keeping.enable == FALSE || http->keeping.cookie_file == FALSE) { - ug_free (http->cookie_file); - http->cookie_file = (src->cookie_file) ? ug_strdup (src->cookie_file) : NULL; + ug_free(http->cookie_file); + http->cookie_file = (src->cookie_file) ? ug_strdup(src->cookie_file) : NULL; http->keeping.cookie_file = src->keeping.cookie_file; } if (http->keeping.enable == FALSE || http->keeping.redirection_limit == FALSE) { @@ -473,11 +512,11 @@ static const UgEntry UgetFtpEntry[] = { - {"user", offsetof (UgetFtp, user), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"password", offsetof (UgetFtp, password), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"active-mode", offsetof (UgetFtp, active_mode), UG_ENTRY_INT, + {"user", offsetof(UgetFtp, user), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"password", offsetof(UgetFtp, password), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"active-mode", offsetof(UgetFtp, active_mode), UG_ENTRY_INT, NULL, NULL}, {NULL}, // null-terminated }; @@ -485,32 +524,31 @@ static const UgDataInfo UgetFtpInfoStatic = { "ftp", // name - sizeof (UgetFtp), // size - UgetFtpEntry, // entry - + sizeof(UgetFtp), // size (UgInitFunc) NULL, (UgFinalFunc) uget_ftp_final, (UgAssignFunc) uget_ftp_assign, + UgetFtpEntry, // entry }; // extern const UgDataInfo* UgetFtpInfo = &UgetFtpInfoStatic; -static void uget_ftp_final (UgetFtp* ftp) +static void uget_ftp_final(UgetFtp* ftp) { - ug_free (ftp->user); - ug_free (ftp->password); + ug_free(ftp->user); + ug_free(ftp->password); } -static int uget_ftp_assign (UgetFtp* ftp, UgetFtp* src) +static int uget_ftp_assign(UgetFtp* ftp, UgetFtp* src) { if (ftp->keeping.enable == FALSE || ftp->keeping.user == FALSE) { - ug_free (ftp->user); - ftp->user = (src->user) ? ug_strdup (src->user) : NULL; + ug_free(ftp->user); + ftp->user = (src->user) ? ug_strdup(src->user) : NULL; ftp->keeping.user = src->keeping.user; } if (ftp->keeping.enable == FALSE || ftp->keeping.password == FALSE) { - ug_free (ftp->password); - ftp->password = (src->password) ? ug_strdup (src->password) : NULL; + ug_free(ftp->password); + ftp->password = (src->password) ? ug_strdup(src->password) : NULL; ftp->keeping.password = src->keeping.password; } @@ -528,19 +566,19 @@ // --------------------------------------------------------------------------- // UgetLog -static void uget_log_final (UgetLog* log); -static void ug_json_write_list_message (UgJson* json, UgList* list); -static UgJsonError ug_json_parse_list_message (UgJson* json, const char* name, - const char* value, - void* list, void* none); +static void uget_log_final(UgetLog* log); +static void ug_json_write_list_message(UgJson* json, UgList* list); +static UgJsonError ug_json_parse_list_message(UgJson* json, const char* name, + const char* value, + void* list, void* none); static const UgEntry UgetLogEntry[] = { - {"added-time", offsetof (UgetLog, added_time), UG_ENTRY_CUSTOM, + {"added-time", offsetof(UgetLog, added_time), UG_ENTRY_CUSTOM, ug_json_parse_time_t, ug_json_write_time_t}, - {"completed-time", offsetof (UgetLog, completed_time), UG_ENTRY_CUSTOM, + {"completed-time", offsetof(UgetLog, completed_time), UG_ENTRY_CUSTOM, ug_json_parse_time_t, ug_json_write_time_t}, - {"messages", offsetof (UgetLog, messages), UG_ENTRY_ARRAY, + {"messages", offsetof(UgetLog, messages), UG_ENTRY_ARRAY, ug_json_parse_list_message, ug_json_write_list_message}, {NULL}, // null-terminated }; @@ -548,111 +586,127 @@ static const UgDataInfo UgetLogInfoStatic = { "log", // name - sizeof (UgetLog), // size - UgetLogEntry, // entry - + sizeof(UgetLog), // size (UgInitFunc) NULL, (UgFinalFunc) uget_log_final, (UgAssignFunc) NULL, + UgetLogEntry, // entry }; // extern const UgDataInfo* UgetLogInfo = &UgetLogInfoStatic; -static void uget_log_final (UgetLog* log) +static void uget_log_final(UgetLog* log) { - ug_list_foreach (&log->messages, (UgForeachFunc) uget_event_free, NULL); + ug_list_foreach(&log->messages, (UgForeachFunc) uget_event_free, NULL); } -static UgJsonError ug_json_parse_list_message (UgJson* json, const char* name, - const char* value, - void* list, void* none) +static UgJsonError ug_json_parse_list_message(UgJson* json, const char* name, + const char* value, + void* list, void* none) { UgetEvent* event; if (json->type != UG_JSON_OBJECT) return UG_JSON_ERROR_TYPE_NOT_MATCH; - event = uget_event_new (UGET_EVENT_EMPTY); - ug_list_append (list, (UgLink*) event); - ug_json_push (json, ug_json_parse_entry, event, (void*) UgetEventEntry); + event = uget_event_new(UGET_EVENT_EMPTY); + ug_list_append(list, (UgLink*) event); + ug_json_push(json, ug_json_parse_entry, event, (void*) UgetEventEntry); return UG_JSON_ERROR_NONE; } -void ug_json_write_list_message (UgJson* json, UgList* list) +void ug_json_write_list_message(UgJson* json, UgList* list) { UgetEvent* link; for (link = (void*)list->head; link; link = link->next) { - ug_json_write_object_head (json); - ug_json_write_entry (json, link, UgetEventEntry); - ug_json_write_object_tail (json); + ug_json_write_object_head(json); + ug_json_write_entry(json, link, UgetEventEntry); + ug_json_write_object_tail(json); } } // ---------------------------------------------------------------------------- // UgetRelation -static void uget_relation_init (UgetRelation* relation); +static void uget_relation_init(UgetRelation* relation); +static void uget_relation_final(UgetRelation* relation); -static const UgEntry UgetRelationTaskEntry[] = -{ - {"plugin-name", - offsetof (struct UgetRelationTask, plugin_name), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, - NULL}, - {"priority", - offsetof (struct UgetRelationTask, priority), UG_ENTRY_INT, - NULL, - NULL}, - {NULL} // null-terminated -}; +// deprecated +static UgJsonError ug_json_parse_task_priority (UgJson* json, + const char* name, const char* value, + void* prelation, void* none); static const UgEntry UgetRelationEntry[] = { - {"task", offsetof (UgetRelation, task), UG_ENTRY_OBJECT, - (void*) UgetRelationTaskEntry, - (UgInitFunc) NULL}, + {"group", offsetof(UgetRelation, group), UG_ENTRY_INT, + NULL, NULL}, + {"priority", offsetof(UgetRelation, priority), UG_ENTRY_INT, + NULL, NULL}, + + // deprecated + {"task", 0, UG_ENTRY_CUSTOM, ug_json_parse_task_priority, NULL}, {NULL} // null-terminated }; static const UgDataInfo UgetRelationInfoStatic = { "relation", // name - sizeof (UgetRelation), // size - UgetRelationEntry, + sizeof(UgetRelation), // size (UgInitFunc) uget_relation_init, - (UgFinalFunc) NULL, + (UgFinalFunc) uget_relation_final, (UgAssignFunc) NULL, + UgetRelationEntry, }; // extern const UgDataInfo* UgetRelationInfo = &UgetRelationInfoStatic; -static void uget_relation_init (UgetRelation* relation) +static void uget_relation_init(UgetRelation* relation) { - relation->task.priority = UGET_PRIORITY_NORMAL; + relation->priority = UGET_PRIORITY_NORMAL; +} + +static void uget_relation_final(UgetRelation* relation) +{ + ug_free(relation->task); +} + +// deprecated - convert old format to new +static UgJsonError ug_json_parse_task_priority (UgJson* json, + const char* name, const char* value, + void* prelation, void* none) +{ + UgetRelation* relation = prelation; + + if (strcmp(name, "task") == 0 && json->type == UG_JSON_OBJECT) + ug_json_push(json, ug_json_parse_task_priority, relation, none); + else if (strcmp(name, "priority") == 0 && json->type == UG_JSON_NUMBER) + relation->priority = strtol(value, NULL, 10); + + return UG_JSON_ERROR_NONE; } // ---------------------------------------------------------------------------- // UgetCategory -static void uget_category_init (UgetCategory* category); -static void uget_category_final (UgetCategory* category); -static int uget_category_assign (UgetCategory* category, UgetCategory* src); -static void ug_array_str_copy (UgArrayStr* dest, UgArrayStr* src); +static void uget_category_init(UgetCategory* category); +static void uget_category_final(UgetCategory* category); +static int uget_category_assign(UgetCategory* category, UgetCategory* src); +static void ug_array_str_copy(UgArrayStr* dest, UgArrayStr* src); static const UgEntry UgetCategoryEntry[] = { - {"hosts", offsetof (UgetCategory, hosts), UG_ENTRY_ARRAY, + {"hosts", offsetof(UgetCategory, hosts), UG_ENTRY_ARRAY, ug_json_parse_array_string, ug_json_write_array_string}, - {"schemes", offsetof (UgetCategory, schemes), UG_ENTRY_ARRAY, + {"schemes", offsetof(UgetCategory, schemes), UG_ENTRY_ARRAY, ug_json_parse_array_string, ug_json_write_array_string}, - {"file-exts", offsetof (UgetCategory, file_exts), UG_ENTRY_ARRAY, + {"file-exts", offsetof(UgetCategory, file_exts), UG_ENTRY_ARRAY, ug_json_parse_array_string, ug_json_write_array_string}, - {"active-limit", offsetof (UgetCategory, active_limit), UG_ENTRY_UINT, + {"active-limit", offsetof(UgetCategory, active_limit), UG_ENTRY_INT, NULL, NULL}, - {"finished-limit", offsetof (UgetCategory, finished_limit), UG_ENTRY_UINT, + {"finished-limit", offsetof(UgetCategory, finished_limit), UG_ENTRY_INT, NULL, NULL}, - {"recycled-limit", offsetof (UgetCategory, recycled_limit), UG_ENTRY_UINT, + {"recycled-limit", offsetof(UgetCategory, recycled_limit), UG_ENTRY_INT, NULL, NULL}, {NULL} // null-terminated }; @@ -660,55 +714,55 @@ static const UgDataInfo UgetCategoryInfoStatic = { "category", // name - sizeof (UgetCategory), // size - UgetCategoryEntry, + sizeof(UgetCategory), // size (UgInitFunc) uget_category_init, (UgFinalFunc) uget_category_final, (UgAssignFunc) uget_category_assign, + UgetCategoryEntry, }; // extern const UgDataInfo* UgetCategoryInfo = &UgetCategoryInfoStatic; -static void uget_category_init (UgetCategory* category) +static void uget_category_init(UgetCategory* category) { - ug_array_init (&category->hosts, sizeof (char*), 8); - ug_array_init (&category->schemes, sizeof (char*), 8); - ug_array_init (&category->file_exts, sizeof (char*), 8); + ug_array_init(&category->hosts, sizeof(char*), 8); + ug_array_init(&category->schemes, sizeof(char*), 8); + ug_array_init(&category->file_exts, sizeof(char*), 8); category->active_limit = 3; category->finished_limit = 300; category->recycled_limit = 300; } -static void uget_category_final (UgetCategory* category) +static void uget_category_final(UgetCategory* category) { - ug_array_foreach_str (&category->hosts, (UgForeachFunc) ug_free, NULL); - ug_array_foreach_str (&category->schemes, (UgForeachFunc) ug_free, NULL); - ug_array_foreach_str (&category->file_exts, (UgForeachFunc) ug_free, NULL); - ug_array_clear (&category->hosts); - ug_array_clear (&category->schemes); - ug_array_clear (&category->file_exts); + ug_array_foreach_str(&category->hosts, (UgForeachFunc) ug_free, NULL); + ug_array_foreach_str(&category->schemes, (UgForeachFunc) ug_free, NULL); + ug_array_foreach_str(&category->file_exts, (UgForeachFunc) ug_free, NULL); + ug_array_clear(&category->hosts); + ug_array_clear(&category->schemes); + ug_array_clear(&category->file_exts); } -static int uget_category_assign (UgetCategory* category, UgetCategory* src) +static int uget_category_assign(UgetCategory* category, UgetCategory* src) { category->active_limit = src->active_limit; category->finished_limit = src->finished_limit; category->recycled_limit = src->recycled_limit; - ug_array_str_copy (&category->schemes, &src->schemes); - ug_array_str_copy (&category->hosts, &src->hosts); - ug_array_str_copy (&category->file_exts, &src->file_exts); + ug_array_str_copy(&category->schemes, &src->schemes); + ug_array_str_copy(&category->hosts, &src->hosts); + ug_array_str_copy(&category->file_exts, &src->file_exts); return TRUE; } -static void ug_array_str_copy (UgArrayStr* dest, UgArrayStr* src) +static void ug_array_str_copy(UgArrayStr* dest, UgArrayStr* src) { int index; - ug_array_foreach_str (dest, (UgForeachFunc) ug_free, NULL); + ug_array_foreach_str(dest, (UgForeachFunc) ug_free, NULL); dest->length = 0; for (index = 0; index < src->length; index++) - *(char**) ug_array_alloc (dest, 1) = ug_strdup (src->at[index]); + *(char**) ug_array_alloc(dest, 1) = ug_strdup(src->at[index]); } diff -Nru uget-2.2.0/uget/UgetData.h uget-2.2.2/uget/UgetData.h --- uget-2.2.0/uget/UgetData.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetData.h 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -38,13 +38,16 @@ #define UGET_DATA_H #include +#include #include +#include #include #ifdef __cplusplus extern "C" { #endif +// group data typedef struct UgetCommon UgetCommon; typedef struct UgetProgress UgetProgress; typedef struct UgetProxy UgetProxy; @@ -63,15 +66,22 @@ extern const UgDataInfo* UgetRelationInfo; extern const UgDataInfo* UgetCategoryInfo; -// ---------------------------------------------------------------------------- -// UgetCommon: It derived from UgData and store in UgInfo. +/* ---------------------------------------------------------------------------- + UgetCommon: It derived from UgData and store in UgInfo. + + UgType + | + `-- UgData + | + `-- UgetCommon + */ struct UgetCommon { - UG_DATA_MEMBERS; // It derived from UgData -// const UgDataInfo* info; + UG_DATA_MEMBERS; +// const UgDataInfo* info; // UgData(UgType) member -// char* name; + char* name; char* uri; char* mirrors; char* file; @@ -101,7 +111,7 @@ struct { uint8_t enable:1; -// uint8_t name:1; + uint8_t name:1; uint8_t uri:1; uint8_t mirrors:1; uint8_t file:1; @@ -123,13 +133,24 @@ } keeping; }; -// ---------------------------------------------------------------------------- -// UgetProgress: It derived from UgData and store in UgInfo. +// helper functions for UgetCommon::name +char* uget_name_from_uri(UgUri* uri); +char* uget_name_from_uri_str(const char* uri); + +/* ---------------------------------------------------------------------------- + UgetProgress: It derived from UgData and store in UgInfo. + + UgType + | + `-- UgData + | + `-- UgetProgress + */ struct UgetProgress { - UG_DATA_MEMBERS; // It derived from UgData -// const UgDataInfo* info; + UG_DATA_MEMBERS; +// const UgDataInfo* info; // UgData(UgType) member int64_t elapsed; // consume time (seconds) int64_t left; // remain time (seconds) @@ -144,8 +165,15 @@ int percent; }; -// ---------------------------------------------------------------------------- -// UgetProxy: It derived from UgData and store in UgInfo. +/* ---------------------------------------------------------------------------- + UgetProxy: It derived from UgData and store in UgInfo. + + UgType + | + `-- UgData + | + `-- UgetProxy + */ typedef enum { @@ -163,8 +191,8 @@ struct UgetProxy { - UG_DATA_MEMBERS; // It derived from UgData -// const UgDataInfo* info; + UG_DATA_MEMBERS; +// const UgDataInfo* info; // UgData(UgType) member char* host; unsigned int port; @@ -201,13 +229,20 @@ #endif // HAVE_LIBPWMD }; -// ---------------------------------------------------------------------------- -// UgetHttp: It derived from UgData and store in UgInfo. +/* ---------------------------------------------------------------------------- + UgetHttp: It derived from UgData and store in UgInfo. + + UgType + | + `-- UgData + | + `-- UgetHttp + */ struct UgetHttp { - UG_DATA_MEMBERS; // It derived from UgData -// const UgDataInfo* info; + UG_DATA_MEMBERS; +// const UgDataInfo* info; // UgData(UgType) member char* user; char* password; @@ -238,13 +273,20 @@ } keeping; }; -// ---------------------------------------------------------------------------- -// UgetFtp: It derived from UgData and store in UgInfo. +/* ---------------------------------------------------------------------------- + UgetFtp: It derived from UgData and store in UgInfo. + + UgType + | + `-- UgData + | + `-- UgetFtp + */ struct UgetFtp { - UG_DATA_MEMBERS; // It derived from UgData -// const UgDataInfo* iface; + UG_DATA_MEMBERS; +// const UgDataInfo* info; // UgData(UgType) member char* user; char* password; @@ -260,13 +302,20 @@ } keeping; }; -// --------------------------------------------------------------------------- -// UgetLog +/* --------------------------------------------------------------------------- + UgetLog + + UgType + | + `-- UgData + | + `-- UgetLog + */ struct UgetLog { - UG_DATA_MEMBERS; // It derived from UgData -// const UgDataInfo* info; + UG_DATA_MEMBERS; +// const UgDataInfo* info; // UgData(UgType) member time_t added_time; time_t completed_time; @@ -274,8 +323,15 @@ UgList messages; // List for UgetEvent }; -// ---------------------------------------------------------------------------- -// UgetRelation: It derived from UgData and store in UgInfo. +/* ---------------------------------------------------------------------------- + UgetRelation: It derived from UgData and store in UgInfo. + + UgType + | + `-- UgData + | + `-- UgetRelation + */ typedef enum { @@ -286,42 +342,36 @@ struct UgetRelation { - UG_DATA_MEMBERS; // It derived from UgData -// const UgDataInfo* info; + UG_DATA_MEMBERS; +// const UgDataInfo* info; // UgData(UgType) member + + int group; // UgetGroup + int priority; // UgetPriority // used by UgetTask struct UgetRelationTask { UgetRelation* prev; UgetPlugin* plugin; - char* plugin_name; - int priority; // UgetPriority // speed control int speed[2]; // current speed int limit[2]; // current speed limit - } task; - - // call destroy.func(destroy.data) when destroying. - struct { - UgNotifyFunc func; - void* data; - } destroy; - - // used by user application - struct { - void* pointer; - void* storage; - void* position; - void* data[4]; - } user; + }* task; }; -// ---------------------------------------------------------------------------- -// UgetCategory: It derived from UgData and store in UgInfo. +/* ---------------------------------------------------------------------------- + UgetCategory: It derived from UgData and store in UgInfo. + + UgType + | + `-- UgData + | + `-- UgetCategory + */ struct UgetCategory { - UG_DATA_MEMBERS; // It derived from UgData -// const UgDataInfo* info; + UG_DATA_MEMBERS; +// const UgDataInfo* info; // UgData(UgType) member // use these to classify download UgArrayStr hosts; @@ -330,10 +380,10 @@ // limit int active_limit; - int finished_limit; // finished: completed and paused + int finished_limit; // finished: completed and stopped int recycled_limit; - // 4 fake sub-category tree + // subcategory in UgetNode::fake UgetNode* active; UgetNode* queuing; UgetNode* finished; @@ -353,15 +403,63 @@ namespace Uget { +const UgDataInfo* const CommonInfo = UgetCommonInfo; +const UgDataInfo* const ProgressInfo = UgetProgressInfo; +const UgDataInfo* const ProxyInfo = UgetProxyInfo; +const UgDataInfo* const HttpInfo = UgetHttpInfo; +const UgDataInfo* const FtpInfo = UgetFtpInfo; +const UgDataInfo* const LogInfo = UgetLogInfo; +const UgDataInfo* const RelationInfo = UgetRelationInfo; +const UgDataInfo* const CategoryInfo = UgetCategoryInfo; + // These are for directly use only. You can NOT derived it. -struct Common : Ug::DataMethod, UgetCommon {}; -struct Progress : Ug::DataMethod, UgetProgress {}; -struct Proxy : Ug::DataMethod, UgetProxy {}; -struct Http : Ug::DataMethod, UgetHttp {}; -struct Ftp : Ug::DataMethod, UgetFtp {}; -struct Log : Ug::DataMethod, UgetLog {}; -struct Relation : Ug::DataMethod, UgetRelation {}; -struct Category : Ug::DataMethod, UgetCategory {}; +struct Common : Ug::DataMethod, UgetCommon +{ + inline void* operator new(size_t size) + { return ug_data_new(UgetCommonInfo); } +}; + +struct Progress : Ug::DataMethod, UgetProgress +{ + inline void* operator new(size_t size) + { return ug_data_new(UgetProgressInfo); } +}; + +struct Proxy : Ug::DataMethod, UgetProxy +{ + inline void* operator new(size_t size) + { return ug_data_new(UgetProxyInfo); } +}; + +struct Http : Ug::DataMethod, UgetHttp +{ + inline void* operator new(size_t size) + { return ug_data_new(UgetHttpInfo); } +}; + +struct Ftp : Ug::DataMethod, UgetFtp +{ + inline void* operator new(size_t size) + { return ug_data_new(UgetFtpInfo); } +}; + +struct Log : Ug::DataMethod, UgetLog +{ + inline void* operator new(size_t size) + { return ug_data_new(UgetLogInfo); } +}; + +struct Relation : Ug::DataMethod, UgetRelation +{ + inline void* operator new(size_t size) + { return ug_data_new(UgetRelationInfo); } +}; + +struct Category : Ug::DataMethod, UgetCategory +{ + inline void* operator new(size_t size) + { return ug_data_new(UgetCategoryInfo); } +}; }; // namespace Uget diff -Nru uget-2.2.0/uget/UgetEvent.c uget-2.2.2/uget/UgetEvent.c --- uget-2.2.0/uget/UgetEvent.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetEvent.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -162,16 +162,7 @@ #endif // HAVE_GLIB } break; -/* - case UGET_EVENT_INSERT: - case UGET_EVENT_REMOVE: - event->value.child = va_arg (arg_list, UgetNode*); - break; - case UGET_EVENT_INFO: - event->value.info = va_arg (arg_list, const UgDataInfo*); - break; -*/ default: break; } diff -Nru uget-2.2.0/uget/UgetEvent.h uget-2.2.2/uget/UgetEvent.h --- uget-2.2.0/uget/UgetEvent.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetEvent.h 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -63,17 +63,10 @@ UGET_EVENT_START, UGET_EVENT_COMPLETED, // Download completed UGET_EVENT_UPLOADING, // Uploading + UGET_EVENT_STOP_UPLOADING, // events for uget_task_dispatch() UGET_EVENT_NAME, // UgetNode's name changed - -/* - // events for uget_plugin_sync() - UGET_EVENT_INSERT, - UGET_EVENT_REMOVE, - UGET_EVENT_RENAME, - UGET_EVENT_INFO, - */ } UgetEventType; typedef enum @@ -127,9 +120,11 @@ struct UgetEvent { UG_LINK_MEMBERS (UgetEvent, UgetEvent, self); -// UgetEvent* self; -// UgetEvent* next; -// UgetEvent* prev; +/* // ------ UgLink members ------ + UgetEvent* self; + UgetEvent* next; + UgetEvent* prev; + */ int type; // UgetEventType time_t time; // date & time (seconds) @@ -137,10 +132,8 @@ // extra data union { - const UgDataInfo* info; // UGET_EVENT_INFO - UgetNode* node; // UGET_EVENT_INSERT or UGET_EVENT_REMOVE void* data; - int code; // UGET_EVENT_ERROR, UGET_EVENT_WARNING, UGET_EVENT_NORMAL + int code; // UGET_EVENT_ERROR, UGET_EVENT_WARNING, UGET_EVENT_NORMAL } value; // } value[3]; }; @@ -151,16 +144,10 @@ #define uget_event_new_error(code, string) uget_event_new (UGET_EVENT_ERROR, code, string) #define uget_event_new_normal(code, string) uget_event_new (UGET_EVENT_NORMAL, code, string) #define uget_event_new_warning(code, string) uget_event_new (UGET_EVENT_WARNING, code, string) -//UgetEvent* uget_event_new_error (int code, const char* string); -//UgetEvent* uget_event_new_normal (int code, const char* string); -//UgetEvent* uget_event_new_warning (int code, const char* string); - /* -// events for uget_plugin_sync() -UgetEvent* uget_event_new_info (UgetNode* node, const UgDataInfo* info, void* data); -UgetEvent* uget_event_new_inserted (UgetNode* node, UgetNode* child); -UgetEvent* uget_event_new_removed (UgetNode* node, UgetNode* child); -UgetEvent* uget_event_new_renamed (UgetNode* node, const char* name); +UgetEvent* uget_event_new_error (int code, const char* string); +UgetEvent* uget_event_new_normal (int code, const char* string); +UgetEvent* uget_event_new_warning (int code, const char* string); */ #ifdef __cplusplus diff -Nru uget-2.2.0/uget/UgetFiles.c uget-2.2.2/uget/UgetFiles.c --- uget-2.2.0/uget/UgetFiles.c 1970-01-01 00:00:00.000000000 +0000 +++ uget-2.2.2/uget/UgetFiles.c 2019-05-19 16:49:06.000000000 +0000 @@ -0,0 +1,337 @@ +/* + * + * Copyright (C) 2018-2019 by C.H. Huang + * plushuang.tw@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * --- + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * You must obey the GNU Lesser General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_GLIB +#include // g_slice_xxx +#endif // HAVE_GLIB + +#include +#include +#include +#include +#include + +// ---------------------------------------------------------------------------- +// UgetFile + +UgetFile* uget_file_new(void) +{ +#ifdef HAVE_GLIB + return g_slice_alloc0(sizeof(UgetFile)); +#else + return ug_malloc0(sizeof(UgetFile)); +#endif // HAVE_GLIB +} + +void uget_file_free(UgetFile* file) +{ +#ifdef HAVE_GLIB + g_slice_free1(sizeof(UgetFile), file); +#else + ug_free(file); +#endif +} + +// ---------------------------------------------------------------------------- +// UgetFiles + +static void uget_files_init(UgetFiles* files); +static void uget_files_final(UgetFiles* files); +static void uget_files_copy(UgetFiles* files, UgetFiles* src); + +static void ug_json_write_list(UgJson* json, void* collection); +static UgJsonError ug_json_parse_list(UgJson* json, + const char* name, const char* value, + void* list, void* none); + +static const UgEntry UgetFilesEntry[] = +{ + {"list", offsetof(UgetFiles, list), UG_ENTRY_ARRAY, + ug_json_parse_list, ug_json_write_list}, + + // deprecated + {"collection", offsetof(UgetFiles, list), UG_ENTRY_ARRAY, + ug_json_parse_list, NULL}, + {NULL} // null-terminated +}; + +static const UgDataInfo UgetFilesInfoStatic = +{ + "files", // name + sizeof(UgetFiles), // size + (UgInitFunc) uget_files_init, + (UgFinalFunc) uget_files_final, + (UgAssignFunc) uget_files_assign, + UgetFilesEntry, +}; +// extern +const UgDataInfo* UgetFilesInfo = &UgetFilesInfoStatic; + +static void uget_files_init(UgetFiles* files) +{ + ug_list_init(&files->list); + files->sync_count = 0; +} + +static void uget_files_final(UgetFiles* files) +{ + // free UgetFile.path in list + ug_list_foreach(&files->list, (UgForeachFunc)ug_free, NULL); + ug_list_clear(&files->list, TRUE); +} + +int uget_files_assign(UgetFiles* files, UgetFiles* src) +{ + // free UgetFile.path in list + ug_list_foreach(&files->list, (UgForeachFunc)ug_free, NULL); + ug_list_clear(&files->list, TRUE); + + uget_files_copy(files, src); + files->sync_count = src->sync_count; + return TRUE; +} + +void uget_files_clear(UgetFiles* files) +{ + ug_list_foreach(&files->list, (UgForeachFunc)ug_free, NULL); + ug_list_clear(&files->list, TRUE); +} + +// sync UgetFile from 'src' to 'files. +// 1. all UgetFile in 'src' will insert/replace into 'files'. +// 2. remove deleted (state == UGET_FILE_STATE_DELETED) UgetFile in 'src'. +// return TRUE if 'files' have added or removed UgetFile. +int uget_files_sync(UgetFiles* files, UgetFiles* src) +{ + UgetFile* sibling; + UgetFile* file1; + UgetFile* file1_src; + UgetFile* src_next; + + if (files->sync_count == src->sync_count) + return FALSE; + + // sync UgetFile from 'src' + for (file1_src = (UgetFile*)src->list.head; file1_src; file1_src = src_next) { + src_next = file1_src->next; + file1 = uget_files_find(files, file1_src->path, &sibling); + // add new UgetFile in files + if (file1 == NULL) { + file1 = uget_file_new(); + ug_list_insert(&files->list, (UgLink*)sibling, (UgLink*)file1); + if (file1_src->path) + file1->path = ug_strdup(file1_src->path); + else + file1->path = NULL; + } + file1->type = file1_src->type; + file1->state = file1_src->state; +// file1->order = file1_src->order; + file1->total = file1_src->total; + file1->complete = file1_src->complete; + + // remove deleted UgetFile in 'src' + if (file1_src->type & UGET_FILE_STATE_DELETED) { + // delete file from src + ug_free(file1_src->path); + ug_list_remove(&src->list, (UgLink*)file1_src); + uget_file_free(file1_src); + } + } + files->sync_count = src->sync_count; + return TRUE; +} + +UgetFile* uget_files_find(UgetFiles* files, const char* path, UgetFile** sibling) +{ + UgetFile* file1; + int diff; + + for (file1 = (UgetFile*)files->list.head; file1; file1 = file1->next) { + diff = strcmp(file1->path, path); + if (diff > 0) { + if (sibling) + sibling[0] = file1; + return NULL; + } + if (diff == 0) + break; + } + + if (sibling) + sibling[0] = file1; + return file1; +} + +UgetFile* uget_files_realloc(UgetFiles* files, const char* path) +{ + UgetFile* file1; + UgetFile* sibling; + + file1 = uget_files_find(files, path, &sibling); + if (file1 == NULL) { + file1 = uget_file_new(); + ug_list_insert(&files->list, (UgLink*)sibling, (UgLink*)file1); + file1->path = ug_strdup(path); + file1->type = 0; + file1->state = 0; +// file1->order = 0; + file1->total = 0; + file1->complete = 0; + files->sync_count++; + } + return file1; +} + +UgetFile* uget_files_replace(UgetFiles* files, const char* path, + int type, int state) +{ + UgetFile* file1; + + file1 = uget_files_realloc(files, path); + file1->type = type; + file1->state = state; + files->sync_count++; + return file1; +} + +void uget_files_apply(UgetFiles* files, int type, int state) +{ + UgetFile* file1; + + for (file1 = (UgetFile*)files->list.head; file1; file1 = file1->next) { + if (file1->type == type || type == UGET_FILE_ALL) + file1->state |= state; + } + files->sync_count++; +} + +void uget_files_erase(UgetFiles* files, int type, int state) +{ + UgetFile* file1; + UgetFile* next; + + for (file1 = (UgetFile*)files->list.head; file1; file1 = next) { + next = file1->next; + if (file1->type != type && type != UGET_FILE_ALL) + continue; + if (file1->state & state) { + // delete file from src + ug_free(file1->path); + ug_list_remove(&files->list, (UgLink*)file1); + uget_file_free(file1); + } + } + files->sync_count -= 10; +} + +// copy UgetFile from 'src' to 'files'. +static void uget_files_copy(UgetFiles* files, UgetFiles* src) +{ + UgetFile* file1; + UgetFile* file1_src; + + for(file1_src = (UgetFile*)src->list.head; file1_src; file1_src = file1_src->next) { + file1 = uget_file_new(); + ug_list_append(&files->list, (UgLink*)file1); + + if (file1_src->path) + file1->path = ug_strdup(file1_src->path); + else + file1->path = NULL; + file1->type = file1_src->type; + file1->state = file1_src->state; +// file1->order = file1_src->order; + file1->total = file1_src->total; + file1->complete = file1_src->complete; + } + files->sync_count++; +} + +// ---------------------------------------------------------------------------- +// JSON + +static const UgEntry UgetFileEntry[] = +{ {"path", offsetof(UgetFile, path), UG_ENTRY_STRING, + NULL, NULL}, + {"type", offsetof(UgetFile, type), UG_ENTRY_CUSTOM, + ug_json_parse_int16, ug_json_write_int16}, + {"state", offsetof(UgetFile, state), UG_ENTRY_CUSTOM, + ug_json_parse_int16, ug_json_write_int16}, +// {"order", offsetof(UgetFile, order), UG_ENTRY_CUSTOM, +// ug_json_parse_int32, ug_json_write_int32}, + {"total", offsetof(UgetFile, total), UG_ENTRY_INT64, + NULL, NULL}, + {"complete", offsetof(UgetFile, complete), UG_ENTRY_INT64, + NULL, NULL}, + {NULL} // null-terminated +}; + +static void ug_json_write_list(UgJson* json, void* list) +{ + UgList* filelist = list; + UgetFile* file1; + + for (file1 = (UgetFile*)filelist->head; file1; file1 = file1->next) { + ug_json_write_object_head(json); + ug_json_write_entry(json, file1, UgetFileEntry); + ug_json_write_object_tail(json); + } +} + +static UgJsonError ug_json_parse_list(UgJson* json, + const char* name, const char* value, + void* list, void* none) +{ + UgList* filelist = list; + UgetFile* file1; + + if (json->type != UG_JSON_OBJECT) { +// if (json->type >= UG_JSON_OBJECT) +// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); + return UG_JSON_ERROR_TYPE_NOT_MATCH; + } + + file1 = uget_file_new(); + ug_list_append(filelist, (UgLink*)file1); + ug_json_push(json, ug_json_parse_entry, + file1, (void*)UgetFileEntry); + return UG_JSON_ERROR_NONE; +} diff -Nru uget-2.2.0/uget/UgetFiles.h uget-2.2.2/uget/UgetFiles.h --- uget-2.2.0/uget/UgetFiles.h 1970-01-01 00:00:00.000000000 +0000 +++ uget-2.2.2/uget/UgetFiles.h 2019-05-19 16:49:06.000000000 +0000 @@ -0,0 +1,210 @@ +/* + * + * Copyright (C) 2018-2019 by C.H. Huang + * plushuang.tw@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * --- + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * You must obey the GNU Lesser General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + * + */ + +#ifndef UGET_FILES_H +#define UGET_FILES_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct UgetFile UgetFile; +typedef struct UgetFiles UgetFiles; + +extern const UgDataInfo* UgetFilesInfo; + +enum UgetFileType +{ + UGET_FILE_REGULAR, + UGET_FILE_FOLDER, + UGET_FILE_ATTACHMENT, // torrent, metalink, or HTTP POST file + UGET_FILE_TEMPORARY, // temporary file. + + UGET_FILE_ALL, +}; + +enum UgetFileState +{ + // state for torrent or metalink +// UGET_FILE_STATE_IGNORE = 0x0001, +// UGET_FILE_STATE_SOURCE = 0x0002, + + // state for output (actually write into storage device) + UGET_FILE_STATE_DELETED = 0x0004, // this file was deleted/renamed + UGET_FILE_STATE_COMPLETED = 0x0008, + + UGET_FILE_STATE_ALL = 0x00FF, +}; + +// ---------------------------------------------------------------------------- +// UgetFile functions + +UgetFile* uget_file_new(void); +void uget_file_free(UgetFile* file); + +/* ---------------------------------------------------------------------------- + UgetFiles: It derived from UgData and store in UgInfo. + + UgType + | + `-- UgData + | + `-- UgetFiles + */ + +struct UgetFiles +{ + UG_DATA_MEMBERS; +// const UgDataInfo* info; // UgData(UgType) member + + UgList list; + + int sync_count; +}; + +int uget_files_assign(UgetFiles* files, UgetFiles* src); + +void uget_files_clear(UgetFiles* files); + +// sync elements from 'src' to 'files. +// 1. all elements in 'src' will insert/replace into 'files'. +// 2. remove deleted (state == UGET_FILE_STATE_DELETED) elements in 'src'. +// return TRUE if 'files' have added or removed elements. +int uget_files_sync(UgetFiles* files, UgetFiles* src); + +UgetFile* uget_files_find(UgetFiles* files, const char* path, + UgetFile** sibling); + +// realloc struct UgetFile by 'path' in array. +UgetFile* uget_files_realloc(UgetFiles* files, const char* path); + +UgetFile* uget_files_replace(UgetFiles* files, const char* path, + int type, int state); + +// apply state to element if type is matched. +void uget_files_apply(UgetFiles* files, int type, int state); +// erase element by state if type is matched. +void uget_files_erase(UgetFiles* files, int type, int state); + +#define uget_files_apply_deleted(files) \ + uget_files_apply(files, UGET_FILE_ALL, UGET_FILE_STATE_DELETED) +#define uget_files_erase_deleted(files) \ + uget_files_erase(files, UGET_FILE_ALL, UGET_FILE_STATE_DELETED) + +#ifdef __cplusplus +} +#endif + +// ---------------------------------------------------------------------------- +// UgetFile structure: file information with list link + +struct UgetFile +{ + UG_LINK_MEMBERS(UgetFile, char, path); +/* // ------ UgLink members ------ + char* path; // absolute file path + UgetFile* next; + UgetFile* prev; + */ + + int16_t type; // UgetFileType + int16_t state; // UgetFileState + + // save original index in torrent and metalink file. +// int32_t order; + + // progress + int64_t total; + int64_t complete; + +#ifdef __cplusplus + inline void* operator new(size_t size) + { return uget_file_new(); } + inline void operator delete(void* p) + { uget_file_free((UgetFile*)p); } +#endif // __cplusplus +}; + +// ---------------------------------------------------------------------------- +// C++11 standard-layout + +#ifdef __cplusplus + +namespace Uget +{ + +const UgDataInfo* const FilesInfo = UgetFilesInfo; + +// These are for directly use only. You can NOT derived it. +typedef struct UgetFile File; + +struct Files : Ug::DataMethod, UgetFiles +{ + inline void* operator new(size_t size) + { return ug_data_new(UgetFilesInfo); } + + inline int sync(UgetFiles* src) + { return uget_files_sync(this, src); } + inline UgetFile* find(const char* path, UgetFile** sibling) + { return uget_files_find(this, path, sibling); } + + inline UgetFile* realloc(const char* path) + { return uget_files_realloc(this, path); } + inline UgetFile* replace(const char* path,int type, int state) + { return uget_files_replace(this, path, type, state); } + + inline void apply(int type, int state) + { uget_files_apply(this, type, state); } + inline void erase(int type, int state) + { uget_files_erase(this, type, state); } + + inline void apply_deleted(void) + { uget_files_apply(this, UGET_FILE_ALL, UGET_FILE_STATE_DELETED); } + inline void erase_deleted(void) + { uget_files_erase(this, UGET_FILE_ALL, UGET_FILE_STATE_DELETED); } +}; + +}; // namespace Uget + +#endif // __cplusplus + + +#endif // End of UGET_FILES_H + diff -Nru uget-2.2.0/uget/UgetHash.c uget-2.2.2/uget/UgetHash.c --- uget-2.2.0/uget/UgetHash.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetHash.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -571,28 +571,28 @@ } } -void uget_uri_hash_add_download (void* uuhash, UgetNode* dnode) +void uget_uri_hash_add_download (void* uuhash, UgInfo* dnode_info) { UgetCommon* common; uintptr_t counts; if (uuhash == NULL) return; - common = ug_info_get (&dnode->info, UgetCommonInfo); + common = ug_info_get(dnode_info, UgetCommonInfo); if (common && common->uri) { counts = (uintptr_t) ug_hash_table_lookup (uuhash, common->uri); ug_hash_table_insert (uuhash, ug_strdup (common->uri), (void*) (++counts)); } } -void uget_uri_hash_remove_download (void* uuhash, UgetNode* dnode) +void uget_uri_hash_remove_download (void* uuhash, UgInfo* dnode_info) { UgetCommon* common; uintptr_t counts; if (uuhash == NULL) return; - common = ug_info_get (&dnode->info, UgetCommonInfo); + common = ug_info_get(dnode_info, UgetCommonInfo); if (common && common->uri) { counts = (uintptr_t) ug_hash_table_lookup (uuhash, common->uri); if (counts > 1) @@ -611,7 +611,7 @@ if (uuhash == NULL) return; for (dnode = cnode->children; dnode; dnode = dnode->next) { - common = ug_info_get (&dnode->info, UgetCommonInfo); + common = ug_info_get (dnode->info, UgetCommonInfo); if (common && common->uri) { counts = (uintptr_t) ug_hash_table_lookup (uuhash, common->uri); ug_hash_table_insert (uuhash, ug_strdup (common->uri), (void*) (++counts)); @@ -628,7 +628,7 @@ if (uuhash == NULL) return; for (dnode = cnode->children; dnode; dnode = dnode->next) { - common = ug_info_get (&dnode->info, UgetCommonInfo); + common = ug_info_get (dnode->info, UgetCommonInfo); if (common && common->uri) { counts = (uintptr_t) ug_hash_table_lookup (uuhash, common->uri); if (counts > 1) diff -Nru uget-2.2.0/uget/UgetHash.h uget-2.2.2/uget/UgetHash.h --- uget-2.2.0/uget/UgetHash.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetHash.h 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -70,8 +70,8 @@ void uget_uri_hash_add (void* uuhash, const char* uri); void uget_uri_hash_remove (void* uuhash, const char* uri); -void uget_uri_hash_add_download (void* uuhash, UgetNode* dnode); -void uget_uri_hash_remove_download (void* uuhash, UgetNode* dnode); +void uget_uri_hash_add_download (void* uuhash, UgInfo* dnode_info); +void uget_uri_hash_remove_download (void* uuhash, UgInfo* dnode_info); void uget_uri_hash_add_category (void* uuhash, UgetNode* cnode); void uget_uri_hash_remove_category (void* uuhash, UgetNode* cnode); diff -Nru uget-2.2.0/uget/UgetMedia.c uget-2.2.2/uget/UgetMedia.c --- uget-2.2.0/uget/UgetMedia.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetMedia.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2015-2018 by C.H. Huang + * Copyright (C) 2015-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -46,54 +46,54 @@ // ---------------------------------------------------------------------------- // UgetMedia -int uget_media_grab_youtube (UgetMedia* umedia, UgetProxy* proxy); +int uget_media_grab_youtube(UgetMedia* umedia, UgetProxy* proxy); -UgetMedia* uget_media_new (const char* url, UgetSiteId site_id) +UgetMedia* uget_media_new(const char* url, UgetSiteId site_id) { UgetMedia* umedia; - umedia = ug_malloc0 (sizeof (UgetMedia)); - umedia->url = ug_strdup (url); + umedia = ug_malloc0(sizeof(UgetMedia)); + umedia->url = ug_strdup(url); if (site_id == UGET_SITE_UNKNOWN) - site_id = uget_site_get_id (url); + site_id = uget_site_get_id(url); umedia->site_id = site_id; return umedia; } -void uget_media_free (UgetMedia* umedia) +void uget_media_free(UgetMedia* umedia) { - uget_media_clear (umedia, TRUE); - ug_free (umedia); + uget_media_clear(umedia, TRUE); + ug_free(umedia); } -void uget_media_clear (UgetMedia* umedia, int free_items) +void uget_media_clear(UgetMedia* umedia, int free_items) { if (free_items== TRUE) { - ug_list_foreach ((UgList*) umedia, + ug_list_foreach((UgList*) umedia, (UgForeachFunc) uget_media_item_free, NULL); - ug_list_clear ((UgList*) umedia, FALSE); + ug_list_clear((UgList*) umedia, FALSE); } - ug_free (umedia->url); + ug_free(umedia->url); umedia->url = NULL; - ug_free (umedia->title); + ug_free(umedia->title); umedia->title = NULL; if (umedia->event) { - uget_event_free (umedia->event); + uget_event_free(umedia->event); umedia->event = NULL; } } -int uget_media_grab_items (UgetMedia* umedia, UgetProxy* proxy) +int uget_media_grab_items(UgetMedia* umedia, UgetProxy* proxy) { int n_items = 0; switch (umedia->site_id) { case UGET_SITE_YOUTUBE: - n_items = uget_media_grab_youtube (umedia, proxy); + n_items = uget_media_grab_youtube(umedia, proxy); break; case UGET_SITE_UNKNOWN: @@ -104,10 +104,10 @@ return n_items; } -UgetMediaItem* uget_media_match (UgetMedia* umedia, - UgetMediaMatchMode mode, - UgetMediaQuality quality, - UgetMediaType type) +UgetMediaItem* uget_media_match(UgetMedia* umedia, + UgetMediaMatchMode mode, + UgetMediaQuality quality, + UgetMediaType type) { UgetMediaItem* cur; UgetMediaItem* prev; @@ -130,8 +130,8 @@ (mode == UGET_MEDIA_MATCH_2 && count_cur >= 2)) { // move matched items to tail of list - ug_list_remove ((UgList*) umedia, (UgLink*) cur); - ug_list_append ((UgList*) umedia, (UgLink*) cur); + ug_list_remove((UgList*) umedia, (UgLink*) cur); + ug_list_append((UgList*) umedia, (UgLink*) cur); if (result == NULL) result = cur; } @@ -141,8 +141,8 @@ count_res = count_cur; continue; } - abs_res = ABS (quality - result->quality); - abs_cur = ABS (quality - cur->quality); + abs_res = ABS(quality - result->quality); + abs_cur = ABS(quality - cur->quality); if (abs_res == abs_cur) { if (count_res < count_cur) { result = cur; @@ -163,8 +163,8 @@ if (mode == UGET_MEDIA_MATCH_NEAR && result) { // move matched items to tail of list - ug_list_remove ((UgList*) umedia, (UgLink*) result); - ug_list_append ((UgList*) umedia, (UgLink*) result); + ug_list_remove((UgList*) umedia, (UgLink*) result); + ug_list_append((UgList*) umedia, (UgLink*) result); } return result; @@ -173,19 +173,21 @@ // ---------------------------------------------------------------------------- // UgetMediaItem -UgetMediaItem* uget_media_item_new (UgetMedia* umedia) +UgetMediaItem* uget_media_item_new(UgetMedia* umedia) { UgetMediaItem* umitem; - umitem = ug_malloc0 (sizeof (UgetMediaItem)); + umitem = ug_malloc0(sizeof(UgetMediaItem)); umitem->self = umitem; - ug_list_append ((UgList*) umedia, (UgLink*) umitem); + umitem->type = UGET_MEDIA_TYPE_UNKNOWN; + umitem->quality = UGET_MEDIA_QUALITY_UNKNOWN; + ug_list_append((UgList*) umedia, (UgLink*) umitem); return umitem; } -void uget_media_item_free (UgetMediaItem* umitem) +void uget_media_item_free(UgetMediaItem* umitem) { - ug_free (umitem->url); - ug_free (umitem); + ug_free(umitem->url); + ug_free(umitem); } diff -Nru uget-2.2.0/uget/UgetMedia.h uget-2.2.2/uget/UgetMedia.h --- uget-2.2.0/uget/UgetMedia.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetMedia.h 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2015-2018 by C.H. Huang + * Copyright (C) 2015-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -63,11 +63,11 @@ { UGET_MEDIA_QUALITY_UNKNOWN = -1, - UGET_MEDIA_QUALITY_240P, // Youtube small - UGET_MEDIA_QUALITY_360P, // Youtube medium - UGET_MEDIA_QUALITY_480P, // Youtube large - UGET_MEDIA_QUALITY_720P, // Youtube hd720 - UGET_MEDIA_QUALITY_1080P, // Youtube hd1080 + UGET_MEDIA_QUALITY_240P, // YouTube small + UGET_MEDIA_QUALITY_360P, // YouTube medium + UGET_MEDIA_QUALITY_480P, // YouTube large + UGET_MEDIA_QUALITY_720P, // YouTube hd720 + UGET_MEDIA_QUALITY_1080P, // YouTube hd1080 UGET_MEDIA_N_QUALITY, } UgetMediaQuality; @@ -81,13 +81,22 @@ UGET_MEDIA_TYPE_3GPP, UGET_MEDIA_TYPE_FLV, + // YouTube MIME type: + // audio/mp4;+codecs="mp4a.40.2" + // audio/webm;+codecs="vorbis" + // audio/webm;+codecs="opus" + UGET_MEDIA_AUDIO_MP4, + UGET_MEDIA_AUDIO_WEBM, +// UGET_MEDIA_AUDIO_WEBM_VORBIS, // YouTube - audio/webm;+codecs="vorbis" +// UGET_MEDIA_AUDIO_WEBM_OPUS, // YouTube - audio/webm;+codecs="opus" + UGET_MEDIA_N_TYPE, } UgetMediaType; struct UgetMedia { - UG_LIST_MEMBERS (UgetMediaItem); + UG_LIST_MEMBERS(UgetMediaItem); // uintptr_t size; // UgetMediaItem* head; // UgetMediaItem* tail; @@ -110,35 +119,50 @@ void* data4; }; -UgetMedia* uget_media_new (const char* url, UgetSiteId site_id); -void uget_media_free (UgetMedia* umedia); -void uget_media_clear (UgetMedia* umedia, int free_items); +UgetMedia* uget_media_new(const char* url, UgetSiteId site_id); +void uget_media_free(UgetMedia* umedia); +void uget_media_clear(UgetMedia* umedia, int free_items); -int uget_media_grab_items (UgetMedia* umedia, UgetProxy* proxy); +int uget_media_grab_items(UgetMedia* umedia, UgetProxy* proxy); // return begin of matched items. Don't free it -UgetMediaItem* uget_media_match (UgetMedia* umedia, - UgetMediaMatchMode mode, - UgetMediaQuality quality, - UgetMediaType type); +UgetMediaItem* uget_media_match(UgetMedia* umedia, + UgetMediaMatchMode mode, + UgetMediaQuality quality, + UgetMediaType type); // ---------------------------------------------------------------------------- // UgetMediaItem struct UgetMediaItem { - UG_LINK_MEMBERS (UgetMediaItem, UgetMediaItem, self); + UG_LINK_MEMBERS(UgetMediaItem, UgetMediaItem, self); // UgetMediaItem* self; // UgetMediaItem* next; // UgetMediaItem* prev; char* url; - int quality; // 480p, 720p + int quality; // video - 480p, 720p + int bitrate; // audio int type; // UgetMediaType + + // for internal use only + int order; + union { + int integer; + char* string; + void* pointer; + } data; + + union { + int integer; + char* string; + void* pointer; + } data1; }; -UgetMediaItem* uget_media_item_new (UgetMedia* umedia); -void uget_media_item_free (UgetMediaItem* umitem); +UgetMediaItem* uget_media_item_new(UgetMedia* umedia); +void uget_media_item_free(UgetMediaItem* umitem); #ifdef __cplusplus } diff -Nru uget-2.2.0/uget/UgetMedia-youtube.c uget-2.2.2/uget/UgetMedia-youtube.c --- uget-2.2.0/uget/UgetMedia-youtube.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetMedia-youtube.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2015-2018 by C.H. Huang + * Copyright (C) 2015-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -76,84 +76,180 @@ char* js; // JavaScript player URL }; -static UgetYouTube* uget_youtube_new (void) +static UgetYouTube* uget_youtube_new(void) { UgetYouTube* uyoutube; - uyoutube = ug_malloc0 (sizeof (UgetYouTube)); + uyoutube = ug_malloc0(sizeof(UgetYouTube)); - ug_buffer_init (&uyoutube->buffer, 4096); + ug_buffer_init(&uyoutube->buffer, 4096); uyoutube->reason = NULL; uyoutube->status = NULL; - ug_html_init (&uyoutube->html); - ug_json_init (&uyoutube->json); + ug_html_init(&uyoutube->html); + ug_json_init(&uyoutube->json); uyoutube->js = NULL; return uyoutube; } -static void uget_youtube_free (UgetYouTube* uyoutube) +static void uget_youtube_free(UgetYouTube* uyoutube) { - ug_buffer_clear (&uyoutube->buffer, TRUE); - ug_free (uyoutube->reason); - ug_free (uyoutube->status); + ug_buffer_clear(&uyoutube->buffer, TRUE); + ug_free(uyoutube->reason); + ug_free(uyoutube->status); - ug_html_final (&uyoutube->html); - ug_json_final (&uyoutube->json); - ug_free (uyoutube->js); + ug_html_final(&uyoutube->html); + ug_json_final(&uyoutube->json); + ug_free(uyoutube->js); - ug_free (uyoutube); + ug_free(uyoutube); } -static void uget_youtube_parse_map (UgetYouTube* uyoutube, UgetMedia* umedia, const char* field) +static void uget_youtube_parse_map(UgetYouTube* uyoutube, UgetMedia* umedia, const char* field) { UgetMediaItem* umitem = NULL; + char* temp; - while (ug_uri_query_part (&uyoutube->query, field)) { + while (ug_uri_query_part(&uyoutube->query, field)) { // debug -// printf (" %.*s=%.*s\n", +// printf(" %.*s=%.*s\n", // uyoutube->query.field_len, field, // uyoutube->query.value_len, uyoutube->query.value); if (umitem == NULL) - umitem = uget_media_item_new (umedia); + umitem = uget_media_item_new(umedia); - if (strncmp ("url", field, uyoutube->query.field_len) == 0) { - ug_decode_uri (uyoutube->query.value, uyoutube->query.value_len, - uyoutube->query.value); - umitem->url = ug_strdup (uyoutube->query.value); - } - else if (strncmp ("type", field, uyoutube->query.field_len) == 0) { - ug_decode_uri (uyoutube->query.value, uyoutube->query.value_len, - uyoutube->query.value); - if (strncmp ("video/webm", uyoutube->query.value, 10) == 0) + if (strncmp("url", field, uyoutube->query.field_len) == 0) { + ug_decode_uri(uyoutube->query.value, uyoutube->query.value_len, + uyoutube->query.value); + umitem->url = ug_strdup(uyoutube->query.value); + } + else if (strncmp("sig", field, uyoutube->query.field_len) == 0) { + // signature. + // If it exist, append "&signature=xxxx" to umitem->url + umitem->data.string = ug_strndup(uyoutube->query.value, + uyoutube->query.value_len); + } + else if (strncmp("type", field, uyoutube->query.field_len) == 0) { + ug_decode_uri(uyoutube->query.value, uyoutube->query.value_len, + uyoutube->query.value); + if (strncmp("video/webm", uyoutube->query.value, 10) == 0) umitem->type = UGET_MEDIA_TYPE_WEBM; - else if (strncmp ("video/mp4", uyoutube->query.value, 9) == 0) + else if (strncmp("video/mp4", uyoutube->query.value, 9) == 0) umitem->type = UGET_MEDIA_TYPE_MP4; - else if (strncmp ("video/x-flv", uyoutube->query.value, 11) == 0) + else if (strncmp("video/x-flv", uyoutube->query.value, 11) == 0) umitem->type = UGET_MEDIA_TYPE_FLV; - else if (strncmp ("video/3gpp", uyoutube->query.value, 10) == 0) + else if (strncmp("video/3gpp", uyoutube->query.value, 10) == 0) umitem->type = UGET_MEDIA_TYPE_3GPP; else umitem->type = UGET_MEDIA_TYPE_UNKNOWN; } - else if (strncmp (field, "quality", uyoutube->query.field_len) == 0) { -// ug_decode_uri (uyoutube->query.value, uyoutube->query.value_len, uyoutube->query.value); - if (strncmp ("small", uyoutube->query.value, uyoutube->query.value_len) == 0) + else if (strncmp(field, "quality", uyoutube->query.field_len) == 0) { +// ug_decode_uri(uyoutube->query.value, uyoutube->query.value_len, uyoutube->query.value); + if (strncmp("small", uyoutube->query.value, uyoutube->query.value_len) == 0) umitem->quality = UGET_MEDIA_QUALITY_240P; - else if (strncmp ("medium", uyoutube->query.value, uyoutube->query.value_len) == 0) + else if (strncmp("medium", uyoutube->query.value, uyoutube->query.value_len) == 0) umitem->quality = UGET_MEDIA_QUALITY_360P; - else if (strncmp ("large", uyoutube->query.value, uyoutube->query.value_len) == 0) + else if (strncmp("large", uyoutube->query.value, uyoutube->query.value_len) == 0) umitem->quality = UGET_MEDIA_QUALITY_480P; - else if (strncmp ("hd720", uyoutube->query.value, uyoutube->query.value_len) == 0) + else if (strncmp("hd720", uyoutube->query.value, uyoutube->query.value_len) == 0) umitem->quality = UGET_MEDIA_QUALITY_720P; - else if (strncmp ("hd1080", uyoutube->query.value, uyoutube->query.value_len) == 0) + else if (strncmp("hd1080", uyoutube->query.value, uyoutube->query.value_len) == 0) umitem->quality = UGET_MEDIA_QUALITY_1080P; else umitem->quality = UGET_MEDIA_QUALITY_UNKNOWN; } if (uyoutube->query.value_next) { + // append "&signature=xxxx" to url + if (umitem->data.string) { + temp = ug_strdup_printf("%s" "&signature=%s", + umitem->url, umitem->data.string); + ug_free(umitem->url); + ug_free(umitem->data.string); + umitem->url = temp; + umitem->data.string = NULL; + } + umitem->order = 1; + field = uyoutube->query.value_next; + umitem = NULL; + } + else + field = uyoutube->query.field_next; + } +} + +static void uget_youtube_parse_adaptive_fmts(UgetYouTube* uyoutube, UgetMedia* umedia, const char* field) +{ + UgetMediaItem* umitem = NULL; + char* temp; + + while (ug_uri_query_part(&uyoutube->query, field)) { + // debug + printf(" %.*s=%.*s\n", + uyoutube->query.field_len, field, + uyoutube->query.value_len, uyoutube->query.value); + + if (umitem == NULL) + umitem = uget_media_item_new(umedia); + + if (strncmp("url", field, uyoutube->query.field_len) == 0) { + ug_decode_uri(uyoutube->query.value, uyoutube->query.value_len, + uyoutube->query.value); + umitem->url = ug_strdup(uyoutube->query.value); + } + else if (strncmp("sig", field, uyoutube->query.field_len) == 0) { + // signature. + // If it exist, append "&signature=xxxx" to umitem->url + umitem->data.string = ug_strndup(uyoutube->query.value, + uyoutube->query.value_len); + } + else if (strncmp("type", field, uyoutube->query.field_len) == 0) { + ug_decode_uri(uyoutube->query.value, uyoutube->query.value_len, + uyoutube->query.value); + if (strncmp("video/webm", uyoutube->query.value, 10) == 0) + umitem->type = UGET_MEDIA_TYPE_WEBM; + else if (strncmp("video/mp4", uyoutube->query.value, 9) == 0) + umitem->type = UGET_MEDIA_TYPE_MP4; + else if (strncmp("video/x-flv", uyoutube->query.value, 11) == 0) + umitem->type = UGET_MEDIA_TYPE_FLV; + else if (strncmp("video/3gpp", uyoutube->query.value, 10) == 0) + umitem->type = UGET_MEDIA_TYPE_3GPP; + else if (strncmp("audio/mp4", uyoutube->query.value, 9) == 0) + umitem->type = UGET_MEDIA_AUDIO_MP4; + else if (strncmp("audio/webm", uyoutube->query.value, 10) == 0) + umitem->type = UGET_MEDIA_AUDIO_WEBM; + else + umitem->type = UGET_MEDIA_TYPE_UNKNOWN; + } + else if (strncmp(field, "quality_label", uyoutube->query.field_len) == 0) { +// ug_decode_uri(uyoutube->query.value, uyoutube->query.value_len, uyoutube->query.value); + if (strncmp("240p", uyoutube->query.value, uyoutube->query.value_len) == 0) + umitem->quality = UGET_MEDIA_QUALITY_240P; + else if (strncmp("360p", uyoutube->query.value, uyoutube->query.value_len) == 0) + umitem->quality = UGET_MEDIA_QUALITY_360P; + else if (strncmp("480p", uyoutube->query.value, uyoutube->query.value_len) == 0) + umitem->quality = UGET_MEDIA_QUALITY_480P; + else if (strncmp("720p", uyoutube->query.value, uyoutube->query.value_len) == 0) + umitem->quality = UGET_MEDIA_QUALITY_720P; + else if (strncmp("1080p", uyoutube->query.value, uyoutube->query.value_len) == 0) + umitem->quality = UGET_MEDIA_QUALITY_1080P; + else + umitem->quality = UGET_MEDIA_QUALITY_UNKNOWN; + } + else if (strncmp(field, "bitrate", uyoutube->query.field_len) == 0) { +// ug_decode_uri(uyoutube->query.value, uyoutube->query.value_len, uyoutube->query.value); + umitem->bitrate = strtol(uyoutube->query.value, NULL, 10); + } + + if (uyoutube->query.value_next) { + // append "&signature=xxxx" to url + if (umitem->data.string) { + temp = ug_strdup_printf("%s" "&signature=%s", + umitem->url, umitem->data.string); + umitem->url = temp; + umitem->data.string = NULL; + } field = uyoutube->query.value_next; umitem = NULL; } @@ -167,47 +263,53 @@ // https://www.youtube.com/get_video_info?video_id=xxxxxxxxxxx // https://www.youtube.com/get_video_info?video_id=xxxxxxxxxxx&el=vevo&el=embedded&asv=3&sts=15902 -static void uget_youtube_parse_query (UgetYouTube* uyoutube, UgetMedia* umedia) +static void uget_youtube_parse_query(UgetYouTube* uyoutube, UgetMedia* umedia) { - if (ug_uri_query_part (&uyoutube->query, uyoutube->buffer.beg) == 0) + if (ug_uri_query_part(&uyoutube->query, uyoutube->buffer.beg) == 0) return; // debug -// printf ("%.*s\n", uyoutube->query.field_len, uyoutube->buffer.beg); +// printf("%.*s\n", uyoutube->query.field_len, uyoutube->buffer.beg); if (uyoutube->query.field_len == 26 && - strncmp (uyoutube->buffer.beg, "url_encoded_fmt_stream_map", 26) == 0) + strncmp(uyoutube->buffer.beg, "url_encoded_fmt_stream_map", 26) == 0) { - ug_decode_uri (uyoutube->query.value, uyoutube->query.value_len, uyoutube->query.value); - uget_youtube_parse_map (uyoutube, umedia, uyoutube->query.value); + ug_decode_uri(uyoutube->query.value, uyoutube->query.value_len, uyoutube->query.value); + uget_youtube_parse_map(uyoutube, umedia, uyoutube->query.value); + } + else if (uyoutube->query.field_len == 13 && + strncmp(uyoutube->buffer.beg, "adaptive_fmts", 13) == 0) + { + ug_decode_uri(uyoutube->query.value, uyoutube->query.value_len, uyoutube->query.value); + uget_youtube_parse_adaptive_fmts(uyoutube, umedia, uyoutube->query.value); } else if (uyoutube->query.field_len == 5 && - strncmp (uyoutube->buffer.beg, "title", 5) == 0) + strncmp(uyoutube->buffer.beg, "title", 5) == 0) { - umedia->title = ug_strndup (uyoutube->query.value, uyoutube->query.value_len); - ug_decode_uri (umedia->title, uyoutube->query.value_len, umedia->title); + umedia->title = ug_strndup(uyoutube->query.value, uyoutube->query.value_len); + ug_decode_uri(umedia->title, uyoutube->query.value_len, umedia->title); } else if (uyoutube->query.field_len == 6 && - strncmp (uyoutube->buffer.beg, "reason", 6) == 0) + strncmp(uyoutube->buffer.beg, "reason", 6) == 0) { - uyoutube->reason = ug_strndup (uyoutube->query.value, uyoutube->query.value_len); - ug_decode_uri (uyoutube->reason, uyoutube->query.value_len, uyoutube->reason); + uyoutube->reason = ug_strndup(uyoutube->query.value, uyoutube->query.value_len); + ug_decode_uri(uyoutube->reason, uyoutube->query.value_len, uyoutube->reason); } else if (uyoutube->query.field_len == 6 && - strncmp (uyoutube->buffer.beg, "status", 6) == 0) + strncmp(uyoutube->buffer.beg, "status", 6) == 0) { - uyoutube->status = ug_strndup (uyoutube->query.value, uyoutube->query.value_len); - ug_decode_uri (uyoutube->status, uyoutube->query.value_len, uyoutube->status); + uyoutube->status = ug_strndup(uyoutube->query.value, uyoutube->query.value_len); + ug_decode_uri(uyoutube->status, uyoutube->query.value_len, uyoutube->status); } else if (uyoutube->query.field_len == 9 && - strncmp (uyoutube->buffer.beg, "errorcode", 9) == 0) + strncmp(uyoutube->buffer.beg, "errorcode", 9) == 0) { - uyoutube->error_code = strtol (uyoutube->query.value, NULL, 10); + uyoutube->error_code = strtol(uyoutube->query.value, NULL, 10); } } -static size_t curl_output_youtube (char* beg, size_t size, - size_t nmemb, void* data) +static size_t curl_output_youtube(char* beg, size_t size, + size_t nmemb, void* data) { UgetMedia* umedia = data; UgBuffer* buffer = &((UgetYouTube*)umedia->data)->buffer; @@ -219,9 +321,9 @@ for (cur = beg; cur < end; cur++) { if (cur[0] == '&') { - ug_buffer_write_data (buffer, beg, cur - beg); - ug_buffer_write_char (buffer, 0); - uget_youtube_parse_query (umedia->data, umedia); + ug_buffer_write_data(buffer, beg, cur - beg); + ug_buffer_write_char(buffer, 0); + uget_youtube_parse_query(umedia->data, umedia); // next field buffer->cur = buffer->beg; beg = cur + 1; // + '&' @@ -229,12 +331,12 @@ } } if (cur == end) - ug_buffer_write_data (buffer, beg, cur - beg); + ug_buffer_write_data(buffer, beg, cur - beg); return size; } -int uget_media_grab_youtube_method_1 (UgetMedia* umedia, UgetProxy* proxy) +int uget_media_grab_youtube_method_1(UgetMedia* umedia, UgetProxy* proxy) { CURL* curl; CURLcode code; @@ -243,34 +345,34 @@ int retry = FALSE; uyoutube = umedia->data; - string = ug_strdup_printf ( + string = ug_strdup_printf( "https://www.youtube.com/get_video_info?video_id=%s", uyoutube->video_id); - curl = curl_easy_init (); + curl = curl_easy_init(); if (proxy) - ug_curl_set_proxy (curl, proxy); + ug_curl_set_proxy(curl, proxy); - curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, curl_output_youtube); - curl_easy_setopt (curl, CURLOPT_WRITEDATA, umedia); - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0L); - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_output_youtube); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, umedia); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); do { - curl_easy_setopt (curl, CURLOPT_URL, string); - code = curl_easy_perform (curl); - ug_free (string); + curl_easy_setopt(curl, CURLOPT_URL, string); + code = curl_easy_perform(curl); + ug_free(string); string = NULL; switch (code) { case CURLE_OK: if (uyoutube->buffer.beg != uyoutube->buffer.cur) { - ug_buffer_write_char (&uyoutube->buffer, 0); - uget_youtube_parse_query (umedia->data, umedia); + ug_buffer_write_char(&uyoutube->buffer, 0); + uget_youtube_parse_query(umedia->data, umedia); } if (uyoutube->error_code == 100) { - umedia->event = uget_event_new_error ( + umedia->event = uget_event_new_error( UGET_EVENT_ERROR_CUSTOM, _("This video has been removed.")); goto break_do_loop; @@ -278,12 +380,12 @@ break; case CURLE_OUT_OF_MEMORY: - umedia->event = uget_event_new_error ( + umedia->event = uget_event_new_error( UGET_EVENT_ERROR_OUT_OF_RESOURCE, NULL); goto break_do_loop; default: - umedia->event = uget_event_new_error ( + umedia->event = uget_event_new_error( UGET_EVENT_ERROR_CUSTOM, _("Error occurred during getting video info.")); goto break_do_loop; @@ -294,17 +396,17 @@ retry = FALSE; // decrypt_signature } - else if (uyoutube->status && strcmp (uyoutube->status, "ok") != 0) { - if (uyoutube->reason && strstr (uyoutube->reason, "VEVO") == NULL) + else if (uyoutube->status && strcmp(uyoutube->status, "ok") != 0) { + if (uyoutube->reason && strstr(uyoutube->reason, "VEVO") == NULL) break; retry = TRUE; // reset data if we need retry ug_buffer_restart(&uyoutube->buffer); - ug_free (uyoutube->reason); + ug_free(uyoutube->reason); uyoutube->reason = NULL; - ug_free (uyoutube->status); + ug_free(uyoutube->status); uyoutube->status = NULL; - string = ug_strdup_printf ( + string = ug_strdup_printf( "https://www.youtube.com/get_video_info?video_id=%s&el=vevo&el=embedded&asv=3&sts=15902", uyoutube->video_id); } @@ -312,7 +414,7 @@ } while (retry == TRUE); break_do_loop: - curl_easy_cleanup (curl); + curl_easy_cleanup(curl); return umedia->size; } @@ -323,28 +425,41 @@ // ------------------------------------ // JSON parser -static UgJsonError ug_json_parse_assets_js (UgJson* json, - const char* name, - const char* value, - void* umedia, void* data) +static UgJsonError ug_json_parse_assets_js(UgJson* json, + const char* name, + const char* value, + void* umedia, void* data) { UgetYouTube* uyoutube; uyoutube = ((UgetMedia*)umedia)->data; - uyoutube->js = ug_strdup (value); + uyoutube->js = ug_strdup(value); return UG_JSON_ERROR_NONE; } -static UgJsonError ug_json_parse_args_map (UgJson* json, - const char* name, - const char* value, - void* umedia, void* data) +static UgJsonError ug_json_parse_args_map(UgJson* json, + const char* name, + const char* value, + void* umedia, void* data) +{ + UgetYouTube* uyoutube; + + uyoutube = ((UgetMedia*)umedia)->data; + uget_youtube_parse_map(uyoutube, (void*) umedia, value); + + return UG_JSON_ERROR_NONE; +} + +static UgJsonError ug_json_parse_args_adaptive_fmts(UgJson* json, + const char* name, + const char* value, + void* umedia, void* data) { UgetYouTube* uyoutube; uyoutube = ((UgetMedia*)umedia)->data; - uget_youtube_parse_map (uyoutube, (void*) umedia, value); + uget_youtube_parse_adaptive_fmts(uyoutube, (void*) umedia, value); return UG_JSON_ERROR_NONE; } @@ -358,10 +473,12 @@ static const UgEntry youtube_args_entry[] = { - {"title", offsetof (UgetMedia, title), + {"title", offsetof(UgetMedia, title), UG_ENTRY_STRING, NULL, NULL}, {"url_encoded_fmt_stream_map", 0, UG_ENTRY_CUSTOM, ug_json_parse_args_map, NULL}, + {"adaptive_fmts", 0, + UG_ENTRY_CUSTOM, ug_json_parse_args_adaptive_fmts, NULL}, {NULL} // null-terminated }; @@ -380,59 +497,59 @@ static const UgHtmlParser youtube_html_parser; static const UgHtmlParser youtube_script_parser; -static void youtube_start_element (UgHtml* uhtml, - const char* element_name, - const char** attribute_names, - const char** attribute_values, - void* dest, - void* data) -{ - if (strcmp (element_name, "script") == 0) - ug_html_push (uhtml, &youtube_script_parser, dest, data); -} - -static void youtube_end_element (UgHtml* uhtml, - const char* element_name, - void* dest, - void* data) -{ - if (strcmp (element_name, "script") == 0) - ug_html_pop (uhtml); -} - -static void youtube_script_text (UgHtml* uhtml, - const char* text, - int text_len, - UgetMedia* umedia, - UgetYouTube* uyoutube) +static void youtube_start_element(UgHtml* uhtml, + const char* element_name, + const char** attribute_names, + const char** attribute_values, + void* dest, + void* data) +{ + if (strcmp(element_name, "script") == 0) + ug_html_push(uhtml, &youtube_script_parser, dest, data); +} + +static void youtube_end_element(UgHtml* uhtml, + const char* element_name, + void* dest, + void* data) +{ + if (strcmp(element_name, "script") == 0) + ug_html_pop(uhtml); +} + +static void youtube_script_text(UgHtml* uhtml, + const char* text, + int text_len, + UgetMedia* umedia, + UgetYouTube* uyoutube) { UgJson* json; char* cur; int cur_len; int diff; -// if (strncmp ("var ytplayer", text, 12) != 0) +// if (strncmp("var ytplayer", text, 12) != 0) // return; for (cur = (char*)text, cur_len = text_len; ; ) { - cur = memchr (cur, 'y', cur_len); + cur = memchr(cur, 'y', cur_len); if (cur == NULL) return; cur_len = text_len - (cur - text); - if (cur_len < 15) // strlen ("ytplayer.config") + if (cur_len < 15) // strlen("ytplayer.config") return; - diff = memcmp (cur, "ytplayer.config", 15); + diff = memcmp(cur, "ytplayer.config", 15); cur++; cur_len--; if (diff != 0) continue; - cur = memchr (cur, '=', cur_len); + cur = memchr(cur, '=', cur_len); if (cur == NULL) return; cur_len = text_len - (cur - text); - cur = memchr (cur, '{', cur_len); + cur = memchr(cur, '{', cur_len); if (cur == NULL) return; @@ -440,11 +557,11 @@ } json = &uyoutube->json; - ug_json_begin_parse (json); - ug_json_push (json, ug_json_parse_entry, umedia, (void*) youtube_config_entry); - ug_json_push (json, ug_json_parse_object, NULL, NULL); - ug_json_parse (json, cur, text_len - (cur - text)); - ug_json_end_parse (json); + ug_json_begin_parse(json); + ug_json_push(json, ug_json_parse_entry, umedia, (void*) youtube_config_entry); + ug_json_push(json, ug_json_parse_object, NULL, NULL); + ug_json_parse(json, cur, text_len - (cur - text)); + ug_json_end_parse(json); } static const UgHtmlParser youtube_script_parser = @@ -464,8 +581,8 @@ // ------------------------------------ // curl -static size_t curl_output_youtube_html (char* text, size_t size, - size_t nmemb, void* data) +static size_t curl_output_youtube_html(char* text, size_t size, + size_t nmemb, void* data) { UgetMedia* umedia; UgHtml* uhtml; @@ -474,75 +591,75 @@ uhtml = &((UgetYouTube*)umedia->data)->html; size *= nmemb; - ug_html_parse (uhtml, text, size); + ug_html_parse(uhtml, text, size); return size; } -int uget_media_grab_youtube_method_2 (UgetMedia* umedia, UgetProxy* proxy) +int uget_media_grab_youtube_method_2(UgetMedia* umedia, UgetProxy* proxy) { CURL* curl; CURLcode code; UgetYouTube* uyoutube; char* string; - ug_free (umedia->title); + ug_free(umedia->title); umedia->title = NULL; uyoutube = umedia->data; // create URL string - string = ug_strdup_printf ("https://www.youtube.com/watch?v=%s", - uyoutube->video_id); + string = ug_strdup_printf("https://www.youtube.com/watch?v=%s", + uyoutube->video_id); // setup option - curl = curl_easy_init (); + curl = curl_easy_init(); if (proxy) - ug_curl_set_proxy (curl, proxy); - curl_easy_setopt (curl, CURLOPT_URL, string); - curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0L); - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, curl_output_youtube_html); - curl_easy_setopt (curl, CURLOPT_WRITEDATA, umedia); + ug_curl_set_proxy(curl, proxy); + curl_easy_setopt(curl, CURLOPT_URL, string); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_output_youtube_html); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, umedia); // run & parse - ug_html_begin_parse (&uyoutube->html); - ug_html_push (&uyoutube->html, &youtube_html_parser, umedia, uyoutube); - code = curl_easy_perform (curl); - ug_html_end_parse (&uyoutube->html); + ug_html_begin_parse(&uyoutube->html); + ug_html_push(&uyoutube->html, &youtube_html_parser, umedia, uyoutube); + code = curl_easy_perform(curl); + ug_html_end_parse(&uyoutube->html); // free URL string - ug_free (string); + ug_free(string); switch (code) { case CURLE_OK: // player URL - if (uyoutube->js && strncmp (uyoutube->js, "//", 2) == 0) { - string = ug_malloc (strlen (uyoutube->js) + 6 + 1); // "https:" + '\0' + if (uyoutube->js && strncmp(uyoutube->js, "//", 2) == 0) { + string = ug_malloc(strlen(uyoutube->js) + 6 + 1); // "https:" + '\0' string[0] = 0; - strcat (string, "https:"); - strcat (string, uyoutube->js); - ug_free (uyoutube->js); + strcat(string, "https:"); + strcat(string, uyoutube->js); + ug_free(uyoutube->js); uyoutube->js = string; } break; case CURLE_OUT_OF_MEMORY: - umedia->event = uget_event_new_error ( + umedia->event = uget_event_new_error( UGET_EVENT_ERROR_OUT_OF_RESOURCE, NULL); break; default: - umedia->event = uget_event_new_error ( + umedia->event = uget_event_new_error( UGET_EVENT_ERROR_CUSTOM, _("Error occurred during getting video web page.")); break; } - curl_easy_cleanup (curl); + curl_easy_cleanup(curl); return umedia->size; } // ---------------------------------------------------------------------------- // UgetMedia functions -int uget_media_is_youtube (UgUri* uuri) +int uget_media_is_youtube(UgUri* uuri) { int length; const char* string; @@ -551,13 +668,13 @@ // https://youtube.com/watch?=xxxxxxxxxxx // https://youtu.be/xxxxxxxxxxx - length = ug_uri_host (uuri, &string); - if (length >= 11 && strncmp (string + length - 11, "youtube.com", 11) == 0) + length = ug_uri_host(uuri, &string); + if (length >= 11 && strncmp(string + length - 11, "youtube.com", 11) == 0) { - if (strncmp (uuri->uri + uuri->file , "watch?", 6) == 0) + if (strncmp(uuri->uri + uuri->file , "watch?", 6) == 0) return TRUE; } - else if (length >= 8 && strncmp (string + length - 8, "youtu.be", 8) == 0) + else if (length >= 8 && strncmp(string + length - 8, "youtu.be", 8) == 0) { if (uuri->file != -1) return TRUE; @@ -566,10 +683,44 @@ return FALSE; } -int uget_media_grab_youtube_method_1 (UgetMedia* umedia, UgetProxy* proxy); -int uget_media_grab_youtube_method_2 (UgetMedia* umedia, UgetProxy* proxy); +int uget_media_grab_youtube_method_1(UgetMedia* umedia, UgetProxy* proxy); +int uget_media_grab_youtube_method_2(UgetMedia* umedia, UgetProxy* proxy); + +static void erase_duplicate(UgetMedia* umedia) +{ + UgList list; + UgetMediaItem* cur; + UgetMediaItem* cur_next; + UgetMediaItem* matched; + UgetMediaItem* matched_next; + + ug_list_init(&list); + // grab media from YouTube's 'url_encoded_fmt_stream_map' + for (cur = umedia->head; cur; cur = cur_next) { + cur_next = cur->next; + if (cur->order == 1) { + // move items to list + ug_list_remove((UgList*) umedia, (UgLink*) cur); + ug_list_append(&list, (UgLink*) cur); + } + } + // preserve media from YouTube's 'url_encoded_fmt_stream_map' + for (cur = (UgetMediaItem*)list.head; cur; cur = cur_next) { + cur_next = cur->next; + matched = uget_media_match(umedia, UGET_MEDIA_MATCH_2, + cur->quality, cur->type); + for (; matched; matched = matched_next) { + matched_next = matched->next; + ug_list_remove((UgList*) umedia, (UgLink*) matched); + uget_media_item_free(matched); + } + ug_list_remove(&list, (UgLink*) cur); + ug_list_prepend((UgList*) umedia, (UgLink*) cur); + } + ug_list_clear(&list, FALSE); +} -int uget_media_grab_youtube (UgetMedia* umedia, UgetProxy* proxy) +int uget_media_grab_youtube(UgetMedia* umedia, UgetProxy* proxy) { int n; char* string; @@ -578,7 +729,7 @@ UgUriQuery* query; UgetYouTube* uyoutube; - ug_uri_init (&umedia->uuri, umedia->url); + ug_uri_init(&umedia->uuri, umedia->url); query = &umedia->uquery; video_id_str = NULL; video_id_len = 0; @@ -587,8 +738,8 @@ if (umedia->uuri.query != -1) { // https://www.youtube.com/watch?v=xxxxxxxxxxx string = umedia->url + umedia->uuri.query; - while (ug_uri_query_part (query, string)) { - if (strncmp ("v", string, query->field_len) == 0 && query->value) { + while (ug_uri_query_part(query, string)) { + if (strncmp("v", string, query->field_len) == 0 && query->value) { video_id_str = query->value; video_id_len = query->value_len; break; @@ -598,31 +749,32 @@ } else { // http://youtu.be/xxxxxxxxxxx - video_id_len = ug_uri_file (&umedia->uuri, (const char**)&video_id_str); + video_id_len = ug_uri_file(&umedia->uuri, (const char**)&video_id_str); } if (video_id_str == NULL || video_id_len == 0) { - umedia->event = uget_event_new_error (UGET_EVENT_ERROR_CUSTOM, + umedia->event = uget_event_new_error(UGET_EVENT_ERROR_CUSTOM, _("No video_id found in URL of YouTube.")); return 0; } - uyoutube = uget_youtube_new (); - uyoutube->video_id = ug_strndup (video_id_str, video_id_len); + uyoutube = uget_youtube_new(); + uyoutube->video_id = ug_strndup(video_id_str, video_id_len); umedia->data = uyoutube; - n = uget_media_grab_youtube_method_1 (umedia, proxy); + n = uget_media_grab_youtube_method_1(umedia, proxy); if (n == 0 && uyoutube->error_code != 100) { - ug_free (umedia->title); + ug_free(umedia->title); umedia->title = NULL; if (umedia->event) { - uget_event_free (umedia->event); + uget_event_free(umedia->event); umedia->event = NULL; } - n = uget_media_grab_youtube_method_2 (umedia, proxy); + n = uget_media_grab_youtube_method_2(umedia, proxy); } - uget_youtube_free (uyoutube); + uget_youtube_free(uyoutube); + erase_duplicate(umedia); umedia->data = NULL; return n; diff -Nru uget-2.2.0/uget/UgetNode.c uget-2.2.2/uget/UgetNode.c --- uget-2.2.0/uget/UgetNode.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetNode.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -38,12 +38,6 @@ #include #endif -#ifdef _MSC_VER -#define _CRT_SECURE_NO_WARNINGS -#endif - -#include -#include #include #include #include @@ -52,23 +46,46 @@ #include // g_slice_xxx #endif +static void uget_node_call_fake_filter (UgetNode* parent, UgetNode* sibling, UgetNode* child); +static UgJsonError ug_json_parse_state2group (UgJson* json, + const char* name, const char* value, + void* node, void* none); +static UgJsonError ug_json_parse_name2data (UgJson* json, + const char* name, const char* value, + void* node, void* none); // ---------------------------------------------------------------------------- // UgetNode -static struct UgetNodeNotification notification = { - (UgetNodeFunc) NULL, NULL, NULL, - (UgNotifyFunc) NULL, NULL, 0, NULL +struct UgetNodeNotifier uget_node_default_notifier = +{ + NULL, // UgetNodeFunc inserted; + NULL, // UgetNodeFunc removed; + NULL, // UgNotifyFunc updated; + NULL, // void* data; // extra data for user +}; + +struct UgetNodeControl uget_node_default_control = +{ +// NULL, // struct UgetNodeControl* children; + &uget_node_default_notifier, // struct UgetNodeNotifier* notifier; + {NULL, FALSE}, // struct UgetNodeSort sort; + NULL, // UgetNodeFunc filter; }; const UgEntry UgetNodeEntry[] = { - {"name", offsetof (UgetNode, name), UG_ENTRY_STRING, NULL, NULL}, - {"type", offsetof (UgetNode, type), UG_ENTRY_INT, NULL, NULL}, - {"state", offsetof (UgetNode, state), UG_ENTRY_INT, NULL, NULL}, {"info", offsetof (UgetNode, info), UG_ENTRY_CUSTOM, - ug_json_parse_info, ug_json_write_info}, + ug_json_parse_info_ptr, ug_json_write_info_ptr}, {"children", 0, UG_ENTRY_ARRAY, ug_json_parse_uget_node_children, ug_json_write_uget_node_children}, + + // deprecated + {"name", 0, UG_ENTRY_CUSTOM, + ug_json_parse_name2data, NULL}, + {"state", 0, UG_ENTRY_CUSTOM, + ug_json_parse_state2group, NULL}, + {"data", offsetof (UgetNode, info), UG_ENTRY_CUSTOM, + ug_json_parse_info_ptr, NULL}, {NULL} // null-terminated }; @@ -85,81 +102,76 @@ return node; } +void uget_node_free(UgetNode* node) +{ + uget_node_final(node); +#ifdef HAVE_GLIB + g_slice_free1(sizeof(UgetNode), node); +#else + ug_free(node); +#endif // HAVE_GLIB +} + void uget_node_init (UgetNode* node, UgetNode* node_real) { memset (node, 0, sizeof (UgetNode)); - node->ref_count = 1; - node->notification = ¬ification; + node->control = &uget_node_default_control; if (node_real == NULL) { - node->data = node; // pointer to self - ug_info_init (&node->info, 8, 2); - node->info.at[0].key = (void*) UgetRelationInfo; - node->info.at[1].key = (void*) UgetProgressInfo; + node->base = node; // pointer to self + node->info = ug_info_new(8, 2); + node->info->at[0].key = (void*) UgetRelationInfo; + node->info->at[1].key = (void*) UgetProgressInfo; } else { // this is a fake node. -// node->state = 0; - node->data = node_real->data; - node->type = node_real->type; +// node->group = 0; + node->base = node_real->base; node->real = node_real; node->peer = node_real->fake; node_real->fake = node; - ug_info_init (&node->info, 0, 0); + node->info = node_real->info; + ug_info_ref(node->info); } } -void uget_node_ref (UgetNode* node) +void uget_node_final(UgetNode* node) { - node->ref_count++; -} + if (node->parent) + uget_node_remove(node->parent, node); + if (node->real) + uget_node_remove_fake(node->real, node); -void uget_node_unref (UgetNode* node) -{ - if (--node->ref_count == 0) { - if (node->parent) - uget_node_remove (node->parent, node); - if (node->real) - uget_node_remove_fake (node->real, node); - - uget_node_unref_fake (node); - uget_node_unref_children (node); -// ug_node_unlink ((UgNode*)node); - ug_info_final (&node->info); - ug_free (node->name); - -#ifdef HAVE_GLIB - g_slice_free1 (sizeof (UgetNode), node); -#else - ug_free (node); -#endif // HAVE_GLIB - } + uget_node_clear_fake(node); + uget_node_clear_children(node); +// ug_node_unlink((UgNode*)node); + ug_info_unref(node->info); } -void uget_node_unref_children (UgetNode* node) +void uget_node_clear_children (UgetNode* node) { UgetNode* next; UgetNode* children; for (children = node->children; children; children = next) { next = children->next; - uget_node_unref (children); + uget_node_free(children); } node->children = NULL; } -void uget_node_unref_fake (UgetNode* node) +void uget_node_clear_fake (UgetNode* node) { UgetNode* peer; UgetNode* fake; for (fake = node->fake; fake; fake = peer) { peer = fake->peer; - fake->real = NULL; // speed up uget_node_unref() - uget_node_unref (fake); + fake->real = NULL; // speed up uget_node_free() + uget_node_free(fake); } - node->fake = NULL; // speed up uget_node_unref() + node->fake = NULL; // speed up uget_node_free() } void uget_node_move (UgetNode* node, UgetNode* sibling, UgetNode* child) @@ -194,13 +206,14 @@ UgetNodeFunc inserted; ug_node_insert ((UgNode*) node, (UgNode*) sibling, (UgNode*) child); - child->notification = node->notification; + child->control = node->control; +// child->control = node->control->children; - inserted = node->notification->inserted; + inserted = node->control->notifier->inserted; if (inserted) inserted (node, sibling, child); - uget_node_created (node, sibling, child); + uget_node_call_fake_filter (node, sibling, child); } static void uget_node_unlink_children_real (UgetNode* node) @@ -226,7 +239,7 @@ sibling = child->next; ug_node_remove ((UgNode*) parent, (UgNode*) child); // notify - removed = parent->notification->removed; + removed = parent->control->notifier->removed; if (removed) removed (parent, sibling, child); } @@ -242,7 +255,7 @@ uget_node_unlink_fake_parent (child); uget_node_unlink_children_real (child); - removed = node->notification->removed; + removed = node->control->notifier->removed; if (removed) removed (node, sibling, child); } @@ -252,13 +265,14 @@ UgetNodeFunc inserted; ug_node_append ((UgNode*) node, (UgNode*) child); - child->notification = node->notification; + child->control = node->control; +// child->control = node->control->children; - inserted = node->notification->inserted; + inserted = node->control->notifier->inserted; if (inserted) inserted (node, NULL, child); - uget_node_created (node, NULL, child); + uget_node_call_fake_filter (node, NULL, child); } void uget_node_prepend (UgetNode* node, UgetNode* child) @@ -268,15 +282,75 @@ sibling = node->children; ug_node_prepend ((UgNode*) node, (UgNode*) child); - child->notification = node->notification; + child->control = node->control; +// child->control = node->control->children; - inserted = node->notification->inserted; + inserted = node->control->notifier->inserted; if (inserted) inserted (node, sibling, child); - uget_node_created (node, sibling, child); + uget_node_call_fake_filter (node, sibling, child); +} + +// used by uget_node_sort() +static void uget_node_qsort(UgetNode** array, int left, int right, UgCompareFunc compare) +{ + UgetNode* temp; + UgetNode* pivot = array[(left + right) / 2]; + int i = left, j = right; + + /* partition */ + while (i <= j) { + while (compare(array[i], pivot) < 0) + i++; + while (compare(array[j], pivot) > 0) + j--; + if (i <= j) { + temp = array[i]; + array[i] = array[j]; + array[j] = temp; + i++; + j--; + } + }; + + /* recursion */ + if (left < j) + uget_node_qsort(array, left, j, compare); + if (i < right) + uget_node_qsort(array, i, right, compare); +} + +void uget_node_sort(UgetNode* node, UgCompareFunc compare, int reversed) +{ + int index; + UgetNode** array; + UgetNode* cur; + + if (node->n_children == 0) + return; + array = (UgetNode**) ug_malloc(sizeof(UgetNode*) * node->n_children); + for (index = 0, cur = node->children; cur; cur = cur->next, index++) + array[index] = cur; + + uget_node_qsort(array, 0, node->n_children -1, compare); + + if (reversed) { + for (index = node->n_children-1; index >=0; index--) { + uget_node_remove(node, array[index]); + uget_node_append(node, array[index]); + } + } + else { + for (index = 0; index < node->n_children; index++) { + uget_node_remove(node, array[index]); + uget_node_append(node, array[index]); + } + } + ug_free(array); } +/* void uget_node_sort (UgetNode* node, UgCompareFunc compare, int reversed) { UgetNode* beg; @@ -302,19 +376,20 @@ uget_node_move (node, beg, unsorted); } } + */ void uget_node_insert_sorted (UgetNode* node, UgetNode* child) { UgCompareFunc compare; UgetNode* cur; - int reversed; + int reverse; - compare = node->notification->compare; - reversed = node->notification->reversed; + compare = node->control->sort.compare; + reverse = node->control->sort.reverse; if (compare == NULL) return; - if (reversed == FALSE) { + if (reverse == FALSE) { for (cur = node->children; cur; cur = cur->next) { if (compare (cur, child) > 0) { uget_node_insert (node, cur, child); @@ -406,11 +481,25 @@ if (node->fake == NULL) return; for (child = node->children; child; child = child->next) { - uget_node_created (node, NULL, child); + uget_node_call_fake_filter (node, NULL, child); uget_node_make_fake (child); } } +// fake filter node from real. +// If real node inserted a child node, all fake nodes call this to filter. +static void uget_node_call_fake_filter (UgetNode* parent, UgetNode* sibling, UgetNode* child) +{ + UgetNode* fake; + UgetNodeFunc filter; + + for (fake = parent->fake; fake; fake = fake->peer) { + filter = fake->control->filter; + if (filter) + filter (fake, sibling, child); + } +} + // ---------------------------------------------------------------------------- // position UgetNode* uget_node_nth_fake (UgetNode* node, int nth) @@ -424,15 +513,6 @@ return NULL; } -UgetNode* uget_node_fake_from_state (UgetNode* node, int state) -{ - for (node = node->fake; node; node = node->peer) { - if (node->state & state) - return node; - } - return NULL; -} - int uget_node_fake_position (UgetNode* node, UgetNode* fake) { int position = 0; @@ -445,65 +525,13 @@ } // ---------------------------------------------------------------------------- - -void uget_node_set_name_by_uri (UgetNode* node, UgUri* uuri) -{ - const char* filename; - int length; - - ug_free (node->name); - - if (uuri->scheme_len == 6 && strncmp (uuri->uri, "magnet", 6) == 0) { - length = 0; - filename = strstr (uuri->uri + uuri->file, "dn="); - if (filename) { - filename = filename + 3; - length = strcspn (filename, "&"); - node->name = ug_malloc (length + 1); - ug_decode_uri (filename, length, node->name); - if (ug_utf8_get_invalid (node->name, NULL) != -1) { - ug_free (node->name); - node->name = ug_strndup (filename, length); - } - } - } - else { - length = ug_uri_file (uuri, &filename); - if (length == 0) - node->name = ug_strdup (uuri->uri); - else - node->name = ug_uri_get_file (uuri); - } -} - -void uget_node_set_name_by_uri_string (UgetNode* node, const char* uri) -{ - UgUri uuri; - - ug_uri_init (&uuri, uri); - uget_node_set_name_by_uri (node, &uuri); -} - -// ---------------------------------------------------------------------------- // notify -void uget_node_created (UgetNode* parent, UgetNode* sibling, UgetNode* child) -{ - UgetNode* fake; - UgetNodeFunc created; - - for (fake = parent->fake; fake; fake = fake->peer) { - created = fake->notification->created; - if (created) - created (fake, sibling, child); - } -} - void uget_node_updated (UgetNode* node) { UgNotifyFunc updated; - updated = node->notification->updated; + updated = node->control->notifier->updated; if (updated) updated (node); // update fake node @@ -541,167 +569,51 @@ } } -// ---------------------------------------------------------------------------- -// callback functions for UgetNode.notification.created -// These functions used by UgetApp - -// sibling_real, child_real -void uget_node_create_split (UgetNode* node, UgetNode* sibling, UgetNode* child_real) -{ - UgetNode* child; - - if (node->parent == NULL) { - // node is root. child_real is category - // - child = uget_node_new (child_real); - child->state = UGET_STATE_RECYCLED; - uget_node_prepend (node, child); - // - child = uget_node_new (child_real); - child->state = UGET_STATE_FINISHED; - uget_node_prepend (node, child); - // - child = uget_node_new (child_real); - child->state = UGET_STATE_QUEUING; - uget_node_prepend (node, child); - // - child = uget_node_new (child_real); - child->state = UGET_STATE_ACTIVE; - uget_node_prepend (node, child); - } - else if (node->parent->parent == NULL) { - // node is category. child_real is download - child = child_real->data; - if ((node->state & child->state) || - ( (child->state & UGET_STATE_CATEGORY) == 0 && - (node->state & UGET_STATE_QUEUING) ) ) - { - // insert sorted - if (node->notification->compare) { - uget_node_insert_sorted (node, uget_node_new (child_real)); - return; - } - - // original order - if (sibling) { - for (sibling = sibling->fake; sibling; sibling = sibling->peer) { - if (sibling->parent == node) - break; - } - } - uget_node_insert (node, sibling, uget_node_new (child_real)); - } - } -} - -void uget_node_create_sorted (UgetNode* node, UgetNode* sibling, UgetNode* child) +// convert old format to new +static UgJsonError ug_json_parse_name2data (UgJson* json, + const char* name, const char* value, + void* nodev, void* none) { - child = uget_node_new (child); - - if (node->parent == NULL) { - // node is root. - uget_node_append (node, child); - } - else if (node->parent->parent == NULL) { - // node is category. - // insert sorted - if (node->notification->compare) { - uget_node_insert_sorted (node, child); - return; - } + UgetNode* node = nodev; + union { + UgetCommon* common; + UgetFiles* files; + } temp; - // original order - if (sibling) { - for (sibling = sibling->fake; sibling; sibling = sibling->peer) { - if (sibling->parent == node) - break; - } - } + if (json->type != UG_JSON_STRING) + return UG_JSON_ERROR_TYPE_NOT_MATCH; - uget_node_insert (node, sibling, child); + // Now root node is category node + if (node->parent == NULL || node->parent->parent == NULL) { + // category or download node + temp.common = ug_info_realloc(node->info, UgetCommonInfo); + temp.common->name = ug_strdup(value); + } + else if (node->parent->parent->parent == NULL) { + // file node + temp.files = ug_info_realloc(node->parent->info, UgetFilesInfo); + uget_files_realloc(temp.files, value); } + return UG_JSON_ERROR_NONE; } -// This one is not the same with uget_node_create_sorted() -// sibling_real, child_real -void uget_node_create_mix (UgetNode* node, UgetNode* sibling, UgetNode* child) +// convert old format to new +static UgJsonError ug_json_parse_state2group (UgJson* json, + const char* name, const char* value, + void* nodev, void* none) { - UgetNode* fake; - - child = uget_node_new (child); - - if (node->parent == NULL) { - // node is root. - uget_node_append (node, child); - } - else if (node->parent->parent == NULL) { - // node is category. - // insert sorted - node = node->parent->children; - if (node->notification->compare) { - // add all download to first category - uget_node_insert_sorted (node, child); - return; - } + UgetRelation* relation; + UgetNode* node = nodev; + int group; - // reorder by state - if ( sibling && - ((sibling->data->state & UGET_STATE_CATEGORY) != - (child->data->state & UGET_STATE_CATEGORY)) ) - { - sibling = NULL; - } - if (node->fake && sibling == NULL) { - switch (child->data->state & UGET_STATE_CATEGORY) { - case UGET_STATE_ACTIVE: - fake = uget_node_fake_from_state (node, UGET_STATE_QUEUING); - if (fake == NULL || fake->children == NULL) - fake = uget_node_fake_from_state (node, UGET_STATE_FINISHED); - if (fake == NULL || fake->children == NULL) - fake = uget_node_fake_from_state (node, UGET_STATE_RECYCLED); - break; - - case UGET_STATE_QUEUING: - default: - fake = uget_node_fake_from_state (node, UGET_STATE_FINISHED); - if (fake == NULL || fake->children == NULL) - fake = uget_node_fake_from_state (node, UGET_STATE_RECYCLED); - break; - - case UGET_STATE_FINISHED: - fake = uget_node_fake_from_state (node, UGET_STATE_RECYCLED); - break; - - case UGET_STATE_RECYCLED: - fake = NULL; - break; - } - if (fake && fake->children) { - uget_node_insert (node, fake->children->real, child); - return; - } - } - - // original order - if (sibling) { - for (sibling = sibling->fake; sibling; sibling = sibling->peer) { -// if (sibling->parent == node) - if (sibling->parent == node) - break; - } + if (json->type != UG_JSON_NUMBER) + return UG_JSON_ERROR_TYPE_NOT_MATCH; + else { + group = strtol(value, NULL, 10); + if (group != 0) { + relation = ug_info_realloc(node->info, UgetRelationInfo); + relation->group = group; } - // insert childNode to first (mixed) category - uget_node_insert (node, sibling, child); } -} - -void uget_node_create_mix_split (UgetNode* node, UgetNode* sibling, UgetNode* child_real) -{ - UgetNode* real; - - // if REAL category node is not first child, this function do nothing. - real = node->real; - if (real->parent == NULL && real->children != child_real) - return; - uget_node_create_split (node, sibling, child_real); + return UG_JSON_ERROR_NONE; } diff -Nru uget-2.2.0/uget/UgetNode-compare.c uget-2.2.2/uget/UgetNode-compare.c --- uget-2.2.0/uget/UgetNode-compare.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetNode-compare.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -44,20 +44,23 @@ int uget_node_compare_name (UgetNode* node1, UgetNode* node2) { - node1 = node1->data; - node2 = node2->data; + UgetCommon* common1; + UgetCommon* common2; - if (node1->name) { - if (node2->name == NULL) + common1 = ug_info_get(node1->info, UgetCommonInfo); + common2 = ug_info_get(node2->info, UgetCommonInfo); + + if (common1 && common1->name) { + if (common2->name == NULL) return 1; } else { - if (node2->name == NULL) - return 0; - else + if (common2 && common2->name) return -1; + else + return 0; } - return strcmp (node1->name, node2->name); + return strcmp (common1->name, common2->name); } int uget_node_compare_complete (UgetNode* node1, UgetNode* node2) @@ -65,10 +68,10 @@ UgetProgress* progress1; UgetProgress* progress2; - node1 = node1->data; - node2 = node2->data; - progress1 = ug_info_get (&node1->info, UgetProgressInfo); - progress2 = ug_info_get (&node2->info, UgetProgressInfo); + node1 = node1->base; + node2 = node2->base; + progress1 = ug_info_get (node1->info, UgetProgressInfo); + progress2 = ug_info_get (node2->info, UgetProgressInfo); if (progress1) { if (progress2 == NULL) return 1; @@ -93,10 +96,10 @@ UgetProgress* progress1; UgetProgress* progress2; - node1 = node1->data; - node2 = node2->data; - progress1 = ug_info_get (&node1->info, UgetProgressInfo); - progress2 = ug_info_get (&node2->info, UgetProgressInfo); + node1 = node1->base; + node2 = node2->base; + progress1 = ug_info_get (node1->info, UgetProgressInfo); + progress2 = ug_info_get (node2->info, UgetProgressInfo); if (progress1) { if (progress2 == NULL) return 1; @@ -121,10 +124,10 @@ UgetProgress* progress1; UgetProgress* progress2; - node1 = node1->data; - node2 = node2->data; - progress1 = ug_info_get (&node1->info, UgetProgressInfo); - progress2 = ug_info_get (&node2->info, UgetProgressInfo); + node1 = node1->base; + node2 = node2->base; + progress1 = ug_info_get (node1->info, UgetProgressInfo); + progress2 = ug_info_get (node2->info, UgetProgressInfo); if (progress1) { if (progress2 == NULL) return 1; @@ -149,10 +152,10 @@ UgetProgress* progress1; UgetProgress* progress2; - node1 = node1->data; - node2 = node2->data; - progress1 = ug_info_get (&node1->info, UgetProgressInfo); - progress2 = ug_info_get (&node2->info, UgetProgressInfo); + node1 = node1->base; + node2 = node2->base; + progress1 = ug_info_get (node1->info, UgetProgressInfo); + progress2 = ug_info_get (node2->info, UgetProgressInfo); if (progress1) { if (progress2 == NULL) return 1; @@ -177,10 +180,10 @@ UgetProgress* progress1; UgetProgress* progress2; - node1 = node1->data; - node2 = node2->data; - progress1 = ug_info_get (&node1->info, UgetProgressInfo); - progress2 = ug_info_get (&node2->info, UgetProgressInfo); + node1 = node1->base; + node2 = node2->base; + progress1 = ug_info_get (node1->info, UgetProgressInfo); + progress2 = ug_info_get (node2->info, UgetProgressInfo); if (progress1) { if (progress2 == NULL) return 1; @@ -205,10 +208,10 @@ UgetProgress* progress1; UgetProgress* progress2; - node1 = node1->data; - node2 = node2->data; - progress1 = ug_info_get (&node1->info, UgetProgressInfo); - progress2 = ug_info_get (&node2->info, UgetProgressInfo); + node1 = node1->base; + node2 = node2->base; + progress1 = ug_info_get (node1->info, UgetProgressInfo); + progress2 = ug_info_get (node2->info, UgetProgressInfo); if (progress1) { if (progress2 == NULL) return 1; @@ -233,10 +236,10 @@ UgetProgress* progress1; UgetProgress* progress2; - node1 = node1->data; - node2 = node2->data; - progress1 = ug_info_get (&node1->info, UgetProgressInfo); - progress2 = ug_info_get (&node2->info, UgetProgressInfo); + node1 = node1->base; + node2 = node2->base; + progress1 = ug_info_get (node1->info, UgetProgressInfo); + progress2 = ug_info_get (node2->info, UgetProgressInfo); if (progress1) { if (progress2 == NULL) return 1; @@ -261,10 +264,10 @@ UgetProgress* progress1; UgetProgress* progress2; - node1 = node1->data; - node2 = node2->data; - progress1 = ug_info_get (&node1->info, UgetProgressInfo); - progress2 = ug_info_get (&node2->info, UgetProgressInfo); + node1 = node1->base; + node2 = node2->base; + progress1 = ug_info_get (node1->info, UgetProgressInfo); + progress2 = ug_info_get (node2->info, UgetProgressInfo); if (progress1) { if (progress2 == NULL) return 1; @@ -289,10 +292,10 @@ UgetProgress* progress1; UgetProgress* progress2; - node1 = node1->data; - node2 = node2->data; - progress1 = ug_info_get (&node1->info, UgetProgressInfo); - progress2 = ug_info_get (&node2->info, UgetProgressInfo); + node1 = node1->base; + node2 = node2->base; + progress1 = ug_info_get (node1->info, UgetProgressInfo); + progress2 = ug_info_get (node2->info, UgetProgressInfo); if (progress1) { if (progress2 == NULL) return 1; @@ -317,10 +320,10 @@ UgetCommon* common1; UgetCommon* common2; - node1 = node1->data; - node2 = node2->data; - common1 = ug_info_get (&node1->info, UgetCommonInfo); - common2 = ug_info_get (&node2->info, UgetCommonInfo); + node1 = node1->base; + node2 = node2->base; + common1 = ug_info_get (node1->info, UgetCommonInfo); + common2 = ug_info_get (node2->info, UgetCommonInfo); if (common1) { if (common2 == NULL) return 1; @@ -342,20 +345,7 @@ int uget_node_compare_parent_name (UgetNode* node1, UgetNode* node2) { - node1 = node1->data->parent; - node2 = node2->data->parent; - - if (node1->name) { - if (node2->name == NULL) - return 1; - } - else { - if (node2->name == NULL) - return 0; - else - return -1; - } - return strcmp (node1->name, node2->name); + return uget_node_compare_name(node1->base->parent, node2->base->parent); } int uget_node_compare_uri (UgetNode* node1, UgetNode* node2) @@ -363,10 +353,10 @@ UgetCommon* common1; UgetCommon* common2; - node1 = node1->data; - node2 = node2->data; - common1 = ug_info_get (&node1->info, UgetCommonInfo); - common2 = ug_info_get (&node2->info, UgetCommonInfo); + node1 = node1->base; + node2 = node2->base; + common1 = ug_info_get (node1->info, UgetCommonInfo); + common2 = ug_info_get (node2->info, UgetCommonInfo); if (common1) { if (common2 == NULL) return 1; @@ -385,10 +375,10 @@ UgetLog* log1; UgetLog* log2; - node1 = node1->data; - node2 = node2->data; - log1 = ug_info_get (&node1->info, UgetLogInfo); - log2 = ug_info_get (&node2->info, UgetLogInfo); + node1 = node1->base; + node2 = node2->base; + log1 = ug_info_get (node1->info, UgetLogInfo); + log2 = ug_info_get (node2->info, UgetLogInfo); if (log1) { if (log2 == NULL) return 1; @@ -413,10 +403,10 @@ UgetLog* log1; UgetLog* log2; - node1 = node1->data; - node2 = node2->data; - log1 = ug_info_get (&node1->info, UgetLogInfo); - log2 = ug_info_get (&node2->info, UgetLogInfo); + node1 = node1->base; + node2 = node2->base; + log1 = ug_info_get (node1->info, UgetLogInfo); + log2 = ug_info_get (node2->info, UgetLogInfo); if (log1) { if (log2 == NULL) return 1; diff -Nru uget-2.2.0/uget/UgetNode-filter.c uget-2.2.2/uget/UgetNode-filter.c --- uget-2.2.0/uget/UgetNode-filter.c 1970-01-01 00:00:00.000000000 +0000 +++ uget-2.2.2/uget/UgetNode-filter.c 2019-05-19 16:49:06.000000000 +0000 @@ -0,0 +1,250 @@ +/* + * + * Copyright (C) 2012-2019 by C.H. Huang + * plushuang.tw@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * --- + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * You must obey the GNU Lesser General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. + * + */ + +#include +#include + +#define N_SPLIT_GROUPS 4 + +static int split_groups[N_SPLIT_GROUPS] = +{ + UGET_GROUP_ACTIVE, + UGET_GROUP_QUEUING, + UGET_GROUP_FINISHED, + UGET_GROUP_RECYCLED, +}; + +// ---------------------------------------------------------------------------- +// callback functions for UgetNode.control.filter + +// sibling_real, child_real +void uget_node_filter_split (UgetNode* node, UgetNode* sibling, UgetNode* child_real) +{ + UgetRelation* relation; + UgetNode* child; + int group; + + if (node->parent == NULL) { + // node is root. child_real is category + for (group=0; group < N_SPLIT_GROUPS; group++) { + child = uget_node_new (child_real); + uget_node_prepend (node, child); + } + } + else if (node->parent->parent == NULL) { + // node is category. child_real is download + child = child_real->base; + relation = ug_info_realloc(child->info, UgetRelationInfo); + group = uget_node_get_group(node); + if ((relation->group & UGET_GROUP_MAJOR) == 0) + relation->group |= UGET_GROUP_QUEUING; + if (group & relation->group) { + // insert sorted + if (node->control->sort.compare) { + uget_node_insert_sorted (node, uget_node_new (child_real)); + return; + } + + // original order + if (sibling) { + for (sibling = sibling->fake; sibling; sibling = sibling->peer) { + if (sibling->parent == node) + break; + } + } + uget_node_insert (node, sibling, uget_node_new (child_real)); + } + } +} + +void uget_node_filter_sorted (UgetNode* node, UgetNode* sibling, UgetNode* child) +{ + child = uget_node_new (child); + + if (node->parent == NULL) { + // node is root. + uget_node_append (node, child); + } + else if (node->parent->parent == NULL) { + // node is category. + // insert sorted + if (node->control->sort.compare) { + uget_node_insert_sorted (node, child); + return; + } + + // original order + if (sibling) { + for (sibling = sibling->fake; sibling; sibling = sibling->peer) { + if (sibling->parent == node) + break; + } + } + + uget_node_insert (node, sibling, child); + } +} + +// sibling_real, child_real +void uget_node_filter_mix (UgetNode* node, UgetNode* sibling, UgetNode* child) +{ + UgetNode* fake; + UgetRelation* relation_child; + UgetRelation* relation_sibling; + + child = uget_node_new (child); + + if (node->parent == NULL) { + // node is root. + uget_node_append (node, child); + } + else if (node->parent->parent == NULL) { + // node is category. + // insert sorted + node = node->parent->children; + if (node->control->sort.compare) { + // add all download to first category + uget_node_insert_sorted (node, child); + return; + } + + // reorder by group + relation_child = ug_info_realloc(child->info, UgetRelationInfo); + if (sibling) { + relation_sibling = ug_info_realloc(sibling->info, UgetRelationInfo); + if ((relation_sibling->group & UGET_GROUP_MAJOR) != + (relation_child->group & UGET_GROUP_MAJOR)) + { + sibling = NULL; + } + } + // get inserting position by group + if (node->fake && sibling == NULL) { + switch (relation_child->group & UGET_GROUP_MAJOR) { + case UGET_GROUP_ACTIVE: + fake = uget_node_get_split(node, UGET_GROUP_QUEUING); + if (fake == NULL || fake->children == NULL) + fake = uget_node_get_split(node, UGET_GROUP_FINISHED); + if (fake == NULL || fake->children == NULL) + fake = uget_node_get_split(node, UGET_GROUP_RECYCLED); + break; + + case UGET_GROUP_QUEUING: + default: + fake = uget_node_get_split(node, UGET_GROUP_FINISHED); + if (fake == NULL || fake->children == NULL) + fake = uget_node_get_split(node, UGET_GROUP_RECYCLED); + break; + + case UGET_GROUP_FINISHED: + fake = uget_node_get_split(node, UGET_GROUP_RECYCLED); + break; + + case UGET_GROUP_RECYCLED: + fake = NULL; + break; + } + // insert into specified position by group + if (fake && fake->children) { + uget_node_insert (node, fake->children->real, child); + return; + } + } + + // original order + if (sibling) { + for (sibling = sibling->fake; sibling; sibling = sibling->peer) { + if (sibling->parent == node) + break; + } + } + // insert childNode to first (mixed) category + uget_node_insert (node, sibling, child); + } +} + +void uget_node_filter_mix_split (UgetNode* node, UgetNode* sibling, UgetNode* child_real) +{ + UgetNode* real; + + // if REAL category node is not first child, this function do nothing. + real = node->real; + if (real->parent == NULL && real->children != child_real) + return; + uget_node_filter_split (node, sibling, child_real); +} + +// ---------------------------------------------------------------------------- +// helper functions for uget_node_filter_split(), uget_node_filter_mix_split() + +UgetNode* uget_node_get_split(UgetNode* node, int group) +{ + UgetNodeFunc filter; + int nth; + + for (nth = 0, node = node->fake; node; node = node->peer) { + filter = node->control->filter; + if (filter == uget_node_filter_split || + filter == uget_node_filter_mix_split) + { + if (split_groups[nth] & group) + return node; + nth++; // must place here + } + } + return NULL; +} + +int uget_node_get_group(UgetNode* node) +{ + UgetNodeFunc filter; + UgetNode* fake; + int nth; + + if (node->real == NULL) + return UGET_GROUP_NULL; + for (nth = 0, fake = node->real->fake; fake; fake = fake->peer) { + filter = fake->control->filter; + if (filter == uget_node_filter_split || + filter == uget_node_filter_mix_split) + { + if (fake == node) + return split_groups[nth]; + nth++; // must place here + } + } + return UGET_GROUP_NULL; +} diff -Nru uget-2.2.0/uget/UgetNode.h uget-2.2.2/uget/UgetNode.h --- uget-2.2.0/uget/UgetNode.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetNode.h 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -37,42 +37,7 @@ #ifndef UGET_NODE_H #define UGET_NODE_H -// Uget Tree chart: -// -// Root -+- Category1 -+- Download1 (URI) -+- File -// | | | -// | | + cookie or post file (attachment) -// | | -// | +- Download2 (URI) -+- File1 -// | | (torrent path) | -// | | +- File2 -// | | | -// | | +- torrent file (attachment) -// | | -// | +- Download3 (URI) -+- File -// | (metalink path) | -// | +- metalink file (attachment) -// +-- Category2 -// - -// UgNode is base node type. -// UgetNode extend from UgNode and add pointers (real, fake, and peer). -// -// prev / prev / -// | fake | fake -// | / | / -// | / | / -// |/ |/ -// ... <---> parent <--------------> child <----> ... -// /| /| -// / | / | -// / | / | -// real | real | -// / | / | -// next next -// - -#include // offsetof () +#include // offsetof() #include // int16_t #include #include @@ -82,51 +47,77 @@ extern "C" { #endif -// ---------------------------------------------------------------------------- -// UgetNode +/* ---------------------------------------------------------------------------- + UgetNode: extend from UgNode and add pointers (real, fake, and peer). + + * Tree chart 1: (parent and child nodes) + + Root --+-- Category1 --+-- Download1 (URI) + | | + | | + | | + | +-- Download2 (URI) + | (torrent path) + | + | + +-- Category2 --+-- Download3 (URI) + | (metalink path) + | + | + +-- Download4 (URI) + + * Tree chart 2: + + fake ----- peer -----> fake + / / + prev / prev / + | / | / + | / | / + | / | / + |/ |/ + ... <---> parent <--------------> child <----> ... + /| /| + / | / | + / | / | + / | / | + / | / | + / next / next + / / + real real + */ -typedef struct UgetTree UgetTree; -typedef struct UgetNode UgetNode; +typedef struct UgetNode UgetNode; +/* +typedef struct UgetNodeControl UgetNodeControl; +typedef struct UgetNodeNotifier UgetNodeNotifier; +typedef struct UgetNodeSort UgetNodeSort; + */ typedef void (*UgetNodeFunc)(UgetNode* node, UgetNode* sibling, UgetNode* child); extern const UgEntry UgetNodeEntry[]; typedef enum { - UGET_NODE_ROOT, - UGET_NODE_CATEGORY, - UGET_NODE_DOWNLOAD, - UGET_NODE_FILE, - UGET_NODE_FOLDER, - UGET_NODE_ATTACHMENT, - UGET_NODE_REMOTE_FILE, -} UgetNodeType; + UGET_GROUP_NULL = 0, + UGET_GROUP_QUEUING = 1 << 0, -typedef enum { - UGET_STATE_QUEUING = 1 << 0, + UGET_GROUP_PAUSED = 1 << 1, + UGET_GROUP_ACTIVE = 1 << 2, + UGET_GROUP_COMPLETED = 1 << 3, + UGET_GROUP_UPLOADING = 1 << 4, + UGET_GROUP_ERROR = 1 << 5, + + UGET_GROUP_FINISHED = 1 << 6, + UGET_GROUP_RECYCLED = 1 << 7, + + UGET_GROUP_MAJOR = UGET_GROUP_ACTIVE | UGET_GROUP_QUEUING | UGET_GROUP_FINISHED | UGET_GROUP_RECYCLED, + UGET_GROUP_INACTIVE = UGET_GROUP_PAUSED | UGET_GROUP_ERROR, + UGET_GROUP_UNRUNNABLE = UGET_GROUP_PAUSED | UGET_GROUP_ERROR | UGET_GROUP_FINISHED | UGET_GROUP_RECYCLED, + UGET_GROUP_UNFINISHED = UGET_GROUP_ACTIVE | UGET_GROUP_UPLOADING, +} UgetGroup; - UGET_STATE_PAUSED = 1 << 1, - UGET_STATE_ACTIVE = 1 << 2, - UGET_STATE_COMPLETED = 1 << 3, - UGET_STATE_UPLOADING = 1 << 4, - UGET_STATE_ERROR = 1 << 5, - - UGET_STATE_FINISHED = 1 << 6, - UGET_STATE_RECYCLED = 1 << 7, - - UGET_STATE_CATEGORY = UGET_STATE_ACTIVE | UGET_STATE_QUEUING | UGET_STATE_FINISHED | UGET_STATE_RECYCLED, - UGET_STATE_INACTIVE = UGET_STATE_PAUSED | UGET_STATE_ERROR, - UGET_STATE_UNRUNNABLE = UGET_STATE_PAUSED | UGET_STATE_ERROR | UGET_STATE_FINISHED | UGET_STATE_RECYCLED, - UGET_STATE_UNFINISHED = UGET_STATE_ACTIVE | UGET_STATE_UPLOADING, -} UgetState; - -struct UgetNodeNotification +struct UgetNodeNotifier { -// struct UgetNodeNotification* child; - - // notify fake node when real node create a new child node. - UgetNodeFunc created; - // notify when node has inserted a child node. UgetNodeFunc inserted; @@ -138,46 +129,40 @@ // UgNotifyFunc destroy; - // for sorting - UgCompareFunc compare; - int reversed; - - // extra data - void* data; + void* data; // extra data for user }; -struct UgetNode +struct UgetNodeSort { - UG_NODE_MEMBERS (UgetNode, UgetNode, data); -// UgetNode* data; -// UgetNode* next; -// UgetNode* prev; -// UgetNode* parent; -// UgetNode* children; -// UgetNode* last; -// int n_children; - - UgetNode* real; - UgetNode* fake; - UgetNode* peer; + UgCompareFunc compare; + int reverse; // TRUE or FALSE +}; - int ref_count; +struct UgetNodeControl +{ +// struct UgetNodeControl* children; // control of children node + struct UgetNodeNotifier* notifier; + struct UgetNodeSort sort; + + // filter child of real node and decide how to insert child of fake node. + // If real node inserted a child node, all fake nodes call this to filter. + UgetNodeFunc filter; +}; - char* name; // fake node doesn't use this - int type; // UgetNodeType - int state; // UgetState - UgInfo info; // fake node doesn't use this +extern struct UgetNodeControl uget_node_default_control; +extern struct UgetNodeNotifier uget_node_default_notifier; - struct UgetNodeNotification* notification; -}; +// ---------------------------------------------------------------------------- +// UgetNode functions UgetNode* uget_node_new (UgetNode* node_real); -void uget_node_init (UgetNode* node, UgetNode* node_real); +void uget_node_free (UgetNode* node); -void uget_node_ref (UgetNode* node); -void uget_node_unref (UgetNode* node); -void uget_node_unref_fake (UgetNode* node); -void uget_node_unref_children (UgetNode* node); +void uget_node_init (UgetNode* node, UgetNode* node_real); +void uget_node_final (UgetNode* node); + +void uget_node_clear_fake (UgetNode* node); +void uget_node_clear_children (UgetNode* node); void uget_node_move (UgetNode* node, UgetNode* sibling, UgetNode* child); void uget_node_insert (UgetNode* node, UgetNode* sibling, UgetNode* child); @@ -198,19 +183,13 @@ #define uget_node_child_position(node,child) \ ug_node_child_position((UgNode*)node, (UgNode*)child) UgetNode* uget_node_nth_fake (UgetNode* node, int nth); -UgetNode* uget_node_fake_from_state (UgetNode* node, int state); int uget_node_fake_position (UgetNode* node, UgetNode* fake); -// ---------------------------------------------------------------------------- - -void uget_node_set_name_by_uri (UgetNode* node, UgUri* uuri); -void uget_node_set_name_by_uri_string (UgetNode* node, const char* uri); - // notify -void uget_node_created (UgetNode* node, UgetNode* sibling, UgetNode* child); void uget_node_updated (UgetNode* node); -// for UgetNode.children +// ---------------------------------------------------------------------------- + // JSON parser used with UG_ENTRY_ARRAY. UgJsonError ug_json_parse_uget_node_children (UgJson* json, const char* name, const char* value, @@ -218,10 +197,10 @@ // JSON writer used with UG_ENTRY_ARRAY. void ug_json_write_uget_node_children (UgJson* json, const UgetNode* node); -// ---------------------------------------------------------------------------- -// compare functions for uget_node_sort() -// UgetNode-compare.c - +/* ---------------------------------------------------------------------------- + compare functions for UgetNode.control.sort.compare and uget_node_sort() + these function implemented in UgetNode-compare.c + */ int uget_node_compare_name (UgetNode* node1, UgetNode* node2); int uget_node_compare_complete (UgetNode* node1, UgetNode* node2); int uget_node_compare_size (UgetNode* node1, UgetNode* node2); @@ -238,13 +217,33 @@ int uget_node_compare_added_time (UgetNode* node1, UgetNode* node2); int uget_node_compare_completed_time (UgetNode* node1, UgetNode* node2); -// ---------------------------------------------------------------------------- -// callback functions for UgetNode.notification.created -// These functions used by UgetApp -void uget_node_create_mix (UgetNode* node, UgetNode* sibling, UgetNode* child_real); -void uget_node_create_split (UgetNode* node, UgetNode* sibling, UgetNode* child_real); -void uget_node_create_mix_split (UgetNode* node, UgetNode* sibling, UgetNode* child_real); -void uget_node_create_sorted (UgetNode* node, UgetNode* sibling, UgetNode* child_real); +/* ---------------------------------------------------------------------------- + callback functions for UgetNode.control.filter (they are used by UgetApp) + these function implemented in UgetNode-filter.c + */ +void uget_node_filter_mix (UgetNode* node, UgetNode* sibling, UgetNode* child_real); +void uget_node_filter_split (UgetNode* node, UgetNode* sibling, UgetNode* child_real); +void uget_node_filter_mix_split (UgetNode* node, UgetNode* sibling, UgetNode* child_real); +void uget_node_filter_sorted (UgetNode* node, UgetNode* sibling, UgetNode* child_real); + +/* + uget_node_filter_split() + v + ,-----------. ,--------. + | real node | ---> | filter | --+---> fake node (UGET_GROUP_ACTIVE) + `-----------' `--------' | + +---> fake node (UGET_GROUP_QUEUING) + | + +---> fake node (UGET_GROUP_FINISHED) + | + `---> fake node (UGET_GROUP_RECYCLED) + + * helper functions for uget_node_filter_split(), uget_node_filter_mix_split() + uget_node_get_split() use 'group' (UgetGroup) to find fake node. + uget_node_get_group() return UgetGroup if it is split fake node. + */ +UgetNode* uget_node_get_split(UgetNode* node, int group); +int uget_node_get_group(UgetNode* node); #ifdef __cplusplus @@ -252,19 +251,81 @@ #endif // ---------------------------------------------------------------------------- -// C++11 standard-layout - -#ifdef __cplusplus +// UgetNode structure -namespace Uget +struct UgetNode { + UG_NODE_MEMBERS(UgetNode, UgetNode, base); +/* // ------ UgNode members ------ + UgetNode* base; // the realest UgetNode (real->real->real-> ...) + UgetNode* next; + UgetNode* prev; + UgetNode* parent; + UgetNode* children; + UgetNode* last; + int n_children; + */ -struct TreeMethod {}; + UgetNode* real; + UgetNode* fake; + UgetNode* peer; -struct Node : Ug::NodeMethod, UgetNode -{ + UgInfo* info; + struct UgetNodeControl* control; + +#ifdef __cplusplus + inline void* operator new(size_t size, UgetNode* node_real = NULL) + { return uget_node_new(node_real); } + inline void operator delete(void* p) + { uget_node_free((UgetNode*)p); } + + inline void init(UgetNode* node_real = NULL) + { uget_node_init(this, node_real); } + inline void final() + { uget_node_final(this); } + + inline void clearFake(void) + { uget_node_clear_fake(this); } + inline void clearChildren(void) + { uget_node_clear_children(this); } + + inline void move(UgetNode* sibling, UgetNode* child) + { uget_node_move(this, sibling, child); } + inline void insert(UgetNode* sibling, UgetNode* child) + { uget_node_insert(this, sibling, child); } + inline void remove(UgetNode* child) + { uget_node_remove(this, child); } + inline void append(UgetNode* child) + { uget_node_append(this, child); } + inline void prepend(UgetNode* child) + { uget_node_prepend(this, child); } + + inline UgetNode* nthChild(int nth) + { return uget_node_nth_child(this, nth); } + inline int childPosition(UgetNode* child) + { return uget_node_child_position(this, child); } + + inline UgetNode* nthFake(int nth) + { return uget_node_nth_fake(this, nth); } + inline int fakePosition(UgetNode* fake) + { return uget_node_fake_position(this, fake); } + + inline UgetNode* getSplit(int group) + { return uget_node_get_split(this, group); } + inline int getGroup() + { return uget_node_get_group(this); } +#endif // __cplusplus }; +// ---------------------------------------------------------------------------- +// C++11 standard-layout + +#ifdef __cplusplus + +namespace Uget +{ +// This one is for directly use only. You can NOT derived it. +typedef struct UgetNode Node; }; // namespace Uget #endif // __cplusplus diff -Nru uget-2.2.0/uget/UgetOption.c uget-2.2.2/uget/UgetOption.c --- uget-2.2.0/uget/UgetOption.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetOption.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -108,37 +108,37 @@ UgetFtp* ftp; } temp; - if (mem_is_zero ((char*) &ivalue->common, sizeof (ivalue->common)) == FALSE) { - temp.common = ug_info_realloc (info, UgetCommonInfo); + if (mem_is_zero((char*) &ivalue->common, sizeof(ivalue->common)) == FALSE) { + temp.common = ug_info_realloc(info, UgetCommonInfo); temp.common->keeping.enable = TRUE; if (ivalue->common.folder) { - ug_free (temp.common->folder); + ug_free(temp.common->folder); temp.common->folder = ivalue->common.folder; temp.common->keeping.folder = TRUE; ivalue->common.folder = NULL; } if (ivalue->common.file) { - ug_free (temp.common->file); + ug_free(temp.common->file); temp.common->file = ivalue->common.file; temp.common->keeping.file = TRUE; ivalue->common.file = NULL; } if (ivalue->common.user) { - ug_free (temp.common->user); + ug_free(temp.common->user); temp.common->user = ivalue->common.user; temp.common->keeping.user = TRUE; ivalue->common.user = NULL; } if (ivalue->common.password) { - ug_free (temp.common->password); + ug_free(temp.common->password); temp.common->password = ivalue->common.password; temp.common->keeping.password = TRUE; ivalue->common.password = NULL; } } - if (mem_is_zero ((char*) &ivalue->proxy, sizeof (ivalue->proxy)) == FALSE) { - temp.proxy = ug_info_realloc (info, UgetProxyInfo); + if (mem_is_zero((char*) &ivalue->proxy, sizeof(ivalue->proxy)) == FALSE) { + temp.proxy = ug_info_realloc(info, UgetProxyInfo); temp.proxy->keeping.enable = TRUE; if (ivalue->proxy.type) { temp.proxy->type = ivalue->proxy.type; @@ -146,7 +146,7 @@ ivalue->proxy.type = 0; } if (ivalue->proxy.host) { - ug_free (temp.proxy->host); + ug_free(temp.proxy->host); temp.proxy->host = ivalue->proxy.host; temp.proxy->keeping.host = TRUE; ivalue->proxy.host = NULL; @@ -157,83 +157,83 @@ ivalue->proxy.port = 0; } if (ivalue->proxy.user) { - ug_free (temp.proxy->user); + ug_free(temp.proxy->user); temp.proxy->user = ivalue->proxy.user; temp.proxy->keeping.user = TRUE; ivalue->proxy.user = NULL; } if (ivalue->proxy.password) { - ug_free (temp.proxy->password); + ug_free(temp.proxy->password); temp.proxy->password = ivalue->proxy.password; temp.proxy->keeping.password = TRUE; ivalue->proxy.password = NULL; } } - if (mem_is_zero ((char*) &ivalue->http, sizeof (ivalue->http)) == FALSE) { - temp.http = ug_info_realloc (info, UgetHttpInfo); + if (mem_is_zero((char*) &ivalue->http, sizeof(ivalue->http)) == FALSE) { + temp.http = ug_info_realloc(info, UgetHttpInfo); temp.http->keeping.enable = TRUE; if (ivalue->http.user) { - ug_free (temp.http->user); + ug_free(temp.http->user); temp.http->user = ivalue->http.user; temp.http->keeping.user = TRUE; ivalue->http.user = NULL; } if (ivalue->http.password) { - ug_free (temp.http->password); + ug_free(temp.http->password); temp.http->password = ivalue->http.password; temp.http->keeping.password = TRUE; ivalue->http.password = NULL; } if (ivalue->http.referrer) { - ug_free (temp.http->referrer); + ug_free(temp.http->referrer); temp.http->referrer = ivalue->http.referrer; temp.http->keeping.referrer = TRUE; ivalue->http.referrer = NULL; } if (ivalue->http.user_agent) { - ug_free (temp.http->user_agent); + ug_free(temp.http->user_agent); temp.http->user_agent = ivalue->http.user_agent; temp.http->keeping.user_agent = TRUE; ivalue->http.user_agent = NULL; } if (ivalue->http.cookie_data) { - ug_free (temp.http->cookie_data); + ug_free(temp.http->cookie_data); temp.http->cookie_data = ivalue->http.cookie_data; temp.http->keeping.cookie_data = TRUE; ivalue->http.cookie_data = NULL; } if (ivalue->http.cookie_file) { - ug_free (temp.http->cookie_file); + ug_free(temp.http->cookie_file); temp.http->cookie_file = ivalue->http.cookie_file; temp.http->keeping.cookie_file = TRUE; ivalue->http.cookie_file = NULL; } if (ivalue->http.post_data) { - ug_free (temp.http->post_data); + ug_free(temp.http->post_data); temp.http->post_data = ivalue->http.post_data; temp.http->keeping.post_data = TRUE; ivalue->http.post_data = NULL; } if (ivalue->http.post_file) { - ug_free (temp.http->post_file); + ug_free(temp.http->post_file); temp.http->post_file = ivalue->http.post_file; temp.http->keeping.post_file = TRUE; ivalue->http.post_file = NULL; } } - if (mem_is_zero ((char*) &ivalue->ftp, sizeof (ivalue->ftp)) == FALSE) { - temp.ftp = ug_info_realloc (info, UgetFtpInfo); + if (mem_is_zero((char*) &ivalue->ftp, sizeof(ivalue->ftp)) == FALSE) { + temp.ftp = ug_info_realloc(info, UgetFtpInfo); temp.ftp->keeping.enable = TRUE; if (ivalue->ftp.user) { - ug_free (temp.ftp->user); + ug_free(temp.ftp->user); temp.ftp->user = ivalue->ftp.user; temp.ftp->keeping.user = TRUE; ivalue->ftp.user = NULL; } if (ivalue->ftp.password) { - ug_free (temp.ftp->password); + ug_free(temp.ftp->password); temp.ftp->password = ivalue->ftp.password; temp.ftp->keeping.password = TRUE; ivalue->ftp.password = NULL; diff -Nru uget-2.2.0/uget/UgetOption.h uget-2.2.2/uget/UgetOption.h --- uget-2.2.0/uget/UgetOption.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetOption.h 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uget/UgetPluginAgent.c uget-2.2.2/uget/UgetPluginAgent.c --- uget-2.2.0/uget/UgetPluginAgent.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetPluginAgent.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2016-2018 by C.H. Huang + * Copyright (C) 2016-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -34,10 +34,6 @@ * */ -// UgetPluginAgent - -#include - #include #include #include @@ -59,17 +55,17 @@ // ---------------------------------------------------------------------------- // global functions -UgetResult uget_plugin_agent_global_init (void) +UgetResult uget_plugin_agent_global_init(void) { if (global.default_plugin == NULL) { #if defined _WIN32 || defined _WIN64 WSADATA WSAData; - WSAStartup (MAKEWORD (2, 2), &WSAData); + WSAStartup(MAKEWORD(2, 2), &WSAData); #endif // _WIN32 || _WIN64 - if (curl_global_init (CURL_GLOBAL_ALL) != CURLE_OK) { + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { #if defined _WIN32 || defined _WIN64 - WSACleanup (); + WSACleanup(); #endif return UGET_RESULT_ERROR; } @@ -79,12 +75,12 @@ return UGET_RESULT_OK; } -void uget_plugin_agent_global_ref (void) +void uget_plugin_agent_global_ref(void) { global.ref_count++; } -void uget_plugin_agent_global_unref (void) +void uget_plugin_agent_global_unref(void) { if (global.default_plugin == NULL) return; @@ -92,25 +88,25 @@ global.ref_count--; if (global.ref_count == 0) { global.default_plugin = NULL; - curl_global_cleanup (); + curl_global_cleanup(); #if defined _WIN32 || defined _WIN64 - WSACleanup (); + WSACleanup(); #endif } } -UgetResult uget_plugin_agent_global_set (int option, void* parameter) +UgetResult uget_plugin_agent_global_set(int option, void* parameter) { switch (option) { - case UGET_PLUGIN_INIT: + case UGET_PLUGIN_GLOBAL_INIT: // do global initialize/finalize here if (parameter) - return uget_plugin_agent_global_init (); + return uget_plugin_agent_global_init(); else - uget_plugin_agent_global_unref (); + uget_plugin_agent_global_unref(); break; - case UGET_PLUGIN_AGENT_DEFAULT_PLUGIN: + case UGET_PLUGIN_AGENT_GLOBAL_PLUGIN: global.default_plugin = parameter; break; @@ -121,15 +117,15 @@ return UGET_RESULT_OK; } -UgetResult uget_plugin_agent_global_get (int option, void* parameter) +UgetResult uget_plugin_agent_global_get(int option, void* parameter) { switch (option) { - case UGET_PLUGIN_INIT: + case UGET_PLUGIN_GLOBAL_INIT: if (parameter) *(int*)parameter = global.ref_count; break; - case UGET_PLUGIN_AGENT_DEFAULT_PLUGIN: + case UGET_PLUGIN_AGENT_GLOBAL_PLUGIN: *(void**)parameter = (void*)global.default_plugin; break; @@ -143,40 +139,30 @@ // ---------------------------------------------------------------------------- // instance functions -void uget_plugin_agent_init (UgetPluginAgent* plugin) +void uget_plugin_agent_init(UgetPluginAgent* plugin) { if (global.ref_count == 0) - uget_plugin_agent_global_init (); + uget_plugin_agent_global_init(); else - uget_plugin_agent_global_ref (); + uget_plugin_agent_global_ref(); } -void uget_plugin_agent_final (UgetPluginAgent* plugin) +void uget_plugin_agent_final(UgetPluginAgent* plugin) { // extent data and plug-in - if (plugin->target_node) - uget_node_unref (plugin->target_node); + if (plugin->target_info) + ug_info_unref(plugin->target_info); if (plugin->target_plugin) - uget_plugin_unref (plugin->target_plugin); - - // unlink node - if (plugin->node) - uget_node_unref (plugin->node); + uget_plugin_unref(plugin->target_plugin); - uget_plugin_agent_global_unref (); + uget_plugin_agent_global_unref(); } -int uget_plugin_agent_ctrl (UgetPluginAgent* plugin, int code, void* data) +int uget_plugin_agent_ctrl(UgetPluginAgent* plugin, int code, void* data) { - UgAssignFunc assign; - switch (code) { case UGET_PLUGIN_CTRL_START: - // assign a UgetNode to UgetPlugin to start download - assign = plugin->info->assign; - if (plugin->node == NULL && assign != NULL) - return assign (plugin, data); - break; + return FALSE; case UGET_PLUGIN_CTRL_STOP: plugin->paused = TRUE; @@ -184,73 +170,79 @@ case UGET_PLUGIN_CTRL_SPEED: // speed control - return uget_plugin_agent_ctrl_speed (plugin, data); + return uget_plugin_agent_ctrl_speed(plugin, data); - // output --------------- - case UGET_PLUGIN_CTRL_ACTIVE: + // state ---------------- + case UGET_PLUGIN_GET_STATE: *(int*)data = (plugin->stopped) ? FALSE : TRUE; return TRUE; - // unused --------------- default: break; } return FALSE; } -int uget_plugin_agent_ctrl_speed (UgetPluginAgent* plugin, int* speed) +int uget_plugin_agent_ctrl_speed(UgetPluginAgent* plugin, int* speed) { - UgetCommon* common; - int value; + UgetCommon* common; + int value; - // Don't do anything if speed limit keep no change. - if (plugin->limit[0] == speed[0] && plugin->limit[1] == speed[1]) - return TRUE; + // notify plug-in that speed limit has been changed + if (plugin->limit[0] != speed[0] || plugin->limit[1] != speed[1]) + plugin->limit_changed = TRUE; // decide speed limit by user specified data. - if (plugin->node == NULL) { + if (plugin->target_info) + common = ug_info_get(plugin->target_info, UgetCommonInfo); + else + common = NULL; + + if (common == NULL) { plugin->limit[0] = speed[0]; plugin->limit[1] = speed[1]; } else { - common = ug_info_realloc (&plugin->node->info, UgetCommonInfo); // download value = speed[0]; if (common->max_download_speed) { - if (value > common->max_download_speed || value == 0) + if (value > common->max_download_speed || value == 0) { value = common->max_download_speed; + plugin->limit_changed = TRUE; + } } plugin->limit[0] = value; // upload value = speed[1]; if (common->max_upload_speed) { - if (value > common->max_upload_speed || value == 0) + if (value > common->max_upload_speed || value == 0) { value = common->max_upload_speed; + plugin->limit_changed = TRUE; + } } plugin->limit[1] = value; } - // notify plug-in that speed limit has been changed - plugin->limit_changed = TRUE; - return TRUE; + return plugin->limit_changed; } // ---------------------------------------------------------------------------- // sync functions -void uget_plugin_agent_sync_common (UgetPluginAgent* plugin, - UgetCommon* common, - UgetCommon* target) +void uget_plugin_agent_sync_common(UgetPluginAgent* plugin, + UgetCommon* common, + UgetCommon* target) { - if (common == NULL) - common = ug_info_realloc (&plugin->node->info, UgetCommonInfo); if (target == NULL) - target = ug_info_realloc (&plugin->target_node->info, UgetCommonInfo); + target = ug_info_realloc(plugin->target_info, UgetCommonInfo); // sync speed limit from common to target - if (target->max_upload_speed != common->max_upload_speed || + if (target->max_upload_speed != common->max_upload_speed || target->max_download_speed != common->max_download_speed) { - target->max_upload_speed = common->max_upload_speed; + target->max_upload_speed = common->max_upload_speed; target->max_download_speed = common->max_download_speed; + plugin->limit[1] = common->max_upload_speed; + plugin->limit[0] = common->max_download_speed; + uget_plugin_agent_ctrl_speed(plugin, plugin->limit); } target->max_connections = common->max_connections; @@ -258,16 +250,14 @@ common->retry_count = target->retry_count; } -void uget_plugin_agent_sync_progress (UgetPluginAgent* plugin, - UgetProgress* progress, - UgetProgress* target) +void uget_plugin_agent_sync_progress(UgetPluginAgent* plugin, + UgetProgress* progress, + UgetProgress* target) { - if (progress == NULL) - progress = ug_info_realloc (&plugin->node->info, UgetProgressInfo); if (target == NULL) - target = ug_info_realloc (&plugin->target_node->info, UgetProgressInfo); + target = ug_info_realloc(plugin->target_info, UgetProgressInfo); - // sync progress from target to common + // sync progress from target to progress progress->complete = target->complete; progress->total = target->total; progress->download_speed = target->download_speed; @@ -278,159 +268,33 @@ progress->left = target->left; } -// sync child nodes from target_node to node -int uget_plugin_agent_sync_children (UgetPluginAgent* plugin, int is_target_active) -{ - UgetNode* node = plugin->node; - UgetNode* src = plugin->target_node; - UgetNode* node_child; - UgetNode* src_child; - UgetNode* new_child; - int link_changed = FALSE; - - // lock & unlock for uget_plugin_agent_sync_plugin() - ug_mutex_lock (&plugin->mutex); - - for (src_child = src->children; src_child; src_child = src_child->next) { - for (node_child = node->children; node_child; node_child = node_child->next) { - if (strcmp (src_child->name, node_child->name) == 0) - break; - } - // if found node that has the same name - if (node_child) { - // clear UGET_STATE_ACTIVE if not active - if (is_target_active == FALSE) - node_child->state = 0; - } - else { - link_changed = TRUE; - // add new node if not found - new_child = uget_node_new (NULL); - new_child->name = ug_strdup (src_child->name); - new_child->type = src_child->type; - new_child->state = (is_target_active) ? UGET_STATE_ACTIVE : 0; - uget_node_prepend (node, new_child); - } - } - - // delete unused/removed file node - if (is_target_active == FALSE) { - for (node_child = node->children; node_child; node_child = new_child) { - new_child = node_child->next; - if (node_child->state == UGET_STATE_ACTIVE) { - uget_node_remove (node, node_child); - uget_node_unref (node_child); - link_changed = TRUE; - } - } - } - - ug_mutex_unlock (&plugin->mutex); - return link_changed; -} - // ---------------------------------------------------------------------------- -// other functions +// thread functions -int uget_plugin_agent_start_thread (UgetPluginAgent* plugin, UgetNode* node, - UgThreadFunc thread_func) +int uget_plugin_agent_start(UgetPluginAgent* plugin, + UgThreadFunc thread_func) { UgThread thread; int ok; - // assign node - uget_node_ref (node); - plugin->node = node; - // try to start thread plugin->paused = FALSE; plugin->stopped = FALSE; - uget_plugin_ref ((UgetPlugin*) plugin); - ok = ug_thread_create (&thread, (UgThreadFunc) thread_func, plugin); + uget_plugin_ref((UgetPlugin*) plugin); + ok = ug_thread_create(&thread, (UgThreadFunc) thread_func, plugin); if (ok == UG_THREAD_OK) - ug_thread_unjoin (&thread); + ug_thread_unjoin(&thread); else { // failed to start thread ----------------- plugin->paused = TRUE; plugin->stopped = TRUE; - // don't assign node - uget_node_unref (plugin->node); - plugin->node = NULL; // post error message and decreases the reference count - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error (UGET_EVENT_ERROR_THREAD_CREATE_FAILED, - NULL)); - uget_plugin_unref ((UgetPlugin*) plugin); + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_error(UGET_EVENT_ERROR_THREAD_CREATE_FAILED, + NULL)); + uget_plugin_unref((UgetPlugin*) plugin); return FALSE; } return TRUE; } - -int uget_plugin_agent_sync_plugin (UgetPluginAgent* plugin) -{ - int active; - - // lock & unlock for uget_plugin_agent_sync_children() - ug_mutex_lock (&plugin->mutex); - active = uget_plugin_sync (plugin->target_plugin); - ug_mutex_unlock (&plugin->mutex); - - return active; -} - -// handle events from target_plugin by default action. -// return remain events -UgetEvent* uget_plugin_agent_handle_message (UgetPluginAgent* plugin, ...) -{ - int type; - va_list arg_list; - UgetEvent* msg_head; - UgetEvent* msg_next; - UgetEvent* msg; - - // move event from target_plugin to plug-in - msg_head = uget_plugin_pop ((UgetPlugin*) plugin->target_plugin); - for (msg = msg_head; msg; msg = msg_next) { - msg_next = msg->next; - - // filter message - va_start (arg_list, plugin); - do { - type = va_arg (arg_list, int); - if (msg->type == type || type == -1) - break; - } while (type != 0); - va_end (arg_list); - if (type == 0) - continue; - - // remove message from list - if (msg->prev) - msg->prev->next = msg->next; - else - msg_head = msg->next; - if (msg->next) - msg->next->prev = msg->prev; - msg->prev = NULL; - msg->next = NULL; - - // handle or discard some message - switch (msg->type) { - case UGET_EVENT_STOP: - case UGET_EVENT_ERROR: - // stop downloading if error occurred - plugin->paused = TRUE; - break; - - case UGET_EVENT_COMPLETED: - plugin->node->state |= UGET_STATE_COMPLETED; - break; - } - // post event to plug-in - uget_plugin_post ((UgetPlugin*) plugin, msg); - } - - return msg_head; -} - diff -Nru uget-2.2.0/uget/UgetPluginAgent.h uget-2.2.2/uget/UgetPluginAgent.h --- uget-2.2.0/uget/UgetPluginAgent.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetPluginAgent.h 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2016-2018 by C.H. Huang + * Copyright (C) 2016-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -46,20 +46,27 @@ typedef struct UgetPluginAgent UgetPluginAgent; typedef enum { - UGET_PLUGIN_AGENT_BEGIN = UGET_PLUGIN_OPTION_DERIVED, // begin + UGET_PLUGIN_AGENT_GLOBAL = UGET_PLUGIN_GLOBAL_DERIVED, // begin - UGET_PLUGIN_AGENT_DEFAULT_PLUGIN, // set parameter = (UgetPluginInfo*) + UGET_PLUGIN_AGENT_GLOBAL_PLUGIN, // set parameter = (UgetPluginInfo*) - UGET_PLUGIN_AGENT_OPTION_DERIVED, -} UgetPluginAgentCode; + UGET_PLUGIN_AGENT_GLOBAL_DERIVED, +} UgetPluginAgentGlobalCode; -// ---------------------------------------------------------------------------- -// UgetPluginAgent: It derived from UgetPlugin. +/* ---------------------------------------------------------------------------- + UgetPluginAgent: It derived from UgetPlugin. + It use other(curl/aria2) plug-in to download file. + + UgType + | + `--- UgetPlugin + | + `--- UgetPluginAgent + */ #define UGET_PLUGIN_AGENT_MEMBERS \ UGET_PLUGIN_MEMBERS; \ - UgetNode* node; \ - UgetNode* target_node; \ + UgInfo* target_info; \ UgetPlugin* target_plugin; \ int limit[2]; \ uint8_t limit_changed:1; \ @@ -69,33 +76,33 @@ struct UgetPluginAgent { UGET_PLUGIN_AGENT_MEMBERS; +/* // ------ UgType members ------ + const UgetPluginInfo* info; // ------ UgetPlugin members ------ -// const UgetPluginInfo* info; -// UgetEvent* messages; -// UgMutex mutex; -// int ref_count; + UgetEvent* messages; + UgMutex mutex; + int ref_count; // ------ UgetPluginAgent members ------ - // pointer to UgetNode that store in UgetApp -// UgetNode* node; - // This plug-in use other plug-in to download files, - // so we need extra UgetPlugin and UgetNode. - // - // plugin->target_node is a copy of plugin->node -// UgetNode* target_node; - // target_plugin use target_node to download -// UgetPlugin* target_plugin; + // so we need extra UgetPlugin and UgInfo. + + // plugin->target_info is a copy of UgInfo that store in UgetApp + UgInfo* target_info; + // target_plugin use target_info to download + UgetPlugin* target_plugin; - // control flags // speed limit control // limit[0] = download speed limit // limit[1] = upload speed limit -// int limit[2]; -// uint8_t limit_changed:1; // speed limit changed by user -// uint8_t paused:1; // paused by user -// uint8_t stopped:1; // all downloading thread are stopped + int limit[2]; + uint8_t limit_changed:1; // speed limit changed by user or program + + // control flags + uint8_t paused:1; // paused by user or program + uint8_t stopped:1; // all downloading thread are stopped + */ }; @@ -119,33 +126,21 @@ int uget_plugin_agent_ctrl_speed (UgetPluginAgent* plugin, int* speed); // sync functions --------------------- -// sync common data (include speed limit) between node and target_node -// parameter common and target can be NULL. +// sync common data (include speed limit) between 'common' and 'target' +// if parameter 'target' is NULL, it get/alloc 'target' from plugin->target_info void uget_plugin_agent_sync_common (UgetPluginAgent* plugin, UgetCommon* common, UgetCommon* target); -// sync progress data from target_node to node -// parameter progress and target can be NULL. +// sync progress data from 'target' to 'progress' +// if parameter 'target' is NULL, it get/alloc 'target' from plugin->target_info void uget_plugin_agent_sync_progress (UgetPluginAgent* plugin, UgetProgress* progress, UgetProgress* target); -// sync child nodes from target_node to node -int uget_plugin_agent_sync_children (UgetPluginAgent* plugin, - int is_target_active); - // thread functions ------------------- -int uget_plugin_agent_start_thread (UgetPluginAgent* plugin, UgetNode* node, - UgThreadFunc thread_func); - -// sync data between target_plugin and target_node -// if target_plugin is active, return TRUE -int uget_plugin_agent_sync_plugin (UgetPluginAgent* plugin); - -// handle events from target_plugin by default action. -// return remain events -UgetEvent* uget_plugin_agent_handle_message (UgetPluginAgent* plugin, ...); +int uget_plugin_agent_start (UgetPluginAgent* plugin, + UgThreadFunc thread_func); // ---------------------------------------------------------------------------- // C++11 standard-layout @@ -157,7 +152,13 @@ // This one is for derived use only. No data members here. // Your derived struct/class must be C++11 standard-layout -struct PluginAgentMethod : Uget::PluginMethod {}; +struct PluginAgentMethod : Uget::PluginMethod +{ + inline void syncCommon(UgetCommon* common, UgetCommon* target) + { uget_plugin_agent_sync_common((UgetPluginAgent*)this, common, target); } + inline void syncProgress(UgetProgress* progress, UgetProgress* target) + { uget_plugin_agent_sync_progress((UgetPluginAgent*)this, progress, target); } +}; // This one is for directly use only. You can NOT derived it. struct PluginAgent : Uget::PluginAgentMethod, UgetPluginAgent {}; diff -Nru uget-2.2.0/uget/UgetPluginAria2.c uget-2.2.2/uget/UgetPluginAria2.c --- uget-2.2.0/uget/UgetPluginAria2.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetPluginAria2.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2011-2018 by C.H. Huang + * Copyright (C) 2011-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -50,7 +50,7 @@ #ifdef HAVE_LIBPWMD #include "pwmd.h" -static gboolean uget_plugin_aria2_set_proxy_pwmd (UgetPluginAria2 *plugin, UgValue* options); +static gboolean uget_plugin_aria2_set_proxy_pwmd (UgetPluginAria2 *plugin, UgInfo* info, UgValue* options); #endif #if defined _WIN32 || defined _WIN64 @@ -69,16 +69,14 @@ #define _(x) x #endif -static UgJsonrpcObject* alloc_speed_request (UgetPluginAria2* plugin); -static void recycle_speed_request (UgJsonrpcObject* object); -static UgJsonrpcObject* alloc_status_request (UgValue** gid); -static void recycle_status_request (UgJsonrpcObject* object); - -static void aria2_file_clear (Aria2File* afile); -static void* aria2_file_array_find (Aria2FileArray* afiles, const char* path); -static void* ug_file_to_base64 (const char* file, int* length); -static int decide_file_type (UgetPluginAria2* plugin); -static void add_uri_mirrors (UgValue* varray, const char* mirrors); +static UgJsonrpcObject* alloc_speed_request(UgetPluginAria2* plugin); +static void recycle_speed_request(UgJsonrpcObject* object); +static UgJsonrpcObject* alloc_status_request(UgValue** gid); +static void recycle_status_request(UgJsonrpcObject* object); + +static void* ug_file_to_base64(const char* file, int* length); +static int decide_file_type(UgetPluginAria2* plugin); +static void add_uri_mirrors(UgValue* varray, const char* mirrors); enum UgetPluginAria2UriType { URI_UNSUPPORTED, @@ -102,14 +100,15 @@ } Aria2Status; // ---------------------------------------------------------------------------- -// UgetPluginInfo (derived from UgDataInfo) +// UgetPluginInfo (derived from UgTypeInfo) -static void plugin_init (UgetPluginAria2* plugin); -static void plugin_final (UgetPluginAria2* plugin); -static int plugin_ctrl (UgetPluginAria2* plugin, int code, void* data); -static int plugin_sync (UgetPluginAria2* plugin); -static UgetResult global_set (int code, void* parameter); -static UgetResult global_get (int code, void* parameter); +static void plugin_init (UgetPluginAria2* plugin); +static void plugin_final(UgetPluginAria2* plugin); +static int plugin_ctrl (UgetPluginAria2* plugin, int code, void* data); +static int plugin_accept(UgetPluginAria2* plugin, UgInfo* node_info); +static int plugin_sync (UgetPluginAria2* plugin, UgInfo* node_info); +static UgetResult global_set(int code, void* parameter); +static UgetResult global_get(int code, void* parameter); static const char* schemes[] = {"http", "https", "ftp", "magnet", NULL}; static const char* types[] = {"torrent", "metalink", "meta4", NULL}; @@ -117,18 +116,17 @@ static const UgetPluginInfo UgetPluginAria2InfoStatic = { "aria2", - sizeof (UgetPluginAria2), - (const UgEntry*) NULL, + sizeof(UgetPluginAria2), (UgInitFunc) plugin_init, (UgFinalFunc) plugin_final, - (UgAssignFunc) NULL, - (UgetPluginCtrlFunc) plugin_ctrl, + (UgetPluginSyncFunc) plugin_accept, (UgetPluginSyncFunc) plugin_sync, + (UgetPluginCtrlFunc) plugin_ctrl, NULL, schemes, types, - (UgetPluginSetFunc) global_set, - (UgetPluginGetFunc) global_get + (UgetPluginGlobalFunc) global_set, + (UgetPluginGlobalFunc) global_get }; // extern const UgetPluginInfo* UgetPluginAria2Info = &UgetPluginAria2InfoStatic; @@ -142,22 +140,22 @@ int ref_count; } global = {NULL, 0}; -static UgetResult global_init (void) +static UgetResult global_init(void) { if (global.data == NULL) { - global.data = uget_aria2_new (); - uget_aria2_start_thread (global.data); + global.data = uget_aria2_new(); + uget_aria2_start_thread(global.data); } global.ref_count++; return UGET_RESULT_OK; } -static void global_ref (void) +static void global_ref(void) { global.ref_count++; } -static void global_unref (void) +static void global_unref(void) { if (global.data == NULL) return; @@ -165,77 +163,77 @@ global.ref_count--; if (global.ref_count == 0) { if (global.data->shutdown) - uget_aria2_shutdown (global.data); - uget_aria2_stop_thread (global.data); - uget_aria2_unref (global.data); + uget_aria2_shutdown(global.data); + uget_aria2_stop_thread(global.data); + uget_aria2_unref(global.data); global.data = NULL; } } -static UgetResult global_set (int option, void* parameter) +static UgetResult global_set(int option, void* parameter) { UgetPluginAria2Setting* setting; switch (option) { - case UGET_PLUGIN_INIT: + case UGET_PLUGIN_GLOBAL_INIT: // do global initialize/uninitialize here if (parameter) - return global_init (); + return global_init(); else - global_unref (); + global_unref(); break; - case UGET_PLUGIN_SPEED_LIMIT: + case UGET_PLUGIN_GLOBAL_SPEED_LIMIT: if (global.data) { - uget_aria2_set_speed (global.data, + uget_aria2_set_speed(global.data, ((int*)parameter)[0], ((int*)parameter)[1]); } break; - case UGET_PLUGIN_ARIA2_URI: + case UGET_PLUGIN_ARIA2_GLOBAL_URI: if (parameter) - uget_aria2_set_uri (global.data, (char*) parameter); + uget_aria2_set_uri(global.data, (char*) parameter); break; - case UGET_PLUGIN_ARIA2_PATH: - uget_aria2_set_path (global.data, (char*) parameter); + case UGET_PLUGIN_ARIA2_GLOBAL_PATH: + uget_aria2_set_path(global.data, (char*) parameter); break; - case UGET_PLUGIN_ARIA2_ARGUMENT: - uget_aria2_set_args (global.data, (char*) parameter); + case UGET_PLUGIN_ARIA2_GLOBAL_ARGUMENT: + uget_aria2_set_args(global.data, (char*) parameter); break; - case UGET_PLUGIN_ARIA2_TOKEN: - uget_aria2_set_token (global.data, (char*) parameter); + case UGET_PLUGIN_ARIA2_GLOBAL_TOKEN: + uget_aria2_set_token(global.data, (char*) parameter); break; - case UGET_PLUGIN_ARIA2_LAUNCH: + case UGET_PLUGIN_ARIA2_GLOBAL_LAUNCH: if (parameter != NULL) - if (uget_aria2_launch (global.data) == FALSE) + if (uget_aria2_launch(global.data) == FALSE) return UGET_RESULT_ERROR; break; - case UGET_PLUGIN_ARIA2_SHUTDOWN: + case UGET_PLUGIN_ARIA2_GLOBAL_SHUTDOWN: if (parameter) global.data->shutdown = TRUE; else global.data->shutdown = FALSE; break; - case UGET_PLUGIN_ARIA2_SHUTDOWN_NOW: + case UGET_PLUGIN_ARIA2_GLOBAL_SHUTDOWN_NOW: if (parameter && global.data) - uget_aria2_shutdown (global.data); + uget_aria2_shutdown(global.data); break; - case UGET_PLUGIN_SETTING: + case UGET_PLUGIN_GLOBAL_SETTING: setting = parameter; global.data->polling_interval = setting->polling_interval; global.data->shutdown = setting->shutdown; - uget_aria2_set_uri (global.data, setting->uri); - uget_aria2_set_path (global.data, setting->path); - uget_aria2_set_args (global.data, setting->arguments); + uget_aria2_set_uri (global.data, setting->uri); + uget_aria2_set_path(global.data, setting->path); + uget_aria2_set_args(global.data, setting->arguments); if (setting->launch) - uget_aria2_launch (global.data); + uget_aria2_launch(global.data); break; default: @@ -245,20 +243,20 @@ return UGET_RESULT_OK; } -static UgetResult global_get (int option, void* parameter) +static UgetResult global_get(int option, void* parameter) { switch (option) { - case UGET_PLUGIN_INIT: + case UGET_PLUGIN_GLOBAL_INIT: if (parameter) *(int*)parameter = global.data ? TRUE : FALSE; break; - case UGET_PLUGIN_ERROR_CODE: + case UGET_PLUGIN_GLOBAL_ERROR_CODE: if (parameter) *(int*)parameter = global.data->error; break; - case UGET_PLUGIN_ARIA2_LAUNCH: + case UGET_PLUGIN_ARIA2_GLOBAL_LAUNCH: if (parameter) *(int*)parameter = global.data->launched; break; @@ -313,50 +311,47 @@ static const char* aria2_no_response = N_("No response. Is aria2 shutdown?"); -static void plugin_init (UgetPluginAria2* plugin) +static void plugin_init(UgetPluginAria2* plugin) { if (global.data == NULL) - global_init (); + global_init(); else - global_ref (); + global_ref(); - ug_array_init (&plugin->gids, sizeof (char*), 16); - ug_array_init (&plugin->files, sizeof (Aria2File), 8); + ug_array_init(&plugin->gids, sizeof(char*), 16); plugin->stopped = TRUE; plugin->paused = TRUE; plugin->synced = TRUE; } -static void plugin_final (UgetPluginAria2* plugin) +static void plugin_final(UgetPluginAria2* plugin) { - ug_array_foreach_str (&plugin->gids, (UgForeachFunc) ug_free, NULL); - ug_array_clear (&plugin->gids); - ug_array_foreach (&plugin->files, (UgForeachFunc) aria2_file_clear, NULL); - ug_array_clear (&plugin->files); + ug_array_foreach_str(&plugin->gids, (UgForeachFunc) ug_free, NULL); + ug_array_clear(&plugin->gids); + // clear UgetFiles + if (plugin->files) + ug_data_free(plugin->files); // clear and recycle start_request object if (plugin->start_request) { - ug_value_foreach (&plugin->start_request->params, ug_value_set_name, NULL); - uget_aria2_recycle (global.data, plugin->start_request); + ug_value_foreach(&plugin->start_request->params, ug_value_set_name, NULL); + uget_aria2_recycle(global.data, plugin->start_request); } - // unassign node - if (plugin->node) - uget_node_unref (plugin->node); - global_unref (); + global_unref(); } // ---------------------------------------------------------------------------- // plugin_ctrl -static int plugin_ctrl_speed (UgetPluginAria2* plugin, int* speed); -static int plugin_start (UgetPluginAria2* plugin, UgetNode* node); +static int plugin_ctrl_speed(UgetPluginAria2* plugin, int* speed); +static int plugin_start(UgetPluginAria2* plugin); -static int plugin_ctrl (UgetPluginAria2* plugin, int code, void* data) +static int plugin_ctrl(UgetPluginAria2* plugin, int code, void* data) { switch (code) { case UGET_PLUGIN_CTRL_START: - if (plugin->node == NULL) - return plugin_start (plugin, data); + if (plugin->start_request) + return plugin_start(plugin); break; case UGET_PLUGIN_CTRL_STOP: @@ -365,15 +360,13 @@ case UGET_PLUGIN_CTRL_SPEED: // speed control - return plugin_ctrl_speed (plugin, data); + return plugin_ctrl_speed(plugin, data); - // output --------------- - case UGET_PLUGIN_CTRL_ACTIVE: + // state ---------------- + case UGET_PLUGIN_GET_STATE: *(int*)data = (plugin->stopped) ? FALSE : TRUE; return TRUE; - // unused --------------- - case UGET_PLUGIN_CTRL_NODE_UPDATED: default: break; } @@ -381,55 +374,45 @@ return FALSE; } -static int plugin_ctrl_speed (UgetPluginAria2* plugin, int* speed) +static int plugin_ctrl_speed(UgetPluginAria2* plugin, int* speed) { - UgetCommon* common; - int value; + int value; - // Don't do anything if speed limit keep no change. - if (plugin->limit[0] == speed[0] && plugin->limit[1] == speed[1]) - if (plugin->limit_by_user == FALSE) - return TRUE; - plugin->limit_by_user = FALSE; + // notify plug-in that speed limit has been changed + if (plugin->limit[0] != speed[0] || plugin->limit[1] != speed[1]) + plugin->limit_changed = TRUE; // decide speed limit by user specified data. - if (plugin->node == NULL) { - plugin->limit[0] = speed[0]; - plugin->limit[1] = speed[1]; + value = speed[0]; + if (plugin->limit_upper[0] > 0) { + if (value > plugin->limit_upper[0] || value == 0) { + value = plugin->limit_upper[0]; + plugin->limit_changed = TRUE; + } } - else { - common = ug_info_realloc (&plugin->node->info, UgetCommonInfo); - // download - value = speed[0]; - if (common->max_download_speed) { - if (value > common->max_download_speed || value == 0) - value = common->max_download_speed; - } - plugin->limit[0] = value; - // upload - value = speed[1]; - if (common->max_upload_speed) { - if (value > common->max_upload_speed || value == 0) - value = common->max_upload_speed; + plugin->limit[0] = value; + + value = speed[1]; + if (plugin->limit_upper[1] > 0) { + if (value > plugin->limit_upper[1] || value == 0) { + value = plugin->limit_upper[1]; + plugin->limit_changed = TRUE; } - plugin->limit[1] = value; } - // notify plug-in that speed limit has been changed - plugin->limit_changed = TRUE; - return TRUE; + plugin->limit[1] = value; + + return plugin->limit_changed; } // ---------------------------------------------------------------------------- // plugin_sync -static int plugin_insert_node (UgetPluginAria2* plugin, - const char* fpath, int is_attachment); - // return FALSE if plug-in was stopped. -static int plugin_sync (UgetPluginAria2* plugin) +static int plugin_sync(UgetPluginAria2* plugin, UgInfo* node_info) { - int index; - UgetNode* node; - UgetEvent* event; + int index; + UgetEvent* event; + UgetFiles* files; + UgetFile* file1; struct { UgetCommon* common; UgetProgress* progress; @@ -440,17 +423,15 @@ return FALSE; plugin->synced = TRUE; } - else if (plugin->synced == TRUE) + else if (plugin->synced == TRUE) // maybe thread is accessing plugin->gids return TRUE; - // avoid crash if plug-in plug-in failed to start. - if (plugin->node == NULL) - return TRUE; - - node = plugin->node; - // sync data between plug-in and node + // avoid crash if plug-in failed to start. + if (plugin->start_request == NULL) + return FALSE; + // sync data between plug-in and foreign UgData // ------------------------------------------------ // update progress - temp.progress = ug_info_realloc (&node->info, UgetProgressInfo); + temp.progress = ug_info_realloc(node_info, UgetProgressInfo); temp.progress->complete = plugin->completedLength; temp.progress->total = plugin->totalLength; temp.progress->download_speed = plugin->downloadSpeed; @@ -471,54 +452,44 @@ if (temp.progress->download_speed > 0 && temp.progress->total > 0) temp.progress->left = (temp.progress->total - temp.progress->complete) / temp.progress->download_speed; - temp.common = ug_info_realloc (&node->info, UgetCommonInfo); + temp.common = ug_info_realloc(node_info, UgetCommonInfo); // ------------------------------------------------ - // sync changed limit from UgetNode - if (plugin->limit[1] != temp.common->max_upload_speed || - plugin->limit[0] != temp.common->max_download_speed) + // sync changed limit from foreign UgInfo + if (plugin->limit_upper[1] != temp.common->max_upload_speed || + plugin->limit_upper[0] != temp.common->max_download_speed) { - plugin->limit_by_user = TRUE; - } - - // add nodes by files - if (plugin->files_per_gid_prev != plugin->files_per_gid) { -#ifndef NDEBUG - // debug - if (temp.common->debug_level) { - printf ("n_files: old %d - new %d\n", - plugin->files_per_gid_prev, - plugin->files_per_gid); - } -#endif - // add child node if aria2 add/create more files - index = plugin->files_per_gid_prev; - for (; index < plugin->files.length; index++) { - if (plugin_insert_node (plugin, plugin->files.at[index].path, FALSE)) { -#ifndef NDEBUG - // debug - if (temp.common->debug_level) - printf ("new child node name = %s\n", plugin->files.at[index].path); -#endif - } - } - plugin->files_per_gid_prev = plugin->files_per_gid; + // speed control + plugin->limit_upper[1] = temp.common->max_upload_speed; + plugin->limit_upper[0] = temp.common->max_download_speed; + plugin_ctrl_speed(plugin, plugin->limit_upper); } - // change node name. - if (plugin->node_named == FALSE && plugin->files_per_gid > 0) { - plugin->node_named = TRUE; + // update UgetFiles + files = ug_info_realloc(node_info, UgetFilesInfo); + uget_plugin_lock(plugin); + uget_files_sync(files, plugin->files); + uget_plugin_unlock(plugin); + + // change name. + if (files->list.size > 0 && + plugin->named == FALSE && plugin->files_per_gid > 0) + { + plugin->named = TRUE; if (plugin->uri_type == URI_NET && temp.common->file == NULL) { - ug_uri_init (&plugin->uri_part, node->children->name); + uget_plugin_lock(plugin); + file1 = (UgetFile*) plugin->files->list.head; + ug_uri_init(&plugin->uri_part, file1->path); + uget_plugin_unlock(plugin); index = plugin->uri_part.file; if (index != -1) { - ug_free (node->name); - node->name = ug_uri_get_file (&plugin->uri_part); - event = uget_event_new (UGET_EVENT_NAME); - uget_plugin_post ((UgetPlugin*) plugin, event); + ug_free(temp.common->name); + temp.common->name = ug_uri_get_file(&plugin->uri_part); + event = uget_event_new(UGET_EVENT_NAME); + uget_plugin_post((UgetPlugin*) plugin, event); #ifndef NDEBUG // debug if (temp.common->debug_level) - printf ("base node name = %s\n", node->name); + printf("base name = %s\n", temp.common->name); #endif } } @@ -529,70 +500,63 @@ if (plugin->completedLength > 0 && plugin->completedLength == plugin->totalLength) { -#ifndef NDEBUG - // debug - if (temp.common->debug_level) { - if ((node->state & UGET_STATE_UPLOADING) == 0) - printf ("uploading...\n"); - } -#endif - node->state |= UGET_STATE_UPLOADING; + event = uget_event_new(UGET_EVENT_UPLOADING); + uget_plugin_post((UgetPlugin*) plugin, event); } break; case ARIA2_STATUS_WAITING: // clear uploading state - node->state &= ~UGET_STATE_UPLOADING; + event = uget_event_new(UGET_EVENT_STOP_UPLOADING); + uget_plugin_post((UgetPlugin*) plugin, event); break; case ARIA2_STATUS_COMPLETE: // clear uploading state - node->state &= ~UGET_STATE_UPLOADING; + event = uget_event_new(UGET_EVENT_STOP_UPLOADING); + uget_plugin_post((UgetPlugin*) plugin, event); // remove completed gid - ug_free (plugin->gids.at[0]); - plugin->gids.length -= 1; - memmove (plugin->gids.at, plugin->gids.at + 1, - sizeof (char*) * plugin->gids.length); + if (plugin->gids.length > 0) { + ug_free(plugin->gids.at[0]); + ug_array_erase(&plugin->gids, 0, 1); + } // If there is only one followed gid and file, change uri. - if (plugin->gids.length == 1 && plugin->files.length == 1) { + if (plugin->gids.length == 1 && plugin->files_per_gid == 1) { // If URI scheme is not "magnet" and aria2 runs in local device if (global.data->uri_remote == FALSE && plugin->uri_type != URI_MAGNET) { // change URI - ug_free (temp.common->uri); - ug_free (temp.common->file); + ug_free(temp.common->uri); + ug_free(temp.common->name); + ug_free(temp.common->file); + file1 = (UgetFile*) plugin->files->list.head; + temp.common->uri = ug_strdup(file1->path); + temp.common->name = uget_name_from_uri_str(temp.common->uri); temp.common->file = NULL; - if (node->children && node->children->name) - temp.common->uri = ug_strdup (node->children->name); - else - temp.common->uri = ug_strdup (plugin->files.at[0].path); - uget_node_set_name_by_uri_string (node, temp.common->uri); - // set node type - node->children->type = UGET_NODE_ATTACHMENT; #ifndef NDEBUG // debug if (temp.common->debug_level) - printf ("uri followed to %s\n", temp.common->uri); + printf("uri followed to %s\n", temp.common->uri); #endif } } // If no followed gid, it was completed. else if (plugin->gids.length == 0) { - node->state |= UGET_STATE_COMPLETED; - event = uget_event_new (UGET_EVENT_COMPLETED); - uget_plugin_post ((UgetPlugin*)plugin, event); - } - // clear plugin->files - ug_array_foreach (&plugin->files, (UgForeachFunc)aria2_file_clear, NULL); - plugin->files.length = 0; + event = uget_event_new(UGET_EVENT_COMPLETED); + uget_plugin_post((UgetPlugin*)plugin, event); + } + // clear files + uget_plugin_lock(plugin); + uget_files_clear(plugin->files); + uget_plugin_unlock(plugin); plugin->files_per_gid = 0; - plugin->files_per_gid_prev = 0; break; case ARIA2_STATUS_ERROR: // clear uploading state - node->state &= ~UGET_STATE_UPLOADING; + event = uget_event_new(UGET_EVENT_STOP_UPLOADING); + uget_plugin_post((UgetPlugin*) plugin, event); #ifdef NO_RETRY_IF_CONNECT_FAILED // download speed was too slow if (plugin->errorCode == 5) { @@ -609,14 +573,13 @@ #ifndef NDEBUG // debug if (temp.common->debug_level) - printf ("retry %d\n", temp.common->retry_count); + printf("retry %d\n", temp.common->retry_count); #endif } else { -// plugin->node->state |= UGET_STATE_ERROR; - event = uget_event_new_error ( + event = uget_event_new_error( UGET_EVENT_ERROR_TOO_MANY_RETRIES, NULL); - uget_plugin_post ((UgetPlugin*) plugin, event); + uget_plugin_post((UgetPlugin*) plugin, event); } } else { @@ -624,36 +587,36 @@ plugin->errorCode = 1; // if this is last gid. if (plugin->gids.length == 1) { -// plugin->node->state |= UGET_STATE_ERROR; #ifdef HAVE_GLIB - event = uget_event_new_error (0, - gettext (error_string[plugin->errorCode])); + event = uget_event_new_error(0, + gettext(error_string[plugin->errorCode])); #else - event = uget_event_new_error (0, + event = uget_event_new_error(0, error_string[plugin->errorCode]); #endif - uget_plugin_post ((UgetPlugin*)plugin, event); + uget_plugin_post((UgetPlugin*)plugin, event); } } // remove stopped gid - ug_free (plugin->gids.at[0]); + ug_free(plugin->gids.at[0]); plugin->gids.length -= 1; - memmove (plugin->gids.at, plugin->gids.at + 1, - sizeof (char*) * plugin->gids.length); + memmove(plugin->gids.at, plugin->gids.at + 1, + sizeof(char*) * plugin->gids.length); break; case ARIA2_STATUS_REMOVED: // clear uploading state - node->state &= ~UGET_STATE_UPLOADING; + event = uget_event_new(UGET_EVENT_STOP_UPLOADING); + uget_plugin_post((UgetPlugin*) plugin, event); // debug - event = uget_event_new_normal (0, _("aria2: gid was removed.")); - uget_plugin_post ((UgetPlugin*)plugin, event); + event = uget_event_new_normal(0, _("aria2: gid was removed.")); + uget_plugin_post((UgetPlugin*)plugin, event); // remove completed gid - ug_free (plugin->gids.at[0]); + ug_free(plugin->gids.at[0]); plugin->gids.length -= 1; - memmove (plugin->gids.at, plugin->gids.at + 1, - sizeof (char*) * plugin->gids.length); + memmove(plugin->gids.at, plugin->gids.at + 1, + sizeof(char*) * plugin->gids.length); break; } @@ -664,7 +627,7 @@ #ifndef NDEBUG // debug if (temp.common->debug_level) - printf ("gids.length = %d\n", plugin->gids.length); + printf("gids.length = %d\n", plugin->gids.length); #endif // If no followed gid and no need to retry, it must stop. if (plugin->restart == FALSE) @@ -677,102 +640,62 @@ return TRUE; } -// ------------------------------------ - -static int plugin_insert_node (UgetPluginAria2* plugin, - const char* fpath, int is_attachment) -{ - UgetNode* node; - char* ctrl_file; - - // aria2 magnet metadata file -// if (plugin->uri_type == URI_MAGNET) { -// if (strncmp ("[METADATA]", fpath, 10) == 0) -// fpath += 10; -// } - - for (node = plugin->node->children; node; node = node->next) { - if (strcmp (node->name, fpath) == 0) - return FALSE; - } - - // aria2 control file must add first - ctrl_file = ug_malloc (strlen (fpath) + 6 + 1); // + ".aria2" + '\0' - ctrl_file[0] = 0; - strcat (ctrl_file, fpath); - strcat (ctrl_file, ".aria2"); - node = uget_node_new (NULL); - node->name = ctrl_file; - node->type = UGET_NODE_ATTACHMENT; - uget_node_prepend (plugin->node, node); - // download file - node = uget_node_new (NULL); - node->name = ug_strdup (fpath); - uget_node_prepend (plugin->node, node); - if (is_attachment) - node->type = UGET_NODE_ATTACHMENT; - - return TRUE; -} - // ---------------------------------------------------------------------------- // plugin_thread -static void add_gids_by_value_array (UgArrayStr* gids, UgValueArray* varray) +static void add_gids_by_value_array(UgArrayStr* gids, UgValueArray* varray) { UgValue* value; int index; #ifndef NDEBUG // debug - printf ("add %d gids\n", varray->length); + printf("add %d gids\n", varray->length); #endif for (index = 0; index < varray->length; index++) { value = varray->at + index; - *(char**) ug_array_alloc (gids, 1) = value->c.string; + *(char**) ug_array_alloc(gids, 1) = value->c.string; value->c.string = NULL; value->type = UG_VALUE_NONE; } } -static int send_start_request (UgetPluginAria2* plugin) +static int send_start_request(UgetPluginAria2* plugin) { UgJsonrpcObject* res; - uget_aria2_request (global.data, plugin->start_request); - res = uget_aria2_respond (global.data, plugin->start_request); + uget_aria2_request(global.data, plugin->start_request); + res = uget_aria2_respond(global.data, plugin->start_request); if (res == NULL) { #ifdef HAVE_GLIB - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error(0, gettext (aria2_no_response))); + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_error(0, gettext(aria2_no_response))); #else - uget_plugin_post ((UgetPlugin*) plugin, + uget_plugin_post((UgetPlugin*) plugin, uget_event_new_error(0, aria2_no_response)); #endif -// plugin->node->state |= UGET_STATE_ERROR; return FALSE; } if (res->error.code) { - uget_plugin_post ((UgetPlugin*)plugin, + uget_plugin_post((UgetPlugin*)plugin, uget_event_new_error(0, res->error.message)); - uget_aria2_recycle (global.data, res); -// plugin->node->state |= UGET_STATE_ERROR; + uget_aria2_recycle(global.data, res); return FALSE; } // add gid from response if (plugin->uri_type == URI_METALINK) - add_gids_by_value_array (&plugin->gids, res->result.c.array); + add_gids_by_value_array(&plugin->gids, res->result.c.array); else { - *(char**) ug_array_alloc (&plugin->gids, 1) = - ug_strdup (res->result.c.string); + *(char**) ug_array_alloc(&plugin->gids, 1) = + ug_strdup(res->result.c.string); } // recycle response - uget_aria2_recycle (global.data, res); + uget_aria2_recycle(global.data, res); return TRUE; } -static int plugin_delay (UgetPluginAria2* plugin) +static int plugin_delay(UgetPluginAria2* plugin) { unsigned int count; @@ -780,12 +703,12 @@ if (plugin->paused) return FALSE; // sleep 1 second every time - ug_sleep (1000); + ug_sleep(1000); } return TRUE; } -static UG_THREAD_RETURN_TYPE plugin_thread (UgetPluginAria2* plugin) +static UgThreadResult plugin_thread(UgetPluginAria2* plugin) { UgJsonrpcObject* req; UgJsonrpcObject* res; @@ -796,30 +719,30 @@ int count; // create status_req and initialize status_gid - status_req = alloc_status_request (&status_gid); + status_req = alloc_status_request(&status_gid); // send start_request to server plugin->restart = FALSE; - if (send_start_request (plugin) == FALSE) + if (send_start_request(plugin) == FALSE) goto exit; while (plugin->paused == FALSE) { // retry if (plugin->restart == TRUE) { - if (plugin_delay (plugin) == FALSE) + if (plugin_delay(plugin) == FALSE) continue; #ifndef NDEBUG // debug - printf ("retry\n"); + printf("retry\n"); #endif // send start_request to server again plugin->restart = FALSE; - if (send_start_request (plugin) == FALSE) + if (send_start_request(plugin) == FALSE) goto exit; } // Don't update status until user call plugin_sync() if (plugin->synced == FALSE) { // sleep 0.5 second - ug_sleep (500); + ug_sleep(500); continue; } @@ -827,42 +750,40 @@ // status_req->params.c.array->at[0].c.string = plugin->gids.at[0]; status_gid->c.string = plugin->gids.at[0]; // status request - uget_aria2_request (global.data, status_req); + uget_aria2_request(global.data, status_req); // speed control : speed request & response if (plugin->limit_changed) { plugin->limit_changed = FALSE; // request & response - req = alloc_speed_request (plugin); - uget_aria2_request (global.data, req); - res = uget_aria2_respond (global.data, req); + req = alloc_speed_request(plugin); + uget_aria2_request(global.data, req); + res = uget_aria2_respond(global.data, req); // recycle - uget_aria2_recycle (global.data, res); - recycle_speed_request (req); + uget_aria2_recycle(global.data, res); + recycle_speed_request(req); } // status respond - res = uget_aria2_respond (global.data, status_req); + res = uget_aria2_respond(global.data, status_req); if (res == NULL) { #ifdef HAVE_GLIB - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error(0, gettext (aria2_no_response))); + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_error(0, gettext(aria2_no_response))); #else - uget_plugin_post ((UgetPlugin*) plugin, + uget_plugin_post((UgetPlugin*) plugin, uget_event_new_error(0, aria2_no_response)); #endif -// plugin->node->state |= UGET_STATE_ERROR; goto exit; } if (res->error.code) { - uget_plugin_post ((UgetPlugin*)plugin, + uget_plugin_post((UgetPlugin*)plugin, uget_event_new_error(0, res->error.message)); - uget_aria2_recycle (global.data, res); -// plugin->node->state |= UGET_STATE_ERROR; + uget_aria2_recycle(global.data, res); goto exit; } // parse status response --- start --- - ug_value_sort_name (&res->result); - value = ug_value_find_name (&res->result, "status"); + ug_value_sort_name(&res->result); + value = ug_value_find_name(&res->result, "status"); switch (value->c.string[0]) { case 'a': plugin->status = ARIA2_STATUS_ACTIVE; @@ -886,188 +807,194 @@ plugin->status = ARIA2_N_STATUS; break; } - value = ug_value_find_name (&res->result, "errorCode"); - plugin->errorCode = (value) ? ug_value_get_int (value) : 0; - value = ug_value_find_name (&res->result, "totalLength"); - plugin->totalLength = ug_value_get_int64 (value); - value = ug_value_find_name (&res->result, "completedLength"); - plugin->completedLength = ug_value_get_int64 (value); - value = ug_value_find_name (&res->result, "uploadLength"); - plugin->uploadLength = ug_value_get_int64 (value); - value = ug_value_find_name (&res->result, "downloadSpeed"); - plugin->downloadSpeed = ug_value_get_int (value); - value = ug_value_find_name (&res->result, "uploadSpeed"); - plugin->uploadSpeed = ug_value_get_int (value); - value = ug_value_find_name (&res->result, "followedBy"); + value = ug_value_find_name(&res->result, "errorCode"); + plugin->errorCode = (value) ? ug_value_get_int(value) : 0; + value = ug_value_find_name(&res->result, "totalLength"); + plugin->totalLength = ug_value_get_int64(value); + value = ug_value_find_name(&res->result, "completedLength"); + plugin->completedLength = ug_value_get_int64(value); + value = ug_value_find_name(&res->result, "uploadLength"); + plugin->uploadLength = ug_value_get_int64(value); + value = ug_value_find_name(&res->result, "downloadSpeed"); + plugin->downloadSpeed = ug_value_get_int(value); + value = ug_value_find_name(&res->result, "uploadSpeed"); + plugin->uploadSpeed = ug_value_get_int(value); + value = ug_value_find_name(&res->result, "followedBy"); if (value) - add_gids_by_value_array (&plugin->gids, value->c.array); - value = ug_value_find_name (&res->result, "files"); - if (value && value->c.array->length != plugin->files_per_gid) { - UgValueArray* files; - Aria2File* afile; - - files = value->c.array; - for (count = 0; count < files->length; count++) { - value = files->at + count; - ug_value_sort_name (value); - member = ug_value_find_name (value, "path"); - if (member == NULL || member->c.string[0] == '\0') - continue; - if (aria2_file_array_find (&plugin->files, member->c.string)) + add_gids_by_value_array(&plugin->gids, value->c.array); + value = ug_value_find_name(&res->result, "files"); + if (value && ug_value_length(value) != plugin->files_per_gid) { + UgValueArray* array; + UgetFile* ufile; + char* string; + + array = value->c.array; + plugin->files_per_gid = ug_value_length(value); + for (count = 0; count < array->length; count++) { + value = array->at + count; + ug_value_sort_name(value); + member = ug_value_find_name(value, "path"); + if (member == NULL || member->c.string[0] == '\0') { + plugin->files_per_gid--; continue; - plugin->files_per_gid++; - afile = ug_array_alloc (&plugin->files, 1); - member = ug_value_find_name (value, "completedLength"); - afile->completedLength = ug_value_get_int64 (member); - member = ug_value_find_name (value, "length"); - afile->length = ug_value_get_int64 (member); - member = ug_value_find_name (value, "path"); - afile->path = member->c.string; - member->c.string = NULL; - member->type = UG_VALUE_NONE; + } + uget_plugin_lock(plugin); + // add .aria2 control file first + if (plugin->files_per_gid == 1) { + string = ug_strdup_printf("%s.aria2", member->c.string); + ufile = uget_files_realloc(plugin->files, string); + ufile->type = UGET_FILE_TEMPORARY; + ug_free(string); + } + // add downloading file + ufile = uget_files_realloc(plugin->files, member->c.string); + member = ug_value_find_name(value, "completedLength"); + ufile->complete = ug_value_get_int64(member); + member = ug_value_find_name(value, "length"); + ufile->total = ug_value_get_int64(member); + uget_plugin_unlock(plugin); } } // parse status response --- end --- // recycle status response - uget_aria2_recycle (global.data, res); - // plug-in and it's node will update + uget_aria2_recycle(global.data, res); + // plugin_sync() will exchange data plugin->synced = FALSE; } if (plugin->gids.length) { - req = uget_aria2_alloc (global.data, TRUE, TRUE); + req = uget_aria2_alloc(global.data, TRUE, TRUE); req->method_static = "aria2.remove"; // if there is no secret token in params. if (req->params.type == UG_VALUE_NONE) - ug_value_init_array (&req->params, plugin->gids.length); + ug_value_init_array(&req->params, plugin->gids.length); // add gids to params. - value = ug_value_alloc (&req->params, plugin->gids.length); + value = ug_value_alloc(&req->params, plugin->gids.length); for (count = 0; count < plugin->gids.length; count++, value++) { value->type = UG_VALUE_STRING; - value->c.string = ug_strdup (plugin->gids.at[count]); + value->c.string = ug_strdup(plugin->gids.at[count]); } // call "aria2.remove" - uget_aria2_request (global.data, req); - res = uget_aria2_respond (global.data, req); + uget_aria2_request(global.data, req); + res = uget_aria2_respond(global.data, req); #ifndef NDEBUG // debug if (res->error.code) { - printf ("aria2.remove() response error code = %d" "\n" - " message = \"%s\"." "\n", - res->error.code, res->error.message); + printf("aria2.remove() response error code = %d" "\n" + " message = \"%s\"." "\n", + res->error.code, res->error.message); } #endif - uget_aria2_recycle (global.data, res); - uget_aria2_recycle (global.data, req); + uget_aria2_recycle(global.data, res); + uget_aria2_recycle(global.data, req); } exit: - recycle_status_request (status_req); + recycle_status_request(status_req); plugin->stopped = TRUE; - uget_plugin_unref ((UgetPlugin*)plugin); - return UG_THREAD_RETURN_VALUE; + uget_plugin_unref((UgetPlugin*)plugin); + return UG_THREAD_RESULT; } // ---------------------------------------------------------------------------- -// plugin_start +// plugin_accept/plugin_start -static int plugin_start (UgetPluginAria2* plugin, UgetNode* node) +static int plugin_accept(UgetPluginAria2* plugin, UgInfo* node_info) { UgJsonrpcObject* request; UgValue* value; UgValue* member; - UgThread thread; char* uri; - char* data = NULL; + char* str = NULL; char* user = NULL; char* password = NULL; union { UgetCommon* common; + UgetFiles* files; UgetProxy* proxy; UgetHttp* http; UgetHttp* ftp; - int ok; } temp; - temp.common = ug_info_get (&node->info, UgetCommonInfo); + temp.common = ug_info_get(node_info, UgetCommonInfo); if (temp.common == NULL || temp.common->uri == NULL) return FALSE; uri = temp.common->uri; plugin->uri_type = URI_NET; - ug_uri_init (&plugin->uri_part, uri); - if ((plugin->uri_part.scheme_len == 4 && strncmp (uri, "file", 4) == 0) || - (plugin->uri_part.scheme_len == 0 && plugin->uri_part.file >= 0)) + ug_uri_init(&plugin->uri_part, uri); + if ((plugin->uri_part.scheme_len == 4 && strncmp(uri, "file", 4) == 0) || + (plugin->uri_part.scheme_len == 0 && plugin->uri_part.file >= 0)) { // file type is torrent or metalink? - if (decide_file_type (plugin) == URI_UNSUPPORTED) { - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error (UGET_EVENT_ERROR_UNSUPPORTED_FILE, + if (decide_file_type(plugin) == URI_UNSUPPORTED) { + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_error(UGET_EVENT_ERROR_UNSUPPORTED_FILE, NULL)); return FALSE; } // load file and convert it's binary to base64 if (plugin->uri_part.path > 0) - data = ug_file_to_base64 (uri + plugin->uri_part.path + 1, NULL); + str = ug_file_to_base64(uri + plugin->uri_part.path + 1, NULL); else - data = ug_file_to_base64 (uri, NULL); - if (data == NULL) { - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error (UGET_EVENT_ERROR_FILE_OPEN_FAILED, + str = ug_file_to_base64(uri, NULL); + if (str == NULL) { + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_error(UGET_EVENT_ERROR_FILE_OPEN_FAILED, NULL)); return FALSE; } } - else if (plugin->uri_part.scheme_len == 6 && strncmp (uri, "magnet", 6) == 0) + else if (plugin->uri_part.scheme_len == 6 && strncmp(uri, "magnet", 6) == 0) plugin->uri_type = URI_MAGNET; - request = uget_aria2_alloc (global.data, TRUE, TRUE); + request = uget_aria2_alloc(global.data, TRUE, TRUE); if (request->params.type == UG_VALUE_NONE) - ug_value_init_array (&request->params, 3); + ug_value_init_array(&request->params, 3); switch (plugin->uri_type) { case URI_NET: case URI_MAGNET: request->method_static = "aria2.addUri"; // parameter1 : URIs - value = ug_value_alloc (&request->params, 1); - ug_value_init_array (value, 8); - member = ug_value_alloc (value, 1); + value = ug_value_alloc(&request->params, 1); + ug_value_init_array(value, 8); + member = ug_value_alloc(value, 1); member->type = UG_VALUE_STRING; - member->c.string = ug_strdup (uri); + member->c.string = ug_strdup(uri); // mirrors - add_uri_mirrors (value, temp.common->mirrors); + add_uri_mirrors(value, temp.common->mirrors); // parameter2 : options break; case URI_TORRENT: request->method_static = "aria2.addTorrent"; // parameter1 : encoded torrent file - value = ug_value_alloc (&request->params, 1); + value = ug_value_alloc(&request->params, 1); value->type = UG_VALUE_STRING; - value->c.string = data; + value->c.string = str; // parameter2 : URIs - value = ug_value_alloc (&request->params, 1); - ug_value_init_array (value, 0); + value = ug_value_alloc(&request->params, 1); + ug_value_init_array(value, 0); // parameter3 : options break; case URI_METALINK: // parameter1 : encoded metalink file request->method_static = "aria2.addMetalink"; - value = ug_value_alloc (&request->params, 1); + value = ug_value_alloc(&request->params, 1); value->type = UG_VALUE_STRING; - value->c.string = data; + value->c.string = str; // parameter2 : options break; } // parameterX : options - value = ug_value_alloc (&request->params, 1); - ug_value_init_object (value, 16); - member = ug_value_alloc (value, 1); + value = ug_value_alloc(&request->params, 1); + ug_value_init_object(value, 16); + member = ug_value_alloc(value, 1); member->name = "continue"; member->type = UG_VALUE_BOOL; member->c.boolean = TRUE; @@ -1080,107 +1007,118 @@ } if (temp.common->folder) { - member = ug_value_alloc (value, 1); + member = ug_value_alloc(value, 1); member->name = "dir"; member->type = UG_VALUE_STRING; - member->c.string = ug_strdup (temp.common->folder); + member->c.string = ug_strdup(temp.common->folder); } if (temp.common->file) { - member = ug_value_alloc (value, 1); + member = ug_value_alloc(value, 1); member->name = "out"; member->type = UG_VALUE_STRING; - member->c.string = ug_strdup (temp.common->file); + member->c.string = ug_strdup(temp.common->file); } - member = ug_value_alloc (value, 1); + member = ug_value_alloc(value, 1); member->name = "remote-time"; member->type = UG_VALUE_BOOL; member->c.boolean = temp.common->timestamp; - member = ug_value_alloc (value, 1); + member = ug_value_alloc(value, 1); member->name = "retry-wait"; member->type = UG_VALUE_STRING; - member->c.string = ug_strdup_printf ("%u", temp.common->retry_delay); + member->c.string = ug_strdup_printf("%u", temp.common->retry_delay); - member = ug_value_alloc (value, 1); + member = ug_value_alloc(value, 1); member->name = "max-tries"; member->type = UG_VALUE_STRING; - member->c.string = ug_strdup_printf ("%u", temp.common->retry_limit); + member->c.string = ug_strdup_printf("%u", temp.common->retry_limit); + + // speed control: decide speed limit before starting plug-in + plugin->limit_upper[1] = temp.common->max_upload_speed; + plugin->limit_upper[0] = temp.common->max_download_speed; + plugin_ctrl_speed(plugin, plugin->limit); - member = ug_value_alloc (value, 1); + member = ug_value_alloc(value, 1); member->name = "max-download-limit"; member->type = UG_VALUE_STRING; -// member->c.string = ug_strdup_printf ("%d", temp.common->max_download_speed); - member->c.string = ug_strdup_printf ("%d", plugin->limit[0]); +// member->c.string = ug_strdup_printf("%d", temp.common->max_download_speed); + member->c.string = ug_strdup_printf("%d", plugin->limit[0]); - member = ug_value_alloc (value, 1); + member = ug_value_alloc(value, 1); member->name = "max-upload-limit"; member->type = UG_VALUE_STRING; -// member->c.string = ug_strdup_printf ("%d", temp.common->max_upload_speed); - member->c.string = ug_strdup_printf ("%d", plugin->limit[1]); +// member->c.string = ug_strdup_printf("%d", temp.common->max_upload_speed); + member->c.string = ug_strdup_printf("%d", plugin->limit[1]); - member = ug_value_alloc (value, 1); + member = ug_value_alloc(value, 1); member->name = "lowest-speed-limit"; member->type = UG_VALUE_STRING; - member->c.string = ug_strdup_printf ("%u", 128); + member->c.string = ug_strdup_printf("%u", 128); // Don't set connection limit if max_connections is 0. if (temp.common->max_connections != 0) { // aria2 doesn't accept "max-connection-per-server" large than 16. - member = ug_value_alloc (value, 1); + member = ug_value_alloc(value, 1); member->name = "max-connection-per-server"; member->type = UG_VALUE_STRING; - member->c.string = ug_strdup_printf ("%u", + member->c.string = ug_strdup_printf("%u", (temp.common->max_connections <= 16) ? temp.common->max_connections : 16); // split - member = ug_value_alloc (value, 1); + member = ug_value_alloc(value, 1); member->name = "split"; member->type = UG_VALUE_STRING; - member->c.string = ug_strdup_printf ("%u", + member->c.string = ug_strdup_printf("%u", temp.common->max_connections); } - temp.proxy = ug_info_get (&node->info, UgetProxyInfo); + temp.files = ug_info_get(node_info, UgetFilesInfo); + if (temp.files) + plugin->files = ug_data_copy(temp.files); + else + plugin->files = ug_data_new(UgetFilesInfo); + + temp.proxy = ug_info_get(node_info, UgetProxyInfo); #ifdef HAVE_LIBPWMD if (temp.proxy && temp.proxy->type == UGET_PROXY_PWMD) { - if (uget_plugin_aria2_set_proxy_pwmd (plugin, member) == FALSE) + if (uget_plugin_aria2_set_proxy_pwmd(plugin, node_info, member) == FALSE) return FALSE; } else #endif if (temp.proxy && temp.proxy->host) { - member = ug_value_alloc (value, 1); + member = ug_value_alloc(value, 1); member->name = "all-proxy"; member->type = UG_VALUE_STRING; if (temp.proxy->port == 0) - member->c.string = ug_strdup (temp.proxy->host); + member->c.string = ug_strdup(temp.proxy->host); else { - member->c.string = ug_strdup_printf ("%s:%d", + member->c.string = ug_strdup_printf("%s:%d", temp.proxy->host, temp.proxy->port); } if ((temp.proxy->user && temp.proxy->user[0]) || (temp.proxy->password && temp.proxy->password[0])) { - member = ug_value_alloc (value, 1); + member = ug_value_alloc(value, 1); member->name = "all-proxy-user"; member->type = UG_VALUE_STRING; - member->c.string = ug_strdup ( + member->c.string = ug_strdup( (temp.proxy->user) ? temp.proxy->user : ""); - member = ug_value_alloc (value, 1); + member = ug_value_alloc(value, 1); member->name = "all-proxy-password"; member->type = UG_VALUE_STRING; - member->c.string = ug_strdup ( + member->c.string = ug_strdup( (temp.proxy->password) ? temp.proxy->password : ""); } } - temp.http = ug_info_get (&node->info, UgetHttpInfo); + temp.http = ug_info_get(node_info, UgetHttpInfo); if (temp.http) { if (plugin->uri_part.scheme_len >= 4 && - strncmp (uri, "http", 4) == 0) + strncmp(uri, "http", 4) == 0) { if ((temp.http->user && temp.http->user[0]) || (temp.http->password && temp.http->password[0])) @@ -1190,28 +1128,28 @@ } } if (temp.http->referrer) { - member = ug_value_alloc (value, 1); + member = ug_value_alloc(value, 1); member->name = "referer"; member->type = UG_VALUE_STRING; - member->c.string = ug_strdup (temp.http->referrer); + member->c.string = ug_strdup(temp.http->referrer); } // if (temp.http->cookie_file) { -// member = ug_value_alloc (value, 1); +// member = ug_value_alloc(value, 1); // member->name = "load-cookies"; // member->type = UG_VALUE_STRING; -// member->c.string = ug_strdup (temp.http->cookie_file); +// member->c.string = ug_strdup(temp.http->cookie_file); // } if (temp.http->user_agent) { - member = ug_value_alloc (value, 1); + member = ug_value_alloc(value, 1); member->name = "user-agent"; member->type = UG_VALUE_STRING; - member->c.string = ug_strdup (temp.http->user_agent); + member->c.string = ug_strdup(temp.http->user_agent); } } - temp.ftp = ug_info_get (&node->info, UgetFtpInfo); + temp.ftp = ug_info_get(node_info, UgetFtpInfo); if (temp.ftp) { - if (plugin->uri_part.scheme_len >= 3 && strncmp (uri, "ftp", 3) == 0) { + if (plugin->uri_part.scheme_len >= 3 && strncmp(uri, "ftp", 3) == 0) { if ((temp.ftp->user && temp.ftp->user[0]) || (temp.ftp->password && temp.ftp->password[0])) { @@ -1223,54 +1161,52 @@ if (plugin->uri_type == URI_NET && plugin->uri_part.host != -1) { if (user || password) { - data = ug_malloc (strlen (user) + strlen (password) + - strlen (uri) + 2 + 1); // + ':' + '@' + '\0' - data[plugin->uri_part.host] = 0; - strncpy (data, uri, plugin->uri_part.host); - strcat (data, user); - strcat (data, ":"); - strcat (data, password); - strcat (data, "@"); - strcat (data, uri + plugin->uri_part.host); + str = ug_malloc(strlen(user) + strlen(password) + + strlen(uri) + 2 + 1); // + ':' + '@' + '\0' + str[plugin->uri_part.host] = 0; + strncpy(str, uri, plugin->uri_part.host); + strcat(str, user); + strcat(str, ":"); + strcat(str, password); + strcat(str, "@"); + strcat(str, uri + plugin->uri_part.host); // reset uri for aria2.addUri, request->params[0][0] value = request->params.c.array->at; value = value->c.array->at; - ug_free (value->c.string); - value->c.string = ug_strdup (data); + ug_free(value->c.string); + value->c.string = ug_strdup(str); } } plugin->files_per_gid = 0; - plugin->files_per_gid_prev = 0; plugin->synced = TRUE; - plugin->start_time = time (NULL); + plugin->start_time = time(NULL); plugin->start_request = request; - // assign node - uget_node_ref (node); - plugin->node = node; - // speed control - plugin_ctrl_speed (plugin, plugin->limit); + return TRUE; +} + +static int plugin_start(UgetPluginAria2* plugin) +{ + UgThread thread; + int ok; // try to start thread plugin->paused = FALSE; plugin->stopped = FALSE; - uget_plugin_ref ((UgetPlugin*) plugin); - temp.ok = ug_thread_create (&thread, (UgThreadFunc) plugin_thread, plugin); - if (temp.ok == UG_THREAD_OK) - ug_thread_unjoin (&thread); + uget_plugin_ref((UgetPlugin*) plugin); + ok = ug_thread_create(&thread, (UgThreadFunc) plugin_thread, plugin); + if (ok == UG_THREAD_OK) + ug_thread_unjoin(&thread); else { // failed to start thread ----------------- plugin->paused = TRUE; plugin->stopped = TRUE; - // don't assign node - uget_node_unref (plugin->node); - plugin->node = NULL; // post error message and decreases the reference count - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error (UGET_EVENT_ERROR_THREAD_CREATE_FAILED, - NULL)); - uget_plugin_unref ((UgetPlugin*) plugin); + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_error(UGET_EVENT_ERROR_THREAD_CREATE_FAILED, + NULL)); + uget_plugin_unref((UgetPlugin*) plugin); return FALSE; } return TRUE; @@ -1280,79 +1216,79 @@ // JSON-RPC request // speed control -static UgJsonrpcObject* alloc_speed_request (UgetPluginAria2* plugin) +static UgJsonrpcObject* alloc_speed_request(UgetPluginAria2* plugin) { UgJsonrpcObject* object; UgValue* options; UgValue* value; - object = uget_aria2_alloc (global.data, TRUE, TRUE); + object = uget_aria2_alloc(global.data, TRUE, TRUE); object->method_static = "aria2.changeOption"; if (object->params.type == UG_VALUE_NONE) - ug_value_init_array (&object->params, 2); + ug_value_init_array(&object->params, 2); // gid - value = ug_value_alloc (&object->params, 1); + value = ug_value_alloc(&object->params, 1); value->type = UG_VALUE_STRING; value->c.string = plugin->gids.at[0]; // object - options = ug_value_alloc (&object->params, 1); - ug_value_init_object (options, 2); + options = ug_value_alloc(&object->params, 1); + ug_value_init_object(options, 2); // max-download-limit - value = ug_value_alloc (options, 1); - value->name = ug_strdup ("max-download-limit"); + value = ug_value_alloc(options, 1); + value->name = ug_strdup("max-download-limit"); value->type = UG_VALUE_STRING; - value->c.string = ug_strdup_printf ("%d", plugin->limit[0]); + value->c.string = ug_strdup_printf("%d", plugin->limit[0]); // max-upload-limit - value = ug_value_alloc (options, 1); - value->name = ug_strdup ("max-upload-limit"); + value = ug_value_alloc(options, 1); + value->name = ug_strdup("max-upload-limit"); value->type = UG_VALUE_STRING; - value->c.string = ug_strdup_printf ("%d", plugin->limit[1]); + value->c.string = ug_strdup_printf("%d", plugin->limit[1]); return object; } -static void recycle_speed_request (UgJsonrpcObject* object) +static void recycle_speed_request(UgJsonrpcObject* object) { UgValue* value; - value = uget_aria2_clear_token (object); + value = uget_aria2_clear_token(object); // params[0] is gid // value = object->params.c.array->at; value->type = UG_VALUE_NONE; value->c.array = NULL; // ready to recycle it - uget_aria2_recycle (global.data, object); + uget_aria2_recycle(global.data, object); } -static UgJsonrpcObject* alloc_status_request (UgValue** gid) +static UgJsonrpcObject* alloc_status_request(UgValue** gid) { UgJsonrpcObject* object; UgValue* params; UgValue* keys; // prepare JSON-RPC object for "aria2.tellStatus" - object = uget_aria2_alloc (global.data, TRUE, TRUE); + object = uget_aria2_alloc(global.data, TRUE, TRUE); object->method_static = "aria2.tellStatus"; params = &object->params; if (params->type == UG_VALUE_NONE) - ug_value_init_array (params, 2); + ug_value_init_array(params, 2); // gid - gid[0] = ug_value_alloc (params, 1); + gid[0] = ug_value_alloc(params, 1); gid[0]->type = UG_VALUE_STRING; gid[0]->c.string = NULL; // keys array from UgetAria2.status_keys - keys = ug_value_alloc (params, 1); + keys = ug_value_alloc(params, 1); keys->type = UG_VALUE_ARRAY; keys->c.array = global.data->status_keys.c.array; return object; } -static void recycle_status_request (UgJsonrpcObject* object) +static void recycle_status_request(UgJsonrpcObject* object) { UgValue* value; - value = uget_aria2_clear_token (object); + value = uget_aria2_clear_token(object); // params[0] is gid // value = object->params.c.array->at; value->type = UG_VALUE_NONE; @@ -1363,34 +1299,13 @@ value->type = UG_VALUE_NONE; value->c.array = NULL; // ready to recycle it - uget_aria2_recycle (global.data, object); + uget_aria2_recycle(global.data, object); } // ---------------------------------------------------------------------------- // static utility functions -static void aria2_file_clear (Aria2File* afile) -{ - afile->completedLength = 0; - afile->length = 0; - ug_free (afile->path); -} - -static void* aria2_file_array_find (Aria2FileArray* afiles, const char* path) -{ - Aria2File* beg; - Aria2File* end; - - beg = afiles->at; - end = beg + afiles->length; - for (; beg < end; beg++) { - if (strcmp (beg->path, path) == 0) - return beg; - } - return NULL; -} - -static void* ug_file_to_base64 (const char* file, int* length) +static void* ug_file_to_base64(const char* file, int* length) { int fd; int fsize, fpos = 0; @@ -1398,38 +1313,38 @@ void* buffer; void* result; -// fd = open (file, O_RDONLY | O_BINARY, S_IREAD); - fd = ug_open (file, UG_O_READONLY | UG_O_BINARY, UG_S_IREAD); +// fd = open(file, O_RDONLY | O_BINARY, S_IREAD); + fd = ug_open(file, UG_O_READONLY | UG_O_BINARY, UG_S_IREAD); if (fd == -1) return NULL; -// lseek (fd, 0, SEEK_END); - ug_seek (fd, 0, SEEK_END); - fsize = (int) ug_tell (fd); - buffer = ug_malloc (fsize); -// lseek (fd, 0, SEEK_SET); - ug_seek (fd, 0, SEEK_SET); +// lseek(fd, 0, SEEK_END); + ug_seek(fd, 0, SEEK_END); + fsize = (int) ug_tell(fd); + buffer = ug_malloc(fsize); +// lseek(fd, 0, SEEK_SET); + ug_seek(fd, 0, SEEK_SET); do { - result_len = ug_read (fd, buffer, fsize - fpos); -// result_len = read (fd, buffer, fsize - fpos); + result_len = ug_read(fd, buffer, fsize - fpos); +// result_len = read(fd, buffer, fsize - fpos); fpos += result_len; } while (result_len > 0); -// close (fd); - ug_close (fd); +// close(fd); + ug_close(fd); if (fsize != fpos) { - ug_free (buffer); + ug_free(buffer); return NULL; } - result = ug_base64_encode (buffer, fsize, &result_len); - ug_free (buffer); + result = ug_base64_encode(buffer, fsize, &result_len); + ug_free(buffer); if (length) *length = result_len; return result; } -static int decide_file_type (UgetPluginAria2* plugin) +static int decide_file_type(UgetPluginAria2* plugin) { char buf[11]; union { @@ -1444,21 +1359,21 @@ if (temp.path > 0 && plugin->uri_part.uri[temp.path] != 0) temp.path++; // - temp.fd = ug_open (plugin->uri_part.uri + temp.path, + temp.fd = ug_open(plugin->uri_part.uri + temp.path, UG_O_READONLY | UG_O_BINARY, UG_S_IREAD); - if (temp.fd != -1 && ug_read (temp.fd, buf, 11) == 11) { - if (strncmp (buf, "d8:announce", 11) == 0) + if (temp.fd != -1 && ug_read(temp.fd, buf, 11) == 11) { + if (strncmp(buf, "d8:announce", 11) == 0) plugin->uri_type = URI_TORRENT; else { buf[10] = 0; - if (strchr (buf, '<')) + if (strchr(buf, '<')) plugin->uri_type = URI_METALINK; } } - ug_close (temp.fd); + ug_close(temp.fd); if (plugin->uri_type == URI_UNSUPPORTED && - ug_uri_part_file_ext (&plugin->uri_part, &temp.ext)) + ug_uri_part_file_ext(&plugin->uri_part, &temp.ext)) { if (temp.ext[0] == 'm' || temp.ext[0] == 'M') plugin->uri_type = URI_METALINK; @@ -1471,7 +1386,7 @@ return plugin->uri_type; } -static void add_uri_mirrors (UgValue* varray, const char* mirrors) +static void add_uri_mirrors(UgValue* varray, const char* mirrors) { UgValue* value; const char* curr; @@ -1482,13 +1397,13 @@ while (curr[0] == ' ') curr++; prev = curr; - curr = curr + strcspn (curr, " "); + curr = curr + strcspn(curr, " "); - value = ug_value_alloc (varray, 1); + value = ug_value_alloc(varray, 1); value->type = UG_VALUE_STRING; - value->c.string = ug_malloc (curr - prev + 1); + value->c.string = ug_malloc(curr - prev + 1); value->c.string[curr - prev] = 0; // NULL terminated - strncpy (value->c.string, prev, curr - prev); + strncpy(value->c.string, prev, curr - prev); } } @@ -1496,7 +1411,7 @@ // PWMD // #ifdef HAVE_LIBPWMD -static gboolean uget_plugin_aria2_set_proxy_pwmd (UgetPluginAria2 *plugin, UgValue* options) +static gboolean uget_plugin_aria2_set_proxy_pwmd(UgetPluginAria2 *plugin, UgInfo* info, UgValue* options) { struct pwmd_proxy_s pwmd; gpg_error_t rc; @@ -1504,7 +1419,7 @@ UgetProxy *proxy; memset(&pwmd, 0, sizeof(pwmd)); - proxy = ug_info_get (&plugin->node->info, UgetProxyInfo); + proxy = ug_info_get(info, UgetProxyInfo); rc = ug_set_pwmd_proxy_options(&pwmd, proxy); if (rc) @@ -1512,27 +1427,27 @@ // proxy host and port // host - UgValue *value = ug_value_alloc (options, 1); - value->name = ug_strdup ("all-proxy"); + UgValue *value = ug_value_alloc(options, 1); + value->name = ug_strdup("all-proxy"); value->type = UG_VALUE_STRING; if (pwmd.port == 0) - value->c.string = ug_strdup (pwmd.hostname); + value->c.string = ug_strdup(pwmd.hostname); else { - value->c.string = ug_strdup_printf ("%s:%u", pwmd.hostname, pwmd.port); + value->c.string = ug_strdup_printf("%s:%u", pwmd.hostname, pwmd.port); } // proxy user and password if (pwmd.username || pwmd.password) { // user - value = ug_value_alloc (options, 1); - value->name = ug_strdup ("all-proxy-user"); + value = ug_value_alloc(options, 1); + value->name = ug_strdup("all-proxy-user"); value->type = UG_VALUE_STRING; - value->c.string = ug_strdup (pwmd.username ? pwmd.username : ""); + value->c.string = ug_strdup(pwmd.username ? pwmd.username : ""); // password - value = ug_value_alloc (options, 1); - value->name = ug_strdup ("all-proxy-password"); + value = ug_value_alloc(options, 1); + value->name = ug_strdup("all-proxy-password"); value->type = UG_VALUE_STRING; - value->c.string = ug_strdup (pwmd.password ? pwmd.password : ""); + value->c.string = ug_strdup(pwmd.password ? pwmd.password : ""); } ug_close_pwmd(&pwmd); @@ -1541,9 +1456,8 @@ fail: ug_close_pwmd(&pwmd); gchar *e = g_strdup_printf("Pwmd ERR %i: %s", rc, gpg_strerror(rc)); - message = uget_event_new_error (UGET_EVENT_ERROR_CUSTOM, e); - uget_plugin_post ((UgetPlugin*) plugin, message); - fprintf(stderr, "%s\n", e); + message = uget_event_new_error(UGET_EVENT_ERROR_CUSTOM, e); + uget_plugin_post((UgetPlugin*) plugin, message); g_free(e); return FALSE; } diff -Nru uget-2.2.0/uget/UgetPluginAria2.h uget-2.2.2/uget/UgetPluginAria2.h --- uget-2.2.0/uget/UgetPluginAria2.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetPluginAria2.h 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2011-2018 by C.H. Huang + * Copyright (C) 2011-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -46,23 +46,22 @@ extern "C" { #endif -typedef struct Aria2File Aria2File; typedef struct UgetPluginAria2 UgetPluginAria2; typedef struct UgetPluginAria2Setting UgetPluginAria2Setting; extern const UgetPluginInfo* UgetPluginAria2Info; typedef enum { - UGET_PLUGIN_ARIA2_OPTION = UGET_PLUGIN_OPTION_DERIVED, - UGET_PLUGIN_ARIA2_URI, // set parameter = (char* ) -// UGET_PLUGIN_ARIA2_LOCAL, // set parameter = (intptr_t) - UGET_PLUGIN_ARIA2_PATH, // set parameter = (char* ) - UGET_PLUGIN_ARIA2_ARGUMENT, // set parameter = (char* ) - UGET_PLUGIN_ARIA2_TOKEN, // set parameter = (char* ) - UGET_PLUGIN_ARIA2_LAUNCH, // get/set parameter = (intptr_t) - UGET_PLUGIN_ARIA2_SHUTDOWN, // set parameter = (intptr_t) - UGET_PLUGIN_ARIA2_SHUTDOWN_NOW, // set parameter = (intptr_t) -} UgetPluginAria2Code; + UGET_PLUGIN_ARIA2_GLOBAL = UGET_PLUGIN_GLOBAL_DERIVED, + UGET_PLUGIN_ARIA2_GLOBAL_URI, // set parameter = (char* ) +// UGET_PLUGIN_ARIA2_GLOBAL_LOCAL, // set parameter = (intptr_t) + UGET_PLUGIN_ARIA2_GLOBAL_PATH, // set parameter = (char* ) + UGET_PLUGIN_ARIA2_GLOBAL_ARGUMENT, // set parameter = (char* ) + UGET_PLUGIN_ARIA2_GLOBAL_TOKEN, // set parameter = (char* ) + UGET_PLUGIN_ARIA2_GLOBAL_LAUNCH, // get/set parameter = (intptr_t) + UGET_PLUGIN_ARIA2_GLOBAL_SHUTDOWN, // set parameter = (intptr_t) + UGET_PLUGIN_ARIA2_GLOBAL_SHUTDOWN_NOW, // set parameter = (intptr_t) +} UgetPluginAria2GlobalCode; typedef enum { UGET_PLUGIN_ARIA2_ERROR_NONE, @@ -70,31 +69,27 @@ UGET_PLUGIN_ARIA2_ERROR_LAUNCH, } UgetPluginAria2Error; -// ---------------------------------------------------------------------------- -// UgetPluginAria2File - -struct Aria2File -{ - char* path; - int64_t completedLength; - int64_t length; -}; - -typedef UG_ARRAY(Aria2File) Aria2FileArray; +/* ---------------------------------------------------------------------------- + UgetPluginAria2: aria2 plug-in that derived from UgetPlugin. -// ---------------------------------------------------------------------------- -// UgetPluginAria2: It derived from UgetPlugin. + UgType + | + `--- UgetPlugin + | + `--- UgetPluginAria2 + */ struct UgetPluginAria2 { - UGET_PLUGIN_MEMBERS; // It derived from UgetPlugin -// const UgetPluginInfo* info; -// UgetEvent* messages; -// UgMutex mutex; -// int ref_count; - - // pointer to UgetNode that store in UgetApp - UgetNode* node; + UGET_PLUGIN_MEMBERS; +/* // ------ UgType members ------ + const UgetPluginInfo* info; + + // ------ UgetPlugin members ------ + UgetEvent* messages; + UgMutex mutex; + int ref_count; + */ // aria2.addUri, aria2.addTorrent, aria2.addMetalink UgJsonrpcObject* start_request; @@ -104,9 +99,8 @@ unsigned int retry_delay; // all gids and it's files UgArrayStr gids; - Aria2FileArray files; + UgetFiles* files; int files_per_gid; - int files_per_gid_prev; // aria2.tellStatus int status; @@ -120,16 +114,16 @@ // speed limit control // limit[0] = download speed limit // limit[1] = upload speed limit - int limit[2]; - uint8_t limit_changed:1; - uint8_t limit_by_user:1; // speed limit changed by user + int limit[2]; + int limit_upper[2]; + uint8_t limit_changed:1; // speed limit changed by user or program // flags uint8_t synced:1; uint8_t paused:1; // paused by user or program uint8_t stopped:1; // download is stopped uint8_t restart:1; // for retry - uint8_t node_named:1; + uint8_t named:1; }; // ---------------------------------------------------------------------------- @@ -160,12 +154,18 @@ namespace Uget { +const PluginInfo* const PluginAria2Info = (PluginInfo*) UgetPluginAria2Info; + // This one is for derived use only. No data members here. // Your derived struct/class must be C++11 standard-layout -struct PluginAria2Method : Uget::PluginMethod {}; +struct PluginAria2Method : PluginMethod {}; // This one is for directly use only. You can NOT derived it. -struct PluginAria2 : Uget::PluginAria2Method, UgetPluginAria2 {}; +struct PluginAria2 : PluginAria2Method, UgetPluginAria2 +{ + inline void* operator new(size_t size) + { return uget_plugin_new(PluginAria2Info); } +}; }; // namespace Uget diff -Nru uget-2.2.0/uget/UgetPlugin.c uget-2.2.2/uget/UgetPlugin.c --- uget-2.2.0/uget/UgetPlugin.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetPlugin.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -41,39 +41,39 @@ // ------------------------------------ // UgetPluginInfo global functions -UgetPlugin* uget_plugin_new (const UgetPluginInfo* info) +UgetPlugin* uget_plugin_new(const UgetPluginInfo* info) { UgetPlugin* plugin; - plugin = ug_malloc0 (info->size); + plugin = ug_malloc0(info->size); plugin->info = info; - ug_mutex_init (&plugin->mutex); + ug_mutex_init(&plugin->mutex); plugin->ref_count = 1; - info->init (plugin); + info->init(plugin); return plugin; } -UgetResult uget_plugin_set (const UgetPluginInfo* info, int option, void* parameter) +UgetResult uget_plugin_global_set(const UgetPluginInfo* info, int option, void* parameter) { - UgetPluginSetFunc set; + UgetPluginGlobalFunc global_set; - set = info->set; - if (set) - return set (option, parameter); + global_set = info->global_set; + if (global_set) + return global_set(option, parameter); return UGET_RESULT_UNSUPPORT; } -UgetResult uget_plugin_get (const UgetPluginInfo* info, int option, void* parameter) +UgetResult uget_plugin_global_get(const UgetPluginInfo* info, int option, void* parameter) { - UgetPluginGetFunc get; + UgetPluginGlobalFunc global_get; - get = info->get; - if (get) - return get (option, parameter); + global_get = info->global_get; + if (global_get) + return global_get(option, parameter); return UGET_RESULT_UNSUPPORT; } -int uget_plugin_match (const UgetPluginInfo* info, UgUri* uuri) +int uget_plugin_match(const UgetPluginInfo* info, UgUri* uuri) { UgetResult res; const char* str; @@ -83,11 +83,12 @@ if (info == NULL) return 0; - if (info->hosts && (len = ug_uri_part_host (uuri, &str))) { - if (ug_uri_match_hosts (uuri, (char**)info->hosts) >= 0) { + if (info->hosts && (len = ug_uri_part_host(uuri, &str))) { + if (ug_uri_match_hosts(uuri, (char**)info->hosts) >= 0) { matched_count++; // Don't match this plug-in if it is for specify host. - res = uget_plugin_get (info, UGET_PLUGIN_MATCH, (void*) uuri->uri); + res = uget_plugin_global_get(info, UGET_PLUGIN_GLOBAL_MATCH, + (void*) uuri->uri); if (res == UGET_RESULT_FAILED) matched_count = -1; else if (res == UGET_RESULT_OK) @@ -95,13 +96,13 @@ } } - if (info->schemes && (len = ug_uri_part_scheme (uuri, &str))) { - if (ug_uri_match_schemes (uuri, (char**)info->schemes) >= 0) + if (info->schemes && (len = ug_uri_part_scheme(uuri, &str))) { + if (ug_uri_match_schemes(uuri, (char**)info->schemes) >= 0) matched_count++; } - if (info->file_exts && (len = ug_uri_part_file_ext (uuri, &str))) { - if (ug_uri_match_file_exts (uuri, (char**)info->file_exts) >= 0) + if (info->file_exts && (len = ug_uri_part_file_ext(uuri, &str))) { + if (ug_uri_match_file_exts(uuri, (char**)info->file_exts) >= 0) matched_count++; } @@ -111,72 +112,92 @@ // ------------------------------------ // UgetPlugin functions -//void uget_plugin_init (UgetPlugin* plugin); -//void uget_plugin_final (UgetPlugin* plugin); -//void uget_plugin_assign (UgetPlugin* plugin, UgetPlugin* node); +//void uget_plugin_init(UgetPlugin* plugin); +#define uget_plugin_init ug_type_init -int uget_plugin_ctrl (UgetPlugin* plugin, int code, void* data) +//void uget_plugin_final(UgetPlugin* plugin); +#define uget_plugin_final ug_type_final + +void uget_plugin_ref(UgetPlugin* plugin) { - UgetPluginCtrlFunc ctrl; + plugin->ref_count++; +} - ctrl = plugin->info->ctrl; - if (ctrl) - return ctrl (plugin, code, data); +void uget_plugin_unref(UgetPlugin* plugin) +{ + UgetEvent* curr; + UgetEvent* next; + + if (--plugin->ref_count == 0) { + uget_plugin_final(plugin); + ug_mutex_clear(&plugin->mutex); + // free events + for (curr = plugin->events; curr; curr = next) { + next = curr->next; + uget_event_free(curr); + } + // free plug-in + ug_free(plugin); + } +} + +int uget_plugin_accept(UgetPlugin* plugin, UgInfo* info) +{ + UgetPluginSyncFunc accept; + + accept = plugin->info->accept; + if (accept) + return accept(plugin, info); return FALSE; } -int uget_plugin_sync (UgetPlugin* plugin) +int uget_plugin_sync(UgetPlugin* plugin, UgInfo* info) { UgetPluginSyncFunc sync; sync = plugin->info->sync; if (sync) - return sync (plugin); + return sync(plugin, info); return FALSE; } -void uget_plugin_ref (UgetPlugin* plugin) +int uget_plugin_ctrl(UgetPlugin* plugin, int code, void* data) { - plugin->ref_count++; + UgetPluginCtrlFunc ctrl; + + ctrl = plugin->info->ctrl; + if (ctrl) + return ctrl(plugin, code, data); + return FALSE; } -void uget_plugin_unref (UgetPlugin* plugin) +int uget_plugin_get_state(UgetPlugin* plugin) { - UgetEvent* curr; - UgetEvent* next; + int is_active; - if (--plugin->ref_count == 0) { - uget_plugin_final (plugin); - ug_mutex_clear (&plugin->mutex); - // free events - for (curr = plugin->events; curr; curr = next) { - next = curr->next; - uget_event_free (curr); - } - // free plug-in - ug_free (plugin); - } + uget_plugin_ctrl(plugin, UGET_PLUGIN_GET_STATE, &is_active); + return is_active; } -void uget_plugin_post (UgetPlugin* plugin, UgetEvent* message) +void uget_plugin_post(UgetPlugin* plugin, UgetEvent* message) { - ug_mutex_lock (&plugin->mutex); + ug_mutex_lock(&plugin->mutex); if (plugin->events) plugin->events->prev = message; message->next = plugin->events; plugin->events = message; - ug_mutex_unlock (&plugin->mutex); + ug_mutex_unlock(&plugin->mutex); } -UgetEvent* uget_plugin_pop (UgetPlugin* plugin) +UgetEvent* uget_plugin_pop(UgetPlugin* plugin) { UgetEvent* curr; UgetEvent* next; - ug_mutex_lock (&plugin->mutex); + ug_mutex_lock(&plugin->mutex); curr = plugin->events; plugin->events = NULL; - ug_mutex_unlock (&plugin->mutex); + ug_mutex_unlock(&plugin->mutex); // revert while (curr) { diff -Nru uget-2.2.0/uget/UgetPluginCurl.c uget-2.2.2/uget/UgetPluginCurl.c --- uget-2.2.0/uget/UgetPluginCurl.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetPluginCurl.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -62,7 +62,7 @@ #else #include // posix_fallocate() #include // sleep(), usleep() -#define ug_sleep(millisecond) usleep (millisecond * 1000) +#define ug_sleep(millisecond) usleep(millisecond * 1000) #endif // _WIN32 || _WIN64 #if defined(_MSC_VER) @@ -77,7 +77,7 @@ typedef struct UriLink UriLink; struct UriLink { - UG_LINK_MEMBERS (UriLink, UriLink, self); + UG_LINK_MEMBERS(UriLink, UriLink, self); // UriLink* self; // UriLink* next; // UriLink* prev; @@ -90,32 +90,32 @@ }; // ---------------------------------------------------------------------------- -// UgetPluginInfo (derived from UgDataInfo) +// UgetPluginInfo (derived from UgTypeInfo) -static void plugin_init (UgetPluginCurl* plugin); -static void plugin_final (UgetPluginCurl* plugin); -static int plugin_ctrl (UgetPluginCurl* plugin, int code, void* data); -static int plugin_sync (UgetPluginCurl* plugin); -static UgetResult global_set (int code, void* parameter); -static UgetResult global_get (int code, void* parameter); +static void plugin_init (UgetPluginCurl* plugin); +static void plugin_final(UgetPluginCurl* plugin); +static int plugin_ctrl (UgetPluginCurl* plugin, int code, void* data); +static int plugin_accept(UgetPluginCurl* plugin, UgInfo* node_info); +static int plugin_sync (UgetPluginCurl* plugin, UgInfo* node_info); +static UgetResult global_set(int code, void* parameter); +static UgetResult global_get(int code, void* parameter); static const char* schemes[] = {"http", "https", "ftp", "ftps", NULL}; static const UgetPluginInfo UgetPluginCurlInfoStatic = { "curl", - sizeof (UgetPluginCurl), - (const UgEntry*) NULL, + sizeof(UgetPluginCurl), (UgInitFunc) plugin_init, (UgFinalFunc) plugin_final, - (UgAssignFunc) NULL, - (UgetPluginCtrlFunc) plugin_ctrl, + (UgetPluginSyncFunc) plugin_accept, (UgetPluginSyncFunc) plugin_sync, + (UgetPluginCtrlFunc) plugin_ctrl, NULL, schemes, NULL, - (UgetPluginSetFunc) global_set, - (UgetPluginGetFunc) global_get + (UgetPluginGlobalFunc) global_set, + (UgetPluginGlobalFunc) global_get }; // extern const UgetPluginInfo* UgetPluginCurlInfo = &UgetPluginCurlInfoStatic; @@ -129,17 +129,17 @@ int ref_count; } global = {0, 0}; -static UgetResult global_init (void) +static UgetResult global_init(void) { if (global.initialized == FALSE) { #if defined _WIN32 || defined _WIN64 WSADATA WSAData; - WSAStartup (MAKEWORD (2, 2), &WSAData); + WSAStartup(MAKEWORD(2, 2), &WSAData); #endif // _WIN32 || _WIN64 - if (curl_global_init (CURL_GLOBAL_ALL) != CURLE_OK) { + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { #if defined _WIN32 || defined _WIN64 - WSACleanup (); + WSACleanup(); #endif return UGET_RESULT_ERROR; } @@ -150,12 +150,12 @@ return UGET_RESULT_OK; } -static void global_ref (void) +static void global_ref(void) { global.ref_count++; } -static void global_unref (void) +static void global_unref(void) { if (global.initialized == FALSE) return; @@ -163,22 +163,22 @@ global.ref_count--; if (global.ref_count == 0) { global.initialized = FALSE; - curl_global_cleanup (); + curl_global_cleanup(); #if defined _WIN32 || defined _WIN64 - WSACleanup (); + WSACleanup(); #endif } } -static UgetResult global_set (int option, void* parameter) +static UgetResult global_set(int option, void* parameter) { switch (option) { - case UGET_PLUGIN_INIT: + case UGET_PLUGIN_GLOBAL_INIT: // do global initialize/uninitialize here if (parameter) - return global_init (); + return global_init(); else - global_unref (); + global_unref(); break; default: @@ -188,10 +188,10 @@ return UGET_RESULT_OK; } -static UgetResult global_get (int option, void* parameter) +static UgetResult global_get(int option, void* parameter) { switch (option) { - case UGET_PLUGIN_INIT: + case UGET_PLUGIN_GLOBAL_INIT: if (parameter) *(int*)parameter = global.initialized; break; @@ -206,55 +206,56 @@ // ---------------------------------------------------------------------------- // plug-in functions -static void plugin_init (UgetPluginCurl* plugin) +static void plugin_init(UgetPluginCurl* plugin) { if (global.initialized == FALSE) - global_init (); + global_init(); else - global_ref (); + global_ref(); - ug_list_init (&plugin->segment.list); + ug_list_init(&plugin->segment.list); plugin->file.time = -1; plugin->synced = TRUE; plugin->paused = TRUE; plugin->stopped = TRUE; } -static void plugin_final (UgetPluginCurl* plugin) +static void plugin_final(UgetPluginCurl* plugin) { if (plugin->common) - ug_data_free (plugin->common); + ug_data_free(plugin->common); + if (plugin->files) + ug_data_free(plugin->files); if (plugin->proxy) - ug_data_free (plugin->proxy); + ug_data_free(plugin->proxy); if (plugin->http) - ug_data_free (plugin->http); + ug_data_free(plugin->http); if (plugin->ftp) - ug_data_free (plugin->ftp); + ug_data_free(plugin->ftp); // free uri.list (UriLink), all link will be freed. - ug_list_foreach (&plugin->uri.list, (UgForeachFunc) ug_free, NULL); + ug_list_foreach(&plugin->uri.list, (UgForeachFunc) ug_free, NULL); -// curl_slist_free_all (plugin->ftp_command); - ug_free (plugin->file.path); - ug_free (plugin->aria2.path); - // unassign node - if (plugin->node) - uget_node_unref (plugin->node); +// curl_slist_free_all(plugin->ftp_command); + ug_free(plugin->folder.path); + ug_free(plugin->file.name_fmt); + ug_free(plugin->file.path); + ug_free(plugin->aria2.path); - global_unref (); + global_unref(); } // ---------------------------------------------------------------------------- // plugin_ctrl -static int plugin_ctrl_speed (UgetPluginCurl* plugin, int* speed); -static int plugin_start (UgetPluginCurl* plugin, UgetNode* node); +static int plugin_ctrl_speed(UgetPluginCurl* plugin, int* speed); +static int plugin_start(UgetPluginCurl* plugin); -static int plugin_ctrl (UgetPluginCurl* plugin, int code, void* data) +static int plugin_ctrl(UgetPluginCurl* plugin, int code, void* data) { switch (code) { case UGET_PLUGIN_CTRL_START: - if (plugin->node == NULL) - return plugin_start (plugin, data); + if (plugin->common) + return plugin_start(plugin); break; case UGET_PLUGIN_CTRL_STOP: @@ -263,14 +264,13 @@ case UGET_PLUGIN_CTRL_SPEED: // speed control - return plugin_ctrl_speed (plugin, data); + return plugin_ctrl_speed(plugin, data); - // output --------------- - case UGET_PLUGIN_CTRL_ACTIVE: + // state ---------------- + case UGET_PLUGIN_GET_STATE: *(int*)data = (plugin->stopped) ? FALSE : TRUE; return TRUE; - // unused --------------- default: break; } @@ -278,85 +278,83 @@ return FALSE; } -static int plugin_ctrl_speed (UgetPluginCurl* plugin, int* speed) +static int plugin_ctrl_speed(UgetPluginCurl* plugin, int* speed) { UgetCommon* common; int value; - // Don't do anything if speed limit keep no change. - if (plugin->limit.download == speed[0] && plugin->limit.upload == speed[1]) - if (plugin->limit_by_user == FALSE) - return TRUE; - plugin->limit_by_user = FALSE; + // notify plug-in that speed limit has been changed + if (plugin->limit.download != speed[0] || plugin->limit.upload != speed[1]) + plugin->limit_changed = TRUE; // decide speed limit by user specified data. - if (plugin->node == NULL) { + common = plugin->common; + if (common == NULL) { plugin->limit.download = speed[0]; - plugin->limit.upload = speed[1]; + plugin->limit.upload = speed[1]; } else { - common = plugin->common; // download value = speed[0]; if (common->max_download_speed) { - if (value > common->max_download_speed || value == 0) + if (value > common->max_download_speed || value == 0) { value = common->max_download_speed; + plugin->limit_changed = TRUE; + } } plugin->limit.download = value; // upload value = speed[1]; if (common->max_upload_speed) { - if (value > common->max_upload_speed || value == 0) + if (value > common->max_upload_speed || value == 0) { value = common->max_upload_speed; + plugin->limit_changed = TRUE; + } } plugin->limit.upload = value; } - // notify plug-in that speed limit has been changed - plugin->limit_changed = TRUE; - return TRUE; + return plugin->limit_changed; } // ---------------------------------------------------------------------------- // plugin_sync -static void plugin_clear_node (UgetPluginCurl* plugin); -static void plugin_remove_node (UgetPluginCurl* plugin, const char* fpath); -static int plugin_insert_node (UgetPluginCurl* plugin, - const char* fpath, int is_attachment); - -static int plugin_sync (UgetPluginCurl* plugin) +static int plugin_sync(UgetPluginCurl* plugin, UgInfo* node_info) { - UgetNode* node; UgetCommon* common; + UgetFiles* files; UgetProgress* progress; char* name; + int speed[2]; if (plugin->stopped) { if (plugin->synced) return FALSE; plugin->synced = TRUE; } - // avoid crash if plug-in plug-in failed to start. - if (plugin->node == NULL) - return TRUE; + // avoid crash if plug-in failed to start. + if (plugin->common == NULL) + return FALSE; - node = plugin->node; - // sync data between plug-in and node - common = ug_info_realloc (&node->info, UgetCommonInfo); + // sync data between plug-in and foreign UgData + common = ug_info_realloc(node_info, UgetCommonInfo); common->retry_count = plugin->common->retry_count; - // sync changed limit from UgetNode - if (plugin->common->max_upload_speed != common->max_upload_speed || + // sync changed limit from node_info + if (plugin->common->max_upload_speed != common->max_upload_speed || plugin->common->max_download_speed != common->max_download_speed) { - plugin->common->max_upload_speed = common->max_upload_speed; + // speed control + plugin->common->max_upload_speed = common->max_upload_speed; plugin->common->max_download_speed = common->max_download_speed; - plugin->limit_by_user = TRUE; + speed[1] = common->max_upload_speed; + speed[0] = common->max_download_speed; + plugin_ctrl_speed(plugin, speed); } plugin->common->max_connections = common->max_connections; plugin->common->retry_limit = common->retry_limit; if (common->max_connections > 0) plugin->segment.n_max = common->max_connections; - progress = ug_info_realloc (&node->info, UgetProgressInfo); + progress = ug_info_realloc(node_info, UgetProgressInfo); progress->upload_speed = plugin->speed.upload; progress->download_speed = plugin->speed.download; @@ -381,182 +379,141 @@ // consume time progress->elapsed = time(NULL) - plugin->start_time; - // add UgetNode for file & attachment + // update UgetFiles + files = ug_info_realloc(node_info, UgetFilesInfo); + uget_plugin_lock(plugin); + uget_files_sync(files, plugin->files); + uget_plugin_unlock(plugin); + // set name if (plugin->file_renamed && plugin->file.path) { plugin->file_renamed = FALSE; - plugin->a2cf_named = FALSE; - plugin_clear_node (plugin); - plugin_insert_node (plugin, plugin->file.path, FALSE); - // change node name + // change name #if defined _WIN32 || defined _WIN64 - name = strrchr (plugin->file.path, '\\'); + name = strrchr(plugin->file.path, '\\'); #else - name = strrchr (plugin->file.path, '/'); + name = strrchr(plugin->file.path, '/'); #endif if (name && name[1]) { - if (node->name == NULL || strcmp (name, node->name)) { - ug_free (node->name); - node->name = ug_strdup (name + 1); - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new (UGET_EVENT_NAME)); + if (common->name == NULL || strcmp(name, common->name)) { + ug_free(common->name); + common->name = ug_strdup(name + 1); + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new(UGET_EVENT_NAME)); } - ug_free (common->file); - common->file = ug_strdup (name + 1); - } - } - if (plugin->aria2.path) { - if (plugin->file.size == plugin->size.download) - plugin_remove_node (plugin, plugin->aria2.path); - else if (plugin->a2cf_named == FALSE) { - plugin->a2cf_named = TRUE; - plugin_insert_node (plugin, plugin->aria2.path, TRUE); + ug_free(common->file); + common->file = ug_strdup(name + 1); } } - return TRUE; -} - -static int plugin_insert_node (UgetPluginCurl* plugin, - const char* fpath, int is_attachment) -{ - UgetNode* node; - for (node = plugin->node->children; node; node = node->next) { - if (strcmp (node->name, fpath) == 0) - return FALSE; - } - - node = uget_node_new (NULL); - node->name = ug_strdup (fpath); - uget_node_prepend (plugin->node, node); - if (is_attachment) - node->type = UGET_NODE_ATTACHMENT; return TRUE; } -static void plugin_remove_node (UgetPluginCurl* plugin, const char* fpath) -{ - UgetNode* node; - - for (node = plugin->node->children; node; node = node->next) { - if (strcmp (node->name, fpath) == 0) { - uget_node_remove (plugin->node, node); - uget_node_unref (node); - return; - } - } -} - -static void plugin_clear_node (UgetPluginCurl* plugin) -{ - UgetNode* node; - UgetNode* next; - - for (node = plugin->node->children; node; node = next) { - next = node->next; - uget_node_remove (plugin->node, node); - uget_node_unref (node); - } -} - // ---------------------------------------------------------------------------- -// plugin_start +// plugin_accept/plugin_start -static void plugin_setup_uris (UgetPluginCurl* plugin); -static UG_THREAD_RETURN_TYPE plugin_thread (UgetPluginCurl* plugin); +static void plugin_decide_uris(UgetPluginCurl* plugin); +static void plugin_decide_folder(UgetPluginCurl* plugin); +static void plugin_decide_files(UgetPluginCurl* plugin); +static UgThreadResult plugin_thread(UgetPluginCurl* plugin); -static int plugin_start (UgetPluginCurl* plugin, UgetNode* node) +static int plugin_accept(UgetPluginCurl* plugin, UgInfo* node_info) { - UgThread thread; - int speed[2]; union { UgetCommon* common; + UgetFiles* files; UgetProxy* proxy; UgetHttp* http; - UgetHttp* ftp; - int ok; + UgetFtp* ftp; } temp; + int speed[2]; - temp.common = ug_info_get (&node->info, UgetCommonInfo); + temp.common = ug_info_get(node_info, UgetCommonInfo); if (temp.common == NULL || temp.common->uri == NULL) return FALSE; - plugin->common = ug_data_copy (temp.common); - plugin_setup_uris (plugin); + plugin->common = ug_data_copy(temp.common); + plugin_decide_uris(plugin); + plugin_decide_folder(plugin); + // speed control: decide speed limit before starting plug-in + speed[0] = plugin->limit.download; + speed[1] = plugin->limit.upload; + plugin_ctrl_speed(plugin, speed); + + temp.files = ug_info_get(node_info, UgetFilesInfo); + if (temp.files) + plugin->files = ug_data_copy(temp.files); + else + plugin->files = ug_data_new(UgetFilesInfo); - temp.proxy = ug_info_get (&node->info, UgetProxyInfo); + temp.proxy = ug_info_get(node_info, UgetProxyInfo); if (temp.proxy) - plugin->proxy = ug_data_copy (temp.proxy); + plugin->proxy = ug_data_copy(temp.proxy); - temp.http = ug_info_get (&node->info, UgetHttpInfo); + temp.http = ug_info_get(node_info, UgetHttpInfo); if (temp.http) { - plugin->http = ug_data_copy (temp.http); + plugin->http = ug_data_copy(temp.http); // check http->post_file if (temp.http->post_file) { - if (ug_file_is_exist (temp.http->post_file) == FALSE) { - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error (UGET_EVENT_ERROR_POST_FILE_NOT_FOUND, - NULL)); + if (ug_file_is_exist(temp.http->post_file) == FALSE) { + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_error(UGET_EVENT_ERROR_POST_FILE_NOT_FOUND, + NULL)); return FALSE; } } // check http->cookie_file if (temp.http->cookie_file) { - if (ug_file_is_exist (temp.http->cookie_file) == FALSE) { - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error (UGET_EVENT_ERROR_COOKIE_FILE_NOT_FOUND, - NULL)); + if (ug_file_is_exist(temp.http->cookie_file) == FALSE) { + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_error(UGET_EVENT_ERROR_COOKIE_FILE_NOT_FOUND, + NULL)); return FALSE; } } } - temp.ftp = ug_info_get (&node->info, UgetFtpInfo); + temp.ftp = ug_info_get(node_info, UgetFtpInfo); if (temp.ftp) - plugin->ftp = ug_data_copy (temp.ftp); + plugin->ftp = ug_data_copy(temp.ftp); - plugin->start_time = time (NULL); - // assign node before speed control - uget_node_ref (node); - plugin->node = node; - // speed control - speed[0] = plugin->limit.download; - speed[1] = plugin->limit.upload; - plugin_ctrl_speed (plugin, speed); - // Don't notify speed limit changed if user set it before plug-in start. - plugin->limit_changed = FALSE; + return TRUE; +} + +static int plugin_start(UgetPluginCurl* plugin) +{ + UgThread thread; + int ok; + plugin->start_time = time(NULL); // try to start thread plugin->paused = FALSE; plugin->stopped = FALSE; - uget_plugin_ref ((UgetPlugin*) plugin); - temp.ok = ug_thread_create (&thread, (UgThreadFunc) plugin_thread, plugin); - if (temp.ok == UG_THREAD_OK) - ug_thread_unjoin (&thread); + uget_plugin_ref((UgetPlugin*) plugin); + ok = ug_thread_create(&thread, (UgThreadFunc) plugin_thread, plugin); + if (ok == UG_THREAD_OK) + ug_thread_unjoin(&thread); else { // failed to start thread ----------------- plugin->paused = TRUE; plugin->stopped = TRUE; - // don't assign node - uget_node_unref (node); - plugin->node = NULL; // post error message and decreases the reference count - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error (UGET_EVENT_ERROR_THREAD_CREATE_FAILED, - NULL)); - uget_plugin_unref ((UgetPlugin*) plugin); + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_error(UGET_EVENT_ERROR_THREAD_CREATE_FAILED, + NULL)); + uget_plugin_unref((UgetPlugin*) plugin); return FALSE; } return TRUE; } -static UriLink* plugin_replace_uri (UgetPluginCurl* plugin, UriLink* old_link, - const char* uri, int uri_len) +static UriLink* plugin_replace_uri(UgetPluginCurl* plugin, UriLink* old_link, + const char* uri, int uri_len) { UriLink* uri_link; if (uri_len == -1) - uri_len = strlen (uri); - uri_link = ug_malloc (sizeof (UriLink) + uri_len); - strncpy (uri_link->uri, uri, uri_len); + uri_len = strlen(uri); + uri_link = ug_malloc(sizeof(UriLink) + uri_len); + strncpy(uri_link->uri, uri, uri_len); uri_link->uri[uri_len] = 0; // null terminated uri_link->self = uri_link; uri_link->next = NULL; @@ -568,20 +525,20 @@ // add to list if (old_link == NULL) - ug_list_append (&plugin->uri.list, (void*) uri_link); + ug_list_append(&plugin->uri.list, (void*) uri_link); else { - ug_list_insert (&plugin->uri.list, (void*) old_link, + ug_list_insert(&plugin->uri.list, (void*) old_link, (void*) uri_link); - ug_list_remove (&plugin->uri.list, (void*) old_link); + ug_list_remove(&plugin->uri.list, (void*) old_link); if (plugin->uri.link == (void*) old_link) plugin->uri.link = (void*) uri_link; - ug_free (old_link); + ug_free(old_link); } return uri_link; } -static void plugin_setup_uris (UgetPluginCurl* plugin) +static void plugin_decide_uris(UgetPluginCurl* plugin) { UgetCommon* common; const char* curr; @@ -589,9 +546,9 @@ common = plugin->common; // uri - plugin->uri.link = (void*) plugin_replace_uri (plugin, NULL, - common->uri, -1); - ug_free (common->uri); + plugin->uri.link = (void*) plugin_replace_uri(plugin, NULL, + common->uri, -1); + ug_free(common->uri); common->uri = NULL; // mirrors for (curr = common->mirrors; curr && curr[0];) { @@ -599,31 +556,76 @@ while (curr[0] == ' ') curr++; prev = curr; - curr = curr + strcspn (curr, " "); + curr = curr + strcspn(curr, " "); // add to uri.list - plugin_replace_uri (plugin, NULL, prev, curr - prev); + plugin_replace_uri(plugin, NULL, prev, curr - prev); } - ug_free (common->mirrors); + ug_free(common->mirrors); common->mirrors = NULL; } +static void plugin_decide_folder(UgetPluginCurl* plugin) +{ + UgetCommon* common; + int length; + int value; + + // folder + common = plugin->common; + if (common->folder == NULL || common->folder[0] == 0) + length = 0; + else { + length = strlen(common->folder); + value = common->folder[length - 1]; + plugin->folder.path = ug_malloc(length + 2); // + '/' + '\x0' + plugin->folder.path[0] = 0; + strcpy(plugin->folder.path, common->folder); + if (value != '\\' || value != '/') { +#if defined _WIN32 || defined _WIN64 + strcat(plugin->folder.path, "\\"); +#else + strcat(plugin->folder.path, "/"); +#endif + length++; + } + } + plugin->folder.length = length; +} + +static void plugin_decide_files(UgetPluginCurl* plugin) +{ + // update UgetFiles + uget_plugin_lock(plugin); + // insert/replace file into files + if (plugin->aria2.path) { + uget_files_replace(plugin->files, + plugin->aria2.path, + UGET_FILE_TEMPORARY, 0); + } + uget_files_replace(plugin->files, + plugin->file.path, + UGET_FILE_REGULAR, 0); + uget_plugin_unlock(plugin); +} + // ---------------------------------------------------------------------------- // plugin_thread #define N_THREAD(plugin) ((plugin)->segment.list.size) -static void delay_ms (UgetPluginCurl* plugin, int milliseconds); -static int switch_uri (UgetPluginCurl* plugin, UgetCurl* ugcurl, int is_resumable); -static int prepare_file (UgetCurl* ugcurl, UgetPluginCurl* plugin); -static void complete_file (UgetPluginCurl* plugin); -static int load_file_info (UgetPluginCurl* plugin); -static void clear_file_info (UgetPluginCurl* plugin); -static int reuse_download (UgetPluginCurl* plugin, UgetCurl* ugcurl, int next_uri); -static int split_download (UgetPluginCurl* plugin, UgetCurl* ugcurl); -static void adjust_speed_limit (UgetPluginCurl* plugin); -static UgetCurl* create_segment (UgetPluginCurl* plugin); +static void delay_ms(UgetPluginCurl* plugin, int milliseconds); +static int switch_uri(UgetPluginCurl* plugin, UgetCurl* ugcurl, int is_resumable); +static int prepare_file(UgetCurl* ugcurl, UgetPluginCurl* plugin); +static char* get_repeating_fmt_string(char* filename); +static void complete_file(UgetPluginCurl* plugin); +static int load_file_info(UgetPluginCurl* plugin); +static void clear_file_info(UgetPluginCurl* plugin); +static int reuse_download(UgetPluginCurl* plugin, UgetCurl* ugcurl, int next_uri); +static int split_download(UgetPluginCurl* plugin, UgetCurl* ugcurl); +static void adjust_speed_limit(UgetPluginCurl* plugin); +static UgetCurl* create_segment(UgetPluginCurl* plugin); -static UG_THREAD_RETURN_TYPE plugin_thread (UgetPluginCurl* plugin) +static UgThreadResult plugin_thread(UgetPluginCurl* plugin) { UgetCommon* common; UgetCurl* ugcurl; @@ -642,33 +644,33 @@ plugin->segment.n_max = 1; // create new segment and add it to segment.list - ugcurl = create_segment (plugin); - if (load_file_info (plugin)) { - uget_curl_open_file (ugcurl, plugin->file.path); + ugcurl = create_segment(plugin); + if (load_file_info(plugin)) { + uget_curl_open_file(ugcurl, plugin->file.path); ugcurl->beg = plugin->segment.beg; - uget_a2cf_lack (&plugin->aria2.ctrl, - (uint64_t*) &ugcurl->beg, - (uint64_t*) &ugcurl->end); + uget_a2cf_lack(&plugin->aria2.ctrl, + (uint64_t*) &ugcurl->beg, + (uint64_t*) &ugcurl->end); plugin->segment.beg = ugcurl->end; - // plugin_sync() will add file node for existing file + // plugin_sync() will set foreign UgetCommon::name plugin->file_renamed = TRUE; plugin->synced = FALSE; } else { - clear_file_info (plugin); + clear_file_info(plugin); ugcurl->prepare.func = (UgetCurlFunc) prepare_file; ugcurl->prepare.data = plugin; ugcurl->header_store = TRUE; } - ug_list_append (&plugin->segment.list, (void*) ugcurl); + ug_list_append(&plugin->segment.list, (void*) ugcurl); // start curl - uget_curl_run (ugcurl, FALSE); + uget_curl_run(ugcurl, FALSE); // main loop for (counter = 0; N_THREAD(plugin) > 0; counter++) { // sleep 0.5 second - ug_sleep (500); + ug_sleep(500); // reset data, plug-in will count them (in segment loop) later plugin->segment.n_active = 0; size.upload = 0; @@ -694,9 +696,9 @@ ugcurl->size[0] = 0; #ifndef NDEBUG if (common->debug_level) { - printf ("\n" - "previous segment overwrite at %u KiB\n", - (unsigned) (ugcurl->beg / 1024)); + printf("\n" + "previous segment overwrite at %u KiB\n", + (unsigned) (ugcurl->beg / 1024)); } #endif } @@ -712,9 +714,9 @@ } #ifndef NDEBUG if (common->debug_level) { - printf ("\n" - "split new segment at %u KiB\n", - (unsigned) (ugcurl->beg / 1024)); + printf("\n" + "split new segment at %u KiB\n", + (unsigned) (ugcurl->beg / 1024)); } #endif } @@ -727,7 +729,7 @@ } // update aria2 control file progress if (plugin->aria2.path) - uget_a2cf_fill (&plugin->aria2.ctrl, ugcurl->beg, ugcurl->pos); + uget_a2cf_fill(&plugin->aria2.ctrl, ugcurl->beg, ugcurl->pos); // progress if (ugcurl->state >= UGET_CURL_OK) { // ugcurl has stopped @@ -754,65 +756,65 @@ ugcurl->state = UGET_CURL_RESPLIT; // special case for unknown file size if (plugin->file.size == 0 && N_THREAD (plugin) == 1) { - complete_file (plugin); + complete_file(plugin); // delete download - ug_list_remove (&plugin->segment.list, (void*)ugcurl); - uget_curl_free (ugcurl); + ug_list_remove(&plugin->segment.list, (void*)ugcurl); + uget_curl_free(ugcurl); } break; case UGET_CURL_ABORT: // delete download - ug_list_remove (&plugin->segment.list, (void*)ugcurl); - uget_curl_free (ugcurl); + ug_list_remove(&plugin->segment.list, (void*)ugcurl); + uget_curl_free(ugcurl); break; case UGET_CURL_ERROR: // if no other downloading segment, plug-in response error - if (N_THREAD (plugin) == 1) { -// plugin->node->state |= UGET_STATE_ERROR; + if (N_THREAD(plugin) == 1) { + // post error message if (ugcurl->event) { - uget_plugin_post ((UgetPlugin*) plugin, ugcurl->event); + uget_plugin_post((UgetPlugin*) plugin, ugcurl->event); ugcurl->event = NULL; } // delete download - ug_list_remove (&plugin->segment.list, (void*)ugcurl); - uget_curl_free (ugcurl); + ug_list_remove(&plugin->segment.list, (void*)ugcurl); + uget_curl_free(ugcurl); } else { // try to reuse download - reuse_download (plugin, ugcurl, TRUE); + reuse_download(plugin, ugcurl, TRUE); } break; case UGET_CURL_RETRY: // if no other downloading segment - if (N_THREAD (plugin) == 1) { + if (N_THREAD(plugin) == 1) { common->retry_count++; if (common->retry_count < common->retry_limit || common->retry_limit == 0) { ugcurl->beg = ugcurl->pos; - delay_ms (plugin, common->retry_delay * 1000); - uget_curl_run (ugcurl, FALSE); + delay_ms(plugin, common->retry_delay * 1000); + uget_curl_run(ugcurl, FALSE); } else { // delete segment - ug_list_remove (&plugin->segment.list, (void*)ugcurl); - uget_curl_free (ugcurl); + ug_list_remove(&plugin->segment.list, (void*)ugcurl); + uget_curl_free(ugcurl); } } else { // try to reuse download - reuse_download (plugin, ugcurl, FALSE); + reuse_download(plugin, ugcurl, FALSE); } break; case UGET_CURL_NOT_RESUMABLE: // if no other downloading segment - if (N_THREAD (plugin) == 1) { - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_normal ( + if (N_THREAD(plugin) == 1) { + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_normal( UGET_EVENT_NORMAL_NOT_RESUMABLE, NULL)); common->retry_count++; if (common->retry_count < common->retry_limit || @@ -822,19 +824,19 @@ plugin->size.download = 0; ugcurl->beg = 0; ugcurl->end = plugin->file.size; - delay_ms (plugin, common->retry_delay * 1000); - switch_uri (plugin, ugcurl, TRUE); - uget_curl_run (ugcurl, FALSE); + delay_ms(plugin, common->retry_delay * 1000); + switch_uri(plugin, ugcurl, TRUE); + uget_curl_run(ugcurl, FALSE); } else { // delete download - ug_list_remove (&plugin->segment.list, (void*)ugcurl); - uget_curl_free (ugcurl); + ug_list_remove(&plugin->segment.list, (void*)ugcurl); + uget_curl_free(ugcurl); } } else { // try to reuse download - reuse_download (plugin, ugcurl, TRUE); + reuse_download(plugin, ugcurl, TRUE); } break; } @@ -845,10 +847,10 @@ for (; ugcurl; ugcurl = ugnext) { ugnext = ugcurl->next; if (ugcurl->state == UGET_CURL_RESPLIT) { - if (split_download (plugin, ugcurl) == FALSE) { + if (split_download(plugin, ugcurl) == FALSE) { // delete download - ug_list_remove (&plugin->segment.list, (void*)ugcurl); - uget_curl_free (ugcurl); + ug_list_remove(&plugin->segment.list, (void*)ugcurl); + uget_curl_free(ugcurl); } } } @@ -869,21 +871,21 @@ #ifndef NDEBUG if (common->debug_level) { - printf ("file size is different\n"); - printf ("plugin->file.size = %d\n", (int)plugin->file.size); - printf ("plugin->size.download = %d\n", (int)plugin->size.download); + printf("file size is different\n"); + printf("plugin->file.size = %d\n", (int)plugin->file.size); + printf("plugin->size.download = %d\n", (int)plugin->size.download); } #endif // NDEBUG plugin->size.download = plugin->file.size; #else plugin->paused = TRUE; - if (N_THREAD (plugin) > 0) + if (N_THREAD(plugin) > 0) continue; // wait other thread else { if (plugin->aria2.path) - ug_unlink (plugin->aria2.path); - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error ( + ug_unlink(plugin->aria2.path); + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_error( UGET_EVENT_ERROR_INCORRECT_SOURCE, NULL)); plugin->synced = FALSE; @@ -893,10 +895,10 @@ } // download completed if (plugin->file.size == plugin->size.download) { - if (N_THREAD (plugin) > 0) + if (N_THREAD(plugin) > 0) continue; // wait other thread else { - complete_file (plugin); + complete_file(plugin); plugin->synced = FALSE; break; } @@ -906,26 +908,26 @@ // adjust speed every 0.5 x 2 = 1 second. if ((counter & 1) == 1 || n_active_last != plugin->segment.n_active) { n_active_last = plugin->segment.n_active; - adjust_speed_limit (plugin); + adjust_speed_limit(plugin); } // save aria2 control file every 0.5 x 4 = 2 seconds. - if ((counter & 3) == 3 || N_THREAD (plugin) == 0) { + if ((counter & 3) == 3 || N_THREAD(plugin) == 0) { if (plugin->aria2.path) - uget_a2cf_save (&plugin->aria2.ctrl, plugin->aria2.path); + uget_a2cf_save(&plugin->aria2.ctrl, plugin->aria2.path); } // split download every 0.5 x 8 = 4 seconds. if ((counter & 7) == 7 && plugin->file.size) { // If some threads are connecting, It doesn't split new segment. - if (N_THREAD (plugin) < plugin->segment.n_max && - N_THREAD (plugin) == plugin->segment.n_active) + if (N_THREAD(plugin) < plugin->segment.n_max && + N_THREAD(plugin) == plugin->segment.n_active) { - split_download (plugin, NULL); + split_download(plugin, NULL); } } // retry ------------------------ if (common->retry_count >= common->retry_limit && common->retry_limit != 0) { - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error ( + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_error( UGET_EVENT_ERROR_TOO_MANY_RETRIES, NULL)); plugin->synced = FALSE; plugin->paused = TRUE; @@ -934,28 +936,28 @@ // count the latest downloaded size if download doesn't complete if ((plugin->file.size != plugin->size.download) && plugin->aria2.path) { - plugin->size.download = uget_a2cf_completed (&plugin->aria2.ctrl); + plugin->size.download = uget_a2cf_completed(&plugin->aria2.ctrl); plugin->synced = FALSE; } // free segment list - ug_list_foreach (&plugin->segment.list, (UgForeachFunc) uget_curl_free, NULL); - ug_list_clear (&plugin->segment.list, FALSE); + ug_list_foreach(&plugin->segment.list, (UgForeachFunc) uget_curl_free, NULL); + ug_list_clear(&plugin->segment.list, FALSE); // - uget_a2cf_clear (&plugin->aria2.ctrl); + uget_a2cf_clear(&plugin->aria2.ctrl); plugin->stopped = TRUE; - uget_plugin_unref ((UgetPlugin*) plugin); - return UG_THREAD_RETURN_VALUE; + uget_plugin_unref((UgetPlugin*) plugin); + return UG_THREAD_RESULT; } -static int prepare_existed (UgetCurl* ugcurl, UgetPluginCurl* plugin) +static int prepare_existed(UgetCurl* ugcurl, UgetPluginCurl* plugin) { double fsize; long ftime; // file.size if (plugin->file.size) { - curl_easy_getinfo (ugcurl->curl, + curl_easy_getinfo(ugcurl->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &fsize); if (plugin->file.size != ugcurl->beg + (int64_t) fsize) { // if remote file size and local file size are not the same, @@ -963,9 +965,9 @@ if (plugin->prepared == FALSE) { // plugin_thread() has initialized/created some data for this function. // program must clear these data before calling prepare_file() - clear_file_info (plugin); - uget_curl_close_file (ugcurl); - return prepare_file (ugcurl, plugin); + clear_file_info(plugin); + uget_curl_close_file(ugcurl); + return prepare_file(ugcurl, plugin); } // don't write INCORRECT data to existed file. ugcurl->event_code = UGET_EVENT_ERROR_INCORRECT_SOURCE; @@ -975,11 +977,11 @@ } // file.time if (plugin->file.time == -1) { - curl_easy_getinfo (ugcurl->curl, CURLINFO_FILETIME, &ftime); + curl_easy_getinfo(ugcurl->curl, CURLINFO_FILETIME, &ftime); plugin->file.time = (time_t) ftime; } - if (uget_curl_open_file (ugcurl, plugin->file.path)) { + if (uget_curl_open_file(ugcurl, plugin->file.path)) { plugin->prepared = TRUE; return TRUE; } @@ -989,13 +991,12 @@ } } -static int prepare_file (UgetCurl* ugcurl, UgetPluginCurl* plugin) +static int prepare_file(UgetCurl* ugcurl, UgetPluginCurl* plugin) { UgetCommon* common; int length; int counts; int value; - int folder_len; union { long ftime; double fsize; @@ -1004,27 +1005,17 @@ } temp; // file.time - curl_easy_getinfo (ugcurl->curl, CURLINFO_FILETIME, &temp.ftime); + curl_easy_getinfo(ugcurl->curl, CURLINFO_FILETIME, &temp.ftime); plugin->file.time = (time_t) temp.ftime; // file.size - curl_easy_getinfo (ugcurl->curl, + curl_easy_getinfo(ugcurl->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &temp.fsize); plugin->file.size = (int64_t) temp.fsize + ugcurl->beg; if (plugin->file.size == -1) plugin->file.size = 0; common = plugin->common; - // folder - if (common->folder == NULL || common->folder[0] == 0) - length = 0; - else { - length = strlen (common->folder); - value = common->folder[length - 1]; - if (value != '\\' || value != '/') - length++; - } - folder_len = length; - + length = plugin->folder.length; // decide filename if (common->file == NULL) { if (ugcurl->header.filename) { @@ -1032,61 +1023,54 @@ ugcurl->header.filename = NULL; } else if (ugcurl->uri.part.file != -1) - common->file = ug_uri_get_file (&ugcurl->uri.part); + common->file = ug_uri_get_file(&ugcurl->uri.part); // if it is still no filename, set default one if (common->file == NULL) - common->file = ug_strdup ("index"); + common->file = ug_strdup("index"); // replace invalid characters \/:*?"<>| by _ in filename. - ug_str_replace_chars (common->file, "\\/:*?\"<>|", '_'); + ug_str_replace_chars(common->file, "\\/:*?\"<>|", '_'); } - length += strlen (common->file); + length += strlen(common->file); // path = folder + filename // length + digits + ".aria2" + '\0' - plugin->file.path = ug_malloc (length + MAX_REPEAT_DIGITS + 6 + 1); + plugin->file.path = ug_malloc(length + MAX_REPEAT_DIGITS + 6 + 1); plugin->file.path[0] = 0; // you need this line if common->folder is NULL. - if (common->folder) { - strcpy (plugin->file.path, common->folder); - if (value != '\\' || value != '/') { -#if defined _WIN32 || defined _WIN64 - strcat (plugin->file.path, "\\"); -#else - strcat (plugin->file.path, "/"); -#endif - } - } - strcat (plugin->file.path, common->file); + if (plugin->folder.path) + strcpy(plugin->file.path, plugin->folder.path); + strcat(plugin->file.path, common->file); + plugin->file.name_fmt = get_repeating_fmt_string(common->file); // create folder - if (ug_create_dir_all (plugin->file.path, folder_len) == -1) { + if (ug_create_dir_all(plugin->file.path, plugin->folder.length) == -1) { ugcurl->event_code = UGET_EVENT_ERROR_FOLDER_CREATE_FAILED; return FALSE; } // create file for (counts = 0; counts < MAX_REPEAT_COUNTS; counts++) { - value = ug_open (plugin->file.path, UG_O_CREATE | UG_O_EXCL | UG_O_WRONLY, + value = ug_open(plugin->file.path, UG_O_CREATE | UG_O_EXCL | UG_O_WRONLY, UG_S_IREAD | UG_S_IWRITE | UG_S_IRGRP | UG_S_IROTH); -// value = ug_open (plugin->file.path, UG_O_CREATE | UG_O_EXCL | UG_O_RDWR, +// value = ug_open(plugin->file.path, UG_O_CREATE | UG_O_EXCL | UG_O_RDWR, // UG_S_IREAD | UG_S_IWRITE | UG_S_IRGRP | UG_S_IROTH); // check if this path can't access -// if (value == -1 && ug_file_is_exist (plugin->file.path) == FALSE) { +// if (value == -1 && ug_file_is_exist(plugin->file.path) == FALSE) { // ugcurl->event_code = UGET_EVENT_ERROR_FILE_CREATE_FAILED; // return FALSE; // error // } // check exist downloaded file & it's control file - strcat (plugin->file.path + length, ".aria2"); + strcat(plugin->file.path + length, ".aria2"); if (value == -1) { - if (uget_a2cf_load (&plugin->aria2.ctrl, plugin->file.path)) { + if (uget_a2cf_load(&plugin->aria2.ctrl, plugin->file.path)) { if (plugin->aria2.ctrl.total_len == plugin->file.size) { - plugin->aria2.path = ug_strdup (plugin->file.path); - plugin->base.download = uget_a2cf_completed (&plugin->aria2.ctrl); + plugin->aria2.path = ug_strdup(plugin->file.path); + plugin->base.download = uget_a2cf_completed(&plugin->aria2.ctrl); plugin->size.download = plugin->base.download; - *(char*) strstr (plugin->file.path + length, ".aria2") = 0; + *(char*) strstr(plugin->file.path + length, ".aria2") = 0; break; } - uget_a2cf_clear (&plugin->aria2.ctrl); + uget_a2cf_clear(&plugin->aria2.ctrl); } } else { @@ -1099,53 +1083,53 @@ #if defined _WIN32 || defined _WIN64 LARGE_INTEGER size; HANDLE handle; - handle = (HANDLE) _get_osfhandle (value); + handle = (HANDLE) _get_osfhandle(value); size.QuadPart = plugin->file.size; - if(SetFilePointerEx (handle ,size, 0, FILE_BEGIN) == FALSE) + if(SetFilePointerEx(handle ,size, 0, FILE_BEGIN) == FALSE) ugcurl->event_code = UGET_EVENT_ERROR_OUT_OF_RESOURCE; - if(SetEndOfFile (handle) == FALSE) + if(SetEndOfFile(handle) == FALSE) ugcurl->event_code = UGET_EVENT_ERROR_OUT_OF_RESOURCE; - SetFilePointer (handle, 0, 0, FILE_BEGIN); + SetFilePointer(handle, 0, 0, FILE_BEGIN); #elif defined HAVE_FTRUNCATE - if (ftruncate (value, plugin->file.size) == -1) + if (ftruncate(value, plugin->file.size) == -1) ugcurl->event_code = UGET_EVENT_ERROR_OUT_OF_RESOURCE; #elif defined __ANDROID__ && __ANDROID_API__ >= 12 - if (ftruncate64 (value, plugin->file.size) == -1) + if (ftruncate64(value, plugin->file.size) == -1) ugcurl->event_code = UGET_EVENT_ERROR_OUT_OF_RESOURCE; #elif defined HAVE_POSIX_FALLOCATE - if (posix_fallocate (value, 0, plugin->file.size) != 0) + if (posix_fallocate(value, 0, plugin->file.size) != 0) ugcurl->event_code = UGET_EVENT_ERROR_OUT_OF_RESOURCE; #elif defined __ANDROID__ && __ANDROID_API__ >= 20 - if (posix_fallocate64 (value, 0, plugin->file.size) != 0) + if (posix_fallocate64(value, 0, plugin->file.size) != 0) ugcurl->event_code = UGET_EVENT_ERROR_OUT_OF_RESOURCE; #else - if (ug_write (value, "O", 1) == -1) // begin of file + if (ug_write(value, "O", 1) == -1) // begin of file ugcurl->event_code = UGET_EVENT_ERROR_OUT_OF_RESOURCE; - if (ug_seek (value, plugin->file.size - 1, SEEK_SET) == -1) + if (ug_seek(value, plugin->file.size - 1, SEEK_SET) == -1) ugcurl->event_code = UGET_EVENT_ERROR_OUT_OF_RESOURCE; - if (ug_write (value, "X", 1) == -1) // end of file + if (ug_write(value, "X", 1) == -1) // end of file ugcurl->event_code = UGET_EVENT_ERROR_OUT_OF_RESOURCE; #endif // _WIN32 || _WIN64 // create aria2 control file if no error if (ugcurl->event_code == 0) { - plugin->aria2.path = ug_strdup (plugin->file.path); - uget_a2cf_init (&plugin->aria2.ctrl, plugin->file.size); - uget_a2cf_save (&plugin->aria2.ctrl, plugin->aria2.path); + plugin->aria2.path = ug_strdup(plugin->file.path); + uget_a2cf_init(&plugin->aria2.ctrl, plugin->file.size); + uget_a2cf_save(&plugin->aria2.ctrl, plugin->aria2.path); } } - ug_close (value); + ug_close(value); // remove tail ".aria2" string in file path - *(char*) strstr (plugin->file.path + length, ".aria2") = 0; + *(char*) strstr(plugin->file.path + length, ".aria2") = 0; // if error occurred while allocating disk space, delete created download file. if (ugcurl->event_code > 0) { - ug_unlink (plugin->file.path); + ug_unlink(plugin->file.path); return FALSE; } break; } - // filename repeat - sprintf (plugin->file.path + length, ".%d", counts); + sprintf(plugin->file.path + plugin->folder.length, + plugin->file.name_fmt, counts); } if (counts == MAX_REPEAT_COUNTS) { @@ -1155,37 +1139,39 @@ // set filename if counts > 0 if (counts) { - ug_free (common->file); - common->file = ug_strdup (plugin->file.path + folder_len); + ug_free(common->file); + common->file = ug_strdup(plugin->file.path + plugin->folder.length); } plugin->file_renamed = TRUE; + // update UgetFiles + plugin_decide_files(plugin); // event if (ugcurl->resumable) { - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_normal (UGET_EVENT_NORMAL_RESUMABLE, NULL)); + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_normal(UGET_EVENT_NORMAL_RESUMABLE, NULL)); } else { - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_normal (UGET_EVENT_NORMAL_NOT_RESUMABLE, NULL)); + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_normal(UGET_EVENT_NORMAL_NOT_RESUMABLE, NULL)); } #ifndef NDEBUG if (common->debug_level) { - printf ("CURL message = %s\n", ugcurl->error_string); - printf ("plugin->file.path = %s\n", plugin->file.path); - printf ("plugin->file.size = %d\n", (int)plugin->file.size); - printf ("plugin->file.time = %d\n", (int)plugin->file.time); - printf ("resumable = %d\n", ugcurl->resumable); + printf("CURL message = %s\n", ugcurl->error_string); + printf("plugin->file.path = %s\n", plugin->file.path); + printf("plugin->file.size = %d\n", (int)plugin->file.size); + printf("plugin->file.time = %d\n", (int)plugin->file.time); + printf("resumable = %d\n", ugcurl->resumable); } #endif // set flags to UriLink if (ugcurl->header.uri) { // HTTP redirection - temp.ulink = plugin_replace_uri (plugin, ugcurl->uri.link, - ugcurl->header.uri, -1); + temp.ulink = plugin_replace_uri(plugin, ugcurl->uri.link, + ugcurl->header.uri, -1); ugcurl->uri.link = temp.ulink; - ug_free (ugcurl->header.uri); + ug_free(ugcurl->header.uri); ugcurl->header.uri = NULL; } else @@ -1201,12 +1187,12 @@ plugin->prepared = TRUE; // file and it's offset temp.val64 = 0; - uget_a2cf_lack (&plugin->aria2.ctrl, - (uint64_t*) &temp.val64, - (uint64_t*) &ugcurl->end); + uget_a2cf_lack(&plugin->aria2.ctrl, + (uint64_t*) &temp.val64, + (uint64_t*) &ugcurl->end); plugin->segment.beg = ugcurl->end; if (ugcurl->beg == temp.val64) { - if (uget_curl_open_file (ugcurl, plugin->file.path) == FALSE) { + if (uget_curl_open_file(ugcurl, plugin->file.path) == FALSE) { ugcurl->event_code = UGET_EVENT_ERROR_FILE_OPEN_FAILED; return FALSE; } @@ -1215,84 +1201,162 @@ else { ugcurl->beg = temp.val64; ugcurl->pos = temp.val64; - curl_easy_setopt (ugcurl->curl, CURLOPT_RESUME_FROM_LARGE, + curl_easy_setopt(ugcurl->curl, CURLOPT_RESUME_FROM_LARGE, (curl_off_t) temp.val64); - if (uget_curl_open_file (ugcurl, plugin->file.path)) + if (uget_curl_open_file(ugcurl, plugin->file.path)) ugcurl->restart = TRUE; return FALSE; } } -static int load_file_info (UgetPluginCurl* plugin) +// used by get_repeating_fmt_string() +enum { + EXT_NUMBER = 0x01, + EXT_UPPER = 0x02, + EXT_LOWER = 0x04, + + EXT_CAMEL = EXT_UPPER | EXT_LOWER, + EXT_ALL = EXT_UPPER | EXT_LOWER | EXT_NUMBER, +}; + +// used by get_repeating_fmt_string() +static char* find_dot_ext(const char* filename, const char* end, uint8_t* status) +{ + uint8_t stat = 0; + const char* cur = NULL; + + for (cur = end-1; cur >= filename; cur--) { + if (cur[0] == '.') { + if (cur == end-1 || cur == filename) + break; + if (status) + status[0] = stat; + return (char*)cur; + } + else if (cur[0] >= '0' && cur[0] <= '9') + stat |= EXT_NUMBER; + else if (cur[0] >= 'A' && cur[0] <= 'Z') + stat |= EXT_UPPER; + else if (cur[0] >= 'a' && cur[0] <= 'z') + stat |= EXT_LOWER; + else + break; + } + return NULL; +} + +static char* get_repeating_fmt_string(char* filename) +{ + char* result; + char* dot[3] = {NULL, NULL, NULL}; + uint8_t stat[3] = {0, 0, 0}; + int index; + int length; + + length = strlen(filename); + result = ug_malloc(length + 3 + 1); // + ".%d" + "\0" + + // dot[0] + dot[0] = find_dot_ext(filename, filename + length, &stat[0]); + if (dot[0]) + dot[1] = find_dot_ext(filename, dot[0], &stat[1]); + if (dot[1]) + dot[2] = find_dot_ext(filename, dot[1], &stat[2]); + + for (index = 2; index >= 0; index--) { + if (dot[index] == NULL) + continue; + + // replace exist number + if (stat[index] == EXT_NUMBER) { + // strncpy() doesn't always null-terminated + strncpy(result, filename, dot[index] - filename); + result[dot[index] - filename] = 0; + strcat(result, ".%d"); + if (index > 0) + strcat(result, dot[index-1]); + return result; + } + + // insert number + if (index == 2) + continue; + // strncpy() doesn't always null-terminated + strncpy(result, filename, dot[index] - filename); + result[dot[index] - filename] = 0; + strcat(result, ".%d"); + strcat(result, dot[index]); + return result; + } + + // append number + strcpy(result, filename); + strcat(result, ".%d"); + + // return printf() format string + return result; +} + +static int load_file_info(UgetPluginCurl* plugin) { UgetCommon* common; char* path; - int value; int length; common = plugin->common; if (common == NULL || common->file == NULL) return FALSE; - // folder - if (common->folder == NULL || common->folder[0] == 0) - length = 0; - else { - length = strlen (common->folder); - value = common->folder[length - 1]; - if (value != '\\' || value != '/') - length++; - } - // filename - length += strlen (common->file); + // folder + filename + length = plugin->folder.length; + length += strlen(common->file); // path - path = ug_malloc (length + 6 + 1); // length + ".aria2" + '\0' + path = ug_malloc(length + 6 + 1); // length + ".aria2" + '\0' path[0] = 0; // you need this line if common->folder is NULL. - if (common->folder) { - strcpy (path, common->folder); - if (value != '\\' || value != '/') { -#if defined _WIN32 || defined _WIN64 - strcat (path, "\\"); -#else - strcat (path, "/"); -#endif - } - } - strcat (path, common->file); - if (ug_file_is_exist (path) == FALSE) { - ug_free (path); + if (plugin->folder.path) + strcpy(path, plugin->folder.path); + strcat(path, common->file); + if (ug_file_is_exist(path) == FALSE) { + ug_free(path); return FALSE; } - strcat (path, ".aria2"); + strcat(path, ".aria2"); // aria2 control file - if (uget_a2cf_load (&plugin->aria2.ctrl, path)) { + if (uget_a2cf_load(&plugin->aria2.ctrl, path)) { plugin->file.size = plugin->aria2.ctrl.total_len; - plugin->file.path = ug_strndup (path, length); + plugin->file.path = ug_strndup(path, length); plugin->aria2.path = path; - plugin->base.download = uget_a2cf_completed (&plugin->aria2.ctrl); + plugin->base.download = uget_a2cf_completed(&plugin->aria2.ctrl); plugin->size.download = plugin->base.download; + // update UgetFiles + plugin_decide_files(plugin); return TRUE; } else { - uget_a2cf_clear (&plugin->aria2.ctrl); - ug_free (path); + uget_a2cf_clear(&plugin->aria2.ctrl); + ug_free(path); return FALSE; } } -static void clear_file_info (UgetPluginCurl* plugin) +static void clear_file_info(UgetPluginCurl* plugin) { - uget_a2cf_clear (&plugin->aria2.ctrl); - ug_free (plugin->aria2.path); + // update UgetFiles + uget_plugin_lock(plugin); + uget_files_apply_deleted(plugin->files); + uget_plugin_unlock(plugin); + + uget_a2cf_clear(&plugin->aria2.ctrl); + ug_free(plugin->aria2.path); plugin->aria2.path = NULL; - ug_free (plugin->file.path); + ug_free(plugin->file.path); plugin->file.path = NULL; plugin->file.size = 0; plugin->base.download = 0; plugin->size.download = 0; } -static int switch_uri (UgetPluginCurl* plugin, UgetCurl* ugcurl, int is_resumable) +static int switch_uri(UgetPluginCurl* plugin, UgetCurl* ugcurl, int is_resumable) { UriLink* uri_link; @@ -1301,7 +1365,7 @@ uri_link = (UriLink*) plugin->uri.list.head; // set URI and decide it's scheme - uget_curl_set_url (ugcurl, uri_link->uri); + uget_curl_set_url(ugcurl, uri_link->uri); uri_link->scheme_type = ugcurl->scheme_type; // sync URI flags to UgetCurl ugcurl->uri.link = uri_link; @@ -1314,43 +1378,52 @@ return TRUE; } -static void complete_file (UgetPluginCurl* plugin) +static void complete_file(UgetPluginCurl* plugin) { if (plugin->aria2.path) { - ug_unlink (plugin->aria2.path); - ug_free (plugin->aria2.path); + // update UgetFiles + uget_plugin_lock(plugin); + uget_files_replace(plugin->files, + plugin->file.path, + UGET_FILE_REGULAR, UGET_FILE_STATE_COMPLETED); + uget_files_replace(plugin->files, + plugin->aria2.path, + UGET_FILE_ATTACHMENT, UGET_FILE_STATE_DELETED); + uget_plugin_unlock(plugin); + // delete aria2 control file + ug_unlink(plugin->aria2.path); + ug_free(plugin->aria2.path); plugin->aria2.path = NULL; } // modify file time if (plugin->common->timestamp == TRUE && plugin->file.time != -1) - ug_modify_file_time (plugin->file.path, plugin->file.time); + ug_modify_file_time(plugin->file.path, plugin->file.time); // completed message - plugin->node->state |= UGET_STATE_COMPLETED; - uget_plugin_post ((UgetPlugin*)plugin, - uget_event_new (UGET_EVENT_COMPLETED)); - uget_plugin_post ((UgetPlugin*)plugin, - uget_event_new (UGET_EVENT_STOP)); + uget_plugin_post((UgetPlugin*)plugin, + uget_event_new(UGET_EVENT_COMPLETED)); + uget_plugin_post((UgetPlugin*)plugin, + uget_event_new(UGET_EVENT_STOP)); } -static int reuse_download (UgetPluginCurl* plugin, UgetCurl* ugcurl, int next_uri) +static int reuse_download(UgetPluginCurl* plugin, UgetCurl* ugcurl, int next_uri) { if (ugcurl->beg == ugcurl->pos) { // delete segment if no downloaded data - ug_list_remove (&plugin->segment.list, (void*)ugcurl); - uget_curl_free (ugcurl); + ug_list_remove(&plugin->segment.list, (void*)ugcurl); + uget_curl_free(ugcurl); return FALSE; } else { // reuse this segment if (next_uri == TRUE) - switch_uri (plugin, ugcurl, TRUE); + switch_uri(plugin, ugcurl, TRUE); ugcurl->beg = ugcurl->pos; - uget_curl_run (ugcurl, FALSE); + uget_curl_run(ugcurl, FALSE); return TRUE; } } -static int split_download (UgetPluginCurl* plugin, UgetCurl* ugcurl) +static int split_download(UgetPluginCurl* plugin, UgetCurl* ugcurl) { UgetCurl* temp; UgetCurl* sibling = NULL; @@ -1362,13 +1435,13 @@ // try to find unused space cur = plugin->segment.beg; - if (uget_a2cf_lack (&plugin->aria2.ctrl, &cur, &end)) { + if (uget_a2cf_lack(&plugin->aria2.ctrl, &cur, &end)) { plugin->segment.beg = end; #ifndef NDEBUG if (plugin->common->debug_level) { - printf ("\n" "lack %u-%u KiB\n", - (unsigned) cur / 1024, - (unsigned) end / 1024); + printf("\n" "lack %u-%u KiB\n", + (unsigned) cur / 1024, + (unsigned) end / 1024); } #endif } @@ -1397,9 +1470,9 @@ #ifndef NDEBUG if (plugin->common->debug_level) { - printf ("\n" "split %u-%u KiB\n", - (unsigned) cur / 1024, - (unsigned) end / 1024); + printf("\n" "split %u-%u KiB\n", + (unsigned) cur / 1024, + (unsigned) end / 1024); } #endif } @@ -1407,54 +1480,54 @@ // reuse or create UgetCurl // if this UgetCurl has been inserted in segment.list, remove it. if (ugcurl) - ug_list_remove (&plugin->segment.list, (UgLink*) ugcurl); + ug_list_remove(&plugin->segment.list, (UgLink*) ugcurl); else - ugcurl = create_segment (plugin); + ugcurl = create_segment(plugin); // add to segment.list if (sibling == NULL) - ug_list_append (&plugin->segment.list, (void*) ugcurl); + ug_list_append(&plugin->segment.list, (void*) ugcurl); else { ugcurl->split = TRUE; - ug_list_insert (&plugin->segment.list, + ug_list_insert(&plugin->segment.list, (void*) sibling->next, (void*) ugcurl); } ugcurl->beg = cur; ugcurl->end = end; - uget_curl_run (ugcurl, FALSE); + uget_curl_run(ugcurl, FALSE); return TRUE; } -static void delay_ms (UgetPluginCurl* plugin, int milliseconds) +static void delay_ms(UgetPluginCurl* plugin, int milliseconds) { while (plugin->paused == FALSE) { if (milliseconds > 500) { milliseconds -= 500; - ug_sleep (500); + ug_sleep(500); continue; } - ug_sleep (milliseconds); + ug_sleep(milliseconds); return; } } -static UgetCurl* create_segment (UgetPluginCurl* plugin) +static UgetCurl* create_segment(UgetPluginCurl* plugin) { UgetCurl* ugcurl; - ugcurl = uget_curl_new (); - uget_curl_set_common (ugcurl, plugin->common); - uget_curl_set_proxy (ugcurl, plugin->proxy); - uget_curl_set_http (ugcurl, plugin->http); - uget_curl_set_ftp (ugcurl, plugin->ftp); + ugcurl = uget_curl_new(); + uget_curl_set_common(ugcurl, plugin->common); + uget_curl_set_proxy(ugcurl, plugin->proxy); + uget_curl_set_http(ugcurl, plugin->http); + uget_curl_set_ftp(ugcurl, plugin->ftp); // set speed limit if (plugin->limit.download) ugcurl->limit[0] = plugin->limit.download / (plugin->segment.list.size + 1); if (plugin->limit.upload) ugcurl->limit[1] = plugin->limit.upload / (plugin->segment.list.size + 1); // select URL - switch_uri (plugin, ugcurl, FALSE); + switch_uri(plugin, ugcurl, FALSE); // set output function ugcurl->prepare.func = (UgetCurlFunc) prepare_existed; ugcurl->prepare.data = plugin; @@ -1462,7 +1535,7 @@ } // speed control -static void adjust_speed_limit_index (UgetPluginCurl* plugin, int idx, int64_t remain) +static void adjust_speed_limit_index(UgetPluginCurl* plugin, int idx, int64_t remain) { UgetCurl* ucurl; @@ -1479,7 +1552,7 @@ } } -static void disable_speed_limit (UgetPluginCurl* plugin, int idx) +static void disable_speed_limit(UgetPluginCurl* plugin, int idx) { UgetCurl* ugcurl; @@ -1490,21 +1563,21 @@ } } -static void adjust_speed_limit (UgetPluginCurl* plugin) +static void adjust_speed_limit(UgetPluginCurl* plugin) { if (plugin->segment.n_active == 0) return; // download if (plugin->limit.download > 0) - adjust_speed_limit_index (plugin, 0, plugin->limit.download - plugin->speed.download); + adjust_speed_limit_index(plugin, 0, plugin->limit.download - plugin->speed.download); else if (plugin->limit_changed) - disable_speed_limit (plugin, 0); + disable_speed_limit(plugin, 0); // upload if (plugin->limit.upload > 0) - adjust_speed_limit_index (plugin, 1, plugin->limit.upload - plugin->speed.upload); + adjust_speed_limit_index(plugin, 1, plugin->limit.upload - plugin->speed.upload); else if (plugin->limit_changed) - disable_speed_limit (plugin, 1); + disable_speed_limit(plugin, 1); plugin->limit_changed = FALSE; } diff -Nru uget-2.2.0/uget/UgetPluginCurl.h uget-2.2.2/uget/UgetPluginCurl.h --- uget-2.2.0/uget/UgetPluginCurl.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetPluginCurl.h 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -48,33 +48,49 @@ extern "C" { #endif -typedef struct UgetPluginCurl UgetPluginCurl; +typedef struct UgetPluginCurl UgetPluginCurl; -extern const UgetPluginInfo* UgetPluginCurlInfo; +extern const UgetPluginInfo* UgetPluginCurlInfo; -// ---------------------------------------------------------------------------- -// UgetPluginCurl: libcurl plug-in that derived from UgetPlugin. +/* ---------------------------------------------------------------------------- + UgetPluginCurl: libcurl plug-in that derived from UgetPlugin. + + UgType + | + `---UgetPlugin + | + `--- UgetPluginCurl + */ struct UgetPluginCurl { - UGET_PLUGIN_MEMBERS; // It derived from UgetPlugin -// const UgetPluginInfo* info; -// UgetEvent* messages; -// UgMutex mutex; -// int ref_count; - - // pointer to UgetNode that store in UgetApp - UgetNode* node; + UGET_PLUGIN_MEMBERS; +/* // ------ UgType members ------ + const UgetPluginInfo* info; + + // ------ UgetPlugin members ------ + UgetEvent* messages; + UgMutex mutex; + int ref_count; + */ - // copy of UgetNode data + // copy these UgData from UgInfo that store in UgetApp UgetCommon* common; + UgetFiles* files; UgetProxy* proxy; UgetHttp* http; UgetFtp* ftp; - // run-time info + // run-time data // struct curl_slist* ftp_command; + struct { + char* path; // folder + int length; + } folder; + + struct { + char* name_fmt; // printf() format string char* path; // folder + filename time_t time; // date and time int64_t size; // total size (0 if size unknown) @@ -82,7 +98,7 @@ // aria2 control file struct { - char* path; + char* path; // folder + filename + ".aria2" UgetA2cf ctrl; } aria2; @@ -117,10 +133,8 @@ } base, size, speed, limit; // flags - uint8_t limit_by_user:1; // speed limit changed by user - uint8_t limit_changed:1; // speed limit changed + uint8_t limit_changed:1; // speed limit changed by user or program uint8_t file_renamed:1; // has file path? - uint8_t a2cf_named:1; // has aria2 ctrl file name? uint8_t synced:1; uint8_t paused:1; // paused by user or program uint8_t stopped:1; // all of downloading thread are stopped @@ -139,12 +153,18 @@ namespace Uget { +const PluginInfo* const PluginCurlInfo = (const PluginInfo*) UgetPluginCurlInfo; + // This one is for derived use only. No data members here. // Your derived struct/class must be C++11 standard-layout -struct PluginCurlMethod : Uget::PluginMethod {}; +struct PluginCurlMethod : PluginMethod {}; // This one is for directly use only. You can NOT derived it. -struct PluginCurl : Uget::PluginCurlMethod, UgetPluginCurl {}; +struct PluginCurl : PluginCurlMethod, UgetPluginCurl +{ + inline void* operator new(size_t size) + { return uget_plugin_new(PluginCurlInfo); } +}; }; // namespace Uget diff -Nru uget-2.2.0/uget/UgetPluginEmpty.c uget-2.2.2/uget/UgetPluginEmpty.c --- uget-2.2.0/uget/UgetPluginEmpty.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetPluginEmpty.c 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -40,14 +40,15 @@ #include // ---------------------------------------------------------------------------- -// UgetPluginInfo (derived from UgDataInfo) +// UgetPluginInfo (derived from UgTypeInfo) -static void plugin_init (UgetPluginEmpty* plugin); -static void plugin_final (UgetPluginEmpty* plugin); -static int plugin_ctrl (UgetPluginEmpty* plugin, int code, void* data); -static int plugin_sync (UgetPluginEmpty* plugin); -static UgetResult global_set (int code, void* parameter); -static UgetResult global_get (int code, void* parameter); +static void plugin_init (UgetPluginEmpty* plugin); +static void plugin_final(UgetPluginEmpty* plugin); +static int plugin_ctrl (UgetPluginEmpty* plugin, int code, void* data); +static int plugin_accept(UgetPluginEmpty* plugin, UgInfo* node_info); +static int plugin_sync (UgetPluginEmpty* plugin, UgInfo* node_info); +static UgetResult global_set(int code, void* parameter); +static UgetResult global_get(int code, void* parameter); static const char* schemes[] = {"http", "ftp", NULL}; static const char* types[] = {"torrent", NULL}; @@ -55,18 +56,17 @@ static const UgetPluginInfo UgetPluginEmptyInfoStatic = { "empty", - sizeof (UgetPluginEmpty), - (const UgEntry*) NULL, + sizeof(UgetPluginEmpty), (UgInitFunc) plugin_init, (UgFinalFunc) plugin_final, - (UgAssignFunc) NULL, - (UgetPluginCtrlFunc) plugin_ctrl, + (UgetPluginSyncFunc) plugin_accept, (UgetPluginSyncFunc) plugin_sync, + (UgetPluginCtrlFunc) plugin_ctrl, NULL, schemes, types, - (UgetPluginSetFunc) global_set, - (UgetPluginGetFunc) global_get + (UgetPluginGlobalFunc) global_set, + (UgetPluginGlobalFunc) global_get }; // extern const UgetPluginInfo* UgetPluginEmptyInfo = &UgetPluginEmptyInfoStatic; @@ -80,7 +80,7 @@ int ref_count; } global = {0, 0}; -static UgetResult global_init (void) +static UgetResult global_init(void) { if (global.initialized == FALSE) { // @@ -89,18 +89,18 @@ // return UGET_RESULT_ERROR; // global.initialized = TRUE; - puts ("UgetPluginEmpty global initialize"); + puts("UgetPluginEmpty global initialize"); } global.ref_count++; return UGET_RESULT_OK; } -static void global_ref (void) +static void global_ref(void) { global.ref_count++; } -static void global_unref (void) +static void global_unref(void) { if (global.initialized == FALSE) return; @@ -111,19 +111,19 @@ // // your global finalized code // - puts ("UgetPluginEmpty global finalize"); + puts("UgetPluginEmpty global finalize"); } } -static UgetResult global_set (int option, void* parameter) +static UgetResult global_set(int option, void* parameter) { switch (option) { - case UGET_PLUGIN_INIT: + case UGET_PLUGIN_GLOBAL_INIT: // do global initialize/uninitialize here if (parameter) - return global_init (); + return global_init(); else - global_unref (); + global_unref(); break; default: @@ -133,15 +133,15 @@ return UGET_RESULT_OK; } -static UgetResult global_get (int option, void* parameter) +static UgetResult global_get(int option, void* parameter) { switch (option) { - case UGET_PLUGIN_INIT: + case UGET_PLUGIN_GLOBAL_INIT: if (parameter) *(int*)parameter = global.initialized; break; - case UGET_PLUGIN_ERROR_CODE: + case UGET_PLUGIN_GLOBAL_ERROR_CODE: if (parameter) *(int*)parameter = 0; break; @@ -156,128 +156,133 @@ // ---------------------------------------------------------------------------- // control functions -static void plugin_init (UgetPluginEmpty* plugin) +static void plugin_init(UgetPluginEmpty* plugin) { if (global.initialized == FALSE) - global_init (); + global_init(); else - global_ref (); + global_ref(); // // your initialized code. // } -static void plugin_final (UgetPluginEmpty* plugin) +static void plugin_final(UgetPluginEmpty* plugin) { // // your finalized code. // - // unassign node - if (plugin->node) - uget_node_unref (plugin->node); + // clear UgetCommon + if (plugin->common) + ug_data_free(plugin->common); - global_unref (); + global_unref(); } // ---------------------------------------------------------------------------- // plugin_ctrl -static int plugin_ctrl_speed (UgetPluginEmpty* plugin, int* speed); -static int plugin_start (UgetPluginEmpty* plugin, UgetNode* node); -static void plugin_stop (UgetPluginEmpty* plugin); +static int plugin_ctrl_speed(UgetPluginEmpty* plugin, int* speed); +static int plugin_start(UgetPluginEmpty* plugin); +static void plugin_stop(UgetPluginEmpty* plugin); -static int plugin_ctrl (UgetPluginEmpty* plugin, int code, void* data) +static int plugin_ctrl(UgetPluginEmpty* plugin, int code, void* data) { switch (code) { case UGET_PLUGIN_CTRL_START: - if (plugin->node == NULL) - return plugin_start (plugin, data); + if (plugin->common) + return plugin_start(plugin); break; case UGET_PLUGIN_CTRL_STOP: - plugin_stop (plugin); + plugin_stop(plugin); return TRUE; case UGET_PLUGIN_CTRL_SPEED: // speed control - return plugin_ctrl_speed (plugin, data); + return plugin_ctrl_speed(plugin, data); - // output --------------- - case UGET_PLUGIN_CTRL_ACTIVE: + // state ---------------- + case UGET_PLUGIN_GET_STATE: *(int*)data = FALSE; return TRUE; - // unused --------------- - case UGET_PLUGIN_CTRL_NODE_UPDATED: default: break; } return FALSE; } -static int plugin_ctrl_speed (UgetPluginEmpty* plugin, int* speed) +static int plugin_ctrl_speed(UgetPluginEmpty* plugin, int* speed) { UgetCommon* common; int value; - // Don't do anything if speed limit keep no change. - if (plugin->limit[0] == speed[0] && plugin->limit[1] == speed[1]) - return TRUE; + // notify plug-in that speed limit has been changed + if (plugin->limit[0] != speed[0] || plugin->limit[1] != speed[1]) + plugin->limit_changed = TRUE; // decide speed limit by user specified data. - if (plugin->node == NULL) { + if (plugin->common == NULL) { plugin->limit[0] = speed[0]; plugin->limit[1] = speed[1]; } else { - common = ug_info_realloc (&plugin->node->info, UgetCommonInfo); + common = plugin->common; // download value = speed[0]; if (common->max_download_speed) { - if (value > common->max_download_speed || value == 0) + if (value > common->max_download_speed || value == 0) { value = common->max_download_speed; + plugin->limit_changed = TRUE; + } } plugin->limit[0] = value; // upload value = speed[1]; if (common->max_upload_speed) { - if (value > common->max_upload_speed || value == 0) + if (value > common->max_upload_speed || value == 0) { value = common->max_upload_speed; + plugin->limit_changed = TRUE; + } } plugin->limit[1] = value; } - // notify plug-in that speed limit has been changed - plugin->limit_changed = TRUE; - return TRUE; + return plugin->limit_changed; } // ---------------------------------------------------------------------------- -// plugin_sync +// plugin_accept/plugin_sync -static int plugin_sync (UgetPluginEmpty* plugin) -{ - // if plug-in was stopped, return FALSE. - return FALSE; -} - -// ---------------------------------------------------------------------------- - -static int plugin_start (UgetPluginEmpty* plugin, UgetNode* node) +// return TRUE if UgInfo was accepted by plug-in. +// return FALSE if UgInfo is lack of necessary data. +static int plugin_accept(UgetPluginEmpty* plugin, UgInfo* node_info) { UgetCommon* common; - common = ug_info_get (&node->info, UgetCommonInfo); + common = ug_info_get(node_info, UgetCommonInfo); if (common == NULL || common->uri == NULL) return FALSE; - // assign node - uget_node_ref (node); - plugin->node = node; + plugin->common = ug_data_copy(plugin->common); + return TRUE; +} + +// return TRUE if plug-in is running or some data need to sync. +// return FALSE if plug-in was stopped and no data need to sync. +static int plugin_sync(UgetPluginEmpty* plugin, UgInfo* node_info) +{ + return FALSE; +} + +// ---------------------------------------------------------------------------- +static int plugin_start(UgetPluginEmpty* plugin) +{ return TRUE; } -static void plugin_stop (UgetPluginEmpty* plugin) +static void plugin_stop(UgetPluginEmpty* plugin) { } diff -Nru uget-2.2.0/uget/UgetPluginEmpty.h uget-2.2.2/uget/UgetPluginEmpty.h --- uget-2.2.0/uget/UgetPluginEmpty.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetPluginEmpty.h 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -43,27 +43,38 @@ extern "C" { #endif -typedef struct UgetPluginEmpty UgetPluginEmpty; +typedef struct UgetPluginEmpty UgetPluginEmpty; + +extern const UgetPluginInfo* UgetPluginEmptyInfo; typedef enum { - UGET_PLUGIN_EMPTY_BEGIN = UGET_PLUGIN_OPTION_DERIVED, // begin + UGET_PLUGIN_EMPTY_GLOBAL = UGET_PLUGIN_GLOBAL_DERIVED, // begin // your setting ID... } UgetPluginEmptyCode; -extern const UgetPluginInfo* UgetPluginEmptyInfo; +/* ---------------------------------------------------------------------------- + UgetPluginEmpty: an empty plug-in. It derived from UgetPlugin. -// ---------------------------------------------------------------------------- -// UgetPluginEmpty: an empty plug-in. It derived from UgetPlugin. + UgType + | + `--- UgetPlugin + | + `--- UgetPluginEmpty + */ struct UgetPluginEmpty { - UGET_PLUGIN_MEMBERS; // It derived from UgetPlugin -// const UgetPluginInfo* info; -// UgetEvent* messages; -// UgMutex mutex; -// int ref_count; + UGET_PLUGIN_MEMBERS; +/* // ------ UgType members ------ + const UgetPluginInfo* info; + + // ------ UgetPlugin members ------ + UgetEvent* messages; + UgMutex mutex; + int ref_count; + */ - UgetNode* node; + UgetCommon* common; // speed limit control // limit[0] = download speed limit @@ -85,12 +96,18 @@ namespace Uget { +const PluginInfo* const PluginEmptyInfo = (const PluginInfo*) UgetPluginEmptyInfo; + // This one is for derived use only. No data members here. // Your derived struct/class must be C++11 standard-layout -struct PluginEmptyMethod : Uget::PluginMethod {}; +struct PluginEmptyMethod : PluginMethod {}; // This one is for directly use only. You can NOT derived it. -struct PluginEmpty : Uget::PluginEmptyMethod, UgetPluginEmpty {}; +struct PluginEmpty : PluginEmptyMethod, UgetPluginEmpty +{ + inline void* operator new(size_t size) + { return uget_plugin_new(PluginEmptyInfo); } +}; }; // namespace Uget diff -Nru uget-2.2.0/uget/UgetPlugin.h uget-2.2.2/uget/UgetPlugin.h --- uget-2.2.0/uget/UgetPlugin.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetPlugin.h 2019-05-19 16:49:06.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -40,8 +40,8 @@ #include #include #include +#include #include -#include #include #ifdef __cplusplus @@ -53,30 +53,27 @@ typedef enum { // input ---------------- - UGET_PLUGIN_CTRL_START, // UgetNode* + UGET_PLUGIN_CTRL_START, UGET_PLUGIN_CTRL_STOP, UGET_PLUGIN_CTRL_SPEED, // int*, int[0] = download, int[1] = upload - // output --------------- - UGET_PLUGIN_CTRL_ACTIVE, // int*, TRUE or FALSE - - // unused --------------- - UGET_PLUGIN_CTRL_NODE_UPDATED, // unused - UGET_PLUGIN_CTRL_LIMIT_CHANGED, // unused + // state ---------------- + UGET_PLUGIN_SET_STATE, // int*, TRUE or FALSE (unused) + UGET_PLUGIN_GET_STATE, // int*, TRUE or FALSE } UgetPluginCtrlCode; // global typedef enum { - UGET_PLUGIN_INIT, // get/set, parameter = (intptr_t = FALSE or TRUE) - UGET_PLUGIN_SETTING, // get/set, parameter = (void* custom_struct) - UGET_PLUGIN_SPEED_LIMIT, // get/set, parameter = (int speed[2]) - UGET_PLUGIN_SPEED, // get, parameter = (int speed[2]) - UGET_PLUGIN_ERROR_CODE, // get, parameter = (int* error_code) - UGET_PLUGIN_ERROR_STRING, // get, parameter = (char** error_string) - UGET_PLUGIN_MATCH, // get, parameter = (char* url) + UGET_PLUGIN_GLOBAL_INIT, // get/set, parameter = (intptr_t = FALSE or TRUE) + UGET_PLUGIN_GLOBAL_SETTING, // get/set, parameter = (void* custom_struct) + UGET_PLUGIN_GLOBAL_SPEED_LIMIT, // get/set, parameter = (int speed[2]) + UGET_PLUGIN_GLOBAL_SPEED, // get, parameter = (int speed[2]) + UGET_PLUGIN_GLOBAL_ERROR_CODE, // get, parameter = (int* error_code) + UGET_PLUGIN_GLOBAL_ERROR_STRING, // get, parameter = (char** error_string) + UGET_PLUGIN_GLOBAL_MATCH, // get, parameter = (char* url) - UGET_PLUGIN_OPTION_DERIVED = 10000, // for derived plug-ins -} UgetPluginOption; + UGET_PLUGIN_GLOBAL_DERIVED = 10000, // for derived plug-ins +} UgetPluginGlobalOption; typedef enum { UGET_RESULT_OK = 0, @@ -85,45 +82,98 @@ UGET_RESULT_UNSUPPORT, } UgetResult; -typedef int (*UgetPluginSyncFunc)(UgetPlugin* plugin); +// accept/sync return TRUE or FALSE +typedef int (*UgetPluginSyncFunc)(UgetPlugin* plugin, UgInfo* info); +// start/stop...etc return TRUE or FALSE. typedef int (*UgetPluginCtrlFunc)(UgetPlugin* plugin, int, void* data); -typedef UgetResult (*UgetPluginSetFunc) (int option, void* parameter); -typedef UgetResult (*UgetPluginGetFunc) (int option, void* parameter); +// global_set/global_get +typedef UgetResult (*UgetPluginGlobalFunc)(int option, void* parameter); -// ---------------------------------------------------------------------------- -// UgetPluginInfo +/* ---------------------------------------------------------------------------- + UgetPluginInfo + + UgTypeInfo + | + `-- UgetPluginInfo + */ struct UgetPluginInfo { - UG_DATA_INFO_MEMBERS; -// const char* name; -// uintptr_t size; -// const UgEntry* entry; -// UgInitFunc init; -// UgFinalFunc final; -// UgAssignFunc assign; + UG_TYPE_INFO_MEMBERS; +/* // ------ UgTypeInfo members ------ + const char* name; + uintptr_t size; + UgInitFunc init; + UgFinalFunc final; + */ + UgetPluginSyncFunc accept; // pass data to plug-in. + UgetPluginSyncFunc sync; // call this to sync/exchange data. UgetPluginCtrlFunc ctrl; - UgetPluginSyncFunc sync; // UgetTask call this to sync data // ---------------------------- // Global data and functions - // UgetTask use below data to match UgetPlugin and UgetNode + // global data is used for matching UgetPlugin and UgInfo const char** hosts; const char** schemes; const char** file_exts; // global set/get function for plug-in special setting. - UgetPluginSetFunc set; - UgetPluginGetFunc get; + UgetPluginGlobalFunc global_set; + UgetPluginGlobalFunc global_get; }; -// ---------------------------------------------------------------------------- -// UgetPlugin: It derived from UgData. -// It it base class/struct that used by plug-ins. +UgetResult uget_plugin_global_set(const UgetPluginInfo* info, + int option, void* parameter); +UgetResult uget_plugin_global_get(const UgetPluginInfo* info, + int option, void* parameter); + +// return matched count. +// return 3 if URI can be matched hosts, schemes, and file_exts. +int uget_plugin_match(const UgetPluginInfo* info, UgUri* uuri); + +/* ---------------------------------------------------------------------------- + UgetPlugin: It is base class/struct that used by plug-ins. + It derived from UgType. + + UgType + | + `-- UgetPlugin + + accept(info) accept(info) + ,----------. -------------> ,-----------. -------------> ,-----------. + | | | | | | + | User App | | plug-in 1 | | plug-in 2 | + | | | | | | + `----------' <------------> `-----------' <------------> `-----------' + sync(info) sync(info) + + // create and start plug-in + plugin = uget_plugin_new(UgetPluginCurlInfo); + uget_plugin_accept(plugin, info); + if (uget_plugin_start(plugin) == FALSE) { + uget_plugin_unref(plugin); + return; + } + + // Running loop sample 1: use uget_plugin_sync() + while (uget_plugin_sync(plugin, info)) { + // sleep(); + // do something here + } + + // Running loop sample 2: use uget_plugin_get_state() + do { + // sleep(); + // do something here + // If you don't want to exchange data (e.g. progress) with plug-in, + // you do not need to call uget_plugin_sync() at last. + uget_plugin_sync(plugin, info); + } while (uget_plugin_get_state(plugin)); + */ -#define UGET_PLUGIN_MEMBERS \ +#define UGET_PLUGIN_MEMBERS \ const UgetPluginInfo* info; \ UgetEvent* events; \ UgMutex mutex; \ @@ -131,64 +181,50 @@ struct UgetPlugin { - UGET_PLUGIN_MEMBERS; // It derived from UgData -// const UgetPluginInfo* info; -// UgetEvent* events; -// UgMutex mutex; -// int ref_count; + UGET_PLUGIN_MEMBERS; +/* // ------ UgType members ------ + const UgetPluginInfo* info; + + // ------ UgetPlugin members ------ + UgetEvent* events; + UgMutex mutex; + int ref_count; + */ }; -// UgetPluginInfo global functions -UgetPlugin* uget_plugin_new (const UgetPluginInfo* info); -UgetResult uget_plugin_set (const UgetPluginInfo* info, int option, void* parameter); -UgetResult uget_plugin_get (const UgetPluginInfo* info, int option, void* parameter); - -// return matched count. -// return 3 if URI can be matched hosts, schemes, and file_exts. -int uget_plugin_match (const UgetPluginInfo* info, UgUri* uuri); - // UgetPlugin functions -//void uget_plugin_init (UgetPlugin* plugin); -#define uget_plugin_init ug_data_init +UgetPlugin* uget_plugin_new(const UgetPluginInfo* info); -//void uget_plugin_final (UgetPlugin* plugin); -#define uget_plugin_final ug_data_final +void uget_plugin_ref(UgetPlugin* plugin); +void uget_plugin_unref(UgetPlugin* plugin); -//void uget_plugin_assign (UgetPlugin* plugin, UgetPlugin* src); -#define uget_plugin_assign ug_data_assign +// return TRUE if UgInfo was accepted by plug-in. +// return FALSE if UgInfo lacks necessary data. +int uget_plugin_accept(UgetPlugin* plugin, UgInfo* info); + +// return TRUE if plug-in is running or some data need to exchange/sync. +// return FALSE if plug-in was stopped and no data need to exchange/sync. +int uget_plugin_sync(UgetPlugin* plugin, UgInfo* info); // return TRUE or FALSE. -int uget_plugin_ctrl (UgetPlugin* plugin, int code, void* data); +int uget_plugin_ctrl(UgetPlugin* plugin, int code, void* data); -#define uget_plugin_start(plugin, node) \ - uget_plugin_ctrl (plugin, UGET_PLUGIN_CTRL_START, node) -#define uget_plugin_stop(plugin) \ - uget_plugin_ctrl (plugin, UGET_PLUGIN_CTRL_STOP, NULL) +#define uget_plugin_start(plugin) \ + uget_plugin_ctrl(plugin, UGET_PLUGIN_CTRL_START, NULL) +#define uget_plugin_stop(plugin) \ + uget_plugin_ctrl(plugin, UGET_PLUGIN_CTRL_STOP, NULL) #define uget_plugin_ctrl_speed(plugin, dl_ul_int_array) \ - uget_plugin_ctrl (plugin, UGET_PLUGIN_CTRL_SPEED, dl_ul_int_array) - -// unused -// notify plug-in when other data was changed -#define uget_plugin_data_changed(plugin) \ - uget_plugin_ctrl (plugin, UGET_PLUGIN_CTRL_DATA_CHANGED, NULL) -// unused -// notify plug-in when speed_limit, retry_limit, max_connections...etc was changed -#define uget_plugin_limit_changed(plugin) \ - uget_plugin_ctrl (plugin, UGET_PLUGIN_CTRL_LIMIT_CHANGED, NULL) - -// teturn TRUE if plug-in running. -// return FALSE if plug-in stopped. -int uget_plugin_sync (UgetPlugin* plugin); + uget_plugin_ctrl(plugin, UGET_PLUGIN_CTRL_SPEED, dl_ul_int_array) -void uget_plugin_ref (UgetPlugin* plugin); -void uget_plugin_unref (UgetPlugin* plugin); +// return > 0 if plug-in is running. +int uget_plugin_get_state(UgetPlugin* plugin); -void uget_plugin_post (UgetPlugin* plugin, UgetEvent* message); -UgetEvent* uget_plugin_pop (UgetPlugin* plugin); +void uget_plugin_post(UgetPlugin* plugin, UgetEvent* message); +UgetEvent* uget_plugin_pop (UgetPlugin* plugin); -#define uget_plugin_lock(plugin) ug_mutex_lock (&(plugin)->mutex) -#define uget_plugin_unlock(plugin) ug_mutex_unlock (&(plugin)->mutex) +#define uget_plugin_lock(plugin) ug_mutex_lock(&(plugin)->mutex) +#define uget_plugin_unlock(plugin) ug_mutex_unlock(&(plugin)->mutex) #ifdef __cplusplus } @@ -206,48 +242,63 @@ // Your derived struct/class must be C++11 standard-layout struct PluginInfoMethod { - inline UgetResult set (int option, void* parameter) - { return uget_plugin_set ((UgetPluginInfo*)this, option, parameter); } - inline UgetResult get (int option, void* parameter) - { return uget_plugin_get ((UgetPluginInfo*)this, option, parameter); } + inline UgetResult globalSet(int option, void* parameter) + { return uget_plugin_global_set((UgetPluginInfo*)this, option, parameter); } + inline UgetResult globalGet(int option, void* parameter) + { return uget_plugin_global_get((UgetPluginInfo*)this, option, parameter); } - inline int match (UgUri* uuri) - { return uget_plugin_match ((UgetPluginInfo*)this, uuri); } + inline int match(UgUri* uuri) + { return uget_plugin_match((UgetPluginInfo*)this, uuri); } }; // This one is for directly use only. You can NOT derived it. -struct PluginInfo : Uget::PluginInfoMethod, UgetPluginInfo {}; +struct PluginInfo : PluginInfoMethod, UgetPluginInfo {}; // This one is for derived use only. No data members here. // Your derived struct/class must be C++11 standard-layout -struct PluginMethod : Ug::DataMethod +struct PluginMethod { - inline void assign (UgetNode* baseNode) - { uget_plugin_assign ((UgetPlugin*) this, baseNode); } - - inline void start (UgetNode* baseNode) - { uget_plugin_start ((UgetPlugin*) this, baseNode); } - - inline void stop (void) - { uget_plugin_stop ((UgetPlugin*) this); } - - inline int sync (void) - { return uget_plugin_sync ((UgetPlugin*) this); } - - inline void ref (void) - { uget_plugin_ref ((UgetPlugin*) this); } - inline void unref (void) - { uget_plugin_unref ((UgetPlugin*) this); } - - inline void post (UgetEvent* message) - { uget_plugin_post ((UgetPlugin*) this, message); } - inline UgetEvent* pop (void) - { return uget_plugin_pop ((UgetPlugin*) this); } + inline void* operator new(size_t size, const UgetPluginInfo* pinfo) + { return uget_plugin_new(pinfo); } + inline void operator delete(void* p) + { uget_plugin_unref((UgetPlugin*)p); } + + inline void ref(void) + { uget_plugin_ref((UgetPlugin*)this); } + inline void unref(void) + { uget_plugin_unref((UgetPlugin*)this); } + + inline int accept(UgInfo* info) + { return uget_plugin_accept((UgetPlugin*)this, info); } + inline int sync(UgInfo* info) + { return uget_plugin_sync((UgetPlugin*)this, info); } + + inline int ctrl(int code, void* data) + { return uget_plugin_ctrl((UgetPlugin*)this, code, data); } + inline int ctrlSpeed(int* DL_UL_array) + { return uget_plugin_ctrl((UgetPlugin*)this, UGET_PLUGIN_CTRL_SPEED, DL_UL_array); } + inline int ctrlSpeed(int dlspeed, int ulspeed) { + int DL_UL_array[2] = {dlspeed, ulspeed}; + return uget_plugin_ctrl((UgetPlugin*)this, UGET_PLUGIN_CTRL_SPEED, DL_UL_array); + } + + inline int start(void) + { return uget_plugin_start((UgetPlugin*)this); } + inline int stop(void) + { return uget_plugin_stop((UgetPlugin*)this); } + + inline int getState(void) + { return uget_plugin_get_state((UgetPlugin*)this); } + + inline void post(UgetEvent* message) + { uget_plugin_post((UgetPlugin*)this, message); } + inline UgetEvent* pop(void) + { return uget_plugin_pop((UgetPlugin*)this); } }; // This one is for directly use only. You can NOT derived it. -struct Plugin : Uget::PluginMethod, UgetPlugin {}; +struct Plugin : PluginMethod, UgetPlugin {}; }; // namespace Uget diff -Nru uget-2.2.0/uget/UgetPluginMedia.c uget-2.2.2/uget/UgetPluginMedia.c --- uget-2.2.0/uget/UgetPluginMedia.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetPluginMedia.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2016-2018 by C.H. Huang + * Copyright (C) 2016-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -34,10 +34,6 @@ * */ -// UgetPluginMedia -// use libcurl to get video info -// use curl plug-in to download media file. - #include #include #include @@ -57,7 +53,7 @@ #define ug_sleep Sleep #else #include // usleep() -#define ug_sleep(millisecond) usleep (millisecond * 1000) +#define ug_sleep(millisecond) usleep(millisecond * 1000) #endif // _WIN32 || _WIN64 #ifdef HAVE_GLIB @@ -69,14 +65,15 @@ #endif // ---------------------------------------------------------------------------- -// UgetPluginInfo (derived from UgDataInfo) +// UgetPluginInfo (derived from UgTypeInfo) -static void plugin_init (UgetPluginMedia* plugin); -static void plugin_final (UgetPluginMedia* plugin); -static int plugin_ctrl (UgetPluginMedia* plugin, int code, void* data); -static int plugin_sync (UgetPluginMedia* plugin); -static UgetResult global_set (int code, void* parameter); -static UgetResult global_get (int code, void* parameter); +static void plugin_init (UgetPluginMedia* plugin); +static void plugin_final(UgetPluginMedia* plugin); +static int plugin_ctrl (UgetPluginMedia* plugin, int code, void* data); +static int plugin_accept(UgetPluginMedia* plugin, UgInfo* node_info); +static int plugin_sync (UgetPluginMedia* plugin, UgInfo* node_info); +static UgetResult global_set(int code, void* parameter); +static UgetResult global_get(int code, void* parameter); static const char* schemes[] = {"http", "https", NULL}; static const char* hosts[] = {"youtube.com", "youtu.be", @@ -85,18 +82,17 @@ static const UgetPluginInfo UgetPluginMediaInfoStatic = { "media", - sizeof (UgetPluginMedia), - (const UgEntry*) NULL, + sizeof(UgetPluginMedia), (UgInitFunc) plugin_init, (UgFinalFunc) plugin_final, - (UgAssignFunc) NULL, - (UgetPluginCtrlFunc) plugin_ctrl, + (UgetPluginSyncFunc) plugin_accept, (UgetPluginSyncFunc) plugin_sync, + (UgetPluginCtrlFunc) plugin_ctrl, hosts, schemes, NULL, - (UgetPluginSetFunc) global_set, - (UgetPluginGetFunc) global_get + (UgetPluginGlobalFunc) global_set, + (UgetPluginGlobalFunc) global_get }; // extern const UgetPluginInfo* UgetPluginMediaInfo = &UgetPluginMediaInfoStatic; @@ -106,112 +102,45 @@ static struct { - const UgetPluginInfo* plugin_info; UgetMediaMatchMode match_mode; UgetMediaQuality quality; UgetMediaType type; - int ref_count; -} global = {NULL, 0, 0, 0, 0}; +} global = {UGET_MEDIA_MATCH_NEAR, UGET_MEDIA_QUALITY_360P, UGET_MEDIA_TYPE_MP4}; -static UgetResult global_init (void) -{ - if (global.plugin_info == NULL) { -#if defined _WIN32 || defined _WIN64 - WSADATA WSAData; - WSAStartup (MAKEWORD (2, 2), &WSAData); -#endif // _WIN32 || _WIN64 - - if (curl_global_init (CURL_GLOBAL_ALL) != CURLE_OK) { -#if defined _WIN32 || defined _WIN64 - WSACleanup (); -#endif - return UGET_RESULT_ERROR; - } - global.plugin_info = UgetPluginCurlInfo; -// global.plugin_info = UgetPluginAria2Info; - // matching mode: UGET_MEDIA_MATCH_1 or UGET_MEDIA_MATCH_NEAR - global.match_mode = UGET_MEDIA_MATCH_NEAR; - global.quality = UGET_MEDIA_QUALITY_360P; - global.type = UGET_MEDIA_TYPE_MP4; - } - global.ref_count++; - return UGET_RESULT_OK; -} - -static void global_ref (void) -{ - global.ref_count++; -} - -static void global_unref (void) -{ - if (global.plugin_info == NULL) - return; - - global.ref_count--; - if (global.ref_count == 0) { - global.plugin_info = NULL; - curl_global_cleanup (); -#if defined _WIN32 || defined _WIN64 - WSACleanup (); -#endif - } -} - -static UgetResult global_set (int option, void* parameter) +static UgetResult global_set(int option, void* parameter) { switch (option) { - case UGET_PLUGIN_INIT: - // do global initialize/uninitialize here - if (parameter) - return global_init (); - else - global_unref (); - break; - - case UGET_PLUGIN_MEDIA_DEFAULT_PLUGIN: - global.plugin_info = parameter; - break; - - case UGET_PLUGIN_MEDIA_MATCH_MODE: + case UGET_PLUGIN_MEDIA_GLOBAL_MATCH_MODE: global.match_mode = (intptr_t) parameter; break; - case UGET_PLUGIN_MEDIA_QUALITY: + case UGET_PLUGIN_MEDIA_GLOBAL_QUALITY: global.quality = (intptr_t) parameter; break; - case UGET_PLUGIN_MEDIA_TYPE: + case UGET_PLUGIN_MEDIA_GLOBAL_TYPE: global.type = (intptr_t) parameter; break; default: - return UGET_RESULT_UNSUPPORT; + // call parent's global_set() + return uget_plugin_agent_global_set(option, parameter); } return UGET_RESULT_OK; } -static UgetResult global_get (int option, void* parameter) +static UgetResult global_get(int option, void* parameter) { switch (option) { - case UGET_PLUGIN_INIT: - if (parameter) - *(int*)parameter = (global.plugin_info) ? TRUE : FALSE; - break; - - case UGET_PLUGIN_ERROR_CODE: - if (parameter) - *(int*)parameter = 0; - break; - - case UGET_PLUGIN_MATCH: - if (uget_site_get_id (parameter) < UGET_SITE_MEDIA) + case UGET_PLUGIN_GLOBAL_MATCH: + if (uget_site_get_id(parameter) < UGET_SITE_MEDIA) return UGET_RESULT_FAILED; - return UGET_RESULT_OK; + break; default: - return UGET_RESULT_UNSUPPORT; + // call parent's global_get() + return uget_plugin_agent_global_get(option, parameter); } return UGET_RESULT_OK; @@ -220,109 +149,46 @@ // ---------------------------------------------------------------------------- // control functions -static void plugin_init (UgetPluginMedia* plugin) +static void plugin_init(UgetPluginMedia* plugin) { - if (global.plugin_info == NULL) - global_init (); - else - global_ref (); + // initialize UgetPluginAgent + uget_plugin_agent_init((UgetPluginAgent*) plugin); } -static void plugin_final (UgetPluginMedia* plugin) +static void plugin_final(UgetPluginMedia* plugin) { - // extent data and plug-in - if (plugin->target_node) - uget_node_unref (plugin->target_node); - if (plugin->target_node_child) - uget_node_unref (plugin->target_node_child); - if (plugin->target_plugin) - uget_plugin_unref (plugin->target_plugin); - // other data - ug_free (plugin->title); - // unassign node - if (plugin->node) - uget_node_unref (plugin->node); - - global_unref (); + ug_free(plugin->title); + uget_plugin_agent_final((UgetPluginAgent*) plugin); } // ---------------------------------------------------------------------------- // plugin_ctrl -static int plugin_ctrl_speed (UgetPluginMedia* plugin, int* speed); -static int plugin_start (UgetPluginMedia* plugin, UgetNode* node); +static UgThreadResult plugin_thread(UgetPluginMedia* plugin); -static int plugin_ctrl (UgetPluginMedia* plugin, int code, void* data) +static int plugin_ctrl(UgetPluginMedia* plugin, int code, void* data) { switch (code) { case UGET_PLUGIN_CTRL_START: - if (plugin->node == NULL) - return plugin_start (plugin, data); + if (plugin->target_info) { + return uget_plugin_agent_start((UgetPluginAgent*)plugin, + (UgThreadFunc)plugin_thread); + } break; - case UGET_PLUGIN_CTRL_STOP: - plugin->paused = TRUE; - return TRUE; - - case UGET_PLUGIN_CTRL_SPEED: - // speed control - return plugin_ctrl_speed (plugin, data); - - // output --------------- - case UGET_PLUGIN_CTRL_ACTIVE: - *(int*)data = (plugin->stopped) ? FALSE : TRUE; - return TRUE; - - // unused --------------- - case UGET_PLUGIN_CTRL_NODE_UPDATED: default: - break; + // call parent's plugin_ctrl() + return uget_plugin_agent_ctrl((UgetPluginAgent*)plugin, code, data); } return FALSE; } -static int plugin_ctrl_speed (UgetPluginMedia* plugin, int* speed) -{ - UgetCommon* common; - int value; - - // Don't do anything if speed limit keep no change. - if (plugin->limit[0] == speed[0] && plugin->limit[1] == speed[1]) - return TRUE; - // decide speed limit by user specified data. - if (plugin->node == NULL) { - plugin->limit[0] = speed[0]; - plugin->limit[1] = speed[1]; - } - else { - common = ug_info_realloc (&plugin->node->info, UgetCommonInfo); - // download - value = speed[0]; - if (common->max_download_speed) { - if (value > common->max_download_speed || value == 0) - value = common->max_download_speed; - } - plugin->limit[0] = value; - // upload - value = speed[1]; - if (common->max_upload_speed) { - if (value > common->max_upload_speed || value == 0) - value = common->max_upload_speed; - } - plugin->limit[1] = value; - } - // notify plug-in that speed limit has been changed - plugin->limit_changed = TRUE; - return TRUE; -} - // ---------------------------------------------------------------------------- // plugin_sync -static int sync_child_node (UgetNode* node, UgetNode* src, int src_is_active); -static int plugin_sync (UgetPluginMedia* plugin) +static int plugin_sync(UgetPluginMedia* plugin, UgInfo* node_info) { - UgetNode* node; + UgetFiles* files; UgetCommon* common; UgetProgress* progress; @@ -331,77 +197,50 @@ return FALSE; plugin->synced = TRUE; } - // avoid crash if plug-in plug-in failed to start. - if (plugin->node == NULL) - return TRUE; + // avoid crash if plug-in failed to start. + if (plugin->target_info == NULL) + return FALSE; + // sync data between plug-in and foreign UgData + common = ug_info_realloc(node_info, UgetCommonInfo); + // sum retry count + common->retry_count = plugin->target_common->retry_count + plugin->retry_count; - node = plugin->node; - // change node name by title ,item_index, and item_total + // change name by title ,item_index, and item_total if (plugin->named == FALSE && plugin->title) { plugin->named = TRUE; - ug_free (node->name); + ug_free(common->name); // decide to show "(current/total) title" or "title" if (plugin->item_total > 1) { - node->name = ug_strdup_printf ("(%d/%d) %s", + common->name = ug_strdup_printf("(%d/%d) %s", plugin->item_index + 1, plugin->item_total, plugin->title); } else - node->name = ug_strdup (plugin->title); + common->name = ug_strdup(plugin->title); } - // sync data between plug-in and node - common = ug_info_realloc (&node->info, UgetCommonInfo); - // sum retry count - common->retry_count = plugin->target_common->retry_count + plugin->retry_count; - // sync changed limit from UgetNode - if (plugin->target_common->max_upload_speed != common->max_upload_speed || - plugin->target_common->max_download_speed != common->max_download_speed) - { - plugin->target_common->max_upload_speed = common->max_upload_speed; - plugin->target_common->max_download_speed = common->max_download_speed; - } - plugin->target_common->max_connections = common->max_connections; - plugin->target_common->retry_limit = common->retry_limit; - + // sync common data (include speed limit) between foreign data and target_info + uget_plugin_agent_sync_common((UgetPluginAgent*) plugin, + common, plugin->target_common); // downloading file name changed if (plugin->file_renamed == TRUE) { plugin->file_renamed = FALSE; - ug_mutex_lock (&plugin->mutex); - ug_free (common->file); - common->file = ug_strdup (plugin->target_common->file); - ug_mutex_unlock (&plugin->mutex); - } - // sync child node from target_node_child - if (plugin->sync_child == TRUE) { - plugin->sync_child = FALSE; - ug_mutex_lock (&plugin->mutex); - sync_child_node (node, plugin->target_node_child, - (plugin->stopped) ? FALSE : TRUE); - ug_mutex_unlock (&plugin->mutex); - } - // sync changed limit from UgetNode to plug-in - if (plugin->target_common->max_upload_speed != common->max_upload_speed || - plugin->target_common->max_download_speed != common->max_download_speed) - { - plugin->target_common->max_upload_speed = common->max_upload_speed; - plugin->target_common->max_download_speed = common->max_download_speed; - plugin->limit_changed = TRUE; - } - plugin->target_common->max_connections = common->max_connections; - plugin->target_common->retry_limit = common->retry_limit; - - // update progress - progress = ug_info_realloc (&node->info, UgetProgressInfo); - progress->complete = plugin->target_progress->complete; - progress->total = plugin->target_progress->total; - progress->download_speed = plugin->target_progress->download_speed; - progress->upload_speed = plugin->target_progress->upload_speed; - progress->uploaded = plugin->target_progress->uploaded; - progress->elapsed = plugin->target_progress->elapsed; - progress->percent = plugin->target_progress->percent; - progress->left = plugin->target_progress->left; + uget_plugin_lock(plugin); + ug_free(common->file); + common->file = ug_strdup(plugin->target_common->file); + uget_plugin_unlock(plugin); + } + // update UgetFiles + files = ug_info_realloc(node_info, UgetFilesInfo); + uget_plugin_lock(plugin); + uget_files_sync(files, plugin->target_files); + uget_plugin_unlock(plugin); + + // sync progress data from target_info to foreign data + progress = ug_info_realloc(node_info, UgetProgressInfo); + uget_plugin_agent_sync_progress((UgetPluginAgent*) plugin, + progress, plugin->target_progress); // recount progress if plug-in download multiple files if (plugin->item_total > 1) { // recount percent @@ -425,57 +264,29 @@ // ---------------------------------------------------------------------------- -static UG_THREAD_RETURN_TYPE plugin_thread (UgetPluginMedia* plugin); - -static int plugin_start (UgetPluginMedia* plugin, UgetNode* node) +static int plugin_accept(UgetPluginMedia* plugin, UgInfo* node_info) { - int ok; - UgThread thread; UgetCommon* common; - common = ug_info_get (&node->info, UgetCommonInfo); + common = ug_info_get(node_info, UgetCommonInfo); if (common == NULL || common->uri == NULL) return FALSE; - plugin->target_node = uget_node_new (NULL); - ug_info_assign (&plugin->target_node->info, &node->info, NULL); - plugin->target_common = ug_info_get (&plugin->target_node->info, UgetCommonInfo); - plugin->target_proxy = ug_info_get (&plugin->target_node->info, UgetProxyInfo); - plugin->target_progress = ug_info_realloc (&plugin->target_node->info, UgetProgressInfo); - - // assign node - uget_node_ref (node); - plugin->node = node; - - // try to start thread - plugin->paused = FALSE; - plugin->stopped = FALSE; - uget_plugin_ref ((UgetPlugin*) plugin); - ok = ug_thread_create (&thread, (UgThreadFunc) plugin_thread, plugin); - if (ok == UG_THREAD_OK) - ug_thread_unjoin (&thread); - else { - // failed to start thread ----------------- - plugin->paused = TRUE; - plugin->stopped = TRUE; - // don't assign node - uget_node_unref (plugin->node); - plugin->node = NULL; - // post error message and decreases the reference count - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error (UGET_EVENT_ERROR_THREAD_CREATE_FAILED, - NULL)); - uget_plugin_unref ((UgetPlugin*) plugin); - return FALSE; - } + plugin->target_info = ug_info_new(8, 0); + ug_info_assign(plugin->target_info, node_info, NULL); + plugin->target_files = ug_info_realloc(plugin->target_info, UgetFilesInfo); + plugin->target_common = ug_info_get(plugin->target_info, UgetCommonInfo); + plugin->target_proxy = ug_info_get(plugin->target_info, UgetProxyInfo); + plugin->target_progress = ug_info_realloc(plugin->target_info, UgetProgressInfo); return TRUE; } -static int is_file_completed (const char* file, const char* folder); +static int is_file_completed(const char* file, const char* folder); -static UG_THREAD_RETURN_TYPE plugin_thread (UgetPluginMedia* plugin) +static UgThreadResult plugin_thread(UgetPluginMedia* plugin) { + UgetPluginInfo* plugin_info; UgetMedia* umedia; UgetMediaItem* umitem; UgetCommon* common; @@ -486,51 +297,49 @@ const char* quality = NULL; common = plugin->target_common; - umedia = uget_media_new (common->uri, 0); - if (uget_media_grab_items (umedia, plugin->target_proxy) == 0) { + umedia = uget_media_new(common->uri, 0); + if (uget_media_grab_items(umedia, plugin->target_proxy) == 0) { if (umedia->event) { - uget_plugin_post ((UgetPlugin*) plugin, umedia->event); + uget_plugin_post((UgetPlugin*) plugin, umedia->event); umedia->event = NULL; } else { - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error (UGET_EVENT_ERROR_CUSTOM, - _("Failed to get media link."))); + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_error(UGET_EVENT_ERROR_CUSTOM, + _("Failed to get media link."))); } goto exit; } - // tell plugin_sync() to change node name + // tell plugin_sync() to change foreign UgetCommon::name if (umedia->title) { plugin->title = umedia->title; umedia->title = NULL; plugin->synced = FALSE; } - umitem = uget_media_match (umedia, global.match_mode, - global.quality, global.type); + umitem = uget_media_match(umedia, global.match_mode, + global.quality, global.type); if (umitem == NULL) { - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error (UGET_EVENT_ERROR_CUSTOM, - _("No matched media."))); + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_error(UGET_EVENT_ERROR_CUSTOM, + _("No matched media."))); goto exit; } // set item_index and item_total plugin->item_index = 0; plugin->item_total = umedia->size - - ug_list_position ((UgList*) umedia, (UgLink*) umitem); + ug_list_position((UgList*) umedia, (UgLink*) umitem); // set HTTP referrer - http = ug_info_realloc (&plugin->target_node->info, UgetHttpInfo); + http = ug_info_realloc(plugin->target_info, UgetHttpInfo); if (http->referrer == NULL) - http->referrer = ug_strdup_printf ("%s%s", common->uri, "# "); + http->referrer = ug_strdup_printf("%s%s", common->uri, "# "); // clear copied common URI - ug_free (common->uri); + ug_free(common->uri); common->uri = NULL; // reset grand total data plugin->elapsed = 0; plugin->retry_count = 0; - // create children node - plugin->target_node_child = uget_node_new (NULL); for (; umitem; umitem = umitem->next) { // stop this loop when user paused this plug-in. @@ -580,23 +389,23 @@ } // generate file name by title, quality, and type. - ug_mutex_lock (&plugin->mutex); - ug_free (common->file); - common->file = ug_strdup_printf ("%s_%s.%s", + uget_plugin_lock(plugin); + ug_free(common->file); + common->file = ug_strdup_printf("%s_%s.%s", (plugin->title) ? plugin->title : "unknown", quality, type); - ug_str_replace_chars (common->file, "\\/:*?\"<>|", '_'); - ug_mutex_unlock (&plugin->mutex); + ug_str_replace_chars(common->file, "\\/:*?\"<>|", '_'); + uget_plugin_unlock(plugin); plugin->file_renamed = TRUE; // skip completed file - if (is_file_completed (common->file, common->folder)) + if (is_file_completed(common->file, common->folder)) continue; // use media link to replace common->uri common->uri = umitem->url; - // tell plugin_sync() to change node name + // tell plugin_sync() to change foreign UgetCommon::name plugin->named = FALSE; // save/reset retry count plugin->retry_count += common->retry_count; @@ -605,36 +414,33 @@ plugin->elapsed += plugin->target_progress->elapsed; plugin->target_progress->elapsed = 0; + uget_plugin_agent_global_get(UGET_PLUGIN_AGENT_GLOBAL_PLUGIN, + &plugin_info); // create target_plugin to download - plugin->target_plugin = uget_plugin_new (global.plugin_info); - uget_plugin_ctrl_speed (plugin->target_plugin, plugin->limit); - if (uget_plugin_start (plugin->target_plugin, plugin->target_node) == FALSE) { - msg = uget_event_new_error (UGET_EVENT_ERROR_THREAD_CREATE_FAILED, - NULL); - uget_plugin_post ((UgetPlugin*) plugin, msg); + plugin->target_plugin = uget_plugin_new(plugin_info); + uget_plugin_accept(plugin->target_plugin, plugin->target_info); + uget_plugin_ctrl_speed(plugin->target_plugin, plugin->limit); + if (uget_plugin_start(plugin->target_plugin) == FALSE) { + msg = uget_event_new_error(UGET_EVENT_ERROR_THREAD_CREATE_FAILED, + NULL); + uget_plugin_post((UgetPlugin*) plugin, msg); } do { // sleep 0.5 second - ug_sleep (500); + ug_sleep(500); // stop target_plugin when user paused this plug-in. if (plugin->paused) { - uget_plugin_stop (plugin->target_plugin); + uget_plugin_stop(plugin->target_plugin); break; } if (plugin->limit_changed) { plugin->limit_changed = FALSE; - uget_plugin_ctrl_speed (plugin->target_plugin, plugin->limit); + uget_plugin_ctrl_speed(plugin->target_plugin, plugin->limit); } - // sync child(file) node from target_node to target_node_child - ug_mutex_lock (&plugin->mutex); - plugin->sync_child = sync_child_node (plugin->target_node_child, - plugin->target_node, TRUE); - ug_mutex_unlock (&plugin->mutex); - // move event from target_plugin to plug-in - msg = uget_plugin_pop ((UgetPlugin*) plugin->target_plugin); + msg = uget_plugin_pop((UgetPlugin*) plugin->target_plugin); for (; msg; msg = msg_next) { msg_next = msg->next; msg->prev = NULL; @@ -655,111 +461,64 @@ case UGET_EVENT_STOP: case UGET_EVENT_COMPLETED: // discard message - uget_event_free (msg); + uget_event_free(msg); continue; } // post event to plug-in - uget_plugin_post ((UgetPlugin*) plugin, msg); + uget_plugin_post((UgetPlugin*) plugin, msg); } // sync data in plugin_sync() plugin->synced = FALSE; - } while (uget_plugin_sync (plugin->target_plugin)); - - // sync file node - ug_mutex_lock (&plugin->mutex); - plugin->sync_child = sync_child_node (plugin->target_node_child, - plugin->target_node, FALSE); - ug_mutex_unlock (&plugin->mutex); + uget_plugin_lock(plugin); + uget_plugin_sync(plugin->target_plugin, + plugin->target_info); + uget_plugin_unlock(plugin); + } while (uget_plugin_get_state(plugin->target_plugin)); // free target_plugin - uget_plugin_unref ((UgetPlugin*) plugin->target_plugin); + uget_plugin_unref(plugin->target_plugin); plugin->target_plugin = NULL; } common->uri = NULL; // Don't free common->uri again. if (plugin->paused == FALSE && umitem == NULL) { - plugin->node->state |= UGET_STATE_COMPLETED; - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new (UGET_EVENT_COMPLETED)); + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new(UGET_EVENT_COMPLETED)); } - uget_plugin_post ((UgetPlugin*)plugin, - uget_event_new (UGET_EVENT_STOP)); + uget_plugin_post((UgetPlugin*)plugin, + uget_event_new(UGET_EVENT_STOP)); exit: plugin->stopped = TRUE; - uget_media_free (umedia); - uget_plugin_unref ((UgetPlugin*) plugin); - return UG_THREAD_RETURN_VALUE; + uget_media_free(umedia); + uget_plugin_unref((UgetPlugin*) plugin); + return UG_THREAD_RESULT; } -static int is_file_completed (const char* file, const char* folder) +static int is_file_completed(const char* file, const char* folder) { char* path; char* temp; int result = FALSE; if (folder == NULL) - path = ug_strdup (file); + path = ug_strdup(file); else - path = ug_build_filename (folder, file, NULL); + path = ug_build_filename(folder, file, NULL); - if (ug_file_is_exist (path)) { - temp = ug_strdup_printf ("%s.%s", path, "aria2"); - ug_free (path); + if (ug_file_is_exist(path)) { + temp = ug_strdup_printf("%s.%s", path, "aria2"); + ug_free(path); path = temp; - if (ug_file_is_exist (path) == FALSE) + if (ug_file_is_exist(path) == FALSE) result = TRUE; } // debug // if (result) -// printf ("%s is completed\n", path); +// printf("%s is completed\n", path); - ug_free (path); + ug_free(path); return result; } - -static int sync_child_node (UgetNode* node, UgetNode* src, int src_is_active) -{ - UgetNode* node_child; - UgetNode* src_child; - UgetNode* new_child; - int link_changed = FALSE; - - for (src_child = src->children; src_child; src_child = src_child->next) { - for (node_child = node->children; node_child; node_child = node_child->next) { - if (strcmp (src_child->name, node_child->name) == 0) - break; - } - // if found node that has the same name - if (node_child) { - // clear UGET_STATE_ACTIVE if not active - if (src_is_active == FALSE) - node_child->state = 0; - } - else { - link_changed = TRUE; - // add new node if not found - new_child = uget_node_new (NULL); - new_child->name = ug_strdup (src_child->name); - new_child->type = src_child->type; - new_child->state = (src_is_active) ? UGET_STATE_ACTIVE : 0; - uget_node_prepend (node, new_child); - } - } - - // delete unused/removed file node - if (src_is_active == FALSE) { - for (node_child = node->children; node_child; node_child = new_child) { - new_child = node_child->next; - if (node_child->state == UGET_STATE_ACTIVE) { - uget_node_remove (node, node_child); - uget_node_unref (node_child); - link_changed = TRUE; - } - } - } - - return link_changed; -} diff -Nru uget-2.2.0/uget/UgetPluginMedia.h uget-2.2.2/uget/UgetPluginMedia.h --- uget-2.2.0/uget/UgetPluginMedia.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetPluginMedia.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2016-2018 by C.H. Huang + * Copyright (C) 2016-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -37,50 +37,76 @@ #ifndef UGET_PLUGIN_MEDIA_H #define UGET_PLUGIN_MEDIA_H -#include +#include #include #ifdef __cplusplus extern "C" { #endif -typedef struct UgetPluginMedia UgetPluginMedia; +typedef struct UgetPluginMedia UgetPluginMedia; -typedef enum { - UGET_PLUGIN_MEDIA_BEGIN = UGET_PLUGIN_OPTION_DERIVED, // begin - - UGET_PLUGIN_MEDIA_DEFAULT_PLUGIN, // set parameter = (UgetPluginInfo*) - UGET_PLUGIN_MEDIA_MATCH_MODE, // set parameter = (UgetMediaMatchMode) - UGET_PLUGIN_MEDIA_QUALITY, // set parameter = (UgetMediaQuality) - UGET_PLUGIN_MEDIA_TYPE, // set parameter = (UgetMediaType) -} UgetPluginMediaCode; +extern const UgetPluginInfo* UgetPluginMediaInfo; -extern const UgetPluginInfo* UgetPluginMediaInfo; +typedef enum { + UGET_PLUGIN_MEDIA_GLOBAL = UGET_PLUGIN_AGENT_GLOBAL_DERIVED, // begin -// ---------------------------------------------------------------------------- -// UgetPluginMedia: It derived from UgetPlugin. + UGET_PLUGIN_MEDIA_GLOBAL_MATCH_MODE, // set parameter = (UgetMediaMatchMode) + UGET_PLUGIN_MEDIA_GLOBAL_QUALITY, // set parameter = (UgetMediaQuality) + UGET_PLUGIN_MEDIA_GLOBAL_TYPE, // set parameter = (UgetMediaType) +} UgetPluginMediaGlobalCode; + +/* ---------------------------------------------------------------------------- + UgetPluginMedia: It derived from UgetPluginAgent. + It use libcurl to get video info. + It use curl/aria2 plug-in to download media file. + + UgType + | + `--- UgetPlugin + | + `--- UgetPluginAgent + | + `--- UgetPluginMedia + */ struct UgetPluginMedia { - UGET_PLUGIN_MEMBERS; // It derived from UgetPlugin -// const UgetPluginInfo* info; -// UgetEvent* messages; -// UgMutex mutex; -// int ref_count; - - // pointer to UgetNode that store in UgetApp - UgetNode* node; - - // This plug-in use other plug-in to download media files, - // so we need extra UgetPlugin and UgetNode. - // plugin->target_node is a copy of plugin->node - UgetNode* target_node; - // copy child nodes from target_node - UgetNode* target_node_child; - // target_plugin use target_node to download + UGET_PLUGIN_AGENT_MEMBERS; +/* // ------ UgType members ------ + const UgetPluginInfo* info; + + // ------ UgetPlugin members ------ + UgetEvent* messages; + UgMutex mutex; + int ref_count; + + // ------ UgetPluginAgent members ------ + // This plug-in use other plug-in to download files, + // so we need extra UgetPlugin and UgInfo. + + // plugin->target_info is a copy of UgInfo that store in UgetApp + UgInfo* target_info; + // target_plugin use target_info to download UgetPlugin* target_plugin; - // copy of UgetNode data, they store in target_node + // speed limit control + // limit[0] = download speed limit + // limit[1] = upload speed limit + int limit[2]; + uint8_t limit_changed:1; // speed limit changed by user or program + + // control flags + uint8_t paused:1; // paused by user or program + uint8_t stopped:1; // all downloading thread are stopped + */ + + uint8_t synced:1; // used by plugin_sync() + uint8_t named:1; // change UgetCommon::name by title + uint8_t file_renamed:1; // downloading filename changed + + // These UgData store in plugin->target_info + UgetFiles* target_files; UgetProxy* target_proxy; UgetCommon* target_common; UgetProgress* target_progress; @@ -93,18 +119,6 @@ int retry_count; int item_index; // downloading nth files int item_total; // number of files to download - - // speed limit control - // limit[0] = download speed limit - // limit[1] = upload speed limit - int limit[2]; - uint8_t limit_changed:1; - uint8_t paused:1; // paused by user or program - uint8_t stopped:1; // all of downloading thread are stopped - uint8_t synced:1; // used by plugin_sync() - uint8_t named:1; // change node name by title - uint8_t file_renamed:1; // downloading filename changed - uint8_t sync_child:1; // target_node_child->children changed }; @@ -120,12 +134,18 @@ namespace Uget { +const PluginInfo* const PluginMediaInfo = (const PluginInfo*) UgetPluginMediaInfo; + // This one is for derived use only. No data members here. // Your derived struct/class must be C++11 standard-layout -struct PluginMediaMethod : Uget::PluginMethod {}; +struct PluginMediaMethod : PluginAgentMethod {}; // This one is for directly use only. You can NOT derived it. -struct PluginMedia : Uget::PluginMediaMethod, UgetPluginMedia {}; +struct PluginMedia : PluginMediaMethod, UgetPluginMedia +{ + inline void* operator new(size_t size) + { return uget_plugin_new(PluginMediaInfo); } +}; }; // namespace Uget diff -Nru uget-2.2.0/uget/UgetPluginMega.c uget-2.2.2/uget/UgetPluginMega.c --- uget-2.2.0/uget/UgetPluginMega.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetPluginMega.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2016-2018 by C.H. Huang + * Copyright (C) 2016-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -74,7 +74,7 @@ #define ug_sleep Sleep #else #include // usleep() -#define ug_sleep(millisecond) usleep (millisecond * 1000) +#define ug_sleep(millisecond) usleep(millisecond * 1000) #endif // _WIN32 || _WIN64 #ifdef HAVE_GLIB @@ -87,24 +87,25 @@ enum { - MEGA_UNKNOWN, + MEGA_INVALID, MEGA_FOLDER, MEGA_FILE, }; // ---------------------------------------------------------------------------- // MEGA site -static int mega_parse_url (UgetPluginMega* plugin, const char* url); -static int mega_request_info (UgetPluginMega* plugin, const char* id); -static int mega_decrypt_file (UgetPluginMega* plugin, int preset_progress); +static int mega_parse_url(UgetPluginMega* plugin, const char* url); +static int mega_request_info(UgetPluginMega* plugin, const char* id); +static int mega_decrypt_file(UgetPluginMega* plugin, int preset_progress); // ---------------------------------------------------------------------------- -// UgetPluginInfo (derived from UgDataInfo) +// UgetPluginInfo (derived from UgTypeInfo) -static void plugin_init (UgetPluginMega* plugin); -static void plugin_final (UgetPluginMega* plugin); -static int plugin_start (UgetPluginMega* plugin, UgetNode* node); -static int plugin_sync (UgetPluginMega* plugin); +static void plugin_init (UgetPluginMega* plugin); +static void plugin_final(UgetPluginMega* plugin); +static int plugin_accept(UgetPluginMega* plugin, UgInfo* node_info); +static int plugin_sync (UgetPluginMega* plugin, UgInfo* node_info); +static int plugin_ctrl (UgetPluginMega* plugin, int code, void* data); static const char* schemes[] = {"https", NULL}; static const char* hosts[] = {"mega.co.nz", "mega.nz", @@ -113,18 +114,17 @@ static const UgetPluginInfo UgetPluginMegaInfoStatic = { "mega", - sizeof (UgetPluginMega), - (const UgEntry*) NULL, + sizeof(UgetPluginMega), (UgInitFunc) plugin_init, (UgFinalFunc) plugin_final, - (UgAssignFunc) plugin_start, - (UgetPluginCtrlFunc) uget_plugin_agent_ctrl, + (UgetPluginSyncFunc) plugin_accept, (UgetPluginSyncFunc) plugin_sync, + (UgetPluginCtrlFunc) plugin_ctrl, hosts, schemes, NULL, - (UgetPluginSetFunc) uget_plugin_agent_global_set, - (UgetPluginGetFunc) uget_plugin_agent_global_get + (UgetPluginGlobalFunc) uget_plugin_agent_global_set, + (UgetPluginGlobalFunc) uget_plugin_agent_global_get }; // extern const UgetPluginInfo* UgetPluginMegaInfo = &UgetPluginMegaInfoStatic; @@ -132,64 +132,81 @@ // ---------------------------------------------------------------------------- // control functions -static void plugin_init (UgetPluginMega* plugin) +static void plugin_init(UgetPluginMega* plugin) { // initialize UgetPluginAgent - uget_plugin_agent_init ((UgetPluginAgent*)plugin); + uget_plugin_agent_init((UgetPluginAgent*)plugin); // initialize UgetPluginMega - ug_json_init (&plugin->json); - ug_value_init_object (&plugin->value, 5); + ug_json_init(&plugin->json); + ug_value_init_object(&plugin->value, 5); } -static void plugin_final (UgetPluginMega* plugin) +static void plugin_final(UgetPluginMega* plugin) { // finalize UgetPluginMega - ug_free (plugin->id); - ug_free (plugin->key); - ug_free (plugin->iv); - ug_free (plugin->url); - ug_free (plugin->file); - ug_json_final (&plugin->json); - ug_value_clear (&plugin->value); + ug_free(plugin->id); + ug_free(plugin->key); + ug_free(plugin->iv); + ug_free(plugin->url); + ug_free(plugin->file); + ug_json_final(&plugin->json); + ug_value_clear(&plugin->value); // finalize UgetPluginAgent - uget_plugin_agent_final ((UgetPluginAgent*)plugin); + uget_plugin_agent_final((UgetPluginAgent*)plugin); } // ---------------------------------------------------------------------------- -static UG_THREAD_RETURN_TYPE plugin_thread (UgetPluginMega* plugin); +static UgThreadResult plugin_thread(UgetPluginMega* plugin); -static int plugin_start (UgetPluginMega* plugin, UgetNode* node) +static int plugin_accept(UgetPluginMega* plugin, UgInfo* node_info) { UgetCommon* common; - common = ug_info_get (&node->info, UgetCommonInfo); + common = ug_info_get(node_info, UgetCommonInfo); if (common == NULL || common->uri == NULL) return FALSE; // parse MEGA URL - if (mega_parse_url (plugin, common->uri) != MEGA_FILE) { - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error (UGET_EVENT_ERROR_CUSTOM, - _("Can't handle this MEGA URL."))); + if (mega_parse_url(plugin, common->uri) != MEGA_FILE) { + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_error(UGET_EVENT_ERROR_CUSTOM, + _("Can't handle this MEGA URL."))); return FALSE; } - plugin->target_node = uget_node_new (NULL); - ug_info_assign (&plugin->target_node->info, &node->info, NULL); - plugin->target_proxy = ug_info_get (&plugin->target_node->info, UgetProxyInfo); - plugin->target_common = ug_info_get (&plugin->target_node->info, UgetCommonInfo); - plugin->target_progress = ug_info_realloc (&plugin->target_node->info, UgetProgressInfo); + plugin->target_info = ug_info_new(8, 0); + ug_info_assign(plugin->target_info, node_info, NULL); + plugin->target_files = ug_info_realloc(plugin->target_info, UgetFilesInfo); + plugin->target_proxy = ug_info_get(plugin->target_info, UgetProxyInfo); + plugin->target_common = ug_info_get(plugin->target_info, UgetCommonInfo); + plugin->target_progress = ug_info_realloc(plugin->target_info, UgetProgressInfo); - return uget_plugin_agent_start_thread ((UgetPluginAgent*)plugin, node, - (UgThreadFunc)plugin_thread); + return TRUE; +} + +int plugin_ctrl(UgetPluginMega* plugin, int code, void* data) +{ + switch (code) { + case UGET_PLUGIN_CTRL_START: + if (plugin->target_info) { + return uget_plugin_agent_start((UgetPluginAgent*)plugin, + (UgThreadFunc)plugin_thread); + } + break; + + default: + // call parent's plugin_ctrl() + return uget_plugin_agent_ctrl((UgetPluginAgent*)plugin, code, data); + } + return FALSE; } -static int is_downloaded (UgetPluginMega* plugin, UgetCommon* target_common); +static int is_downloaded(UgetPluginMega* plugin, UgetCommon* target_common); -static UG_THREAD_RETURN_TYPE plugin_thread (UgetPluginMega* plugin) +static UgThreadResult plugin_thread(UgetPluginMega* plugin) { UgetPluginInfo* plugin_info; UgetCommon* target_common; @@ -197,61 +214,62 @@ UgetEvent* msg; // get MEGA download URL & attributes - if (mega_request_info (plugin, plugin->id) == FALSE) { - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_error (UGET_EVENT_ERROR_CUSTOM, - _("Can't get download URL."))); + if (mega_request_info(plugin, plugin->id) == FALSE) { + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_error(UGET_EVENT_ERROR_CUSTOM, + _("Can't get download URL."))); goto exit; } target_common = plugin->target_common; // set MEGA download URL - ug_free (target_common->uri); + ug_free(target_common->uri); target_common->uri = plugin->url; plugin->url = NULL; // set MEGA output file name if (target_common->file == NULL) plugin->named = TRUE; else { - ug_free (plugin->file); - plugin->file = ug_strdup (target_common->file); + ug_free(plugin->file); + plugin->file = ug_strdup(target_common->file); } - ug_free (target_common->file); - target_common->file = ug_strdup_printf ("%s.enc", plugin->file); + ug_free(target_common->file); + target_common->file = ug_strdup_printf("%s.enc", plugin->file); // check existed file - if (is_downloaded (plugin, target_common) == TRUE) { - mega_decrypt_file (plugin, TRUE); + if (is_downloaded(plugin, target_common) == TRUE) { + mega_decrypt_file(plugin, TRUE); goto exit; } - uget_plugin_agent_global_get (UGET_PLUGIN_AGENT_DEFAULT_PLUGIN, &plugin_info); - + uget_plugin_agent_global_get(UGET_PLUGIN_AGENT_GLOBAL_PLUGIN, + &plugin_info); // create target_plugin to download - plugin->target_plugin = uget_plugin_new (plugin_info); - uget_plugin_ctrl_speed (plugin->target_plugin, plugin->limit); - if (uget_plugin_start (plugin->target_plugin, plugin->target_node) == FALSE) { - msg = uget_event_new_error (UGET_EVENT_ERROR_THREAD_CREATE_FAILED, - NULL); - uget_plugin_post ((UgetPlugin*) plugin, msg); + plugin->target_plugin = uget_plugin_new(plugin_info); + uget_plugin_accept(plugin->target_plugin, plugin->target_info); + uget_plugin_ctrl_speed(plugin->target_plugin, plugin->limit); + if (uget_plugin_start(plugin->target_plugin) == FALSE) { + msg = uget_event_new_error(UGET_EVENT_ERROR_THREAD_CREATE_FAILED, + NULL); + uget_plugin_post((UgetPlugin*) plugin, msg); goto exit; } do { // sleep 0.5 second - ug_sleep (500); + ug_sleep(500); // stop target_plugin when user paused this plug-in. if (plugin->paused) { - uget_plugin_stop (plugin->target_plugin); + uget_plugin_stop(plugin->target_plugin); break; } if (plugin->limit_changed) { plugin->limit_changed = FALSE; - uget_plugin_ctrl_speed (plugin->target_plugin, plugin->limit); + uget_plugin_ctrl_speed(plugin->target_plugin, plugin->limit); } // move event from target_plugin to plug-in - msg = uget_plugin_pop ((UgetPlugin*) plugin->target_plugin); + msg = uget_plugin_pop((UgetPlugin*) plugin->target_plugin); for (; msg; msg = msg_next) { msg_next = msg->next; msg->prev = NULL; @@ -267,117 +285,108 @@ case UGET_EVENT_NORMAL: // ignore "not resumable" event if (msg->value.code == UGET_EVENT_NORMAL_NOT_RESUMABLE) - uget_event_free (msg); + uget_event_free(msg); continue; case UGET_EVENT_STOP: case UGET_EVENT_COMPLETED: // discard message - uget_event_free (msg); + uget_event_free(msg); continue; } // post event to plug-in - uget_plugin_post ((UgetPlugin*) plugin, msg); + uget_plugin_post((UgetPlugin*) plugin, msg); } // sync data in plugin_sync() plugin->synced = FALSE; - } while (uget_plugin_agent_sync_plugin ((UgetPluginAgent*) plugin)); + uget_plugin_lock(plugin); + uget_plugin_sync(plugin->target_plugin, + plugin->target_info); + uget_plugin_unlock(plugin); + } while (uget_plugin_get_state(plugin->target_plugin)); // free target_plugin - uget_plugin_unref ((UgetPlugin*) plugin->target_plugin); + uget_plugin_unref(plugin->target_plugin); plugin->target_plugin = NULL; // if downloading completed, decrypt file if (plugin->paused == FALSE) - mega_decrypt_file (plugin, FALSE); + mega_decrypt_file(plugin, FALSE); exit: plugin->synced = FALSE; plugin->stopped = TRUE; - uget_plugin_post ((UgetPlugin*)plugin, - uget_event_new (UGET_EVENT_STOP)); - uget_plugin_unref ((UgetPlugin*) plugin); - return UG_THREAD_RETURN_VALUE; + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new(UGET_EVENT_STOP)); + uget_plugin_unref((UgetPlugin*) plugin); + return UG_THREAD_RESULT; } -static int plugin_sync (UgetPluginMega* plugin) +static int plugin_sync(UgetPluginMega* plugin, UgInfo* node_info) { - UgetNode* node; + UgetFiles* files; UgetCommon* common; UgetProgress* progress; - char* str; if (plugin->stopped) { if (plugin->synced) return FALSE; plugin->synced = TRUE; } - // avoid crash if plug-in plug-in failed to start. - if (plugin->node == NULL) - return TRUE; - - node = plugin->node; - - // -------------------------------- - // sync data between plugin->node and plugin->target_node - - // sync common data (include speed limit) between node and target_node - common = ug_info_realloc (&node->info, UgetCommonInfo); - uget_plugin_agent_sync_common ((UgetPluginAgent*) plugin, - common, plugin->target_common); - - // sync progress data from target_node to node - progress = ug_info_realloc (&node->info, UgetProgressInfo); - uget_plugin_agent_sync_progress ((UgetPluginAgent*) plugin, - progress, plugin->target_progress); + // avoid crash if plug-in failed to start. + if (plugin->target_common == NULL) + return FALSE; + + // sync common data (include speed limit) between foreign info and target_info + common = ug_info_realloc(node_info, UgetCommonInfo); + uget_plugin_agent_sync_common((UgetPluginAgent*) plugin, + common, plugin->target_common); + + // sync progress data from target_info to foreign info + progress = ug_info_realloc(node_info, UgetProgressInfo); + uget_plugin_agent_sync_progress((UgetPluginAgent*) plugin, + progress, plugin->target_progress); if (plugin->decrypting == FALSE) progress->percent = progress->percent * 96 / 100; - // sync child nodes from target_node to node - uget_plugin_agent_sync_children ((UgetPluginAgent*) plugin, - (plugin->stopped) ? FALSE : TRUE); - - // change child node's name if decrypting completed. - if (plugin->stopped && plugin->decrypting) { - if (plugin->node->children && plugin->node->children->name) { - str = strstr (plugin->node->children->name, ".enc"); - if (str != NULL) - str[0] = 0; - } - } + // update UgetFiles + files = ug_info_realloc(node_info, UgetFilesInfo); + uget_plugin_lock(plugin); + uget_files_sync(files, plugin->target_files); + uget_plugin_unlock(plugin); // plug-in has got file name from server. if (plugin->named) { plugin->named = FALSE; - ug_free (node->name); - node->name = ug_strdup (plugin->file); - ug_free (common->file); - common->file = ug_strdup (plugin->file); + ug_free(common->name); + common->name = ug_strdup(plugin->file); + ug_free(common->file); + common->file = ug_strdup(plugin->file); } // if plug-in was stopped, return FALSE. return TRUE; } -static int is_downloaded (UgetPluginMega* plugin, UgetCommon* target_common) +static int is_downloaded(UgetPluginMega* plugin, UgetCommon* target_common) { char* path; char* temp; // check existed file if (target_common->folder == NULL) - path = ug_strdup (target_common->file); + path = ug_strdup(target_common->file); else - path = ug_build_filename (target_common->folder, target_common->file, NULL); + path = ug_build_filename(target_common->folder, target_common->file, NULL); - if (ug_file_is_exist (path)) { + if (ug_file_is_exist(path)) { temp = path; - path = ug_strdup_printf ("%s.aria2", path); - ug_free (temp); - if (ug_file_is_exist (path) == FALSE) { - ug_free (path); + path = ug_strdup_printf("%s.aria2", path); + ug_free(temp); + if (ug_file_is_exist(path) == FALSE) { + ug_free(path); return TRUE; } - ug_free (path); + ug_free(path); } return FALSE; } @@ -385,57 +394,63 @@ // ---------------------------------------------------------------------------- // MEGA site -static void xor_(uint8_t* dest, uint8_t* src1, uint8_t* src2, int length) +static void xor_n(uint8_t* dest, uint8_t* src1, uint8_t* src2, int length) { for (; length > 0; length--) *dest++ = *src1++ ^ *src2++; } -static int mega_parse_url (UgetPluginMega* plugin, const char* url) +static int mega_parse_url(UgetPluginMega* plugin, const char* url) { uint8_t* binary_key; int length; + int result; - plugin->id = strchr (url, '!'); - if (plugin->id != NULL) { - // folder + plugin->id = strchr(url, '!'); + if (plugin->id == NULL) + return MEGA_INVALID; + else { + // folder or file if (plugin->id != url && *(plugin->id-1) == 'F') - return MEGA_FOLDER; - // file + result = MEGA_FOLDER; + else + result = MEGA_FILE; plugin->id++; - if (plugin->id[0] == 0) - return MEGA_UNKNOWN; } - plugin->key = strchr (plugin->id, '!'); - if (plugin->key != NULL) { + plugin->key = strchr(plugin->id, '!'); + if (plugin->key == NULL) + return MEGA_INVALID; + else { plugin->key++; if (plugin->key[0] == 0) - return MEGA_UNKNOWN; + return MEGA_INVALID; } // copy string from URL - plugin->id = ug_strndup (plugin->id, plugin->key - plugin->id - 1); - plugin->key = ug_strdup (plugin->key); - ug_str_replace_chars (plugin->key, "-", '+'); - ug_str_replace_chars (plugin->key, "_", '/'); - ug_str_remove_chars (plugin->key, plugin->key, ","); - ug_str_remove_chars (plugin->key, plugin->key, "\n"); - - binary_key = ug_base64_decode (plugin->key, strlen (plugin->key), &length); - if (length < 32) { - ug_free (binary_key); - return MEGA_UNKNOWN; - } - - plugin->key = ug_realloc (plugin->key, 16); - xor_ ((uint8_t*)plugin->key+0, binary_key+0, binary_key+16, 8); - xor_ ((uint8_t*)plugin->key+8, binary_key+8, binary_key+24, 8); - - plugin->iv = ug_malloc (16); - memcpy (plugin->iv, binary_key+16, 8); - memset (plugin->iv+8, 0, 8); - return MEGA_FILE; + plugin->id = ug_strndup(plugin->id, plugin->key - plugin->id - 1); + plugin->key = ug_strdup(plugin->key); + ug_str_replace_chars(plugin->key, "-", '+'); + ug_str_replace_chars(plugin->key, "_", '/'); + ug_str_remove_chars(plugin->key, plugin->key, ","); + ug_str_remove_chars(plugin->key, plugin->key, "\n"); + + binary_key = ug_base64_decode(plugin->key, strlen(plugin->key), &length); + plugin->key = ug_realloc(plugin->key, 16); + if (length == 16) + memcpy(plugin->key, binary_key, 16); + else if (length == 32) + xor_n((uint8_t*)plugin->key, binary_key, binary_key+16, 16); + else { + // "Invalid key, please verify your MEGA URL." + ug_free(binary_key); + return MEGA_INVALID; + } + + plugin->iv = ug_malloc(16); + memcpy(plugin->iv, binary_key+16, 8); + memset(plugin->iv+8, 0, 8); + return result; } // ------------------------------------ @@ -448,7 +463,7 @@ // n is filename -static int mega_parse_attributes (UgetPluginMega* plugin, char* attributes) +static int mega_parse_attributes(UgetPluginMega* plugin, char* attributes) { UgValue* member; char* iv; @@ -456,23 +471,23 @@ char* buffer; int length; - ug_str_replace_chars (attributes, "-", '+'); - ug_str_replace_chars (attributes, "_", '/'); - ug_str_remove_chars (attributes, attributes, ","); - ug_str_remove_chars (attributes, attributes, "\n"); - buffer = (char*)ug_base64_decode (attributes, strlen(attributes), &length); - iv = ug_malloc0 (16); + ug_str_replace_chars(attributes, "-", '+'); + ug_str_replace_chars(attributes, "_", '/'); + ug_str_remove_chars(attributes, attributes, ","); + ug_str_remove_chars(attributes, attributes, "\n"); + buffer = (char*)ug_base64_decode(attributes, strlen(attributes), &length); + iv = ug_malloc0(16); attr = NULL; #ifdef USE_OPENSSL { AES_KEY key; - attr = ug_malloc (length); - AES_set_decrypt_key ((uint8_t*)plugin->key, 128, &key); -// AES_cbc_decrypt (temp, attr, length, &key, iv, AES_DECRYPT); - CRYPTO_cbc128_decrypt ((uint8_t*)buffer, (uint8_t*)attr, length, - &key, (uint8_t*)iv, (block128_f)AES_decrypt); + attr = ug_malloc(length); + AES_set_decrypt_key((uint8_t*)plugin->key, 128, &key); +// AES_cbc_decrypt(temp, attr, length, &key, iv, AES_DECRYPT); + CRYPTO_cbc128_decrypt((uint8_t*)buffer, (uint8_t*)attr, length, + &key, (uint8_t*)iv, (block128_f)AES_decrypt); } #endif // USE_OPENSSL @@ -490,44 +505,44 @@ } #endif // USE_GNUTLS - ug_free (iv); - ug_free (buffer); + ug_free(iv); + ug_free(buffer); #ifndef NDEBUG - printf ("%.*s\n", length, attr); + printf("%.*s\n", length, attr); #endif // search JSON object - buffer = strchr (attr, '{'); + buffer = strchr(attr, '{'); if (buffer == NULL) { - ug_free (attr); + ug_free(attr); return FALSE; } length -= buffer - attr; // parse JSON object - ug_value_clear (&plugin->value); - ug_json_begin_parse (&plugin->json); - ug_json_push (&plugin->json, ug_json_parse_value, &plugin->value, NULL); - ug_json_parse (&plugin->json, buffer, length); - ug_json_end_parse (&plugin->json); - ug_free (attr); + ug_value_clear(&plugin->value); + ug_json_begin_parse(&plugin->json); + ug_json_push(&plugin->json, ug_json_parse_value, &plugin->value, NULL); + ug_json_parse(&plugin->json, buffer, length); + ug_json_end_parse(&plugin->json); + ug_free(attr); if (plugin->value.type != UG_VALUE_OBJECT) return FALSE; - ug_value_sort (&plugin->value, ug_value_compare_name); + ug_value_sort(&plugin->value, ug_value_compare_name); // get file name - member = ug_value_find_name (&plugin->value, "n"); + member = ug_value_find_name(&plugin->value, "n"); if (member == NULL || member->type != UG_VALUE_STRING) return FALSE; - plugin->file = ug_strdup (member->c.string); + plugin->file = ug_strdup(member->c.string); return TRUE; } // ------------------------------------ -// MEGA result +// MEGA file info result // [-9] = doesn't exist? // @@ -545,112 +560,117 @@ // g is download URL // s is size -static size_t curl_output_mega_result (char* text, size_t size, - size_t nmemb, UgetPluginMega* plugin) +static size_t curl_output_mega_result(char* text, size_t size, + size_t nmemb, UgetPluginMega* plugin) { size *= nmemb; - ug_json_parse (&plugin->json, text, size); + ug_json_parse(&plugin->json, text, size); #ifndef NDEBUG - printf ("%.*s\n", size, text); + printf("%.*s\n", size, text); #endif return size; } -static int mega_request_info (UgetPluginMega* plugin, const char* id) +static int mega_request_info(UgetPluginMega* plugin, const char* id) { CURL* curl; CURLcode code; UgValue* member; char* string; - ug_json_begin_parse (&plugin->json); - ug_json_push (&plugin->json, ug_json_parse_value, &plugin->value, NULL); - ug_json_push (&plugin->json, ug_json_parse_array, NULL, NULL); + ug_json_begin_parse(&plugin->json); + ug_json_push(&plugin->json, ug_json_parse_value, &plugin->value, NULL); + ug_json_push(&plugin->json, ug_json_parse_array, NULL, NULL); // setup option - string = ug_strdup_printf ("[{\"a\":\"g\",\"g\":1,\"p\":\"%s\"}]", id); - curl = curl_easy_init (); - curl_easy_setopt (curl, CURLOPT_URL, "https://eu.api.mega.co.nz/cs"); - curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (curl, CURLOPT_POST, 1L); - curl_easy_setopt (curl, CURLOPT_POSTFIELDS, string); - curl_easy_setopt (curl, CURLOPT_POSTFIELDSIZE, strlen (string)); - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0L); - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, curl_output_mega_result); - curl_easy_setopt (curl, CURLOPT_WRITEDATA, plugin); - ug_curl_set_proxy (curl, plugin->target_proxy); - code = curl_easy_perform (curl); - ug_free (string); + string = ug_strdup_printf("[{\"a\":\"g\",\"g\":1,\"p\":\"%s\"}]", id); + curl = curl_easy_init(); + curl_easy_setopt(curl, CURLOPT_URL, "https://eu.api.mega.co.nz/cs"); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, string); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(string)); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_output_mega_result); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, plugin); + ug_curl_set_proxy(curl, plugin->target_proxy); + code = curl_easy_perform(curl); + ug_free(string); if (code != CURLE_OK) return FALSE; - if (ug_json_end_parse (&plugin->json) != UG_JSON_ERROR_NONE) + if (ug_json_end_parse(&plugin->json) != UG_JSON_ERROR_NONE) return FALSE; if (plugin->value.type != UG_VALUE_OBJECT) return FALSE; - ug_value_sort (&plugin->value, ug_value_compare_name); + ug_value_sort(&plugin->value, ug_value_compare_name); // get download URL - member = ug_value_find_name (&plugin->value, "g"); + member = ug_value_find_name(&plugin->value, "g"); if (member == NULL || member->type != UG_VALUE_STRING) return FALSE; - plugin->url = ug_strdup (member->c.string); + plugin->url = ug_strdup(member->c.string); // get attributes - member = ug_value_find_name (&plugin->value, "at"); + member = ug_value_find_name(&plugin->value, "at"); if (member == NULL || member->type != UG_VALUE_STRING) return FALSE; - // mega_parse_attributes() will call ug_value_clear (&plugin->value); - mega_parse_attributes (plugin, member->c.string); + // mega_parse_attributes() will call ug_value_clear(&plugin->value); + mega_parse_attributes(plugin, member->c.string); return TRUE; } -int mega_decrypt_file (UgetPluginMega* plugin, int preset_progress) +int mega_decrypt_file(UgetPluginMega* plugin, int preset_progress) { + UgetFile* file; UgetCommon* target_common; - char* path; + char *path_in, *path_out; FILE *file_in, *file_out; target_common = plugin->target_common; + // decrypt input/output file --- + if (target_common->folder == NULL) { + path_out = ug_strdup(plugin->file); + path_in = ug_strdup(target_common->file); + } + else { + path_out = ug_build_filename(target_common->folder, plugin->file, NULL); + path_in = ug_build_filename(target_common->folder, target_common->file, NULL); + } // decrypt output file --- - if (target_common->folder == NULL) - path = ug_strdup (plugin->file); - else - path = ug_build_filename (target_common->folder, plugin->file, NULL); - file_out = ug_fopen (path, "wb"); - ug_free (path); - if (file_out == NULL) + file_out = ug_fopen(path_out, "wb"); + if (file_out == NULL) { + ug_free(path_out); + ug_free(path_in); return FALSE; + } // decrypt input file --- - if (target_common->folder == NULL) - path = ug_strdup (target_common->file); - else - path = ug_build_filename (target_common->folder, target_common->file, NULL); - file_in = ug_fopen (path, "rb"); + file_in = ug_fopen(path_in, "rb"); if (file_in == NULL) { - ug_free (path); - fclose (file_out); + ug_free(path_out); + ug_free(path_in); + fclose(file_out); return FALSE; } // preset progress before decrypting if (preset_progress == TRUE) { - fseek (file_in, 0L, SEEK_END); + fseek(file_in, 0L, SEEK_END); plugin->target_progress->percent = 96; - plugin->target_progress->complete = ftell (file_in); + plugin->target_progress->complete = ug_ftell(file_in); plugin->target_progress->total = plugin->target_progress->complete; - fseek (file_in, 0L, SEEK_SET); // rewind(file_in); + fseek(file_in, 0L, SEEK_SET); // rewind(file_in); } plugin->synced = FALSE; plugin->decrypting = TRUE; - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_normal (0, _("decrypting file..."))); + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_normal(0, _("decrypting file..."))); #ifdef USE_OPENSSL { @@ -661,33 +681,33 @@ unsigned char* data_out; unsigned char* ecount_buf; - data_in = ug_malloc (AES_BLOCK_SIZE * 3); + data_in = ug_malloc(AES_BLOCK_SIZE * 3); data_out = data_in + AES_BLOCK_SIZE; ecount_buf = data_out + AES_BLOCK_SIZE; // set to zeros before the first call to ctr128_encrypt - memset (ecount_buf, 0, AES_BLOCK_SIZE); + memset(ecount_buf, 0, AES_BLOCK_SIZE); num = 0; // CTR mode doesn't need separate encrypt and decrypt method. - AES_set_encrypt_key ((uint8_t*)plugin->key, 128, &aeskey); + AES_set_encrypt_key((uint8_t*)plugin->key, 128, &aeskey); while (1) { - length = fread (data_in, 1, AES_BLOCK_SIZE, file_in); + length = fread(data_in, 1, AES_BLOCK_SIZE, file_in); #if OPENSSL_VERSION_NUMBER >= 0x10100000L CRYPTO_ctr128_encrypt(data_in, data_out, length, &aeskey, (uint8_t*)plugin->iv, ecount_buf, &num, (block128_f)AES_encrypt); #else - AES_ctr128_encrypt (data_in, data_out, length, + AES_ctr128_encrypt(data_in, data_out, length, &aeskey, (uint8_t*)plugin->iv, ecount_buf, &num); #endif - fwrite (data_out, 1, length, file_out); + fwrite(data_out, 1, length, file_out); // decrypting progress - plugin->target_progress->complete = ftell (file_out); + plugin->target_progress->complete = ug_ftell(file_out); plugin->target_progress->percent = 96 + plugin->target_progress->complete * 4 / plugin->target_progress->total; plugin->synced = FALSE; @@ -696,7 +716,7 @@ break; } - ug_free (data_in); + ug_free(data_in); } #endif // USE_OPENSSL @@ -712,13 +732,13 @@ gcry_cipher_setiv(gchd, plugin->iv, 16); gcry_cipher_setctr(gchd, plugin->iv, 16); // counter vector - buffer = ug_malloc (16); + buffer = ug_malloc(16); while (1) { - length = fread (buffer, 1, 16, file_in); + length = fread(buffer, 1, 16, file_in); gcry_cipher_encrypt(gchd, buffer, length, NULL, 0); - fwrite (buffer, 1, length, file_out); + fwrite(buffer, 1, length, file_out); // decrypting progress - plugin->target_progress->complete = ftell (file_out); + plugin->target_progress->complete = ug_ftell(file_out); plugin->target_progress->percent = 96 + plugin->target_progress->complete * 4 / plugin->target_progress->total; plugin->synced = FALSE; @@ -726,25 +746,35 @@ if (length < 16) break; } - ug_free (buffer); + ug_free(buffer); gcry_cipher_close(gchd); } #endif // USE_GNUTLS - fclose (file_out); - fclose (file_in); - // decryption completed - ug_remove (path); - ug_free (path); + fclose(file_out); + fclose(file_in); + ug_remove(path_in); + + // update UgetFiles + uget_plugin_lock(plugin); + file = uget_files_realloc(plugin->target_files, path_in); + file->state |= UGET_FILE_STATE_DELETED; + file = uget_files_replace(plugin->target_files, path_out, + UGET_FILE_REGULAR, UGET_FILE_STATE_COMPLETED); + uget_plugin_unlock(plugin); + + // free path and update progress + ug_free(path_in); + ug_free(path_out); plugin->target_progress->percent = 100; - plugin->node->state |= UGET_STATE_COMPLETED; + // post message - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new_normal (0, _("decryption completed"))); - uget_plugin_post ((UgetPlugin*) plugin, - uget_event_new (UGET_EVENT_COMPLETED)); + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new_normal(0, _("decryption completed"))); + uget_plugin_post((UgetPlugin*) plugin, + uget_event_new(UGET_EVENT_COMPLETED)); return TRUE; } diff -Nru uget-2.2.0/uget/UgetPluginMega.h uget-2.2.2/uget/UgetPluginMega.h --- uget-2.2.0/uget/UgetPluginMega.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetPluginMega.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2016-2018 by C.H. Huang + * Copyright (C) 2016-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -47,51 +47,61 @@ extern "C" { #endif -typedef struct UgetPluginMega UgetPluginMega; +typedef struct UgetPluginMega UgetPluginMega; -extern const UgetPluginInfo* UgetPluginMegaInfo; +extern const UgetPluginInfo* UgetPluginMegaInfo; -// ---------------------------------------------------------------------------- -// UgetPluginMega: It derived from UgetPluginAgent. -// -// UgetPlugin -> UgetPluginAgent -> UgetPluginMega +/* ---------------------------------------------------------------------------- + UgetPluginMega: It derived from UgetPluginAgent. + It use libcurl to get download URL. + It use curl/aria2 plug-in to download file. + + UgType + | + `--- UgetPlugin + | + `--- UgetPluginAgent + | + `--- UgetPluginMega + */ struct UgetPluginMega { UGET_PLUGIN_AGENT_MEMBERS; +/* // ------ UgType members ------ + const UgetPluginInfo* info; // ------ UgetPlugin members ------ -// const UgetPluginInfo* info; -// UgetEvent* messages; -// UgMutex mutex; -// int ref_count; + UgetEvent* messages; + UgMutex mutex; + int ref_count; // ------ UgetPluginAgent members ------ - // pointer to UgetNode that store in UgetApp -// UgetNode* node; - // This plug-in use other plug-in to download files, - // so we need extra UgetPlugin and UgetNode. - // - // plugin->target_node is a copy of plugin->node -// UgetNode* target_node; - // target_plugin use target_node to download -// UgetPlugin* target_plugin; + // so we need extra UgetPlugin and UgInfo. + + // plugin->target_info is a copy of UgInfo that store in UgetApp + UgInfo* target_info; + // target_plugin use target_info to download + UgetPlugin* target_plugin; - // control flags // speed limit control // limit[0] = download speed limit // limit[1] = upload speed limit -// int limit[2]; -// uint8_t limit_changed:1; // speed limit changed by user -// uint8_t paused:1; // paused by user -// uint8_t stopped:1; // all downloading thread are stopped + int limit[2]; + uint8_t limit_changed:1; // speed limit changed by user or program - uint8_t named:1; // change node name + // control flags + uint8_t paused:1; // paused by user or program + uint8_t stopped:1; // all downloading thread are stopped + */ + + uint8_t named:1; // change UgetCommon::name uint8_t synced:1; // used by plugin_sync() uint8_t decrypting:1; // decrypting downloaded file - // copy of UgetNode data, they store in target_node + // These UgData store in target_info + UgetFiles* target_files; UgetProxy* target_proxy; UgetCommon* target_common; UgetProgress* target_progress; @@ -110,10 +120,35 @@ UgValue value; }; - - #ifdef __cplusplus } #endif +// ---------------------------------------------------------------------------- +// C++11 standard-layout + +#ifdef __cplusplus + +namespace Uget +{ + +const PluginInfo* const PluginMegaInfo = (const PluginInfo*) UgetPluginMegaInfo; + +// This one is for derived use only. No data members here. +// Your derived struct/class must be C++11 standard-layout +struct PluginMegaMethod : PluginAgentMethod {}; + +// This one is for directly use only. You can NOT derived it. +struct PluginMega : PluginMegaMethod, UgetPluginMega +{ + inline void* operator new(size_t size) + { return uget_plugin_new(PluginMegaInfo); } +}; + + +}; // namespace Uget + +#endif // __cplusplus + + #endif // End of UGET_PLUGIN_MEGA_H diff -Nru uget-2.2.0/uget/UgetRpc.c uget-2.2.2/uget/UgetRpc.c --- uget-2.2.0/uget/UgetRpc.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetRpc.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2015-2018 by C.H. Huang + * Copyright (C) 2015-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -42,6 +42,7 @@ #include #include #include +#include #define UGET_RPC_PORT "14777" #define UGET_RPC_ADDR "127.0.0.1" @@ -315,7 +316,7 @@ int result; int in_progress = FALSE; int opt_value; - int opt_length; + socklen_t opt_length; fd_set fdset; struct timeval timeout; diff -Nru uget-2.2.0/uget/UgetRpc.h uget-2.2.2/uget/UgetRpc.h --- uget-2.2.0/uget/UgetRpc.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetRpc.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2015-2018 by C.H. Huang + * Copyright (C) 2015-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -58,10 +58,12 @@ struct UgetRpc { UG_JSONRPC_SOCKET_MEMBERS; -// UgJson json; -// UgJsonrpc rpc; -// UgBuffer buffer; -// int socket; +/* // ------ UgJsonrpcSocket members ------ + UgJson json; + UgJsonrpc rpc; + UgBuffer buffer; + int socket; + */ UgSocketServer* server; UgJsonrpcObject jobject; @@ -107,10 +109,12 @@ struct UgetRpcReq { UGET_RPC_REQ_MEMBERS; // UgLink -// intptr_t method_id; -// UgetRpcReq* next; -// UgetRpcReq* prev; -// UgDeleteFunc free; +/* // ------ UgetRpcReq members ------ + intptr_t method_id; + UgetRpcReq* next; + UgetRpcReq* prev; + UgDeleteFunc free; + */ }; UgetRpcReq* uget_rpc_req_new (void); @@ -122,10 +126,12 @@ struct UgetRpcCmd { UGET_RPC_REQ_MEMBERS; // UgLink -// intptr_t method_id; -// UgetRpcReq* next; -// UgetRpcReq* prev; -// UgDeleteFunc free; +/* // ------ UgetRpcReq members ------ + intptr_t method_id; + UgetRpcReq* next; + UgetRpcReq* prev; + UgDeleteFunc free; + */ UgetOptionValue value; UgList uris; diff -Nru uget-2.2.0/uget/UgetRss.c uget-2.2.2/uget/UgetRss.c --- uget-2.2.0/uget/UgetRss.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetRss.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -369,7 +369,7 @@ return nmemb; } -static UG_THREAD_RETURN_TYPE uget_rss_thread (UgetRss* urss) +static UgThreadResult uget_rss_thread (UgetRss* urss) { CURL* curl; CURLcode res; @@ -415,7 +415,7 @@ urss->updating = FALSE; uget_rss_unref (urss); - return UG_THREAD_RETURN_VALUE; + return UG_THREAD_RESULT; } void uget_rss_update (UgetRss* urss, int joinable) diff -Nru uget-2.2.0/uget/UgetRss.h uget-2.2.2/uget/UgetRss.h --- uget-2.2.0/uget/UgetRss.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetRss.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -66,9 +66,12 @@ struct UgetRssItem { UG_LINK_MEMBERS (UgetRssItem, UgetRssItem, self); -// UgetRssItem* self; -// UgetRssItem* next; -// UgetRssItem* prev; +/* // ------ UgLink members ------ + UgetRssItem* self; + UgetRssItem* next; + UgetRssItem* prev; + */ + char* title; char* link; time_t updated; // pubDate @@ -84,9 +87,12 @@ struct UgetRssFeed { UG_LINK_MEMBERS (UgetRssFeed, UgetRssFeed, self); -// UgetRssFeed* self; -// UgetRssFeed* next; -// UgetRssFeed* prev; +/* // ------ UgLink members ------ + UgetRssFeed* self; + UgetRssFeed* next; + UgetRssFeed* prev; + */ + char* title; char* link; time_t updated; // pubDate diff -Nru uget-2.2.0/uget/UgetSequence.c uget-2.2.2/uget/UgetSequence.c --- uget-2.2.0/uget/UgetSequence.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetSequence.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2016-2018 by C.H. Huang + * Copyright (C) 2016-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -56,7 +56,12 @@ UgLinkString* link; link = ug_malloc (sizeof (UgLinkString) + length); + if (link == NULL) + return NULL; + link->data = link->string; + link->prev = NULL; + link->next = NULL; strcpy (link->string, string); return (UgLink*) link; } @@ -192,13 +197,16 @@ UgLink* link; int count; - for (count = 0; range->cur <= range->last; range->cur++, count++) { + for (count = 0; range->cur <= range->last; range->cur++) { if (range+1 <= useq->range_last) count += uget_sequence_generate (useq, pattern, range+1, result); else { uget_sequence_generate1 (useq, pattern); link = ug_link_string_new (useq->buf.beg, ug_buffer_length (&useq->buf)); + if (link == NULL) + break; ug_list_append (result, link); + count++; } } @@ -291,3 +299,8 @@ return 5; } +void uget_sequence_clear_result (UgList* result) +{ + ug_list_foreach_link(result, (UgForeachFunc)ug_free, NULL); + ug_list_clear(result, FALSE); +} diff -Nru uget-2.2.0/uget/UgetSequence.h uget-2.2.2/uget/UgetSequence.h --- uget-2.2.0/uget/UgetSequence.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetSequence.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2016-2018 by C.H. Huang + * Copyright (C) 2016-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -64,10 +64,12 @@ struct UgetSequence { UG_ARRAY_MEMBERS (UgetSeqRange); -// UgetSeqRange* at; -// int length; -// int allocated; -// int element_size; +/* // ------ UgArray members ------ + UgetSeqRange* at; + int length; + int allocated; + int element_size; + */ UgetSeqRange* range_last; // used by uget_sequence_get_list() UgBuffer buf; @@ -81,16 +83,17 @@ int uget_sequence_count (UgetSequence* useq, const char* pattern); -// call ug_list_foreach_link (result, (UgForeachFunc)ug_free, NULL) to free result list +// call uget_sequence_clear_result() to clear result list int uget_sequence_get_list (UgetSequence* useq, const char* pattern, UgList* result); int uget_sequence_get_preview (UgetSequence* useq, const char* pattern, UgList* result); - -// param: pattern is a string that contain wildcard character *. -// e.g. Number-*.jpg -// Number-0.jpg, Number-1.jpg ...etc -// Number-a.jpg, Number-b.jpg ...etc -// Number-A.jpg, Number-B.jpg ...etc - +void uget_sequence_clear_result (UgList* result); +/* + param: pattern is a string that contain wildcard character *. + e.g. Number-*.jpg + Number-0.jpg, Number-1.jpg ...etc + Number-a.jpg, Number-b.jpg ...etc + Number-A.jpg, Number-B.jpg ...etc + */ #ifdef __cplusplus } diff -Nru uget-2.2.0/uget/UgetSite.c uget-2.2.2/uget/UgetSite.c --- uget-2.2.0/uget/UgetSite.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetSite.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2018 by C.H. Huang + * Copyright (C) 2017-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uget/UgetSite.h uget-2.2.2/uget/UgetSite.h --- uget-2.2.0/uget/UgetSite.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetSite.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2018 by C.H. Huang + * Copyright (C) 2017-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uget/UgetTask.c uget-2.2.2/uget/UgetTask.c --- uget-2.2.0/uget/UgetTask.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetTask.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -40,27 +40,32 @@ #include // static function -static int uget_task_dispatch1 (UgetTask* task, UgetNode* node, UgetPlugin* plugin); +static int uget_task_dispatch1(UgetTask* task, UgetNode* node, UgetPlugin* plugin); -void uget_task_init (UgetTask* task) +void uget_task_init(UgetTask* task) { int count; - ug_slinks_init ((UgSLinks*) task, 32); + ug_slinks_init((UgSLinks*) task, 32); for (count = 0; count < UGET_TASK_N_WATCH; count++) { task->watch[count].func = NULL; task->watch[count].data = NULL; } + // current speed & speed limit + task->speed.download = 0; + task->speed.upload = 0; + task->limit.download = 0; + task->limit.upload = 0; } -void uget_task_final (UgetTask* task) +void uget_task_final(UgetTask* task) { - uget_task_remove_all (task); -// ug_slinks_final ((UgSLinks*) task); - ug_array_clear (task); + uget_task_remove_all(task); +// ug_slinks_final((UgSLinks*) task); + ug_array_clear(task); } -int uget_task_add (UgetTask* task, UgetNode* node, const UgetPluginInfo* info) +int uget_task_add(UgetTask* task, UgetNode* node, const UgetPluginInfo* info) { UgetRelation* relation; int dlul_int_array[2]; @@ -71,12 +76,12 @@ } temp; // UgetRelation: check exist plug-in - relation = ug_info_realloc (&node->info, UgetRelationInfo); - if (relation->task.plugin) + relation = ug_info_realloc(node->info, UgetRelationInfo); + if (relation->task) return FALSE; // UgetProgress: clear progress when it completed - temp.progress = ug_info_get (&node->info, UgetProgressInfo); + temp.progress = ug_info_get(node->info, UgetProgressInfo); if (temp.progress) { // reset progress if it's percent is 100%. if (temp.progress->percent == 100) { @@ -90,12 +95,14 @@ } // UgetCommon: clear retry_count - temp.common = ug_info_get (&node->info, UgetCommonInfo); + temp.common = ug_info_get(node->info, UgetCommonInfo); if (temp.common) temp.common->retry_count = 0; // create plug-in and control it - relation->task.plugin = uget_plugin_new (info); + relation->task = ug_malloc0(sizeof(struct UgetRelationTask)); + relation->task->plugin = uget_plugin_new(info); + uget_plugin_accept(relation->task->plugin, node->info); if (task->limit.download || task->limit.upload) { // backup current speed limit temp_int_array[0] = task->limit.download; @@ -103,80 +110,90 @@ // set speed limit for existing task dlul_int_array[0] = task->limit.download / (task->n_links + 1); dlul_int_array[1] = task->limit.upload / (task->n_links + 1); - uget_task_set_speed (task, - temp_int_array[0] - dlul_int_array[0], - temp_int_array[1] - dlul_int_array[1]); + uget_task_set_speed(task, + temp_int_array[0] - dlul_int_array[0], + temp_int_array[1] - dlul_int_array[1]); // set speed limit for new task - uget_plugin_ctrl_speed (relation->task.plugin, dlul_int_array); + uget_plugin_ctrl_speed(relation->task->plugin, dlul_int_array); // restore current speed limit task->limit.download = temp_int_array[0]; task->limit.upload = temp_int_array[1]; } - if (uget_plugin_start (relation->task.plugin, node) == FALSE) { + if (uget_plugin_start(relation->task->plugin) == FALSE) { // dispatch error message from plug-in - uget_task_dispatch1 (task, node, relation->task.plugin); + uget_task_dispatch1(task, node, relation->task->plugin); // release plug-in - uget_plugin_unref (relation->task.plugin); - relation->task.plugin = NULL; + uget_plugin_unref(relation->task->plugin); + // free task runtime data + ug_free(relation->task); + relation->task = NULL; return FALSE; } - relation->task.plugin_name = ug_strdup (info->name); - ug_slinks_add ((UgSLinks*) task, node); + ug_slinks_add((UgSLinks*) task, node); return TRUE; } -int uget_task_remove (UgetTask* task, UgetNode* node) +int uget_task_remove(UgetTask* task, UgetNode* node) { UgSLink* prev; UgetRelation* relation; - if (ug_slinks_find ((UgSLinks*) task, node, &prev)) { - ug_slinks_remove ((UgSLinks*) task, node, prev); - node->state &= ~UGET_STATE_ACTIVE; + if (ug_slinks_find((UgSLinks*) task, node, &prev)) { + ug_slinks_remove((UgSLinks*) task, node, prev); // UgetRelation - relation = ug_info_get (&node->info, UgetRelationInfo); + relation = ug_info_get(node->info, UgetRelationInfo); if (relation) { -// uget_plugin_post (relation->task.plugin, -// uget_event_new_state (node, UGET_STATE_QUEUING)); - uget_plugin_stop (relation->task.plugin); - uget_plugin_unref (relation->task.plugin); - relation->task.plugin = NULL; +// uget_plugin_post(relation->task->plugin, +// uget_event_new_state(node, UGET_GROUP_QUEUING)); + uget_plugin_stop(relation->task->plugin); + uget_plugin_unref(relation->task->plugin); + relation->group &= ~UGET_GROUP_ACTIVE; + // free task runtime data + ug_free(relation->task); + relation->task = NULL; } return TRUE; } return FALSE; } -void uget_task_remove_all (UgetTask* task) +void uget_task_remove_all(UgetTask* task) { while (task->used) - uget_task_remove (task, task->used->data); + uget_task_remove(task, task->used->data); } -static int uget_task_dispatch1 (UgetTask* task, UgetNode* node, UgetPlugin* plugin) +static int uget_task_dispatch1(UgetTask* task, UgetNode* node, UgetPlugin* plugin) { + UgetRelation* relation; UgetEvent* event; UgetEvent* next; int active; union { int count; UgetLog* log; + UgetFiles* files; } temp; - active = uget_plugin_sync (plugin); + active = uget_plugin_sync(plugin, node->info); + // update UgetFiles + temp.files = ug_info_get(node->info, UgetFilesInfo); + if (temp.files) + uget_files_erase_deleted(temp.files); // plug-in was paused by user (see function uget_app_pause_download) - if (node->state & UGET_STATE_PAUSED) + relation = ug_info_realloc(node->info, UgetRelationInfo); + if (relation->group & UGET_GROUP_PAUSED) active = FALSE; // plug-in has stopped if uget_plugin_sync() return FALSE. if (active == FALSE) - node->state &= ~UGET_STATE_ACTIVE; + relation->group &= ~UGET_GROUP_ACTIVE; - event = uget_plugin_pop (plugin); + event = uget_plugin_pop(plugin); for (; event; event = next) { for (temp.count = 0; temp.count < UGET_TASK_N_WATCH; temp.count++) { if (task->watch[temp.count].func) { - task->watch[temp.count].func (task, event, + task->watch[temp.count].func(task, event, node, task->watch[temp.count].data); } } @@ -188,36 +205,41 @@ switch (event->type) { case UGET_EVENT_ERROR: - node->state |= UGET_STATE_ERROR; // don't break here + relation->group |= UGET_GROUP_ERROR; // don't break here case UGET_EVENT_WARNING: case UGET_EVENT_NORMAL: - temp.log = ug_info_realloc (&node->info, UgetLogInfo); - ug_list_prepend (&temp.log->messages, (UgLink*) event); + temp.log = ug_info_realloc(node->info, UgetLogInfo); + ug_list_prepend(&temp.log->messages, (UgLink*) event); break; case UGET_EVENT_START: - node->state |= UGET_STATE_ACTIVE; - uget_event_free (event); + relation->group |= UGET_GROUP_ACTIVE; + uget_event_free(event); break; case UGET_EVENT_STOP: - node->state &= ~UGET_STATE_ACTIVE; - uget_event_free (event); + relation->group &= ~UGET_GROUP_ACTIVE; + uget_event_free(event); active = FALSE; break; -#if 0 case UGET_EVENT_COMPLETED: - node->state |= UGET_STATE_COMPLETED; - uget_event_free (event); + relation->group |= UGET_GROUP_COMPLETED; + uget_event_free(event); + break; + + case UGET_EVENT_UPLOADING: + relation->group |= UGET_GROUP_UPLOADING; + uget_event_free(event); + break; + + case UGET_EVENT_STOP_UPLOADING: + relation->group &= ~UGET_GROUP_UPLOADING; + uget_event_free(event); break; -#endif -// case UGET_EVENT_INFO: -// case UGET_EVENT_REMOVE: -// case UGET_EVENT_INSERT: default: - uget_event_free (event); + uget_event_free(event); break; } } @@ -225,7 +247,7 @@ return active; } -void uget_task_dispatch (UgetTask* task) +void uget_task_dispatch(UgetTask* task) { UgSLink* link; UgetNode* node; @@ -237,21 +259,21 @@ for (link = task->used; link; link = link->next) { node = link->data; - relation = ug_info_get (&node->info, UgetRelationInfo); - if (uget_task_dispatch1 (task, node, relation->task.plugin) == FALSE) + relation = ug_info_get(node->info, UgetRelationInfo); + if (uget_task_dispatch1(task, node, relation->task->plugin) == FALSE) continue; // speed - progress = ug_info_get (&node->info, UgetProgressInfo); + progress = ug_info_get(node->info, UgetProgressInfo); if (progress) { task->speed.download += progress->download_speed; task->speed.upload += progress->upload_speed; - relation->task.speed[0] = progress->download_speed; - relation->task.speed[1] = progress->upload_speed; + relation->task->speed[0] = progress->download_speed; + relation->task->speed[1] = progress->upload_speed; } } } -void uget_task_add_watch (UgetTask* task, UgetWatchFunc func, void* data) +void uget_task_add_watch(UgetTask* task, UgetWatchFunc func, void* data) { int count; @@ -269,38 +291,38 @@ #define SPEED_MIN 512 -static void uget_task_disable_limit_index (UgetTask* task, int idx); -static void uget_task_adjust_speed_index (UgetTask* task, int idx, int limit_new); +static void uget_task_disable_limit_index(UgetTask* task, int idx); +static void uget_task_adjust_speed_index(UgetTask* task, int idx, int limit_new); -void uget_task_set_speed (UgetTask* task, int dl_speed, int ul_speed) +void uget_task_set_speed(UgetTask* task, int dl_speed, int ul_speed) { // download task->limit.download = dl_speed; if (dl_speed == 0) - uget_task_disable_limit_index (task, 0); + uget_task_disable_limit_index(task, 0); else if (task->n_links > 0) - uget_task_adjust_speed_index (task, 0, dl_speed - task->speed.download); + uget_task_adjust_speed_index(task, 0, dl_speed - task->speed.download); // upload task->limit.upload = ul_speed; if (ul_speed == 0) - uget_task_disable_limit_index (task, 1); + uget_task_disable_limit_index(task, 1); else if (task->n_links > 0) - uget_task_adjust_speed_index (task, 1, ul_speed - task->speed.upload); + uget_task_adjust_speed_index(task, 1, ul_speed - task->speed.upload); } -void uget_task_adjust_speed (UgetTask* task) +void uget_task_adjust_speed(UgetTask* task) { if (task->n_links == 0) return; if (task->limit.download > 0) - uget_task_adjust_speed_index (task, 0, task->limit.download - task->speed.download); + uget_task_adjust_speed_index(task, 0, task->limit.download - task->speed.download); if (task->limit.upload > 0) - uget_task_adjust_speed_index (task, 1, task->limit.upload - task->speed.upload); + uget_task_adjust_speed_index(task, 1, task->limit.upload - task->speed.upload); } -static void uget_task_adjust_speed_index (UgetTask* task, int idx, int remain) +static void uget_task_adjust_speed_index(UgetTask* task, int idx, int remain) { UgSLink* link; UgetNode* node; @@ -312,22 +334,22 @@ // increase speed by priority for (link = task->used; link; link = link->next) { node = (UgetNode*) link->data; - relation = ug_info_get (&node->info, UgetRelationInfo); - relation->task.prev = prev; + relation = ug_info_get(node->info, UgetRelationInfo); + relation->task->prev = prev; prev = relation; - n_piece += relation->task.priority + 1; + n_piece += relation->priority + 1; } remain = remain / n_piece; for (; relation; relation = prev) { - relation->task.limit[idx] = relation->task.speed[idx] + - remain * (relation->task.priority+1); - if (relation->task.limit[idx] < SPEED_MIN) - relation->task.limit[idx] = SPEED_MIN; - uget_plugin_ctrl_speed (relation->task.plugin, - relation->task.limit); - prev = relation->task.prev; - relation->task.prev = NULL; + relation->task->limit[idx] = relation->task->speed[idx] + + remain * (relation->priority+1); + if (relation->task->limit[idx] < SPEED_MIN) + relation->task->limit[idx] = SPEED_MIN; + uget_plugin_ctrl_speed(relation->task->plugin, + relation->task->limit); + prev = relation->task->prev; + relation->task->prev = NULL; } } else { @@ -335,17 +357,17 @@ remain = remain / task->n_links; for (link = task->used; link; link = link->next) { node = (UgetNode*) link->data; - relation = ug_info_get (&node->info, UgetRelationInfo); - relation->task.limit[idx] = relation->task.speed[idx] + remain; - if (relation->task.limit[idx] < SPEED_MIN) - relation->task.limit[idx] = SPEED_MIN; - uget_plugin_ctrl_speed (relation->task.plugin, - relation->task.limit); + relation = ug_info_get(node->info, UgetRelationInfo); + relation->task->limit[idx] = relation->task->speed[idx] + remain; + if (relation->task->limit[idx] < SPEED_MIN) + relation->task->limit[idx] = SPEED_MIN; + uget_plugin_ctrl_speed(relation->task->plugin, + relation->task->limit); } } } -static void uget_task_disable_limit_index (UgetTask* task, int idx) +static void uget_task_disable_limit_index(UgetTask* task, int idx) { UgSLink* link; UgetNode* node; @@ -353,9 +375,9 @@ for (link = task->used; link; link = link->next) { node = (UgetNode*) link->data; - relation = ug_info_get (&node->info, UgetRelationInfo); - relation->task.limit[idx] = 0; - uget_plugin_ctrl_speed (relation->task.plugin, - relation->task.limit); + relation = ug_info_get(node->info, UgetRelationInfo); + relation->task->limit[idx] = 0; + uget_plugin_ctrl_speed(relation->task->plugin, + relation->task->limit); } } diff -Nru uget-2.2.0/uget/UgetTask.h uget-2.2.2/uget/UgetTask.h --- uget-2.2.0/uget/UgetTask.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uget/UgetTask.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -51,40 +51,49 @@ extern "C" { #endif +/* UgetTask - match/manage UgetNode and UgetPlugin + - adjust/limit speed + */ + typedef struct UgetTask UgetTask; typedef int (*UgetWatchFunc) (void* instance, UgetEvent* msg, UgetNode* node, void* data); // ---------------------------------------------------------------------------- -// UgetTask : match UgetNode and UgetPlugin +// UgetTask functions -void uget_task_init (UgetTask* task); -void uget_task_final (UgetTask* task); +void uget_task_init(UgetTask* task); +void uget_task_final(UgetTask* task); -int uget_task_add (UgetTask* task, UgetNode* node, const UgetPluginInfo* pinfo); -int uget_task_remove (UgetTask* task, UgetNode* node); -void uget_task_remove_all (UgetTask* task); -void uget_task_dispatch (UgetTask* task); -void uget_task_add_watch (UgetTask* task, UgetWatchFunc func, void* data); +int uget_task_add(UgetTask* task, UgetNode* node, const UgetPluginInfo* pinfo); +int uget_task_remove(UgetTask* task, UgetNode* node); +void uget_task_remove_all(UgetTask* task); +void uget_task_dispatch(UgetTask* task); +void uget_task_add_watch(UgetTask* task, UgetWatchFunc func, void* data); -void uget_task_set_speed (UgetTask* task, int dl_speed, int ul_speed); -void uget_task_adjust_speed (UgetTask* task); +void uget_task_set_speed(UgetTask* task, int dl_speed, int ul_speed); +void uget_task_adjust_speed(UgetTask* task); #ifdef __cplusplus } #endif +// ---------------------------------------------------------------------------- +// UgetTask structure + struct UgetTask { UG_SLINKS_MEMBERS; -// UgSLink* at; -// int length; -// int allocated; -// int element_size; -// int n_links; -// UgSLink* used; -// UgSLink* freed; +/* // ------ UgSLinks members ------ + UgSLink* at; + int length; + int allocated; + int element_size; + int n_links; + UgSLink* used; + UgSLink* freed; + */ struct { UgetWatchFunc func; @@ -92,28 +101,31 @@ } watch[UGET_TASK_N_WATCH]; struct { - int upload; - int download; + int upload; + int download; } speed, limit; #ifdef __cplusplus // C++11 standard-layout - inline void init (void) - { uget_task_init ((UgetTask*) this); } - inline void final (void) - { uget_task_final ((UgetTask*) this); } - - inline int add (UgetNode* node, UgetPluginInfo* info) - { return uget_task_add ((UgetTask*) this, node, info); } - inline void remove (UgetNode* node) - { uget_task_remove ((UgetTask*) this, node); } - inline void dispatch (void) - { uget_task_dispatch ((UgetTask*) this); } - + inline void init(void) + { uget_task_init((UgetTask*) this); } + inline void final(void) + { uget_task_final((UgetTask*) this); } + + inline int add(UgetNode* node, UgetPluginInfo* info) + { return uget_task_add((UgetTask*) this, node, info); } + inline void remove(UgetNode* node) + { uget_task_remove((UgetTask*) this, node); } + inline void dispatch(void) + { uget_task_dispatch((UgetTask*) this); } + + inline void setSpeed(int dl_speed, int ul_speed) + { uget_task_set_speed(this, dl_speed, ul_speed); } + inline void adjustSpeed(void) + { uget_task_adjust_speed(this); } #endif // __cplusplus }; - // ---------------------------------------------------------------------------- // C++11 standard-layout diff -Nru uget-2.2.0/uglib/Makefile.am uget-2.2.2/uglib/Makefile.am --- uget-2.2.0/uglib/Makefile.am 2018-01-08 00:04:05.000000000 +0000 +++ uget-2.2.2/uglib/Makefile.am 2019-05-19 16:49:07.000000000 +0000 @@ -2,6 +2,8 @@ ## add `getconf LFS_CFLAGS` to CFLAGS ## add `getconf LFS_LDFLAGS` to LDFLAGS +AUTOMAKE_OPTIONS = no-dependencies + ## static library --- # lib_LIBRARIES = libuglib.a diff -Nru uget-2.2.0/uglib/Makefile.in uget-2.2.2/uglib/Makefile.in --- uget-2.2.0/uglib/Makefile.in 2018-01-08 00:05:58.000000000 +0000 +++ uget-2.2.2/uglib/Makefile.in 2019-05-19 16:51:34.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -136,9 +136,8 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f +depcomp = +am__maybe_remake_depfiles = AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -182,7 +181,7 @@ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -332,6 +331,7 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = no-dependencies # lib_LIBRARIES = libuglib.a noinst_LIBRARIES = libuglib.a @@ -421,8 +421,8 @@ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -448,425 +448,173 @@ distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgArray.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgBuffer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgData.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgEntry.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgFileUtil.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgHtml.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgHtmlEntry.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgHtmlFilter.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgInfo.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgJson-custom.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgJson.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgJsonFile.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgJsonrpc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgJsonrpcCurl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgJsonrpcSocket.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgList.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgNode.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgOption.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgRegistry.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgSLink.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgSocket.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgStdio.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgString.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgThread.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgUri.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgUtil.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libuglib_a-UgValue.Po@am__quote@ - .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + $(AM_V_CC)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + $(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` libuglib_a-UgStdio.o: UgStdio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgStdio.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgStdio.Tpo -c -o libuglib_a-UgStdio.o `test -f 'UgStdio.c' || echo '$(srcdir)/'`UgStdio.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgStdio.Tpo $(DEPDIR)/libuglib_a-UgStdio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgStdio.c' object='libuglib_a-UgStdio.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgStdio.o `test -f 'UgStdio.c' || echo '$(srcdir)/'`UgStdio.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgStdio.o `test -f 'UgStdio.c' || echo '$(srcdir)/'`UgStdio.c libuglib_a-UgStdio.obj: UgStdio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgStdio.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgStdio.Tpo -c -o libuglib_a-UgStdio.obj `if test -f 'UgStdio.c'; then $(CYGPATH_W) 'UgStdio.c'; else $(CYGPATH_W) '$(srcdir)/UgStdio.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgStdio.Tpo $(DEPDIR)/libuglib_a-UgStdio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgStdio.c' object='libuglib_a-UgStdio.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgStdio.obj `if test -f 'UgStdio.c'; then $(CYGPATH_W) 'UgStdio.c'; else $(CYGPATH_W) '$(srcdir)/UgStdio.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgStdio.obj `if test -f 'UgStdio.c'; then $(CYGPATH_W) 'UgStdio.c'; else $(CYGPATH_W) '$(srcdir)/UgStdio.c'; fi` libuglib_a-UgString.o: UgString.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgString.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgString.Tpo -c -o libuglib_a-UgString.o `test -f 'UgString.c' || echo '$(srcdir)/'`UgString.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgString.Tpo $(DEPDIR)/libuglib_a-UgString.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgString.c' object='libuglib_a-UgString.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgString.o `test -f 'UgString.c' || echo '$(srcdir)/'`UgString.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgString.o `test -f 'UgString.c' || echo '$(srcdir)/'`UgString.c libuglib_a-UgString.obj: UgString.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgString.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgString.Tpo -c -o libuglib_a-UgString.obj `if test -f 'UgString.c'; then $(CYGPATH_W) 'UgString.c'; else $(CYGPATH_W) '$(srcdir)/UgString.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgString.Tpo $(DEPDIR)/libuglib_a-UgString.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgString.c' object='libuglib_a-UgString.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgString.obj `if test -f 'UgString.c'; then $(CYGPATH_W) 'UgString.c'; else $(CYGPATH_W) '$(srcdir)/UgString.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgString.obj `if test -f 'UgString.c'; then $(CYGPATH_W) 'UgString.c'; else $(CYGPATH_W) '$(srcdir)/UgString.c'; fi` libuglib_a-UgThread.o: UgThread.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgThread.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgThread.Tpo -c -o libuglib_a-UgThread.o `test -f 'UgThread.c' || echo '$(srcdir)/'`UgThread.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgThread.Tpo $(DEPDIR)/libuglib_a-UgThread.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgThread.c' object='libuglib_a-UgThread.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgThread.o `test -f 'UgThread.c' || echo '$(srcdir)/'`UgThread.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgThread.o `test -f 'UgThread.c' || echo '$(srcdir)/'`UgThread.c libuglib_a-UgThread.obj: UgThread.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgThread.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgThread.Tpo -c -o libuglib_a-UgThread.obj `if test -f 'UgThread.c'; then $(CYGPATH_W) 'UgThread.c'; else $(CYGPATH_W) '$(srcdir)/UgThread.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgThread.Tpo $(DEPDIR)/libuglib_a-UgThread.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgThread.c' object='libuglib_a-UgThread.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgThread.obj `if test -f 'UgThread.c'; then $(CYGPATH_W) 'UgThread.c'; else $(CYGPATH_W) '$(srcdir)/UgThread.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgThread.obj `if test -f 'UgThread.c'; then $(CYGPATH_W) 'UgThread.c'; else $(CYGPATH_W) '$(srcdir)/UgThread.c'; fi` libuglib_a-UgSocket.o: UgSocket.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgSocket.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgSocket.Tpo -c -o libuglib_a-UgSocket.o `test -f 'UgSocket.c' || echo '$(srcdir)/'`UgSocket.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgSocket.Tpo $(DEPDIR)/libuglib_a-UgSocket.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgSocket.c' object='libuglib_a-UgSocket.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgSocket.o `test -f 'UgSocket.c' || echo '$(srcdir)/'`UgSocket.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgSocket.o `test -f 'UgSocket.c' || echo '$(srcdir)/'`UgSocket.c libuglib_a-UgSocket.obj: UgSocket.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgSocket.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgSocket.Tpo -c -o libuglib_a-UgSocket.obj `if test -f 'UgSocket.c'; then $(CYGPATH_W) 'UgSocket.c'; else $(CYGPATH_W) '$(srcdir)/UgSocket.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgSocket.Tpo $(DEPDIR)/libuglib_a-UgSocket.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgSocket.c' object='libuglib_a-UgSocket.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgSocket.obj `if test -f 'UgSocket.c'; then $(CYGPATH_W) 'UgSocket.c'; else $(CYGPATH_W) '$(srcdir)/UgSocket.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgSocket.obj `if test -f 'UgSocket.c'; then $(CYGPATH_W) 'UgSocket.c'; else $(CYGPATH_W) '$(srcdir)/UgSocket.c'; fi` libuglib_a-UgUtil.o: UgUtil.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgUtil.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgUtil.Tpo -c -o libuglib_a-UgUtil.o `test -f 'UgUtil.c' || echo '$(srcdir)/'`UgUtil.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgUtil.Tpo $(DEPDIR)/libuglib_a-UgUtil.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgUtil.c' object='libuglib_a-UgUtil.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgUtil.o `test -f 'UgUtil.c' || echo '$(srcdir)/'`UgUtil.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgUtil.o `test -f 'UgUtil.c' || echo '$(srcdir)/'`UgUtil.c libuglib_a-UgUtil.obj: UgUtil.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgUtil.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgUtil.Tpo -c -o libuglib_a-UgUtil.obj `if test -f 'UgUtil.c'; then $(CYGPATH_W) 'UgUtil.c'; else $(CYGPATH_W) '$(srcdir)/UgUtil.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgUtil.Tpo $(DEPDIR)/libuglib_a-UgUtil.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgUtil.c' object='libuglib_a-UgUtil.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgUtil.obj `if test -f 'UgUtil.c'; then $(CYGPATH_W) 'UgUtil.c'; else $(CYGPATH_W) '$(srcdir)/UgUtil.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgUtil.obj `if test -f 'UgUtil.c'; then $(CYGPATH_W) 'UgUtil.c'; else $(CYGPATH_W) '$(srcdir)/UgUtil.c'; fi` libuglib_a-UgFileUtil.o: UgFileUtil.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgFileUtil.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgFileUtil.Tpo -c -o libuglib_a-UgFileUtil.o `test -f 'UgFileUtil.c' || echo '$(srcdir)/'`UgFileUtil.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgFileUtil.Tpo $(DEPDIR)/libuglib_a-UgFileUtil.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgFileUtil.c' object='libuglib_a-UgFileUtil.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgFileUtil.o `test -f 'UgFileUtil.c' || echo '$(srcdir)/'`UgFileUtil.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgFileUtil.o `test -f 'UgFileUtil.c' || echo '$(srcdir)/'`UgFileUtil.c libuglib_a-UgFileUtil.obj: UgFileUtil.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgFileUtil.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgFileUtil.Tpo -c -o libuglib_a-UgFileUtil.obj `if test -f 'UgFileUtil.c'; then $(CYGPATH_W) 'UgFileUtil.c'; else $(CYGPATH_W) '$(srcdir)/UgFileUtil.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgFileUtil.Tpo $(DEPDIR)/libuglib_a-UgFileUtil.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgFileUtil.c' object='libuglib_a-UgFileUtil.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgFileUtil.obj `if test -f 'UgFileUtil.c'; then $(CYGPATH_W) 'UgFileUtil.c'; else $(CYGPATH_W) '$(srcdir)/UgFileUtil.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgFileUtil.obj `if test -f 'UgFileUtil.c'; then $(CYGPATH_W) 'UgFileUtil.c'; else $(CYGPATH_W) '$(srcdir)/UgFileUtil.c'; fi` libuglib_a-UgArray.o: UgArray.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgArray.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgArray.Tpo -c -o libuglib_a-UgArray.o `test -f 'UgArray.c' || echo '$(srcdir)/'`UgArray.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgArray.Tpo $(DEPDIR)/libuglib_a-UgArray.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgArray.c' object='libuglib_a-UgArray.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgArray.o `test -f 'UgArray.c' || echo '$(srcdir)/'`UgArray.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgArray.o `test -f 'UgArray.c' || echo '$(srcdir)/'`UgArray.c libuglib_a-UgArray.obj: UgArray.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgArray.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgArray.Tpo -c -o libuglib_a-UgArray.obj `if test -f 'UgArray.c'; then $(CYGPATH_W) 'UgArray.c'; else $(CYGPATH_W) '$(srcdir)/UgArray.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgArray.Tpo $(DEPDIR)/libuglib_a-UgArray.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgArray.c' object='libuglib_a-UgArray.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgArray.obj `if test -f 'UgArray.c'; then $(CYGPATH_W) 'UgArray.c'; else $(CYGPATH_W) '$(srcdir)/UgArray.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgArray.obj `if test -f 'UgArray.c'; then $(CYGPATH_W) 'UgArray.c'; else $(CYGPATH_W) '$(srcdir)/UgArray.c'; fi` libuglib_a-UgList.o: UgList.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgList.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgList.Tpo -c -o libuglib_a-UgList.o `test -f 'UgList.c' || echo '$(srcdir)/'`UgList.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgList.Tpo $(DEPDIR)/libuglib_a-UgList.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgList.c' object='libuglib_a-UgList.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgList.o `test -f 'UgList.c' || echo '$(srcdir)/'`UgList.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgList.o `test -f 'UgList.c' || echo '$(srcdir)/'`UgList.c libuglib_a-UgList.obj: UgList.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgList.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgList.Tpo -c -o libuglib_a-UgList.obj `if test -f 'UgList.c'; then $(CYGPATH_W) 'UgList.c'; else $(CYGPATH_W) '$(srcdir)/UgList.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgList.Tpo $(DEPDIR)/libuglib_a-UgList.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgList.c' object='libuglib_a-UgList.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgList.obj `if test -f 'UgList.c'; then $(CYGPATH_W) 'UgList.c'; else $(CYGPATH_W) '$(srcdir)/UgList.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgList.obj `if test -f 'UgList.c'; then $(CYGPATH_W) 'UgList.c'; else $(CYGPATH_W) '$(srcdir)/UgList.c'; fi` libuglib_a-UgSLink.o: UgSLink.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgSLink.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgSLink.Tpo -c -o libuglib_a-UgSLink.o `test -f 'UgSLink.c' || echo '$(srcdir)/'`UgSLink.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgSLink.Tpo $(DEPDIR)/libuglib_a-UgSLink.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgSLink.c' object='libuglib_a-UgSLink.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgSLink.o `test -f 'UgSLink.c' || echo '$(srcdir)/'`UgSLink.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgSLink.o `test -f 'UgSLink.c' || echo '$(srcdir)/'`UgSLink.c libuglib_a-UgSLink.obj: UgSLink.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgSLink.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgSLink.Tpo -c -o libuglib_a-UgSLink.obj `if test -f 'UgSLink.c'; then $(CYGPATH_W) 'UgSLink.c'; else $(CYGPATH_W) '$(srcdir)/UgSLink.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgSLink.Tpo $(DEPDIR)/libuglib_a-UgSLink.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgSLink.c' object='libuglib_a-UgSLink.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgSLink.obj `if test -f 'UgSLink.c'; then $(CYGPATH_W) 'UgSLink.c'; else $(CYGPATH_W) '$(srcdir)/UgSLink.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgSLink.obj `if test -f 'UgSLink.c'; then $(CYGPATH_W) 'UgSLink.c'; else $(CYGPATH_W) '$(srcdir)/UgSLink.c'; fi` libuglib_a-UgOption.o: UgOption.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgOption.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgOption.Tpo -c -o libuglib_a-UgOption.o `test -f 'UgOption.c' || echo '$(srcdir)/'`UgOption.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgOption.Tpo $(DEPDIR)/libuglib_a-UgOption.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgOption.c' object='libuglib_a-UgOption.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgOption.o `test -f 'UgOption.c' || echo '$(srcdir)/'`UgOption.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgOption.o `test -f 'UgOption.c' || echo '$(srcdir)/'`UgOption.c libuglib_a-UgOption.obj: UgOption.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgOption.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgOption.Tpo -c -o libuglib_a-UgOption.obj `if test -f 'UgOption.c'; then $(CYGPATH_W) 'UgOption.c'; else $(CYGPATH_W) '$(srcdir)/UgOption.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgOption.Tpo $(DEPDIR)/libuglib_a-UgOption.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgOption.c' object='libuglib_a-UgOption.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgOption.obj `if test -f 'UgOption.c'; then $(CYGPATH_W) 'UgOption.c'; else $(CYGPATH_W) '$(srcdir)/UgOption.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgOption.obj `if test -f 'UgOption.c'; then $(CYGPATH_W) 'UgOption.c'; else $(CYGPATH_W) '$(srcdir)/UgOption.c'; fi` libuglib_a-UgUri.o: UgUri.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgUri.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgUri.Tpo -c -o libuglib_a-UgUri.o `test -f 'UgUri.c' || echo '$(srcdir)/'`UgUri.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgUri.Tpo $(DEPDIR)/libuglib_a-UgUri.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgUri.c' object='libuglib_a-UgUri.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgUri.o `test -f 'UgUri.c' || echo '$(srcdir)/'`UgUri.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgUri.o `test -f 'UgUri.c' || echo '$(srcdir)/'`UgUri.c libuglib_a-UgUri.obj: UgUri.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgUri.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgUri.Tpo -c -o libuglib_a-UgUri.obj `if test -f 'UgUri.c'; then $(CYGPATH_W) 'UgUri.c'; else $(CYGPATH_W) '$(srcdir)/UgUri.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgUri.Tpo $(DEPDIR)/libuglib_a-UgUri.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgUri.c' object='libuglib_a-UgUri.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgUri.obj `if test -f 'UgUri.c'; then $(CYGPATH_W) 'UgUri.c'; else $(CYGPATH_W) '$(srcdir)/UgUri.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgUri.obj `if test -f 'UgUri.c'; then $(CYGPATH_W) 'UgUri.c'; else $(CYGPATH_W) '$(srcdir)/UgUri.c'; fi` libuglib_a-UgNode.o: UgNode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgNode.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgNode.Tpo -c -o libuglib_a-UgNode.o `test -f 'UgNode.c' || echo '$(srcdir)/'`UgNode.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgNode.Tpo $(DEPDIR)/libuglib_a-UgNode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgNode.c' object='libuglib_a-UgNode.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgNode.o `test -f 'UgNode.c' || echo '$(srcdir)/'`UgNode.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgNode.o `test -f 'UgNode.c' || echo '$(srcdir)/'`UgNode.c libuglib_a-UgNode.obj: UgNode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgNode.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgNode.Tpo -c -o libuglib_a-UgNode.obj `if test -f 'UgNode.c'; then $(CYGPATH_W) 'UgNode.c'; else $(CYGPATH_W) '$(srcdir)/UgNode.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgNode.Tpo $(DEPDIR)/libuglib_a-UgNode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgNode.c' object='libuglib_a-UgNode.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgNode.obj `if test -f 'UgNode.c'; then $(CYGPATH_W) 'UgNode.c'; else $(CYGPATH_W) '$(srcdir)/UgNode.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgNode.obj `if test -f 'UgNode.c'; then $(CYGPATH_W) 'UgNode.c'; else $(CYGPATH_W) '$(srcdir)/UgNode.c'; fi` libuglib_a-UgData.o: UgData.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgData.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgData.Tpo -c -o libuglib_a-UgData.o `test -f 'UgData.c' || echo '$(srcdir)/'`UgData.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgData.Tpo $(DEPDIR)/libuglib_a-UgData.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgData.c' object='libuglib_a-UgData.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgData.o `test -f 'UgData.c' || echo '$(srcdir)/'`UgData.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgData.o `test -f 'UgData.c' || echo '$(srcdir)/'`UgData.c libuglib_a-UgData.obj: UgData.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgData.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgData.Tpo -c -o libuglib_a-UgData.obj `if test -f 'UgData.c'; then $(CYGPATH_W) 'UgData.c'; else $(CYGPATH_W) '$(srcdir)/UgData.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgData.Tpo $(DEPDIR)/libuglib_a-UgData.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgData.c' object='libuglib_a-UgData.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgData.obj `if test -f 'UgData.c'; then $(CYGPATH_W) 'UgData.c'; else $(CYGPATH_W) '$(srcdir)/UgData.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgData.obj `if test -f 'UgData.c'; then $(CYGPATH_W) 'UgData.c'; else $(CYGPATH_W) '$(srcdir)/UgData.c'; fi` libuglib_a-UgInfo.o: UgInfo.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgInfo.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgInfo.Tpo -c -o libuglib_a-UgInfo.o `test -f 'UgInfo.c' || echo '$(srcdir)/'`UgInfo.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgInfo.Tpo $(DEPDIR)/libuglib_a-UgInfo.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgInfo.c' object='libuglib_a-UgInfo.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgInfo.o `test -f 'UgInfo.c' || echo '$(srcdir)/'`UgInfo.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgInfo.o `test -f 'UgInfo.c' || echo '$(srcdir)/'`UgInfo.c libuglib_a-UgInfo.obj: UgInfo.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgInfo.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgInfo.Tpo -c -o libuglib_a-UgInfo.obj `if test -f 'UgInfo.c'; then $(CYGPATH_W) 'UgInfo.c'; else $(CYGPATH_W) '$(srcdir)/UgInfo.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgInfo.Tpo $(DEPDIR)/libuglib_a-UgInfo.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgInfo.c' object='libuglib_a-UgInfo.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgInfo.obj `if test -f 'UgInfo.c'; then $(CYGPATH_W) 'UgInfo.c'; else $(CYGPATH_W) '$(srcdir)/UgInfo.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgInfo.obj `if test -f 'UgInfo.c'; then $(CYGPATH_W) 'UgInfo.c'; else $(CYGPATH_W) '$(srcdir)/UgInfo.c'; fi` libuglib_a-UgRegistry.o: UgRegistry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgRegistry.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgRegistry.Tpo -c -o libuglib_a-UgRegistry.o `test -f 'UgRegistry.c' || echo '$(srcdir)/'`UgRegistry.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgRegistry.Tpo $(DEPDIR)/libuglib_a-UgRegistry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgRegistry.c' object='libuglib_a-UgRegistry.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgRegistry.o `test -f 'UgRegistry.c' || echo '$(srcdir)/'`UgRegistry.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgRegistry.o `test -f 'UgRegistry.c' || echo '$(srcdir)/'`UgRegistry.c libuglib_a-UgRegistry.obj: UgRegistry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgRegistry.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgRegistry.Tpo -c -o libuglib_a-UgRegistry.obj `if test -f 'UgRegistry.c'; then $(CYGPATH_W) 'UgRegistry.c'; else $(CYGPATH_W) '$(srcdir)/UgRegistry.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgRegistry.Tpo $(DEPDIR)/libuglib_a-UgRegistry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgRegistry.c' object='libuglib_a-UgRegistry.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgRegistry.obj `if test -f 'UgRegistry.c'; then $(CYGPATH_W) 'UgRegistry.c'; else $(CYGPATH_W) '$(srcdir)/UgRegistry.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgRegistry.obj `if test -f 'UgRegistry.c'; then $(CYGPATH_W) 'UgRegistry.c'; else $(CYGPATH_W) '$(srcdir)/UgRegistry.c'; fi` libuglib_a-UgValue.o: UgValue.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgValue.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgValue.Tpo -c -o libuglib_a-UgValue.o `test -f 'UgValue.c' || echo '$(srcdir)/'`UgValue.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgValue.Tpo $(DEPDIR)/libuglib_a-UgValue.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgValue.c' object='libuglib_a-UgValue.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgValue.o `test -f 'UgValue.c' || echo '$(srcdir)/'`UgValue.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgValue.o `test -f 'UgValue.c' || echo '$(srcdir)/'`UgValue.c libuglib_a-UgValue.obj: UgValue.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgValue.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgValue.Tpo -c -o libuglib_a-UgValue.obj `if test -f 'UgValue.c'; then $(CYGPATH_W) 'UgValue.c'; else $(CYGPATH_W) '$(srcdir)/UgValue.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgValue.Tpo $(DEPDIR)/libuglib_a-UgValue.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgValue.c' object='libuglib_a-UgValue.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgValue.obj `if test -f 'UgValue.c'; then $(CYGPATH_W) 'UgValue.c'; else $(CYGPATH_W) '$(srcdir)/UgValue.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgValue.obj `if test -f 'UgValue.c'; then $(CYGPATH_W) 'UgValue.c'; else $(CYGPATH_W) '$(srcdir)/UgValue.c'; fi` libuglib_a-UgEntry.o: UgEntry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgEntry.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgEntry.Tpo -c -o libuglib_a-UgEntry.o `test -f 'UgEntry.c' || echo '$(srcdir)/'`UgEntry.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgEntry.Tpo $(DEPDIR)/libuglib_a-UgEntry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgEntry.c' object='libuglib_a-UgEntry.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgEntry.o `test -f 'UgEntry.c' || echo '$(srcdir)/'`UgEntry.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgEntry.o `test -f 'UgEntry.c' || echo '$(srcdir)/'`UgEntry.c libuglib_a-UgEntry.obj: UgEntry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgEntry.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgEntry.Tpo -c -o libuglib_a-UgEntry.obj `if test -f 'UgEntry.c'; then $(CYGPATH_W) 'UgEntry.c'; else $(CYGPATH_W) '$(srcdir)/UgEntry.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgEntry.Tpo $(DEPDIR)/libuglib_a-UgEntry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgEntry.c' object='libuglib_a-UgEntry.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgEntry.obj `if test -f 'UgEntry.c'; then $(CYGPATH_W) 'UgEntry.c'; else $(CYGPATH_W) '$(srcdir)/UgEntry.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgEntry.obj `if test -f 'UgEntry.c'; then $(CYGPATH_W) 'UgEntry.c'; else $(CYGPATH_W) '$(srcdir)/UgEntry.c'; fi` libuglib_a-UgBuffer.o: UgBuffer.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgBuffer.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgBuffer.Tpo -c -o libuglib_a-UgBuffer.o `test -f 'UgBuffer.c' || echo '$(srcdir)/'`UgBuffer.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgBuffer.Tpo $(DEPDIR)/libuglib_a-UgBuffer.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgBuffer.c' object='libuglib_a-UgBuffer.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgBuffer.o `test -f 'UgBuffer.c' || echo '$(srcdir)/'`UgBuffer.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgBuffer.o `test -f 'UgBuffer.c' || echo '$(srcdir)/'`UgBuffer.c libuglib_a-UgBuffer.obj: UgBuffer.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgBuffer.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgBuffer.Tpo -c -o libuglib_a-UgBuffer.obj `if test -f 'UgBuffer.c'; then $(CYGPATH_W) 'UgBuffer.c'; else $(CYGPATH_W) '$(srcdir)/UgBuffer.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgBuffer.Tpo $(DEPDIR)/libuglib_a-UgBuffer.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgBuffer.c' object='libuglib_a-UgBuffer.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgBuffer.obj `if test -f 'UgBuffer.c'; then $(CYGPATH_W) 'UgBuffer.c'; else $(CYGPATH_W) '$(srcdir)/UgBuffer.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgBuffer.obj `if test -f 'UgBuffer.c'; then $(CYGPATH_W) 'UgBuffer.c'; else $(CYGPATH_W) '$(srcdir)/UgBuffer.c'; fi` libuglib_a-UgJson.o: UgJson.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgJson.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgJson.Tpo -c -o libuglib_a-UgJson.o `test -f 'UgJson.c' || echo '$(srcdir)/'`UgJson.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgJson.Tpo $(DEPDIR)/libuglib_a-UgJson.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgJson.c' object='libuglib_a-UgJson.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJson.o `test -f 'UgJson.c' || echo '$(srcdir)/'`UgJson.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJson.o `test -f 'UgJson.c' || echo '$(srcdir)/'`UgJson.c libuglib_a-UgJson.obj: UgJson.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgJson.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgJson.Tpo -c -o libuglib_a-UgJson.obj `if test -f 'UgJson.c'; then $(CYGPATH_W) 'UgJson.c'; else $(CYGPATH_W) '$(srcdir)/UgJson.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgJson.Tpo $(DEPDIR)/libuglib_a-UgJson.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgJson.c' object='libuglib_a-UgJson.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJson.obj `if test -f 'UgJson.c'; then $(CYGPATH_W) 'UgJson.c'; else $(CYGPATH_W) '$(srcdir)/UgJson.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJson.obj `if test -f 'UgJson.c'; then $(CYGPATH_W) 'UgJson.c'; else $(CYGPATH_W) '$(srcdir)/UgJson.c'; fi` libuglib_a-UgJson-custom.o: UgJson-custom.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgJson-custom.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgJson-custom.Tpo -c -o libuglib_a-UgJson-custom.o `test -f 'UgJson-custom.c' || echo '$(srcdir)/'`UgJson-custom.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgJson-custom.Tpo $(DEPDIR)/libuglib_a-UgJson-custom.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgJson-custom.c' object='libuglib_a-UgJson-custom.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJson-custom.o `test -f 'UgJson-custom.c' || echo '$(srcdir)/'`UgJson-custom.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJson-custom.o `test -f 'UgJson-custom.c' || echo '$(srcdir)/'`UgJson-custom.c libuglib_a-UgJson-custom.obj: UgJson-custom.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgJson-custom.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgJson-custom.Tpo -c -o libuglib_a-UgJson-custom.obj `if test -f 'UgJson-custom.c'; then $(CYGPATH_W) 'UgJson-custom.c'; else $(CYGPATH_W) '$(srcdir)/UgJson-custom.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgJson-custom.Tpo $(DEPDIR)/libuglib_a-UgJson-custom.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgJson-custom.c' object='libuglib_a-UgJson-custom.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJson-custom.obj `if test -f 'UgJson-custom.c'; then $(CYGPATH_W) 'UgJson-custom.c'; else $(CYGPATH_W) '$(srcdir)/UgJson-custom.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJson-custom.obj `if test -f 'UgJson-custom.c'; then $(CYGPATH_W) 'UgJson-custom.c'; else $(CYGPATH_W) '$(srcdir)/UgJson-custom.c'; fi` libuglib_a-UgJsonFile.o: UgJsonFile.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgJsonFile.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgJsonFile.Tpo -c -o libuglib_a-UgJsonFile.o `test -f 'UgJsonFile.c' || echo '$(srcdir)/'`UgJsonFile.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgJsonFile.Tpo $(DEPDIR)/libuglib_a-UgJsonFile.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgJsonFile.c' object='libuglib_a-UgJsonFile.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonFile.o `test -f 'UgJsonFile.c' || echo '$(srcdir)/'`UgJsonFile.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonFile.o `test -f 'UgJsonFile.c' || echo '$(srcdir)/'`UgJsonFile.c libuglib_a-UgJsonFile.obj: UgJsonFile.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgJsonFile.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgJsonFile.Tpo -c -o libuglib_a-UgJsonFile.obj `if test -f 'UgJsonFile.c'; then $(CYGPATH_W) 'UgJsonFile.c'; else $(CYGPATH_W) '$(srcdir)/UgJsonFile.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgJsonFile.Tpo $(DEPDIR)/libuglib_a-UgJsonFile.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgJsonFile.c' object='libuglib_a-UgJsonFile.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonFile.obj `if test -f 'UgJsonFile.c'; then $(CYGPATH_W) 'UgJsonFile.c'; else $(CYGPATH_W) '$(srcdir)/UgJsonFile.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonFile.obj `if test -f 'UgJsonFile.c'; then $(CYGPATH_W) 'UgJsonFile.c'; else $(CYGPATH_W) '$(srcdir)/UgJsonFile.c'; fi` libuglib_a-UgJsonrpc.o: UgJsonrpc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgJsonrpc.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgJsonrpc.Tpo -c -o libuglib_a-UgJsonrpc.o `test -f 'UgJsonrpc.c' || echo '$(srcdir)/'`UgJsonrpc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgJsonrpc.Tpo $(DEPDIR)/libuglib_a-UgJsonrpc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgJsonrpc.c' object='libuglib_a-UgJsonrpc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonrpc.o `test -f 'UgJsonrpc.c' || echo '$(srcdir)/'`UgJsonrpc.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonrpc.o `test -f 'UgJsonrpc.c' || echo '$(srcdir)/'`UgJsonrpc.c libuglib_a-UgJsonrpc.obj: UgJsonrpc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgJsonrpc.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgJsonrpc.Tpo -c -o libuglib_a-UgJsonrpc.obj `if test -f 'UgJsonrpc.c'; then $(CYGPATH_W) 'UgJsonrpc.c'; else $(CYGPATH_W) '$(srcdir)/UgJsonrpc.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgJsonrpc.Tpo $(DEPDIR)/libuglib_a-UgJsonrpc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgJsonrpc.c' object='libuglib_a-UgJsonrpc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonrpc.obj `if test -f 'UgJsonrpc.c'; then $(CYGPATH_W) 'UgJsonrpc.c'; else $(CYGPATH_W) '$(srcdir)/UgJsonrpc.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonrpc.obj `if test -f 'UgJsonrpc.c'; then $(CYGPATH_W) 'UgJsonrpc.c'; else $(CYGPATH_W) '$(srcdir)/UgJsonrpc.c'; fi` libuglib_a-UgJsonrpcSocket.o: UgJsonrpcSocket.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgJsonrpcSocket.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgJsonrpcSocket.Tpo -c -o libuglib_a-UgJsonrpcSocket.o `test -f 'UgJsonrpcSocket.c' || echo '$(srcdir)/'`UgJsonrpcSocket.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgJsonrpcSocket.Tpo $(DEPDIR)/libuglib_a-UgJsonrpcSocket.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgJsonrpcSocket.c' object='libuglib_a-UgJsonrpcSocket.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonrpcSocket.o `test -f 'UgJsonrpcSocket.c' || echo '$(srcdir)/'`UgJsonrpcSocket.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonrpcSocket.o `test -f 'UgJsonrpcSocket.c' || echo '$(srcdir)/'`UgJsonrpcSocket.c libuglib_a-UgJsonrpcSocket.obj: UgJsonrpcSocket.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgJsonrpcSocket.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgJsonrpcSocket.Tpo -c -o libuglib_a-UgJsonrpcSocket.obj `if test -f 'UgJsonrpcSocket.c'; then $(CYGPATH_W) 'UgJsonrpcSocket.c'; else $(CYGPATH_W) '$(srcdir)/UgJsonrpcSocket.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgJsonrpcSocket.Tpo $(DEPDIR)/libuglib_a-UgJsonrpcSocket.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgJsonrpcSocket.c' object='libuglib_a-UgJsonrpcSocket.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonrpcSocket.obj `if test -f 'UgJsonrpcSocket.c'; then $(CYGPATH_W) 'UgJsonrpcSocket.c'; else $(CYGPATH_W) '$(srcdir)/UgJsonrpcSocket.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonrpcSocket.obj `if test -f 'UgJsonrpcSocket.c'; then $(CYGPATH_W) 'UgJsonrpcSocket.c'; else $(CYGPATH_W) '$(srcdir)/UgJsonrpcSocket.c'; fi` libuglib_a-UgJsonrpcCurl.o: UgJsonrpcCurl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgJsonrpcCurl.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgJsonrpcCurl.Tpo -c -o libuglib_a-UgJsonrpcCurl.o `test -f 'UgJsonrpcCurl.c' || echo '$(srcdir)/'`UgJsonrpcCurl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgJsonrpcCurl.Tpo $(DEPDIR)/libuglib_a-UgJsonrpcCurl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgJsonrpcCurl.c' object='libuglib_a-UgJsonrpcCurl.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonrpcCurl.o `test -f 'UgJsonrpcCurl.c' || echo '$(srcdir)/'`UgJsonrpcCurl.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonrpcCurl.o `test -f 'UgJsonrpcCurl.c' || echo '$(srcdir)/'`UgJsonrpcCurl.c libuglib_a-UgJsonrpcCurl.obj: UgJsonrpcCurl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgJsonrpcCurl.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgJsonrpcCurl.Tpo -c -o libuglib_a-UgJsonrpcCurl.obj `if test -f 'UgJsonrpcCurl.c'; then $(CYGPATH_W) 'UgJsonrpcCurl.c'; else $(CYGPATH_W) '$(srcdir)/UgJsonrpcCurl.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgJsonrpcCurl.Tpo $(DEPDIR)/libuglib_a-UgJsonrpcCurl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgJsonrpcCurl.c' object='libuglib_a-UgJsonrpcCurl.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonrpcCurl.obj `if test -f 'UgJsonrpcCurl.c'; then $(CYGPATH_W) 'UgJsonrpcCurl.c'; else $(CYGPATH_W) '$(srcdir)/UgJsonrpcCurl.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgJsonrpcCurl.obj `if test -f 'UgJsonrpcCurl.c'; then $(CYGPATH_W) 'UgJsonrpcCurl.c'; else $(CYGPATH_W) '$(srcdir)/UgJsonrpcCurl.c'; fi` libuglib_a-UgHtml.o: UgHtml.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgHtml.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgHtml.Tpo -c -o libuglib_a-UgHtml.o `test -f 'UgHtml.c' || echo '$(srcdir)/'`UgHtml.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgHtml.Tpo $(DEPDIR)/libuglib_a-UgHtml.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgHtml.c' object='libuglib_a-UgHtml.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgHtml.o `test -f 'UgHtml.c' || echo '$(srcdir)/'`UgHtml.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgHtml.o `test -f 'UgHtml.c' || echo '$(srcdir)/'`UgHtml.c libuglib_a-UgHtml.obj: UgHtml.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgHtml.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgHtml.Tpo -c -o libuglib_a-UgHtml.obj `if test -f 'UgHtml.c'; then $(CYGPATH_W) 'UgHtml.c'; else $(CYGPATH_W) '$(srcdir)/UgHtml.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgHtml.Tpo $(DEPDIR)/libuglib_a-UgHtml.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgHtml.c' object='libuglib_a-UgHtml.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgHtml.obj `if test -f 'UgHtml.c'; then $(CYGPATH_W) 'UgHtml.c'; else $(CYGPATH_W) '$(srcdir)/UgHtml.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgHtml.obj `if test -f 'UgHtml.c'; then $(CYGPATH_W) 'UgHtml.c'; else $(CYGPATH_W) '$(srcdir)/UgHtml.c'; fi` libuglib_a-UgHtmlEntry.o: UgHtmlEntry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgHtmlEntry.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgHtmlEntry.Tpo -c -o libuglib_a-UgHtmlEntry.o `test -f 'UgHtmlEntry.c' || echo '$(srcdir)/'`UgHtmlEntry.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgHtmlEntry.Tpo $(DEPDIR)/libuglib_a-UgHtmlEntry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgHtmlEntry.c' object='libuglib_a-UgHtmlEntry.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgHtmlEntry.o `test -f 'UgHtmlEntry.c' || echo '$(srcdir)/'`UgHtmlEntry.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgHtmlEntry.o `test -f 'UgHtmlEntry.c' || echo '$(srcdir)/'`UgHtmlEntry.c libuglib_a-UgHtmlEntry.obj: UgHtmlEntry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgHtmlEntry.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgHtmlEntry.Tpo -c -o libuglib_a-UgHtmlEntry.obj `if test -f 'UgHtmlEntry.c'; then $(CYGPATH_W) 'UgHtmlEntry.c'; else $(CYGPATH_W) '$(srcdir)/UgHtmlEntry.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgHtmlEntry.Tpo $(DEPDIR)/libuglib_a-UgHtmlEntry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgHtmlEntry.c' object='libuglib_a-UgHtmlEntry.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgHtmlEntry.obj `if test -f 'UgHtmlEntry.c'; then $(CYGPATH_W) 'UgHtmlEntry.c'; else $(CYGPATH_W) '$(srcdir)/UgHtmlEntry.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgHtmlEntry.obj `if test -f 'UgHtmlEntry.c'; then $(CYGPATH_W) 'UgHtmlEntry.c'; else $(CYGPATH_W) '$(srcdir)/UgHtmlEntry.c'; fi` libuglib_a-UgHtmlFilter.o: UgHtmlFilter.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgHtmlFilter.o -MD -MP -MF $(DEPDIR)/libuglib_a-UgHtmlFilter.Tpo -c -o libuglib_a-UgHtmlFilter.o `test -f 'UgHtmlFilter.c' || echo '$(srcdir)/'`UgHtmlFilter.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgHtmlFilter.Tpo $(DEPDIR)/libuglib_a-UgHtmlFilter.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgHtmlFilter.c' object='libuglib_a-UgHtmlFilter.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgHtmlFilter.o `test -f 'UgHtmlFilter.c' || echo '$(srcdir)/'`UgHtmlFilter.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgHtmlFilter.o `test -f 'UgHtmlFilter.c' || echo '$(srcdir)/'`UgHtmlFilter.c libuglib_a-UgHtmlFilter.obj: UgHtmlFilter.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -MT libuglib_a-UgHtmlFilter.obj -MD -MP -MF $(DEPDIR)/libuglib_a-UgHtmlFilter.Tpo -c -o libuglib_a-UgHtmlFilter.obj `if test -f 'UgHtmlFilter.c'; then $(CYGPATH_W) 'UgHtmlFilter.c'; else $(CYGPATH_W) '$(srcdir)/UgHtmlFilter.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libuglib_a-UgHtmlFilter.Tpo $(DEPDIR)/libuglib_a-UgHtmlFilter.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgHtmlFilter.c' object='libuglib_a-UgHtmlFilter.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgHtmlFilter.obj `if test -f 'UgHtmlFilter.c'; then $(CYGPATH_W) 'UgHtmlFilter.c'; else $(CYGPATH_W) '$(srcdir)/UgHtmlFilter.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libuglib_a_CPPFLAGS) $(CPPFLAGS) $(libuglib_a_CFLAGS) $(CFLAGS) -c -o libuglib_a-UgHtmlFilter.obj `if test -f 'UgHtmlFilter.c'; then $(CYGPATH_W) 'UgHtmlFilter.c'; else $(CYGPATH_W) '$(srcdir)/UgHtmlFilter.c'; fi` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique @@ -920,7 +668,10 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -989,7 +740,6 @@ clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -1035,7 +785,6 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff -Nru uget-2.2.0/uglib/UgArray.c uget-2.2.2/uglib/UgArray.c --- uget-2.2.0/uglib/UgArray.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgArray.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -47,12 +47,12 @@ // ---------------------------------------------------------------------------- // UgArray: for UG_ENTRY_ARRAY -void ug_array_init (void* arr, int element_size, int allocated_len) +void ug_array_init(void* arr, int element_size, int allocated_len) { UgArrayChar* array = arr; if (allocated_len) - array->at = ug_malloc (element_size * allocated_len); + array->at = ug_malloc(element_size * allocated_len); else array->at = NULL; array->length = 0; @@ -60,17 +60,17 @@ array->element_size = element_size; } -void ug_array_clear (void* arr) +void ug_array_clear(void* arr) { UgArrayChar* array = arr; - ug_free (array->at); + ug_free(array->at); array->at = NULL; array->length = 0; array->allocated = 0; } -void* ug_array_alloc (void* arr, int nElements) +void* ug_array_alloc(void* arr, int nElements) { UgArrayChar* array = arr; int len; @@ -80,14 +80,14 @@ array->allocated = len * 2; // if (array->allocated < 16) // array->allocated = 16; - array->at = ug_realloc (array->at, array->allocated * array->element_size); + array->at = ug_realloc(array->at, array->allocated * array->element_size); } arr = array->at + array->length * array->element_size; array->length += nElements; return arr; } -void ug_array_foreach (void* array, UgForeachFunc func, void* data) +void ug_array_foreach(void* array, UgForeachFunc func, void* data) { char* cur; char* end; @@ -96,30 +96,112 @@ end = cur + ((UgArrayChar*)array)->element_size * ((UgArrayChar*)array)->length; for (; cur < end; cur+= ((UgArrayChar*)array)->element_size) - func (cur, data); + func(cur, data); } -void ug_array_foreach_ptr (void* array, UgForeachFunc func, void* data) +void ug_array_foreach_ptr(void* array, UgForeachFunc func, void* data) { char* cur = ((UgArrayChar*)array)->at; char* end = cur + ((UgArrayChar*)array)->element_size * ((UgArrayChar*)array)->length; for (; cur < end; cur+= ((UgArrayChar*)array)->element_size) - func (*(void**)cur, data); + func(*(void**)cur, data); +} + +void* ug_array_find_sorted(void* array, const void* key, + UgCompareFunc compare, int* inserted_index) +{ + int low; + int cur; + int high; + int diff; + void* cur_key; + + low = 0; + cur = 0; + high = ((UgArrayChar*)array)->length; + while (low < high) { +// cur = low + ((high - low) / 2); + cur = low + ((high - low) >> 1); + cur_key = ((UgArrayChar*)array)->at + cur * + ((UgArrayChar*)array)->element_size; + + diff = compare(cur_key, key); + if (diff == 0) { + if (inserted_index) + inserted_index[0] = cur; + return ((UgArrayChar*)array)->at + cur * + ((UgArrayChar*)array)->element_size; + } + else if (diff > 0) + high = cur; + else if (diff < 0) + low = cur + 1; + } + + if (inserted_index) { + if (cur < low) + cur++; + inserted_index[0] = cur; + } + return NULL; +} + +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +// C99 or C++ inline functions in UgArray.h +#else +void* ug_array_insert(void* array, int index, int length) +{ + char* addr; + ug_array_alloc(array, length); + memmove(ug_array_addr(array, index + length), + addr = ug_array_addr(array, index), + ug_array_count(array, ug_array_length(array) - index - 1)); + return (void*)addr; +} + +void ug_array_erase(void* array, int index, int length) +{ + memmove(ug_array_addr(array, index), + ug_array_addr(array, index + length), + ug_array_count(array, ug_array_length(array) - index - 1)); + ((UgArrayChar*)array)->length -= length; +} + +void ug_array_sort(void* array, UgCompareFunc compare) +{ + qsort( ((UgArrayChar*)array)->at, ((UgArrayChar*)array)->length, + ((UgArrayChar*)array)->element_size, compare); +} +#endif // __STDC_VERSION__ + +int ug_array_compare_int(const void *s1, const void *s2) +{ + return *(int*)s1 - *(int*)s2; +} + +int ug_array_compare_string(const void *s1, const void *s2) +{ + return strcmp(*(char**)s1, *(char**)s2); +} + +int ug_array_compare_pointer(const void *s1, const void *s2) +{ + return *(char**)s1 - *(char**)s2; } // ---------------------------------------------------------------------------- // UgJsonParseFunc for JSON array elements -UgJsonError ug_json_parse_array_bool (UgJson* json, - const char* name, const char* value, - void* array, void* none) +UgJsonError ug_json_parse_array_bool(UgJson* json, + const char* name, const char* value, + void* array, void* none) { int boolValue; if (json->type != UG_JSON_TRUE && json->type != UG_JSON_FALSE) { // if (json->type >= UG_JSON_OBJECT) -// ug_json_push (json, ug_json_parse_unknown, NULL, NULL); +// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); return UG_JSON_ERROR_TYPE_NOT_MATCH; } @@ -128,138 +210,138 @@ else boolValue = FALSE; - ((UgArrayInt*)array)->element_size = sizeof (int); - *((int*) ug_array_alloc (array, 1)) = boolValue; + ((UgArrayInt*)array)->element_size = sizeof(int); + *((int*) ug_array_alloc(array, 1)) = boolValue; return UG_JSON_ERROR_NONE; } -UgJsonError ug_json_parse_array_int (UgJson* json, - const char* name, const char* value, - void* array, void* none) +UgJsonError ug_json_parse_array_int(UgJson* json, + const char* name, const char* value, + void* array, void* none) { if (json->type != UG_JSON_NUMBER) { // if (json->type >= UG_JSON_OBJECT) -// ug_json_push (json, ug_json_parse_unknown, NULL, NULL); +// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); return UG_JSON_ERROR_TYPE_NOT_MATCH; } - ((UgArrayInt*)array)->element_size = sizeof (int); - *((int*) ug_array_alloc (array, 1)) = strtol (value, NULL, 10); + ((UgArrayInt*)array)->element_size = sizeof(int); + *((int*) ug_array_alloc(array, 1)) = strtol(value, NULL, 10); return UG_JSON_ERROR_NONE; } -UgJsonError ug_json_parse_array_uint (UgJson* json, - const char* name, const char* value, - void* array, void* none) +UgJsonError ug_json_parse_array_uint(UgJson* json, + const char* name, const char* value, + void* array, void* none) { if (json->type != UG_JSON_NUMBER) { // if (json->type >= UG_JSON_OBJECT) -// ug_json_push (json, ug_json_parse_unknown, NULL, NULL); +// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); return UG_JSON_ERROR_TYPE_NOT_MATCH; } - ((UgArrayInt*)array)->element_size = sizeof (unsigned int); - *((unsigned int*) ug_array_alloc (array, 1)) = strtoul (value, NULL, 10); + ((UgArrayInt*)array)->element_size = sizeof(unsigned int); + *((unsigned int*) ug_array_alloc(array, 1)) = strtoul(value, NULL, 10); return UG_JSON_ERROR_NONE; } -UgJsonError ug_json_parse_array_int64 (UgJson* json, - const char* name, const char* value, - void* array, void* none) +UgJsonError ug_json_parse_array_int64(UgJson* json, + const char* name, const char* value, + void* array, void* none) { if (json->type != UG_JSON_NUMBER) { // if (json->type >= UG_JSON_OBJECT) -// ug_json_push (json, ug_json_parse_unknown, NULL, NULL); +// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); return UG_JSON_ERROR_TYPE_NOT_MATCH; } - ((UgArrayInt*)array)->element_size = sizeof (int64_t); - *((int64_t*) ug_array_alloc (array, 1)) = strtoll (value, NULL, 10); + ((UgArrayInt*)array)->element_size = sizeof(int64_t); + *((int64_t*) ug_array_alloc(array, 1)) = strtoll(value, NULL, 10); return UG_JSON_ERROR_NONE; } -UgJsonError ug_json_parse_array_double (UgJson* json, - const char* name, const char* value, - void* array, void* none) +UgJsonError ug_json_parse_array_double(UgJson* json, + const char* name, const char* value, + void* array, void* none) { if (json->type != UG_JSON_NUMBER) { // if (json->type >= UG_JSON_OBJECT) -// ug_json_push (json, ug_json_parse_unknown, NULL, NULL); +// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); return UG_JSON_ERROR_TYPE_NOT_MATCH; } - ((UgArrayInt*)array)->element_size = sizeof (double); - *((double*) ug_array_alloc (array, 1)) = strtod (value, NULL); + ((UgArrayInt*)array)->element_size = sizeof(double); + *((double*) ug_array_alloc(array, 1)) = strtod(value, NULL); return UG_JSON_ERROR_NONE; } -UgJsonError ug_json_parse_array_string (UgJson* json, - const char* name, const char* value, - void* array, void* none) +UgJsonError ug_json_parse_array_string(UgJson* json, + const char* name, const char* value, + void* array, void* none) { char* string; if (json->type == UG_JSON_STRING) - string = ug_strdup (value); + string = ug_strdup(value); else if (json->type == UG_JSON_NULL) string = NULL; else { // if (json->type >= UG_JSON_OBJECT) -// ug_json_push (json, ug_json_parse_unknown, NULL, NULL); +// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); return UG_JSON_ERROR_TYPE_NOT_MATCH; } - ((UgArrayInt*)array)->element_size = sizeof (char*); - *((char**) ug_array_alloc (array, 1)) = string; + ((UgArrayInt*)array)->element_size = sizeof(char*); + *((char**) ug_array_alloc(array, 1)) = string; return UG_JSON_ERROR_NONE; } // ---------------------------------------------------------------------------- // write JSON array elements -void ug_json_write_array_bool (UgJson* json, UgArrayInt* array) +void ug_json_write_array_bool(UgJson* json, UgArrayInt* array) { // UgArrayInt* array = src; int index; for (index = 0; index < array->length; index++) - ug_json_write_bool (json, array->at[index]); + ug_json_write_bool(json, array->at[index]); } -void ug_json_write_array_int (UgJson* json, UgArrayInt* array) +void ug_json_write_array_int(UgJson* json, UgArrayInt* array) { // UgArrayInt* array = src; int index; for (index = 0; index < array->length; index++) - ug_json_write_int (json, array->at[index]); + ug_json_write_int(json, array->at[index]); } -void ug_json_write_array_uint (UgJson* json, UgArrayUint* array) +void ug_json_write_array_uint(UgJson* json, UgArrayUint* array) { int index; for (index = 0; index < array->length; index++) - ug_json_write_uint (json, array->at[index]); + ug_json_write_uint(json, array->at[index]); } -void ug_json_write_array_int64 (UgJson* json, UgArrayInt64* array) +void ug_json_write_array_int64(UgJson* json, UgArrayInt64* array) { int index; for (index = 0; index < array->length; index++) - ug_json_write_int64 (json, array->at[index]); + ug_json_write_int64(json, array->at[index]); } -void ug_json_write_array_double (UgJson* json, UgArrayDouble* array) +void ug_json_write_array_double(UgJson* json, UgArrayDouble* array) { int index; for (index = 0; index < array->length; index++) - ug_json_write_double (json, array->at[index]); + ug_json_write_double(json, array->at[index]); } -void ug_json_write_array_string (UgJson* json, UgArrayStr* array) +void ug_json_write_array_string(UgJson* json, UgArrayStr* array) { int index; char* string; @@ -267,9 +349,9 @@ for (index = 0; index < array->length; index++) { string = array->at[index]; if (string == NULL) - ug_json_write_null (json); + ug_json_write_null(json); else - ug_json_write_string (json, string); + ug_json_write_string(json, string); } } diff -Nru uget-2.2.0/uglib/UgArray.h uget-2.2.2/uglib/UgArray.h --- uget-2.2.0/uglib/UgArray.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgArray.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -40,6 +40,7 @@ // uintptr_t is an unsigned int that is guaranteed to be the same size as a pointer. #include // uintptr_t, int64_t #include // qsort(), malloc(), free() +#include // memmove() #include #include @@ -48,7 +49,137 @@ #endif // ---------------------------------------------------------------------------- -// UgArray is a template C array. It used by UgEntry with UG_ENTRY_ARRAY. +// UgArray functions + +void ug_array_init(void* array, int element_size, int allocated_len); +void ug_array_clear(void* array); +void* ug_array_alloc(void* array, int nElements); +void ug_array_foreach(void* array, UgForeachFunc func, void* data); +void ug_array_foreach_ptr(void* array, UgForeachFunc func, void* data); + +// Binary search for sorted array +void* ug_array_find_sorted(void* array, const void* key, + UgCompareFunc func, int* index); + +#define ug_array_foreach_str ug_array_foreach_ptr + +#define ug_array_count(array, length) \ + ( ((UgArrayChar*)(array))->element_size * (length) ) + +#define ug_array_addr(array, index) \ + ( ((UgArrayChar*)(array))->at + ((UgArrayChar*)(array))->element_size * (index) ) + +#define ug_array_length(array) \ + ( ((UgArrayChar*)(array))->length ) + +#define ug_array_allocated(array) \ + ( ((UgArrayChar*)(array))->allocated ) + +#define ug_array_element_size(array) \ + ( ((UgArrayChar*)(array))->element_size ) + +// Binary search: +// int compareFunc(const void *s1, const void *s2); +#define ug_array_bsearch(array, key, compareFunc) \ + bsearch(key, (array)->at, (array)->length, (array)->element_size, compareFunc) + +#define ug_array_append(array, values, len) \ + memcpy(ug_array_alloc((array), len), values, ((UgArrayChar*)(array))->element_size * len) + +#define ug_array_terminate0(array) \ + memset(ug_array_alloc((array), 1), 0, ((UgArrayChar*)(array))->element_size) + +#define ug_array_end0(array) \ + *((char*) ug_array_alloc((array), 1)) = 0 + +int ug_array_compare_int(const void *s1, const void *s2); +int ug_array_compare_string(const void *s1, const void *s2); +int ug_array_compare_pointer(const void *s1, const void *s2); + +#ifdef __cplusplus +} +#endif + +// ---------------------------------------------------------------------------- +// ArrayMethod : a template C++ struct is used by UgArray and it's children. + +#ifdef __cplusplus + +// These definitions are used by Ug::ArrayMethod +inline void* ug_array_insert(void* array, int index, int length); +inline void ug_array_erase(void* array, int index, int length); +inline void ug_array_sort(void* array, UgCompareFunc func); + +namespace Ug +{ + +// This one is for derived use only, no data members here. +// This one is NOT for directly use only, it must has UgArray data members. +// Your derived struct/class must be C++11 standard-layout. +template struct ArrayMethod +{ + inline void init(int allocated_len) + { ug_array_init(this, sizeof(Type), allocated_len); } + inline void clear(void) + { ug_array_clear(this); } + + inline Type* alloc(int nElements) + { return (Type*) ug_array_alloc(this, nElements); } + inline Type* erase(int index, int nElements) + { return (Type*) ug_array_erase(this, index, nElements); } + inline Type* insert(int index, int nElements) + { return (Type*) ug_array_insert(this, index, nElements); } + + inline void sort(UgCompareFunc func) + { ug_array_sort(this, func); } + inline Type* findSorted(const Type* key, UgCompareFunc func, int* index) + { return (Type*) ug_array_find_sorted(this, key, func, index); } + inline Type* findSorted(const Type& key, UgCompareFunc func, int* index) + { return (Type*) ug_array_find_sorted(this, &key, func, index); } + + // for specialization + void sort(); + Type* findSorted(Type key, int* index); +}; + +// template specialization +template<> inline void ArrayMethod::sort() +{ + ug_array_sort(this, ug_array_compare_int); +}; + +template<> inline int* ArrayMethod::findSorted(int key, int* index) +{ + int value = key; + return (int*) ug_array_find_sorted(this, &value, ug_array_compare_int, index); +}; + +template<> inline void ArrayMethod::sort() +{ + ug_array_sort(this, ug_array_compare_string); +}; + +template<> inline char** ArrayMethod::findSorted(char* key, int* index) +{ + return (char**) ug_array_find_sorted(this, &key, ug_array_compare_string, index); +}; + +template<> inline void ArrayMethod::sort() +{ + ug_array_sort(this, ug_array_compare_pointer); +}; + +template<> inline void** ArrayMethod::findSorted(void* key, int* index) +{ + return (void**) ug_array_find_sorted(this, &key, ug_array_compare_pointer, index); +}; + +}; // namespace Ug + +#endif // __cplusplus + +// ---------------------------------------------------------------------------- +// UgArray is a template array. It used by UgEntry with UG_ENTRY_ARRAY. #define UG_ARRAY_MEMBERS(Type) \ Type* at; \ @@ -56,8 +187,24 @@ int allocated; \ int element_size +#ifdef __cplusplus +// C++ template works with C macro +template +struct UgArray : Ug::ArrayMethod +{ + UG_ARRAY_MEMBERS(Type); +/* // ------ UgArray members ------ + Type* at; + int length; + int allocated; + int element_size; + */ +}; +#define UG_ARRAY(Type) struct UgArray +#else // implement C++ template by C macro -#define UG_ARRAY(Type) struct { UG_ARRAY_MEMBERS (Type); } +#define UG_ARRAY(Type) struct { UG_ARRAY_MEMBERS(Type); } +#endif // __cplusplus typedef UG_ARRAY(char) UgArrayChar; typedef UG_ARRAY(char*) UgArrayStr; @@ -67,60 +214,93 @@ typedef UG_ARRAY(int64_t) UgArrayInt64; typedef UG_ARRAY(double) UgArrayDouble; -void ug_array_init (void* array, int element_size, int allocated_len); -void ug_array_clear (void* array); -void* ug_array_alloc (void* array, int nElements); -void ug_array_foreach (void* array, UgForeachFunc func, void* data); -void ug_array_foreach_ptr (void* array, UgForeachFunc func, void* data); +// ---------------------------------------------------------------------------- +// C/C++ inline function -#define ug_array_foreach_str ug_array_foreach_ptr +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__cplusplus) +// C99 or C++ inline functions -#define ug_array_append(array, values, len) \ - memcpy (ug_array_alloc ((array), len), values, ((UgArrayChar*)(array))->element_size * len) +#ifdef __cplusplus // C++ +inline +#else // C99 +static inline +#endif +void* ug_array_insert(void* array, int index, int length) +{ + char* addr; + ug_array_alloc(array, length); + memmove(ug_array_addr(array, index + length), + addr = ug_array_addr(array, index), + ug_array_count(array, ug_array_length(array) - index - 1)); + return (void*)addr; +} + +#ifdef __cplusplus // C++ +inline +#else // C99 +static inline +#endif +void ug_array_erase(void* array, int index, int length) +{ + memmove(ug_array_addr(array, index), + ug_array_addr(array, index + length), + ug_array_count(array, ug_array_length(array) - index - 1)); + ((UgArrayChar*)array)->length -= length; +} -#define ug_array_terminate0(array) \ - memset (ug_array_alloc ((array), 1), 0, ((UgArrayChar*)(array))->element_size) +#ifdef __cplusplus // C++ +inline +#else // C99 +static inline +#endif +void ug_array_sort(void* array, UgCompareFunc compare) +{ + qsort( ((UgArrayChar*)array)->at, ((UgArrayChar*)array)->length, + ((UgArrayChar*)array)->element_size, compare); +} -#define ug_array_end0(array) \ - *((char*) ug_array_alloc ((array), 1)) = 0 +#else +// C functions +void* ug_array_insert(void* array, int index, int length); +void ug_array_erase(void* array, int index, int length); +void ug_array_sort(void* array, UgCompareFunc func); // Quick sort -// Quick sort and Binary search: -// int compareFunc(const void *s1, const void *s2); -#define ug_array_sort(array, compareFunc) \ - qsort ((array)->at, (array)->length, (array)->element_size, compareFunc) -#define ug_array_bsearch(array, key, compareFunc) \ - bsearch(key, (array)->at, (array)->length, (array)->element_size, compareFunc) +#endif // __STDC_VERSION__ || __cplusplus // ---------------------------------------------------------------------------- +// JSON parser/writer + +#ifdef __cplusplus +extern "C" { +#endif + // UgJsonParseFunc for JSON array elements -UgJsonError ug_json_parse_array_bool (UgJson* json, - const char* name, const char* value, - void* array, void* none); -UgJsonError ug_json_parse_array_int (UgJson* json, +UgJsonError ug_json_parse_array_bool(UgJson* json, + const char* name, const char* value, + void* array, void* none); +UgJsonError ug_json_parse_array_int(UgJson* json, + const char* name, const char* value, + void* array, void* none); +UgJsonError ug_json_parse_array_uint(UgJson* json, const char* name, const char* value, void* array, void* none); -UgJsonError ug_json_parse_array_uint (UgJson* json, +UgJsonError ug_json_parse_array_int64(UgJson* json, const char* name, const char* value, void* array, void* none); -UgJsonError ug_json_parse_array_int64 (UgJson* json, +UgJsonError ug_json_parse_array_double(UgJson* json, + const char* name, const char* value, + void* array, void* none); +UgJsonError ug_json_parse_array_string(UgJson* json, const char* name, const char* value, void* array, void* none); -UgJsonError ug_json_parse_array_double (UgJson* json, - const char* name, const char* value, - void* array, void* none); -UgJsonError ug_json_parse_array_string (UgJson* json, - const char* name, const char* value, - void* array, void* none); -// ---------------------------------------------------------------------------- // write JSON array elements -void ug_json_write_array_bool (UgJson* json, UgArrayInt* array); -void ug_json_write_array_int (UgJson* json, UgArrayInt* array); -void ug_json_write_array_uint (UgJson* json, UgArrayUint* array); -void ug_json_write_array_int64 (UgJson* json, UgArrayInt64* array); -void ug_json_write_array_double (UgJson* json, UgArrayDouble* array); -void ug_json_write_array_string (UgJson* json, UgArrayStr* array); - +void ug_json_write_array_bool(UgJson* json, UgArrayInt* array); +void ug_json_write_array_int(UgJson* json, UgArrayInt* array); +void ug_json_write_array_uint(UgJson* json, UgArrayUint* array); +void ug_json_write_array_int64(UgJson* json, UgArrayInt64* array); +void ug_json_write_array_double(UgJson* json, UgArrayDouble* array); +void ug_json_write_array_string(UgJson* json, UgArrayStr* array); #ifdef __cplusplus } @@ -133,32 +313,14 @@ namespace Ug { -// This one is for derived use only. No data members here. -// Your derived struct/class must be C++11 standard-layout -template struct ArrayMethod -{ - inline void init (int allocated_len) - { ug_array_init (this, sizeof (Type), allocated_len); } - inline void final (void) - { ug_array_clear (this); } - - inline Type* alloc (int nElements) - { return (Type*) ug_array_alloc (this, nElements); } -}; // This one is for directly use only. You can NOT derived it. -template struct Array : ArrayMethod +template struct Array : UgArray { - UG_ARRAY_MEMBERS (Type); -// Type* at; -// int length; -// int allocated; -// int element_size; - - inline Array (int allocated_len = 0) - { ug_array_init (this, sizeof (Type), allocated_len); } - inline ~Array (void) - { ug_array_clear (this); } +// inline Array(int allocated_len = 0) +// { ug_array_init(this, sizeof(Type), allocated_len); } +// inline ~Array(void) +// { ug_array_clear(this); } }; }; // namespace Ug diff -Nru uget-2.2.0/uglib/UgBuffer.c uget-2.2.2/uglib/UgBuffer.c --- uget-2.2.0/uglib/UgBuffer.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgBuffer.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -39,7 +39,7 @@ #include #include -void ug_buffer_init_external (UgBuffer* buffer, char* exbuf, int length) +void ug_buffer_init_external(UgBuffer* buffer, char* exbuf, int length) { buffer->beg = exbuf; buffer->cur = exbuf; @@ -47,34 +47,34 @@ buffer->more = ug_buffer_restart; } -void ug_buffer_init (UgBuffer* buffer, int length) +void ug_buffer_init(UgBuffer* buffer, int length) { - buffer->beg = ug_malloc (length); + buffer->beg = ug_malloc(length); buffer->cur = buffer->beg; buffer->end = buffer->beg + length; buffer->more = ug_buffer_expand; } -void ug_buffer_clear (UgBuffer* buffer, int free_buffer) +void ug_buffer_clear(UgBuffer* buffer, int free_buffer) { if (free_buffer) - ug_free (buffer->beg); + ug_free(buffer->beg); buffer->beg = NULL; buffer->cur = NULL; buffer->end = NULL; } -void ug_buffer_set_size (UgBuffer* buffer, int length) +void ug_buffer_set_size(UgBuffer* buffer, int length) { char* oldbeg; oldbeg = buffer->beg; - buffer->beg = ug_realloc (buffer->beg, length); + buffer->beg = ug_realloc(buffer->beg, length); buffer->cur = buffer->beg + (buffer->cur - oldbeg); buffer->end = buffer->beg + length; } -char* ug_buffer_alloc (UgBuffer* buffer, int length) +char* ug_buffer_alloc(UgBuffer* buffer, int length) { char* result; int buffer_len; @@ -85,7 +85,7 @@ buffer_len = length * 2; else buffer_len *= 2; - ug_buffer_set_size (buffer, buffer_len); + ug_buffer_set_size(buffer, buffer_len); } result = buffer->cur; buffer->cur += length; @@ -93,68 +93,67 @@ } // UgBuffer.more() default function for external buffer. -int ug_buffer_restart (UgBuffer* buffer) +int ug_buffer_restart(UgBuffer* buffer) { buffer->cur = buffer->beg; return 1; } // UgBuffer.more() default function for internal buffer. -int ug_buffer_expand (UgBuffer* buffer) +int ug_buffer_expand(UgBuffer* buffer) { int length; length = (buffer->end - buffer->beg) * 2; if (length < 1024) length = 1024; - ug_buffer_set_size (buffer, length); + ug_buffer_set_size(buffer, length); return 1; } -void ug_buffer_fill (UgBuffer* buffer, char ch, int count) +void ug_buffer_fill(UgBuffer* buffer, char ch, int count) { while (count--) { if (buffer->cur == buffer->end) - buffer->more (buffer); + buffer->more(buffer); *buffer->cur++ = ch; } } -int ug_buffer_write (UgBuffer* buffer, const char* string, int length) +int ug_buffer_write(UgBuffer* buffer, const char* string, int length) { const char* end; if (length == -1) - length = strlen (string); + length = strlen(string); end = string + length; while (string < end && string[0]) { if (buffer->cur == buffer->end) - buffer->more (buffer); + buffer->more(buffer); *buffer->cur++ = *(uint8_t*)string++; } return length; } -void ug_buffer_write_data (UgBuffer* buffer, const char* binary, int length) +void ug_buffer_write_data(UgBuffer* buffer, const char* binary, int length) { const char* end; end = binary + length; while (binary < end) { if (buffer->cur == buffer->end) - buffer->more (buffer); + buffer->more(buffer); *buffer->cur++ = *binary++; } } #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -// C99 -// inline function in UgBuffer.h +// C99 or C++ inline function in UgBuffer.h #else -void ug_buffer_write_char (UgBuffer* buffer, char ch) +void ug_buffer_write_char(UgBuffer* buffer, char ch) { if ((buffer)->cur >= (buffer)->end) - (buffer)->more (buffer); + (buffer)->more(buffer); *(buffer)->cur++ = (char)(ch); } #endif // __STDC_VERSION__ diff -Nru uget-2.2.0/uglib/UgBuffer.h uget-2.2.2/uglib/UgBuffer.h --- uget-2.2.0/uglib/UgBuffer.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgBuffer.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -43,9 +43,48 @@ extern "C" { #endif +// ---------------------------------------------------------------------------- +// UgBuffer functions + typedef struct UgBuffer UgBuffer; typedef int (*UgBufferFunc) (UgBuffer* buffer); +void ug_buffer_init_external(UgBuffer* buffer, char* exbuf, int length); +void ug_buffer_init(UgBuffer* buffer, int length); + +// If you use ug_buffer_init_external() to init UgBuffer, +// you may not free, resize, or allocate buffer. +void ug_buffer_clear(UgBuffer* buffer, int free_buffer); +void ug_buffer_set_size(UgBuffer* buffer, int length); +char* ug_buffer_alloc(UgBuffer* buffer, int length); + +// UgBuffer.more() default function for external buffer. +int ug_buffer_restart(UgBuffer* buffer); +// UgBuffer.more() default function for internal buffer. +int ug_buffer_expand(UgBuffer* buffer); + +void ug_buffer_fill(UgBuffer* buffer, char ch, int count); + +// return number of bytes written +int ug_buffer_write(UgBuffer* buffer, const char* string, int length); +void ug_buffer_write_data(UgBuffer* buffer, const char* binary, int length); + +#define ug_buffer_length(buffer) (int)((buffer)->cur - (buffer)->beg) +#define ug_buffer_allocated(buffer) (int)((buffer)->end - (buffer)->beg) +#define ug_buffer_remain(buffer) (int)((buffer)->end - (buffer)->cur) + +#ifdef __cplusplus +} +#endif + +// This definition is used by UgBuffer::write(char ch) +#ifdef __cplusplus +inline void ug_buffer_write_char(UgBuffer* buffer, char ch); +#endif + +// ---------------------------------------------------------------------------- +// UgBuffer structure + struct UgBuffer { char* beg; @@ -59,45 +98,73 @@ // return = 0 if no more data (read) UgBufferFunc more; // flush/expand (write) or fill/expand (read) void* data; // extra data for UgBuffer.more() + +#ifdef __cplusplus + // C++11 standard-layout + inline void init(int length) + { ug_buffer_init(this, length); } + inline void init(char* exbuf, int length) + { ug_buffer_init_external(this, exbuf, length); } + + // If you use ug_buffer_init_external() to init UgBuffer, + // you may not free, resize, or allocate buffer. + inline void clear(bool free_buffer) + { ug_buffer_clear(this, free_buffer); } + inline void setSize(int length) + { ug_buffer_set_size(this, length); } + inline char* alloc(int length) + { return ug_buffer_alloc(this, length); } + + inline void fill(char ch, int count) + { ug_buffer_fill(this, ch, count); } + + // return number of bytes written + inline int write(const char* string, int length = -1) + { return ug_buffer_write(this, string, length); } + inline void write(char ch) + { ug_buffer_write_char(this, ch); } + inline void writeData(const char* binary, int length) + { ug_buffer_write_data(this, binary, length); } +#endif // __cplusplus }; -void ug_buffer_init_external (UgBuffer* buffer, char* exbuf, int length); -void ug_buffer_init (UgBuffer* buffer, int length); -void ug_buffer_clear (UgBuffer* buffer, int free_buffer); +// ---------------------------------------------------------------------------- +// C/C++ inline function -void ug_buffer_set_size (UgBuffer* buffer, int length); -char* ug_buffer_alloc (UgBuffer* buffer, int length); +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__cplusplus) +// C99 or C++ inline function -// UgBuffer.more() default function for external buffer. -int ug_buffer_restart (UgBuffer* buffer); -// UgBuffer.more() default function for internal buffer. -int ug_buffer_expand (UgBuffer* buffer); - -void ug_buffer_fill (UgBuffer* buffer, char ch, int count); -int ug_buffer_write (UgBuffer* buffer, const char* string, int length); -void ug_buffer_write_data (UgBuffer* buffer, const char* binary, int length); - -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -// C99 +#ifdef __cplusplus // C++ +inline +#else // C99 static inline -void ug_buffer_write_char (UgBuffer* buffer, char ch) +#endif +void ug_buffer_write_char(UgBuffer* buffer, char ch) { if ((buffer)->cur >= (buffer)->end) - (buffer)->more (buffer); + (buffer)->more(buffer); *(buffer)->cur++ = (char)(ch); } + #else -void ug_buffer_write_char (UgBuffer* buffer, char ch); -#endif // __STDC_VERSION__ +// C function +void ug_buffer_write_char(UgBuffer* buffer, char ch); +#endif // __STDC_VERSION__ || __cplusplus -#define ug_buffer_length(buffer) (int)((buffer)->cur - (buffer)->beg) -#define ug_buffer_allocated(buffer) (int)((buffer)->end - (buffer)->beg) -#define ug_buffer_remain(buffer) (int)((buffer)->end - (buffer)->cur) +// ---------------------------------------------------------------------------- +// C++11 standard-layout #ifdef __cplusplus -} -#endif + +namespace Ug +{ +// This one is for directly use only. You can NOT derived it. +typedef struct UgBuffer Buffer; +}; // namespace Ug + +#endif // __cplusplus + #endif // UG_BUFFER_H diff -Nru uget-2.2.0/uglib/UgData.c uget-2.2.2/uglib/UgData.c --- uget-2.2.0/uglib/UgData.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgData.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -46,124 +46,134 @@ #include #include -// UgData* ug_data_new (const UgDataInfo* iface) -void* ug_data_new (const UgDataInfo* info) +// ---------------------------------------------------------------------------- +// UgTypeInfo +// | +// +-- UgDataInfo + +void* ug_type_new(const void* typeinfo) { UgInitFunc init; - UgData* data; + UgType* type; #ifdef HAVE_GLIB - data = g_slice_alloc0 (info->size); + type = g_slice_alloc0(((UgTypeInfo*)typeinfo)->size); #else - data = ug_malloc0 (info->size); + type = ug_malloc0(((UgTypeInfo*)typeinfo)->size); #endif // HAVE_GLIB - data->info = info; - init = info->init; + type->info = typeinfo; + init = type->info->init; if (init) - init (data); - return data; + init(type); + return type; } -// void ug_data_free (UgData* data) -void ug_data_free (void* data) +void ug_type_free(void* type) { UgFinalFunc final; - final = ((UgData*)data)->info->final; + final = ((UgType*)type)->info->final; if (final) - final (data); + final(type); #ifdef HAVE_GLIB - g_slice_free1 (((UgData*)data)->info->size, data); + g_slice_free1(((UgType*)type)->info->size, type); #else - ug_free (data); + ug_free(type); #endif // HAVE_GLIB } -void ug_data_init (void* data) +void ug_type_init(void* type) { UgInitFunc init; - init = ((UgData*)data)->info->init; + init = ((UgType*)type)->info->init; if (init) - init (data); + init(type); } -void ug_data_final (void* data) +void ug_type_final(void* type) { UgFinalFunc final; - final = ((UgData*)data)->info->final; + final = ((UgType*)type)->info->final; if (final) - final (data); + final(type); } -// UgData* ug_data_copy (UgData* data) -void* ug_data_copy (void* data) +// ---------------------------------------------------------------------------- +// UgData + +// UgData* ug_data_copy(UgData* data) +void* ug_data_copy(void* data) { const UgDataInfo* info; + UgInitFunc init; UgAssignFunc assign; void* newone; if (data) { info = ((UgData*)data)->info; + init = info->init; assign = info->assign; if (assign) { #ifdef HAVE_GLIB - newone = g_slice_alloc0 (info->size); + newone = g_slice_alloc0(info->size); #else - newone = ug_malloc0 (info->size); + newone = ug_malloc0(info->size); #endif ((UgData*)newone)->info = info; - assign (newone, data); + if (init) + init(newone); + assign(newone, data); return newone; } } return NULL; } -//void ug_data_assign (UgData* dest, UgData* src) -int ug_data_assign (void* data, void* src) +//void ug_data_assign(UgData* dest, UgData* src) +int ug_data_assign(void* data, void* src) { UgAssignFunc assign; if (data) { assign = ((UgData*)data)->info->assign; - if (assign) - return assign (data, src); + if(assign) + return assign(data, src); } return FALSE; } // UgJsonParseFunc for UgData, used by UgEntry with UG_ENTRY_CUSTOM -UgJsonError ug_json_parse_data (UgJson* json, - const char* name, const char* value, - void* data, void* none) +UgJsonError ug_json_parse_data(UgJson* json, + const char* name, const char* value, + void* data, void* none) { UgData* ugdata = (UgData*)data; // UgData's type is UG_JSON_OBJECT if (json->type != UG_JSON_OBJECT) { // if (json->type == UG_JSON_ARRAY) -// ug_json_push (json, ug_json_parse_unknown, NULL, NULL); +// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); return UG_JSON_ERROR_TYPE_NOT_MATCH; } if (ugdata->info->entry == NULL) - ug_json_push (json, ug_json_parse_unknown, NULL, NULL); + ug_json_push(json, ug_json_parse_unknown, NULL, NULL); else - ug_json_push (json, ug_json_parse_entry, data, (void*)ugdata->info->entry); + ug_json_push(json, ug_json_parse_entry, data, (void*)ugdata->info->entry); return UG_JSON_ERROR_NONE; } // write UgData, used by UgEntry with UG_ENTRY_CUSTOM -void ug_json_write_data (UgJson* json, const UgData* data) +void ug_json_write_data(UgJson* json, const UgData* data) { - ug_json_write_object_head (json); + ug_json_write_object_head(json); if (data->info->entry) - ug_json_write_entry (json, (void*) data, data->info->entry); - ug_json_write_object_tail (json); + ug_json_write_entry(json, (void*) data, data->info->entry); + ug_json_write_object_tail(json); } diff -Nru uget-2.2.0/uglib/UgData.h uget-2.2.2/uglib/UgData.h --- uget-2.2.0/uglib/UgData.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgData.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -44,63 +44,117 @@ extern "C" { #endif +typedef struct UgType UgType; +typedef struct UgTypeInfo UgTypeInfo; typedef struct UgData UgData; typedef struct UgDataInfo UgDataInfo; typedef int (*UgAssignFunc) (void* instance, void* src); // ---------------------------------------------------------------------------- -// UgDataInfo +// UgTypeInfo: a base type info for UgDataInfo and UgetPluginInfo + +#define UG_TYPE_INFO_MEMBERS \ + const char* name; \ + uintptr_t size; \ + UgInitFunc init; \ + UgFinalFunc final + +struct UgTypeInfo +{ + UG_TYPE_INFO_MEMBERS; +/* // ------ UgTypeInfo members ------ + const char* name; + uintptr_t size; + UgInitFunc init; + UgFinalFunc final; + */ +}; + +// ---------------------------------------------------------------------------- +// UgType: a base type for UgData and UgetPlugin + +#define UG_TYPE_MEMBERS \ + const UgTypeInfo* info + +struct UgType +{ + UG_TYPE_MEMBERS; +// const UgTypeInfo* info; // UgType member +}; + +// void* ug_type_new(const UgTypeInfo* typeinfo); +void* ug_type_new(const void* typeinfo); +void ug_type_free(void* type); +void ug_type_init(void* type); +void ug_type_final(void* type); + +/* ---------------------------------------------------------------------------- + UgDataInfo + + UgTypeInfo + | + `-- UgDataInfo + */ #define UG_DATA_INFO_MEMBERS \ - const char* name; \ - uintptr_t size; \ - const UgEntry* entry; \ - UgInitFunc init; \ - UgFinalFunc final; \ - UgAssignFunc assign + UG_TYPE_INFO_MEMBERS; \ + UgAssignFunc assign; \ + const UgEntry* entry struct UgDataInfo { UG_DATA_INFO_MEMBERS; -// const char* name; -// uintptr_t size; -// const UgEntry* entry; -// UgInitFunc init; -// UgFinalFunc final; -// UgAssignFunc assign; +/* // ------ UgTypeInfo members ------ + const char* name; + uintptr_t size; + UgInitFunc init; + UgFinalFunc final; + + // ------ UgDataInfo members ------ + UgAssignFunc assign; + const UgEntry* entry; + */ }; -// ---------------------------------------------------------------------------- -// UgData +/* ---------------------------------------------------------------------------- + UgData: a group of data that store in UgInfo. + + UgType + | + `-- UgData + */ + #define UG_DATA_MEMBERS \ const UgDataInfo* info struct UgData { UG_DATA_MEMBERS; -// const UgDataInfo* info; +// const UgDataInfo* info; // UgType member }; -// UgData* ug_data_new (const UgDataInfo* dinfo); -// void ug_data_free (UgData* data); -void* ug_data_new (const UgDataInfo* dinfo); -void ug_data_free (void* data); - -void ug_data_init (void* data); -void ug_data_final (void* data); - -// UgData* ug_data_copy (UgData* data); -//void ug_data_assign (UgData* data, UgData* src); -void* ug_data_copy (void* data); -int ug_data_assign (void* data, void* src); +// UgData* ug_data_new(const UgDataInfo* dinfo); +// void ug_data_free(UgData* data); +#define ug_data_new ug_type_new +#define ug_data_free ug_type_free + +// void ug_data_init(void* data); +// void ug_data_final(void* data); +#define ug_data_init ug_type_new +#define ug_data_final ug_type_final + +// UgData* ug_data_copy(UgData* data); +// void ug_data_assign(UgData* data, UgData* src); +void* ug_data_copy(void* data); +int ug_data_assign(void* data, void* src); // UgJsonParseFunc for UgData, used by UgEntry with UG_ENTRY_CUSTOM -UgJsonError ug_json_parse_data (UgJson* json, - const char* name, const char* value, - void* data, void* none); +UgJsonError ug_json_parse_data(UgJson* json, + const char* name, const char* value, + void* data, void* none); // write UgData, used by UgEntry with UG_ENTRY_CUSTOM -void ug_json_write_data (UgJson* json, const UgData* data); +void ug_json_write_data(UgJson* json, const UgData* data); #ifdef __cplusplus @@ -114,29 +168,34 @@ namespace Ug { +typedef struct UgTypeInfo TypeInfo; typedef struct UgDataInfo DataInfo; // This one is for derived use only. No data members here. // Your derived struct/class must be C++11 standard-layout +template struct DataMethod { - inline void init (const UgDataInfo* info) { - *(UgDataInfo**)this = (UgDataInfo*)info; - ug_data_init ((void*)this); - } - inline void init () - { ug_data_init ((void*)this); } - inline void final (void) - { ug_data_final ((void*)this); } - - inline int assign (DataMethod* src) - { return ug_data_assign ((void*)this, (void*)src); } - inline DataMethod* copy (void) - { return (DataMethod*) ug_data_copy ((void*)this); } + inline void* operator new(size_t size, const UgDataInfo* dinfo) + { return ug_data_new(dinfo); } + inline void operator delete(void* p) + { ug_data_free(p); } + + /* + inline void init() + { ug_data_init((void*)this); } + inline void final(void) + { ug_data_final((void*)this); } + */ + + inline int assign(DataType* src) + { return ug_data_assign((void*)this, (void*)src); } + inline DataType* copy(void) + { return (DataType*)ug_data_copy((void*)this); } }; // This one is for directly use only. You can NOT derived it. -struct Data : DataMethod, UgData {}; +struct Data : DataMethod, UgData {}; }; // namespace Ug diff -Nru uget-2.2.0/uglib/UgDefine.h uget-2.2.2/uglib/UgDefine.h --- uget-2.2.0/uglib/UgDefine.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgDefine.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgEntry.c uget-2.2.2/uglib/UgEntry.c --- uget-2.2.0/uglib/UgEntry.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgEntry.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -46,15 +46,15 @@ #define strtoull _strtoui64 #endif -UgJsonError ug_json_parse_entry (UgJson* json, - const char* name, const char* value, - void* dest, void* entry0) +UgJsonError ug_json_parse_entry(UgJson* json, + const char* name, const char* value, + void* dest, void* entry0) { const UgEntry* entry; UgJsonError error = UG_JSON_ERROR_NONE; for (entry = entry0; entry->type; entry++) { - if (entry->name && strcmp (entry->name, name) != 0) + if (entry->name && strcmp(entry->name, name) != 0) continue; // get destination dest = ((char*) dest) + entry->offset; @@ -72,14 +72,14 @@ case UG_ENTRY_INT: if (json->type == UG_JSON_NUMBER) - *(int*) dest = strtol (value, NULL, 10); + *(int*) dest = strtol(value, NULL, 10); else error = UG_JSON_ERROR_TYPE_NOT_MATCH; break; case UG_ENTRY_UINT: if (json->type == UG_JSON_NUMBER) - *(unsigned int*) dest = (unsigned int) strtoul (value, NULL, 10); + *(unsigned int*) dest = (unsigned int) strtoul(value, NULL, 10); else error = UG_JSON_ERROR_TYPE_NOT_MATCH; break; @@ -87,7 +87,7 @@ case UG_ENTRY_INT64: // C99 Standard if (json->type == UG_JSON_NUMBER) - *(int64_t*) dest = strtoll (value, NULL, 10); + *(int64_t*) dest = strtoll(value, NULL, 10); else error = UG_JSON_ERROR_TYPE_NOT_MATCH; break; @@ -95,21 +95,21 @@ case UG_ENTRY_UINT64: // C99 Standard if (json->type == UG_JSON_NUMBER) - *(uint64_t*) dest = strtoull (value, NULL, 10); + *(uint64_t*) dest = strtoull(value, NULL, 10); else error = UG_JSON_ERROR_TYPE_NOT_MATCH; break; case UG_ENTRY_DOUBLE: if (json->type == UG_JSON_NUMBER) - *(double*) dest = strtod (value, NULL); + *(double*) dest = strtod(value, NULL); else error = UG_JSON_ERROR_TYPE_NOT_MATCH; break; case UG_ENTRY_STRING: if (json->type == UG_JSON_STRING) - *(char**) dest = ug_strdup (value); + *(char**) dest = ug_strdup(value); else if (json->type == UG_JSON_NULL) *(char**) dest = NULL; else @@ -120,18 +120,18 @@ if (json->type != UG_JSON_OBJECT) return UG_JSON_ERROR_TYPE_NOT_MATCH; if (entry->param2) - ((UgInitFunc) entry->param2) (dest); - ug_json_push (json, ug_json_parse_entry, dest, entry->param1); + ((UgInitFunc)entry->param2)(dest); + ug_json_push(json, ug_json_parse_entry, dest, entry->param1); return UG_JSON_ERROR_NONE; case UG_ENTRY_ARRAY: if (json->type != UG_JSON_ARRAY) return UG_JSON_ERROR_TYPE_NOT_MATCH; - ug_json_push (json, (UgJsonParseFunc) entry->param1, dest, NULL); + ug_json_push(json, (UgJsonParseFunc) entry->param1, dest, NULL); return UG_JSON_ERROR_NONE; case UG_ENTRY_CUSTOM: - return ((UgJsonParseFunc) entry->param1) (json, name, value, + return ((UgJsonParseFunc)entry->param1)(json, name, value, dest, (void*)entry); default: @@ -144,7 +144,7 @@ // if entry->type != UG_ENTRY_OBJECT or UG_ENTRY_ARRAY // but json->type == UG_JSON_OBJECT or UG_JSON_ARRAY // if (json->type >= UG_JSON_OBJECT) { -// ug_json_push (json, ug_json_parse_unknown, NULL, NULL); +// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); // return UG_JSON_ERROR_TYPE_NOT_MATCH; // } @@ -153,7 +153,7 @@ // ---------------------------------------------------------------------------- -void ug_json_write_entry (UgJson* json, void* src, const UgEntry* entry) +void ug_json_write_entry(UgJson* json, void* src, const UgEntry* entry) { union { void* src; @@ -173,76 +173,84 @@ switch (entry->type) { case UG_ENTRY_BOOL: if (entry->name) - ug_json_write_string (json, entry->name); - ug_json_write_bool (json, *(value.pint)); + ug_json_write_string(json, entry->name); + ug_json_write_bool(json, *(value.pint)); break; case UG_ENTRY_INT: if (entry->name) - ug_json_write_string (json, entry->name); - ug_json_write_int (json, *(value.pint)); + ug_json_write_string(json, entry->name); + ug_json_write_int(json, *(value.pint)); break; case UG_ENTRY_UINT: if (entry->name) - ug_json_write_string (json, entry->name); - ug_json_write_uint (json, *(value.puint)); + ug_json_write_string(json, entry->name); + ug_json_write_uint(json, *(value.puint)); break; case UG_ENTRY_INT64: if (entry->name) - ug_json_write_string (json, entry->name); - ug_json_write_int64 (json, *(value.pint64)); + ug_json_write_string(json, entry->name); + ug_json_write_int64(json, *(value.pint64)); break; case UG_ENTRY_UINT64: if (entry->name) - ug_json_write_string (json, entry->name); - ug_json_write_uint64 (json, *(value.puint64)); + ug_json_write_string(json, entry->name); + ug_json_write_uint64(json, *(value.puint64)); break; case UG_ENTRY_DOUBLE: if (entry->name) - ug_json_write_string (json, entry->name); - ug_json_write_double (json, *(value.pdouble)); + ug_json_write_string(json, entry->name); + ug_json_write_double(json, *(value.pdouble)); break; case UG_ENTRY_STRING: - // for UG_ENTRY_SKIP_IF_NULL - if (entry->param1 && *(value.pstring) == NULL) + // for UG_ENTRY_NO_NULL + if ((entry->param2==UG_ENTRY_NO_NULL) && *(value.pstring) == NULL) break; if (entry->name) - ug_json_write_string (json, entry->name); - ug_json_write_string (json, *(value.pstring)); + ug_json_write_string(json, entry->name); + ug_json_write_string(json, *(value.pstring)); break; case UG_ENTRY_OBJECT: if (entry->name) - ug_json_write_string (json, entry->name); - ug_json_write_object_head (json); - ug_json_write_entry (json, value.src, entry->param1); - ug_json_write_object_tail (json); + ug_json_write_string(json, entry->name); + ug_json_write_object_head(json); + ug_json_write_entry(json, value.src, entry->param1); + ug_json_write_object_tail(json); break; case UG_ENTRY_ARRAY: + // Don't output if no UgJsonWriteFunc in entry->param2. + if (entry->param2 == NULL) + break; + if (entry->name) - ug_json_write_string (json, entry->name); - ug_json_write_array_head (json); - ((UgJsonWriteFunc) entry->param2) (json, value.src, (void*)entry); - ug_json_write_array_tail (json); + ug_json_write_string(json, entry->name); + ug_json_write_array_head(json); + ((UgJsonWriteFunc)entry->param2)(json, value.src, (void*)entry); + ug_json_write_array_tail(json); break; case UG_ENTRY_CUSTOM: + // Don't output if no UgJsonWriteFunc in entry->param2. + if (entry->param2 == NULL) + break; + if (entry->param2 == (void*) ug_json_write_value) { // for UgValue only if (value.pvalue->type == UG_VALUE_NONE) continue; if (value.pvalue->name == NULL) - ug_json_write_string (json, entry->name); + ug_json_write_string(json, entry->name); } else if (entry->name) - ug_json_write_string (json, entry->name); - ((UgJsonWriteFunc) entry->param2) (json, value.src, (void*)entry); + ug_json_write_string(json, entry->name); + ((UgJsonWriteFunc) entry->param2)(json, value.src, (void*)entry); break; default: diff -Nru uget-2.2.0/uglib/UgEntry.h uget-2.2.2/uglib/UgEntry.h --- uget-2.2.0/uglib/UgEntry.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgEntry.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -67,64 +67,65 @@ UG_ENTRY_CUSTOM, // JSON value, C functions were used. } UgEntryType; -// You can set this in UgEntry.param1 when UgEntry.type is UG_ENTRY_STRING. +// You can set this in UgEntry.param2 when UgEntry.type is UG_ENTRY_STRING. // ug_json_write_entry() will not output this field when value is NULL. -#define UG_ENTRY_SKIP_IF_NULL ((void*)(uintptr_t) 1) +#define UG_ENTRY_NO_NULL ((void*)(uintptr_t) 0x0001) // ---------------------------------------------------------------------------- // UgEntry: It can defines a object member and it's offset of data structure. -// ------------------------------------ -// sample for JSON - -// typedef struct -// { -// char* user; -// int number; -// } Foo; -// -// static UgEntry FooEntry[] = -// { -// { "user", offsetof (Foo, user), UG_ENTRY_STRING, NULL, NULL}, -// { "number", offsetof (Foo, number), UG_ENTRY_INT, NULL, NULL}, -// { NULL } // null-terminated -// }; -// -// JSON output: -// { -// "user": "guest3", -// "number": 2500, -// } - -// if UgEntry.type == 0, this entry is null-terminated. - -// if UgEntry.name == NULL, it can match no name or any name. -// it usually uses at first or last entry. - -// UgEntryType = UG_ENTRY_STRING -// If you don't want to output anything when string value is NULL, -// set UgEntry.param1 to UG_ENTRY_SKIP_IF_NULL. - -// UgEntryType = UG_ENTRY_OBJECT -// UgEntry.param1 pointer to UgEntry -// UgEntry.param2 pointer to UgInitFunc -// --------- -// if (UgInitFunc) -// UgInitFunc (UserData); - -// UgEntryType = UG_ENTRY_ARRAY -// UgEntry.param1 = UgJsonParseFunc, how to parse JSON array elements. -// UgEntry.param2 = UgJsonWriteFunc, how to write JSON array elements. -// --------- -// parser call UgEntry.param1 to parse JSON array. -// writer call UgEntry.param2 to write JSON array. - -// UgEntryType = UG_ENTRY_CUSTOM -// UgEntry.param1 = UgJsonParseFunc, how to parse JSON value. -// UgEntry.param2 = UgJsonWriteFunc, how to write JSON value. -// --------- -// parser call UgEntry.param1 to parse JSON value. -// writer call UgEntry.param2 to write JSON value. +/* + // --- UgEntry sample for JSON --- + typedef struct + { + char* user; + int number; + } Foo; + + static UgEntry FooEntry[] = + { + { "user", offsetof(Foo, user), UG_ENTRY_STRING, NULL, NULL}, + { "number", offsetof(Foo, number), UG_ENTRY_INT, NULL, NULL}, + { NULL } // null-terminated + }; + + // --- JSON output: --- + { + "user": "guest3", + "number": 2500, + } + + ------------------------------------------------------- + if UgEntry.type == 0, this entry is null-terminated. + + if UgEntry.name == NULL, it can match no name or any name. + it usually uses at first or last entry. + + UgEntryType = UG_ENTRY_STRING + If you don't want to output anything when string value is NULL, + set UG_ENTRY_NO_NULL at UgEntry.param2. + + UgEntryType = UG_ENTRY_OBJECT + UgEntry.param1 pointer to UgEntry + UgEntry.param2 pointer to UgInitFunc + --------- + if (UgInitFunc) + UgInitFunc(UserData); + + UgEntryType = UG_ENTRY_ARRAY + UgEntry.param1 = UgJsonParseFunc, how to parse JSON array elements. + UgEntry.param2 = UgJsonWriteFunc, how to write JSON array elements. + --------- + parser call UgEntry.param1 to parse JSON array. + writer call UgEntry.param2 to write JSON array. + + UgEntryType = UG_ENTRY_CUSTOM + UgEntry.param1 = UgJsonParseFunc, how to parse JSON value. + UgEntry.param2 = UgJsonWriteFunc, how to write JSON value. + --------- + parser call UgEntry.param1 to parse JSON value. + writer call UgEntry.param2 to write JSON value. + */ struct UgEntry { @@ -137,12 +138,12 @@ }; // parse JSON value by UgEntry -UgJsonError ug_json_parse_entry (UgJson* json, - const char* name, const char* value, - void* dest, void* entry); +UgJsonError ug_json_parse_entry(UgJson* json, + const char* name, const char* value, + void* dest, void* entry); // write JSON value by UgEntry -void ug_json_write_entry (UgJson* json, void* src, const UgEntry* entry); +void ug_json_write_entry(UgJson* json, void* src, const UgEntry* entry); #ifdef __cplusplus } diff -Nru uget-2.2.0/uglib/UgFileUtil.c uget-2.2.2/uglib/UgFileUtil.c --- uget-2.2.0/uglib/UgFileUtil.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgFileUtil.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -313,6 +313,7 @@ #endif // _WIN32 || _WIN64 +#ifndef USE__ANDROID__SAF int ug_create_dir_all (const char* dir, int len) { const char* dir_end; @@ -353,8 +354,8 @@ if (element_os == NULL) break; - if (ug_create_dir (element_os) == -1) { - if (ug_file_is_exist (element_os) == FALSE) { + if (ug_file_is_exist (element_os) == FALSE) { + if (ug_create_dir (element_os) == -1) { ug_free (element_os); return -1; } @@ -363,6 +364,7 @@ } return -1; } +#endif // USE__ANDROID__SAF // ---------------------------------------------------------------------------- // File I/O diff -Nru uget-2.2.0/uglib/UgFileUtil.h uget-2.2.2/uglib/UgFileUtil.h --- uget-2.2.0/uglib/UgFileUtil.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgFileUtil.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgHtml.c uget-2.2.2/uglib/UgHtml.c --- uget-2.2.0/uglib/UgHtml.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgHtml.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgHtmlEntry.c uget-2.2.2/uglib/UgHtmlEntry.c --- uget-2.2.0/uglib/UgHtmlEntry.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgHtmlEntry.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgHtmlEntry.h uget-2.2.2/uglib/UgHtmlEntry.h --- uget-2.2.0/uglib/UgHtmlEntry.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgHtmlEntry.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -66,31 +66,31 @@ const char** attribute_values, void* dest, void* entry); +/* + UgHtmlEntry.name = element_name + UgHtmlEntry.offset = offset of structure -// UgHtmlEntry.name = element_name -// UgHtmlEntry.offset = offset of structure - -// if UgHtmlEntry.parser == NULL, this entry is null-terminated. - -// if UgHtmlEntry.name == NULL, it can match any name. -// it usually uses at first or last entry. + if UgHtmlEntry.parser == NULL, this entry is null-terminated. -// if UgHtmlEntry.parser == ug_html_parser_custom -// UgEntry.param1 = start element function (UgHtmlParserStartElementFunc) -// UgEntry.param2 = custom writer function + if UgHtmlEntry.name == NULL, it can match any name. + it usually uses at first or last entry. -// UgHtmlEntry.parser == ug_html_parser_int, ug_html_parser_string...etc -// UgHtmlEntry.param2 = UgHtmlEntry for attribute + if UgHtmlEntry.parser == ug_html_parser_custom + UgEntry.param1 = start element function (UgHtmlParserStartElementFunc) + UgEntry.param2 = custom writer function -// UgHtmlEntry.parser == ug_html_parser_string -// If you don't want to output anything when string value is NULL, -// set UgHtmlEntry.param1 != NULL. -// UgHtmlEntry.param2 = UgHtmlEntry for attribute + UgHtmlEntry.parser == ug_html_parser_int, ug_html_parser_string...etc + UgHtmlEntry.param2 = UgHtmlEntry for attribute -// UgHtmlEntry.parser == ug_html_parser_entry -// UgHtmlEntry.param1 = UgHtmlEntry -// UgHtmlEntry.param2 = UgHtmlEntry for attribute + UgHtmlEntry.parser == ug_html_parser_string + If you don't want to output anything when string value is NULL, + set NULL at UgHtmlEntry.param1. + UgHtmlEntry.param2 = UgHtmlEntry for attribute + UgHtmlEntry.parser == ug_html_parser_entry + UgHtmlEntry.param1 = UgHtmlEntry + UgHtmlEntry.param2 = UgHtmlEntry for attribute + */ // ------------------------------------ // parser for unknown element diff -Nru uget-2.2.0/uglib/UgHtmlFilter.c uget-2.2.2/uglib/UgHtmlFilter.c --- uget-2.2.0/uglib/UgHtmlFilter.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgHtmlFilter.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgHtmlFilter.h uget-2.2.2/uglib/UgHtmlFilter.h --- uget-2.2.0/uglib/UgHtmlFilter.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgHtmlFilter.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgHtml.h uget-2.2.2/uglib/UgHtml.h --- uget-2.2.0/uglib/UgHtml.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgHtml.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgInfo.c uget-2.2.2/uglib/UgInfo.c --- uget-2.2.0/uglib/UgInfo.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgInfo.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -43,12 +43,12 @@ static UgRegistry* ug_info_registry; -UgRegistry* ug_info_get_registry (void) +UgRegistry* ug_info_get_registry(void) { return ug_info_registry; } -void ug_info_set_registry (UgRegistry* registry) +void ug_info_set_registry(UgRegistry* registry) { ug_info_registry = registry; } @@ -56,20 +56,53 @@ // ---------------------------------------------------------------------------- // UgInfo -void ug_info_init (UgInfo* info, int allocated_len, int cache_len) +UgInfo* ug_info_new(int allocated_length, int cache_length) +{ + UgInfo* info; + +#ifdef HAVE_GLIB + info = g_slice_alloc(sizeof(UgInfo)); +#else + info = ug_malloc(sizeof(UgInfo)); +#endif // HAVE_GLIB + ug_info_init(info, allocated_length, cache_length); + return info; +} + +void ug_info_ref(UgInfo* info) +{ + info->ref_count++; +} + +void ug_info_unref(UgInfo* info) +{ + if (--info->ref_count == 0) { + ug_info_final(info); +#ifdef HAVE_GLIB + g_slice_free1(sizeof(UgInfo), info); +#else + ug_free(info); +#endif // HAVE_GLIB + } +} + +void ug_info_init(UgInfo* info, int allocated_length, int cache_length) { int index; - ug_array_init (info, sizeof (UgPair), allocated_len + cache_len); - info->length = cache_len; - info->cache_len = cache_len; - for (index = 0; index < info->allocated; index++) { + ug_array_init(info, sizeof(UgPair), allocated_length + cache_length); + info->length = cache_length; + info->cache_length = cache_length; + info->ref_count = 1; + + // clear cache + for (index = 0; index < info->length; index++) { info->at[index].key = NULL; info->at[index].data = NULL; } } -void ug_info_final (UgInfo* info) +void ug_info_final(UgInfo* info) { UgPair* cur; UgPair* end; @@ -78,87 +111,89 @@ if (cur->key == NULL) continue; if (cur->data) - ug_data_free (cur->data); + ug_data_free(cur->data); } - ug_array_clear (info); + ug_array_clear(info); } -UgPair* ug_info_find (UgInfo* info, const UgDataInfo* key, int* inserted_index) +UgPair* ug_info_find(UgInfo* info, const UgDataInfo* key, int* index) { - UgPair* low; + UgPair* end; UgPair* cur; - UgPair* high; - const UgDataInfo* cur_key; - for (cur = info->at, low = cur + info->cache_len; cur < low; cur++) { + // find key in cache space + for (cur = info->at, end = cur + info->cache_length; cur < end; cur++) { if (cur->key == key) return cur; } - high = info->at + info->length; - while (low < high) { -// cur = low + ((high - low) / 2); - cur = low + ((high - low) >> 1); - cur_key = cur->key; - - if (cur_key == key) - return cur; - else if (cur_key > key) - high = cur; - else if (cur_key < key) - low = cur + 1; - } - - if (inserted_index) { - if (cur < low) - cur++; - *inserted_index = cur - info->at; - } - return NULL; + // find key without cache space + info->at += info->cache_length; + info->length -= info->cache_length; + cur = ug_array_find_sorted(info, &key, ug_array_compare_pointer, index); + info->at -= info->cache_length; + info->length += info->cache_length; + if (index) + index[0] += info->cache_length; + return cur; } -void* ug_info_realloc (UgInfo* info, const UgDataInfo* key) +void* ug_info_realloc(UgInfo* info, const UgDataInfo* key) { UgPair* cur; int index; - cur = ug_info_find (info, key, &index); + cur = ug_info_find(info, key, &index); if (cur == NULL) { - ug_array_alloc (info, 1); - memmove (info->at + index + 1, info->at + index, - sizeof (UgPair) * (info->length - index - 1)); - cur = info->at + index; + cur = ug_array_insert(info, index, 1); cur->key = (void*) key; - cur->data = ug_data_new (key); + cur->data = ug_data_new(key); } else if (cur->data == NULL) - cur->data = ug_data_new (key); + cur->data = ug_data_new(key); return cur->data; } -void ug_info_remove (UgInfo* info, const UgDataInfo* key) +void ug_info_remove(UgInfo* info, const UgDataInfo* key) { UgPair* cur; - cur = ug_info_find (info, key, NULL); + cur = ug_info_find(info, key, NULL); if (cur && cur->data) { - ug_data_free (cur->data); + ug_data_free(cur->data); cur->data = NULL; } } -void* ug_info_get (UgInfo* info, const UgDataInfo* key) +void* ug_info_set(UgInfo* info, const UgDataInfo* key, void* data) { UgPair* cur; + int index; + void* result; - cur = ug_info_find (info, key, NULL); + cur = ug_info_find(info, key, &index); + if (cur == NULL) { + cur = ug_array_insert(info, index, 1); + cur->key = (void*) key; + cur->data = NULL; + } + result = cur->data; + cur->data = data; + return result; +} + +void* ug_info_get(UgInfo* info, const UgDataInfo* key) +{ + UgPair* cur; + + cur = ug_info_find(info, key, NULL); if (cur == NULL) return NULL; return cur->data; } -void ug_info_assign (UgInfo* info, UgInfo* src, const UgDataInfo* exclude_info) +void ug_info_assign(UgInfo* info, UgInfo* src, const UgDataInfo* exclude_info) { int index; UgPair* pair; @@ -170,13 +205,13 @@ continue; if (pair->key == exclude_info) continue; - data = ug_info_realloc (info, pair->key); - ug_data_assign (data, pair->data); + data = ug_info_realloc(info, pair->key); + ug_data_assign(data, pair->data); } } // UgJsonParseFunc for key/data pairs in UgInfo -static UgJsonError ug_json_parse_info_reg (UgJson* json, +static UgJsonError ug_json_parse_info_reg(UgJson* json, const char* name, const char* value, void* info, void* infoRegistry) { @@ -192,57 +227,77 @@ if (registry) { if (registry->sorted == FALSE) - ug_registry_sort (registry); - cur = ug_registry_find (registry, name, NULL); + ug_registry_sort(registry); + cur = ug_registry_find(registry, name, NULL); if (cur) { - ug_json_push (json, ug_json_parse_entry, - ug_info_realloc (info, cur->data), + ug_json_push(json, ug_json_parse_entry, + ug_info_realloc(info, cur->data), (void*)((UgDataInfo*)cur->data)->entry); return UG_JSON_ERROR_NONE; } } if (json->type >= UG_JSON_OBJECT) - ug_json_push (json, ug_json_parse_unknown, NULL, NULL); + ug_json_push(json, ug_json_parse_unknown, NULL, NULL); return UG_JSON_ERROR_CUSTOM; } // ---------------- +// JSON parser/writer that used with UG_ENTRY_CUSTOM. -// JSON parser for UgInfo. -UgJsonError ug_json_parse_info (UgJson* json, - const char* name, const char* value, - void* info, void* none) +// JSON parser for UgInfo pointer. +UgJsonError ug_json_parse_info_ptr(UgJson* json, + const char* name, const char* value, + void** pinfo, void* none) { + UgInfo* info = *pinfo; + // UgInfo's type is UG_JSON_OBJECT if (json->type != UG_JSON_OBJECT) { // if (json->type == UG_JSON_ARRAY) -// ug_json_push (json, ug_json_parse_unknown, NULL, NULL); +// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); return UG_JSON_ERROR_TYPE_NOT_MATCH; } - ug_json_push (json, ug_json_parse_info_reg, info, NULL); + // confirm that target UgInfo is empty. This can avoid parsing UgInfo repeatedly. + if (info->length == info->cache_length) + ug_json_push(json, ug_json_parse_info_reg, info, NULL); return UG_JSON_ERROR_NONE; } -// JSON writer for UgInfo. -void ug_json_write_info (UgJson* json, const UgInfo* info) +// JSON writer for UgInfo pointer. +void ug_json_write_info_ptr(UgJson* json, UgInfo** pinfo) { + UgInfo* info = *pinfo; UgPair* cur; UgPair* end; - ug_json_write_object_head (json); + ug_json_write_object_head(json); for (cur = info->at, end = cur + info->length; cur < end; cur++) { if (cur->data == NULL || ((UgDataInfo*)cur->key)->entry == NULL) continue; - ug_json_write_string (json, ((UgDataInfo*)cur->key)->name); - ug_json_write_object_head (json); - ug_json_write_entry (json, cur->data, + ug_json_write_string(json, ((UgDataInfo*)cur->key)->name); + ug_json_write_object_head(json); + ug_json_write_entry(json, cur->data, ((UgDataInfo*)cur->key)->entry); - ug_json_write_object_tail (json); + ug_json_write_object_tail(json); } - ug_json_write_object_tail (json); + ug_json_write_object_tail(json); +} + +// JSON parser for UgInfo. +UgJsonError ug_json_parse_info(UgJson* json, + const char* name, const char* value, + void* info, void* none) +{ + return ug_json_parse_info_ptr(json, name, value, &info, none); +} + +// JSON writer for UgInfo. +void ug_json_write_info(UgJson* json, UgInfo* info) +{ + ug_json_write_info_ptr(json, &info); } diff -Nru uget-2.2.0/uglib/UgInfo.h uget-2.2.2/uglib/UgInfo.h --- uget-2.2.0/uglib/UgInfo.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgInfo.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -47,83 +47,123 @@ typedef struct UgInfo UgInfo; -// ---------------------------------------------------------------------------- -// UgRegistry for UgInfo +/* ---------------------------------------------------------------------------- + This UgRegistry used by UgInfo. + User can only store UgDataInfo in this UgRegistry. + key pointer to UgDataInfo.name + data pointer to UgDataInfo + */ -UgRegistry* ug_info_get_registry (void); -void ug_info_set_registry (UgRegistry* registry); +UgRegistry* ug_info_get_registry(void); +void ug_info_set_registry(UgRegistry* registry); -// ---------------------------------------------------------------------------- -// UgInfo +/* ---------------------------------------------------------------------------- + UgInfo - collection of UgDataInfo and UgData + - It uses UgDataInfo to get/alloc UgData. + key pointer to UgDataInfo + data pointer to UgData + */ -void ug_info_init (UgInfo* info, int allocated_len, int cache_len); -void ug_info_final (UgInfo* info); +// ---------------------------------------------------------------------------- +// UgInfo functions -void* ug_info_realloc (UgInfo* info, const UgDataInfo* key); -void ug_info_remove (UgInfo* info, const UgDataInfo* key); -void* ug_info_get (UgInfo* info, const UgDataInfo* key); -UgPair* ug_info_find (UgInfo* info, const UgDataInfo* key, int* inserted_index); +UgInfo* ug_info_new(int allocated_length, int cache_length); +void ug_info_ref(UgInfo* info); +void ug_info_unref(UgInfo* info); + +void ug_info_init(UgInfo* info, int allocated_length, int cache_length); +void ug_info_final(UgInfo* info); + +// ug_info_get() and ug_info_realloc() return UgData +// ug_info_set() replace old data by new one. It return old UgData +void* ug_info_realloc(UgInfo* info, const UgDataInfo* key); +void ug_info_remove(UgInfo* info, const UgDataInfo* key); +void* ug_info_get(UgInfo* info, const UgDataInfo* key); +void* ug_info_set(UgInfo* info, const UgDataInfo* key, void* new_data); +UgPair* ug_info_find(UgInfo* info, const UgDataInfo* key, int* inserted_index); -void ug_info_assign (UgInfo* info, UgInfo* src, const UgDataInfo* exclude); +void ug_info_assign(UgInfo* info, UgInfo* src, const UgDataInfo* exclude); // ---------------- -// JSON parser that used with UG_ENTRY_CUSTOM. -// if (UgRegistry*)registry == NULL, use default registry. -UgJsonError ug_json_parse_info (UgJson* json, - const char* name, const char* value, - void* info, void* registry); -// JSON writer that used with UG_ENTRY_CUSTOM. -void ug_json_write_info (UgJson* json, const UgInfo* info); - -// JSON: -// -// { -// "progress": { -// }, -// "common": { -// }, -// "log": { -// } -// } -// +// JSON parser/writer that used with UG_ENTRY_CUSTOM. +// if 'registry' is NULL, use default registry. + +UgJsonError ug_json_parse_info_ptr(UgJson* json, + const char* name, const char* value, + void** pinfo, void* registry); +void ug_json_write_info_ptr(UgJson* json, UgInfo** pinfo); + +UgJsonError ug_json_parse_info(UgJson* json, + const char* name, const char* value, + void* info, void* registry); +void ug_json_write_info(UgJson* json, UgInfo* info); + +/* + // --- JSON output sample --- + { + "progress": { + }, + "common": { + }, + "log": { + } + } + */ #ifdef __cplusplus } #endif +// ---------------------------------------------------------------------------- +// UgInfo structure + struct UgInfo { - UG_ARRAY_MEMBERS (UgPair); -// UgPair* at; -// int length; -// int allocated; -// int element_size; + UG_ARRAY_MEMBERS(UgPair); +/* // ------ UgArray members ------ + UgPair* at; + int length; + int allocated; + int element_size; + */ - int cache_len; + int cache_length; + int ref_count; #ifdef __cplusplus // C++11 standard-layout - inline UgInfo (void) {} - inline UgInfo (int allocated_len, int cache_len) - { ug_info_init (this, allocated_len, cache_len); } - - inline void init (int allocated_len, int cache_len) - { ug_info_init (this, allocated_len, cache_len); } - inline void final (void) - { ug_info_final (this); } - - inline void remove (const UgDataInfo* key) - { ug_info_remove (this, key); } - inline Ug::DataMethod* realloc (const UgDataInfo* key) - { return (Ug::DataMethod*)ug_info_realloc (this, key); } - inline Ug::DataMethod* get (const UgDataInfo* key) - { return (Ug::DataMethod*)ug_info_get (this, key); } + inline void* operator new(size_t size, int allocated_length, int cache_length) + { return ug_info_new(allocated_length, cache_length); } + inline void operator delete(void* p) + { ug_info_unref((UgInfo*)p); } + + inline void ref() + { ug_info_ref(this); } + inline void unref() + { ug_info_unref(this); } + + inline void init(int allocatedLength, int cacheLength) + { ug_info_init(this, allocatedLength, cacheLength); } + inline void final(void) + { ug_info_final(this); } + + inline void remove(const UgDataInfo* key) + { ug_info_remove(this, key); } + inline void* realloc(const UgDataInfo* key) + { return ug_info_realloc(this, key); } + inline void* get(const UgDataInfo* key) + { return ug_info_get(this, key); } + inline void* set(const UgDataInfo* key, void* new_data) + { return ug_info_set(this, key, new_data); } + + inline void assign(UgInfo* src, const UgDataInfo* exclude) + { ug_info_assign(this, src, exclude); } // static method - static inline UgRegistry* getRegistry (void) - { return ug_info_get_registry (); } - static inline void setRegistry (UgRegistry* registry) - { ug_info_set_registry (registry); } + static inline UgRegistry* getRegistry(void) + { return ug_info_get_registry(); } + static inline void setRegistry(UgRegistry* registry) + { ug_info_set_registry(registry); } #endif // __cplusplus }; diff -Nru uget-2.2.0/uglib/UgJson.c uget-2.2.2/uglib/UgJson.c --- uget-2.2.0/uglib/UgJson.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgJson.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgJson-custom.c uget-2.2.2/uglib/UgJson-custom.c --- uget-2.2.0/uglib/UgJson-custom.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgJson-custom.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -49,134 +49,197 @@ // ---------------------------------------------------------------------------- -UgJsonError ug_json_parse_int_string (UgJson* json, - const char* name, const char* value, - void* dest, void* data) +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); +// 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); + *(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) +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); +// 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); + *(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) +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); +// 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); + *(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) +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); +// 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); + *(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) +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) +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) +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); + 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) +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_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; +} + +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_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) +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); +// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); // return UG_JSON_ERROR_TYPE_NOT_MATCH; // } @@ -190,16 +253,16 @@ break; // case UG_JSON_NUMBER: -// if (strtol (value, NULL, 10) == 0) +// if (strtol(value, NULL, 10) == 0) // *(int*) dest = FALSE; // else // *(int*) dest = TRUE; // break; case UG_JSON_STRING: - if (strcmp (value, "true") == 0) + if (strcmp(value, "true") == 0) *(int*) dest = TRUE; - else if (strcmp (value, "false") == 0) + else if (strcmp(value, "false") == 0) *(int*) dest = FALSE; break; @@ -209,25 +272,25 @@ return UG_JSON_ERROR_NONE; } -void ug_json_write_bool_string (UgJson* json, int* value) +void ug_json_write_bool_string(UgJson* json, int* value) { if (*value == FALSE) - ug_json_write_string (json, "false"); + ug_json_write_string(json, "false"); else - ug_json_write_string (json, "true"); + 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); + *(time_t*) dest = strtoll(value, NULL, 10); return UG_JSON_ERROR_NONE; #else struct tm timem; @@ -242,42 +305,42 @@ *(time_t*) dest = mktime(timem); // if (json->type >= UG_JSON_OBJECT) { -// ug_json_push (json, ug_json_parse_unknown, NULL, NULL); +// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); // return UG_JSON_ERROR_TYPE_NOT_MATCH; // } #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; + struct tm* timem; char* timestr; - timem = gmtime ((time_t*) dest); // localtime ((time_t*) dest); - timestr = ug_malloc (32); + 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); + 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 } // ---------------------------------------------------------------------------- // UgJson reparse UgValue: this can convert UgValue to UgEntry // e.g. -// ug_json_begin_parse (json); -// ug_json_push (json, ug_json_parse_entry, entry, dest, data); -// ug_json_reparse_value (json, value); -// ug_json_end_parse (json); +// ug_json_begin_parse(json); +// ug_json_push(json, ug_json_parse_entry, entry, dest, data); +// ug_json_reparse_value(json, value); +// ug_json_end_parse(json); enum { PARSER_STACK_BASE, // 0 @@ -289,7 +352,7 @@ }; // static function -static void ug_json_call_parser_value (UgJson* json, UgValue* uvalue, const char* value) +static void ug_json_call_parser_value(UgJson* json, UgValue* uvalue, const char* value) { UgJsonParseFunc parser; void** stack; @@ -301,17 +364,17 @@ 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)); + 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); + ug_json_push(json, ug_json_parse_unknown, NULL, NULL); } // reset state @@ -321,7 +384,7 @@ json->buf.length = 1; } -void ug_json_parse_by_value (UgJson* json, UgValue* value) +void ug_json_parse_by_value(UgJson* json, UgValue* value) { UgValue* end; @@ -333,134 +396,82 @@ case UG_VALUE_OBJECT: json->type = UG_JSON_OBJECT; - ug_json_call_parser_value (json, value, NULL); + 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); + 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); + 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); + 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"); + ug_json_call_parser_value(json, value, "false"); } else { json->type = UG_JSON_TRUE; - ug_json_call_parser_value (json, value, "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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + ug_json_call_parser_value(json, value, NULL); } else { json->type = UG_JSON_STRING; - ug_json_call_parser_value (json, value, value->c.string); + ug_json_call_parser_value(json, value, value->c.string); } break; } } - -// ---------------------------------------------------------------------------- -// UgValue use UgValueCustom and UgEntry - -#ifdef HAVE_UG_VALUE_CUSTOM - -// parse JSON object by UgEntry. -static UgJsonError parse_entry_object (UgJson* json, - const char* name, const char* value, - void* dest, void* entry) -{ - if (json->type != UG_JSON_OBJECT) { -// if (json->type == UG_JSON_ARRAY) -// ug_json_push (json, ug_json_parse_unknow, NUL, NULL); - return UG_JSON_ERROR_TYPE_NOT_MATCH; - } - ug_json_push (json, ug_json_parse_entry, dest, entry); - return UG_JSON_ERROR_NONE; -} - -// write JSON object by UgEntry. -static void write_entry_object (UgJson* json, void* src, const UgEntry* entry) -{ - ug_json_write_object_head (json); - ug_json_write_entry (json, src, entry); - ug_json_write_object_tail (json); -} - -void ug_value_init_custom_entry (UgValue* value, void* data, - const UgEntry* entry) -{ - UgValueCustom* custom; - - custom = ug_value_custom_new (); - custom->data = data; - custom->data2 = (void*) entry; - if (entry->name) { - custom->parse = (void*) parse_entry_object; - custom->write = (void*) write_entry_object; - } - else { - custom->parse = (void*) ug_json_parse_entry; - custom->write = (void*) ug_json_write_entry; - } - custom->free_this = TRUE; - - value->type = UG_VALUE_CUSTOM; - value->c.custom = custom; -} - -#endif // HAVE_UG_VALUE_CUSTOM - diff -Nru uget-2.2.0/uglib/UgJson-custom.h uget-2.2.2/uglib/UgJson-custom.h --- uget-2.2.0/uglib/UgJson-custom.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgJson-custom.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -50,59 +50,66 @@ // parse and write JSON number as JSON string // below 4 functions can parse JSON number and JSON string. -UgJsonError ug_json_parse_int_string (UgJson* json, +UgJsonError ug_json_parse_int_string(UgJson* json, + const char* name, const char* value, + void* dest, void* data); +UgJsonError ug_json_parse_uint_string(UgJson* json, const char* name, const char* value, void* dest, void* data); -UgJsonError ug_json_parse_uint_string (UgJson* json, +UgJsonError ug_json_parse_int64_string(UgJson* json, const char* name, const char* value, void* dest, void* data); -UgJsonError ug_json_parse_int64_string (UgJson* json, +UgJsonError ug_json_parse_double_string(UgJson* json, const char* name, const char* value, void* dest, void* data); -UgJsonError ug_json_parse_double_string (UgJson* json, - const char* name, const char* value, - void* dest, void* data); - -void ug_json_write_int_string (UgJson* json, int* value); -void ug_json_write_uint_string (UgJson* json, unsigned int* value); -void ug_json_write_int64_string (UgJson* json, int64_t* value); -void ug_json_write_double_string (UgJson* json, double* value); + +void ug_json_write_int_string(UgJson* json, int* value); +void ug_json_write_uint_string(UgJson* json, unsigned int* value); +void ug_json_write_int64_string(UgJson* json, int64_t* value); +void ug_json_write_double_string(UgJson* json, double* value); + +// ---------------------------------------------------------------------------- +// 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); +UgJsonError ug_json_parse_int16(UgJson* json, + const char* name, const char* value, + void* dest, void* data); +UgJsonError ug_json_parse_int32(UgJson* json, + const char* name, const char* value, + void* dest, void* data); +void ug_json_write_uint8(UgJson* json, uint8_t* value); +void ug_json_write_int16(UgJson* json, int16_t* value); +void ug_json_write_int32(UgJson* 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); -void ug_json_write_bool_string (UgJson* json, int* value); +UgJsonError ug_json_parse_bool_string(UgJson* json, + const char* name, const char* value, + void* dest, void* data); +void ug_json_write_bool_string(UgJson* json, int* value); // ---------------------------------------------------------------------------- // UgJsonParseFunc and UgJsonWriteFunc for time_t -UgJsonError ug_json_parse_time_t (UgJson* json, - const char* name, const char* value, - void* dest, void* none); -void ug_json_write_time_t (UgJson* json, void* src); +UgJsonError ug_json_parse_time_t(UgJson* json, + const char* name, const char* value, + void* dest, void* none); +void ug_json_write_time_t(UgJson* json, void* src); // ---------------------------------------------------------------------------- // UgJson parse by UgValue: convert UgValue to UgEntry // e.g. -// ug_json_begin_parse (json); -// ug_json_push (json, ug_json_parse_entry, entry, dest, data); -// ug_json_parse_by_value (json, value); -// ug_json_end_parse (json); - -void ug_json_parse_by_value (UgJson* json, UgValue* value); - -// ---------------------------------------------------------------------------- -// UgValue use UgValueCustom and UgEntry - -#ifdef HAVE_UG_VALUE_CUSTOM +// ug_json_begin_parse(json); +// ug_json_push(json, ug_json_parse_entry, dest, entry); +// ug_json_parse_by_value(json, value); +// ug_json_end_parse(json); -void ug_value_init_custom_entry (UgValue* value, void* data, - const UgEntry* entry); +void ug_json_parse_by_value(UgJson* json, UgValue* value); -#endif // HAVE_UG_VALUE_CUSTOM #ifdef __cplusplus } diff -Nru uget-2.2.0/uglib/UgJsonFile.c uget-2.2.2/uglib/UgJsonFile.c --- uget-2.2.0/uglib/UgJsonFile.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgJsonFile.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgJsonFile.h uget-2.2.2/uglib/UgJsonFile.h --- uget-2.2.0/uglib/UgJsonFile.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgJsonFile.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgJson.h uget-2.2.2/uglib/UgJson.h --- uget-2.2.0/uglib/UgJson.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgJson.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -203,6 +203,9 @@ } #endif +// ---------------------------------------------------------------------------- +// UgJson structure + struct UgJson { // buffer is used by parser & writer @@ -299,7 +302,6 @@ #endif // __cplusplus }; - // ---------------------------------------------------------------------------- // C++11 standard-layout diff -Nru uget-2.2.0/uglib/UgJsonrpc.c uget-2.2.2/uglib/UgJsonrpc.c --- uget-2.2.0/uglib/UgJsonrpc.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgJsonrpc.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -47,27 +47,27 @@ const UgEntry UgJsonrpcErrorEntry[] = { - {"code", offsetof (UgJsonrpcError, code), UG_ENTRY_INT, + {"code", offsetof(UgJsonrpcError, code), UG_ENTRY_INT, NULL, NULL}, - {"message", offsetof (UgJsonrpcError, message), UG_ENTRY_STRING, + {"message", offsetof(UgJsonrpcError, message), UG_ENTRY_STRING, NULL, NULL}, - {"data", offsetof (UgJsonrpcError, data), UG_ENTRY_CUSTOM, + {"data", offsetof(UgJsonrpcError, data), UG_ENTRY_CUSTOM, ug_json_parse_value, ug_json_write_value}, {NULL}, }; -void ug_jsonrpc_error_init (UgJsonrpcError* error) +void ug_jsonrpc_error_init(UgJsonrpcError* error) { - memset (error, 0, sizeof (UgJsonrpcError)); + memset(error, 0, sizeof(UgJsonrpcError)); } -void ug_jsonrpc_error_clear (UgJsonrpcError* error) +void ug_jsonrpc_error_clear(UgJsonrpcError* error) { // error - ug_free (error->message); + ug_free(error->message); error->message = NULL; error->code = 0; - ug_value_clear (&error->data); + ug_value_clear(&error->data); } // ---------------------------------------------------------------------------- @@ -75,135 +75,135 @@ const UgEntry UgJsonrpcObjectEntry[] = { -// {"jsonrpc", offsetof (UgJsonrpcObject, jsonrpc), UG_ENTRY_STRING, +// {"jsonrpc", offsetof(UgJsonrpcObject, jsonrpc), UG_ENTRY_STRING, // NULL, NULL}, - {"id", offsetof (UgJsonrpcObject, id), UG_ENTRY_CUSTOM, + {"id", offsetof(UgJsonrpcObject, id), UG_ENTRY_CUSTOM, ug_json_parse_value, ug_json_write_value}, - {"method", offsetof (UgJsonrpcObject, method), UG_ENTRY_STRING, - UG_ENTRY_SKIP_IF_NULL, NULL}, - {"params", offsetof (UgJsonrpcObject, params), UG_ENTRY_CUSTOM, + {"method", offsetof(UgJsonrpcObject, method), UG_ENTRY_STRING, + NULL, UG_ENTRY_NO_NULL}, + {"params", offsetof(UgJsonrpcObject, params), UG_ENTRY_CUSTOM, ug_json_parse_value, ug_json_write_value}, - {"result", offsetof (UgJsonrpcObject, result), UG_ENTRY_CUSTOM, + {"result", offsetof(UgJsonrpcObject, result), UG_ENTRY_CUSTOM, ug_json_parse_value, ug_json_write_value}, - {"error", offsetof (UgJsonrpcObject, error), UG_ENTRY_OBJECT, + {"error", offsetof(UgJsonrpcObject, error), UG_ENTRY_OBJECT, (void*)UgJsonrpcErrorEntry, NULL}, {NULL}, }; -UgJsonrpcObject* ug_jsonrpc_object_new (void) +UgJsonrpcObject* ug_jsonrpc_object_new(void) { UgJsonrpcObject* jobj; - jobj = ug_malloc0 (sizeof (UgJsonrpcObject)); + jobj = ug_malloc0(sizeof(UgJsonrpcObject)); return jobj; } -void ug_jsonrpc_object_free (UgJsonrpcObject* jobj) +void ug_jsonrpc_object_free(UgJsonrpcObject* jobj) { // check NULL for uget_aria2_unref() if (jobj) { - ug_jsonrpc_object_clear (jobj); - ug_free (jobj); + ug_jsonrpc_object_clear(jobj); + ug_free(jobj); } } -void ug_jsonrpc_object_init (UgJsonrpcObject* jobj) +void ug_jsonrpc_object_init(UgJsonrpcObject* jobj) { - memset (jobj, 0, sizeof (UgJsonrpcObject)); + memset(jobj, 0, sizeof(UgJsonrpcObject)); } -void ug_jsonrpc_object_clear (UgJsonrpcObject* jobj) +void ug_jsonrpc_object_clear(UgJsonrpcObject* jobj) { if (jobj == NULL) return; // jsonrpc -// ug_free (jobj->jsonrpc); +// ug_free(jobj->jsonrpc); // jobj->jsonrpc = NULL; // id - ug_value_clear (&jobj->id); + ug_value_clear(&jobj->id); // method - ug_free (jobj->method); + ug_free(jobj->method); jobj->method = NULL; jobj->method_static = NULL; // params - ug_value_clear (&jobj->params); + ug_value_clear(&jobj->params); // result - ug_value_clear (&jobj->result); + ug_value_clear(&jobj->result); // error - ug_jsonrpc_error_clear (&jobj->error); + ug_jsonrpc_error_clear(&jobj->error); } -void ug_jsonrpc_object_clear_request (UgJsonrpcObject* jobj) +void ug_jsonrpc_object_clear_request(UgJsonrpcObject* jobj) { - ug_free (jobj->method); + ug_free(jobj->method); jobj->method = NULL; jobj->method_static = NULL; - ug_value_clear (&jobj->params); + ug_value_clear(&jobj->params); } -void ug_jsonrpc_object_clear_response (UgJsonrpcObject* jobj) +void ug_jsonrpc_object_clear_response(UgJsonrpcObject* jobj) { - ug_value_clear (&jobj->result); - ug_jsonrpc_error_clear (&jobj->error); + ug_value_clear(&jobj->result); + ug_jsonrpc_error_clear(&jobj->error); } -void ug_json_write_rpc_object (UgJson* json, UgJsonrpcObject* jobj) +void ug_json_write_rpc_object(UgJson* json, UgJsonrpcObject* jobj) { - ug_json_write_object_head (json); + ug_json_write_object_head(json); // jsonrpc - ug_json_write_string (json, "jsonrpc"); - ug_json_write_string (json, "2.0"); -// ug_json_write_string (json, (jobj->jsonrpc) ? jobj->jsonrpc : "2.0"); + ug_json_write_string(json, "jsonrpc"); + ug_json_write_string(json, "2.0"); +// ug_json_write_string(json, (jobj->jsonrpc) ? jobj->jsonrpc : "2.0"); // id if (jobj->id.type != UG_VALUE_NONE) { if (jobj->id.name == NULL) - ug_json_write_string (json, "id"); - ug_json_write_value (json, &jobj->id); + ug_json_write_string(json, "id"); + ug_json_write_value(json, &jobj->id); } if (jobj->result.type == UG_VALUE_NONE && jobj->error.code == 0) { if (jobj->method || jobj->method_static) { - ug_json_write_string (json, "method"); - ug_json_write_string (json, + ug_json_write_string(json, "method"); + ug_json_write_string(json, (jobj->method_static)? jobj->method_static : jobj->method); if (jobj->params.type != UG_VALUE_NONE) { if (jobj->params.name == NULL) - ug_json_write_string (json, "params"); - ug_json_write_value (json, &jobj->params); + ug_json_write_string(json, "params"); + ug_json_write_value(json, &jobj->params); } } } else if (jobj->result.type != UG_VALUE_NONE) { if (jobj->result.name == NULL) - ug_json_write_string (json, "result"); - ug_json_write_value (json, &jobj->result); + ug_json_write_string(json, "result"); + ug_json_write_value(json, &jobj->result); } else { - ug_json_write_string (json, "error"); - ug_json_write_object_head (json); - ug_json_write_entry (json, &jobj->error, UgJsonrpcErrorEntry); - ug_json_write_object_tail (json); + ug_json_write_string(json, "error"); + ug_json_write_object_head(json); + ug_json_write_entry(json, &jobj->error, UgJsonrpcErrorEntry); + ug_json_write_object_tail(json); } - ug_json_write_object_tail (json); + ug_json_write_object_tail(json); } // ---------------------------------------------------------------------------- // UgJsonrpcArray: a UgJsonrpcObject array -//void ug_jsonrpc_array_init (UgJsonrpcArray* joarray, int allocated_len); +//void ug_jsonrpc_array_init(UgJsonrpcArray* joarray, int allocated_len); -void ug_jsonrpc_array_clear (UgJsonrpcArray* joarray, int free_objects) +void ug_jsonrpc_array_clear(UgJsonrpcArray* joarray, int free_objects) { if (free_objects) { - ug_array_foreach_ptr (joarray, + ug_array_foreach_ptr(joarray, (UgForeachFunc) ug_jsonrpc_object_clear, NULL); } - ug_array_clear (joarray); + ug_array_clear(joarray); } -UgJsonrpcObject* ug_jsonrpc_array_find (UgJsonrpcArray* joarray, UgValue* id, int* index) +UgJsonrpcObject* ug_jsonrpc_array_find(UgJsonrpcArray* joarray, UgValue* id, int* index) { UgJsonrpcObject** cur; UgJsonrpcObject** end; @@ -226,7 +226,7 @@ else if (id->type == UG_VALUE_STRING) { for (; cur < end; cur++) { if (cur[0]->id.type == UG_VALUE_STRING && - strcmp (cur[0]->id.c.string, id->c.string) == 0) + strcmp(cur[0]->id.c.string, id->c.string) == 0) { result = *cur; break; @@ -239,18 +239,18 @@ return result; } -UgJsonrpcObject* ug_jsonrpc_array_alloc (UgJsonrpcArray* joarray) +UgJsonrpcObject* ug_jsonrpc_array_alloc(UgJsonrpcArray* joarray) { UgJsonrpcObject** jobj; - jobj = ug_array_alloc (joarray, 1); - *jobj = ug_jsonrpc_object_new (); + jobj = ug_array_alloc(joarray, 1); + *jobj = ug_jsonrpc_object_new(); return *jobj; } -UgJsonError ug_json_parse_rpc_array (UgJson* json, - const char* name, const char* value, - void* jrarray, void* none) +UgJsonError ug_json_parse_rpc_array(UgJson* json, + const char* name, const char* value, + void* jrarray, void* none) { UgJsonrpcArray* array; UgJsonrpcObject* object; @@ -258,38 +258,38 @@ array = (UgJsonrpcArray*) jrarray; if (json->type != UG_JSON_OBJECT) { // if (json->type == UG_JSON_ARRAY) -// ug_json_push (json, ug_json_parse_unknown, NULL, NULL); +// ug_json_push(json, ug_json_parse_unknown, NULL, NULL); return UG_JSON_ERROR_RPC_INVALID; } - object = ug_jsonrpc_array_alloc (array); - ug_json_push (json, ug_json_parse_entry, - object, (void*)UgJsonrpcObjectEntry); + object = ug_jsonrpc_array_alloc(array); + ug_json_push(json, ug_json_parse_entry, + object, (void*)UgJsonrpcObjectEntry); return UG_JSON_ERROR_NONE; } -void ug_json_write_rpc_array (UgJson* json, UgJsonrpcArray* objects, - int noArrayIfPossible) +void ug_json_write_rpc_array(UgJson* json, UgJsonrpcArray* objects, + int noArrayIfPossible) { UgJsonrpcObject** cur; UgJsonrpcObject** end; if (noArrayIfPossible == FALSE || objects->length > 1) - ug_json_write_array_head (json); + ug_json_write_array_head(json); end = objects->at + objects->length; cur = objects->at; for (; cur < end; cur++) - ug_json_write_rpc_object (json, *cur); + ug_json_write_rpc_object(json, *cur); if (noArrayIfPossible == FALSE || objects->length > 1) - ug_json_write_array_tail (json); + ug_json_write_array_tail(json); } // ---------------------------------------------------------------------------- // UgJsonrpc: JSON-RPC -void ug_jsonrpc_init (UgJsonrpc* jrpc, UgJson* json, UgBuffer* buffer) +void ug_jsonrpc_init(UgJsonrpc* jrpc, UgJson* json, UgBuffer* buffer) { jrpc->json = json; jrpc->buffer = buffer; @@ -297,16 +297,16 @@ jrpc->data.id.current = 0; } -void ug_jsonrpc_clear (UgJsonrpc* jrpc) +void ug_jsonrpc_clear(UgJsonrpc* jrpc) { } // ------------------------------------ // client API : set response == NULL if this is notify request -int ug_jsonrpc_call (UgJsonrpc* jrpc, - UgJsonrpcObject* request, - UgJsonrpcObject* response) +int ug_jsonrpc_call(UgJsonrpc* jrpc, + UgJsonrpcObject* request, + UgJsonrpcObject* response) { int n; @@ -315,35 +315,35 @@ jrpc->error = 0; // write --- start --- - ug_json_begin_write (jrpc->json, 0, jrpc->buffer); + ug_json_begin_write(jrpc->json, 0, jrpc->buffer); // notify does NOT have id if (request->id.type != UG_VALUE_NONE) - ug_value_clear (&request->id); + ug_value_clear(&request->id); if (response) { request->id.type = UG_VALUE_INT; request->id.c.integer = jrpc->data.id.current++; } - ug_json_write_rpc_object (jrpc->json, request); - ug_json_end_write (jrpc->json); + ug_json_write_rpc_object(jrpc->json, request); + ug_json_end_write(jrpc->json); // write --- end --- #ifdef DEBUG - printf ("\n%.*s\n", jrpc->buffer->cur - jrpc->buffer->beg, jrpc->buffer->beg); + printf("\n%.*s\n", jrpc->buffer->cur - jrpc->buffer->beg, jrpc->buffer->beg); #endif // DEBUG // parser --- start --- - ug_json_begin_parse (jrpc->json); + ug_json_begin_parse(jrpc->json); if (response == NULL) { - ug_json_push (jrpc->json, ug_json_parse_unknown, - NULL, NULL); + ug_json_push(jrpc->json, ug_json_parse_unknown, + NULL, NULL); } else { - ug_json_push (jrpc->json, ug_json_parse_entry, - response, (void*)UgJsonrpcObjectEntry); - ug_json_push (jrpc->json, ug_json_parse_object, NULL, NULL); + ug_json_push(jrpc->json, ug_json_parse_entry, + response, (void*)UgJsonrpcObjectEntry); + ug_json_push(jrpc->json, ug_json_parse_object, NULL, NULL); } // send request - n = jrpc->send.func (jrpc->send.data); + n = jrpc->send.func(jrpc->send.data); if (n == -1) return -1; @@ -353,10 +353,10 @@ return 0; jrpc->data.id.previous = jrpc->data.id.current; - n = jrpc->receive.func (jrpc->receive.data); + n = jrpc->receive.func(jrpc->receive.data); if (n == -1) return -1; - n = ug_json_end_parse (jrpc->json); + n = ug_json_end_parse(jrpc->json); if (n < 0 || jrpc->error == 0) jrpc->error = n; // parser --- end --- @@ -364,9 +364,9 @@ return 0; // no error } -int ug_jsonrpc_call_batch (UgJsonrpc* jrpc, - UgJsonrpcArray* request, - UgJsonrpcArray* response) +int ug_jsonrpc_call_batch(UgJsonrpc* jrpc, + UgJsonrpcArray* request, + UgJsonrpcArray* response) { UgJsonrpcObject** cur; UgJsonrpcObject** end; @@ -379,8 +379,8 @@ if (request->length == 0) return 0; // write --- start --- - ug_json_begin_write (jrpc->json, 0, jrpc->buffer); - ug_json_write_array_head (jrpc->json); + ug_json_begin_write(jrpc->json, 0, jrpc->buffer); + ug_json_write_array_head(jrpc->json); cur = request->at; end = request->at + request->length; for (; cur < end; cur++) { @@ -388,31 +388,31 @@ continue; // notify does NOT have id if (cur[0]->id.type != UG_VALUE_NONE) { - ug_value_clear (&cur[0]->id); + ug_value_clear(&cur[0]->id); cur[0]->id.type = UG_VALUE_INT; cur[0]->id.c.integer = jrpc->data.id.current++; } - ug_json_write_rpc_object (jrpc->json, cur[0]); + ug_json_write_rpc_object(jrpc->json, cur[0]); } - ug_json_write_array_tail (jrpc->json); - ug_json_end_write (jrpc->json); + ug_json_write_array_tail(jrpc->json); + ug_json_end_write(jrpc->json); // write --- end --- #ifdef DEBUG - printf ("\n%.*s\n", jrpc->buffer->cur - jrpc->buffer->beg, jrpc->buffer->beg); + printf("\n%.*s\n", jrpc->buffer->cur - jrpc->buffer->beg, jrpc->buffer->beg); #endif // parser --- start --- - ug_json_begin_parse (jrpc->json); + ug_json_begin_parse(jrpc->json); if (response == NULL) - ug_json_push (jrpc->json, ug_json_parse_unknown, NULL, NULL); + ug_json_push(jrpc->json, ug_json_parse_unknown, NULL, NULL); else { - ug_json_push (jrpc->json, ug_json_parse_rpc_array, response, NULL); - ug_json_push (jrpc->json, ug_json_parse_array, NULL, NULL); + ug_json_push(jrpc->json, ug_json_parse_rpc_array, response, NULL); + ug_json_push(jrpc->json, ug_json_parse_array, NULL, NULL); } // send request - n = jrpc->send.func (jrpc->send.data); + n = jrpc->send.func(jrpc->send.data); if (n == -1) return -1; @@ -422,10 +422,10 @@ return 0; jrpc->data.id.previous = jrpc->data.id.current; - n = jrpc->receive.func (jrpc->receive.data); + n = jrpc->receive.func(jrpc->receive.data); if (n == -1) return -1; - n = ug_json_end_parse (jrpc->json); + n = ug_json_end_parse(jrpc->json); if (n < 0 || jrpc->error == 0) jrpc->error = n; // parser --- end --- @@ -436,9 +436,9 @@ // ------------------------------------ // server API -int ug_jsonrpc_receive (UgJsonrpc* jrpc, - UgJsonrpcObject* jr_object, - UgJsonrpcArray* jr_array) +int ug_jsonrpc_receive(UgJsonrpc* jrpc, + UgJsonrpcObject* jr_object, + UgJsonrpcArray* jr_array) { int n; int type; @@ -450,23 +450,23 @@ jrpc->data.request.array = jr_array; // parser --- start --- - ug_json_begin_parse (jrpc->json); - ug_json_push (jrpc->json, ug_json_parse_rpc_request, - jrpc, &type); + ug_json_begin_parse(jrpc->json); + ug_json_push(jrpc->json, ug_json_parse_rpc_request, + jrpc, &type); // receive request - n = jrpc->receive.func (jrpc->receive.data); + n = jrpc->receive.func(jrpc->receive.data); if (n <= 0) { - ug_json_end_parse (jrpc->json); + ug_json_end_parse(jrpc->json); return n; } - n = ug_json_end_parse (jrpc->json); + n = ug_json_end_parse(jrpc->json); if (n < 0 || jrpc->error == 0) jrpc->error = n; // parser --- end --- if (jrpc->error == UG_JSON_ERROR_UNCOMPLETED) { // {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null} - jres = ug_jsonrpc_object_new (); + jres = ug_jsonrpc_object_new(); // "id": null jres->id.type = UG_VALUE_STRING; jres->id.c.string = NULL; @@ -474,15 +474,15 @@ jres->error.code = -32700; jres->error.message = "Parse error"; // send response to client - ug_jsonrpc_response (jrpc, jres); + ug_jsonrpc_response(jrpc, jres); // clear response jres->error.message = NULL; - ug_jsonrpc_object_free (jres); + ug_jsonrpc_object_free(jres); return -1; } if (type < UG_JSON_OBJECT) { // {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null} - jres = ug_jsonrpc_object_new (); + jres = ug_jsonrpc_object_new(); // "id": null jres->id.type = UG_VALUE_STRING; jres->id.c.string = NULL; @@ -490,18 +490,18 @@ jres->error.code = -32600; jres->error.message = "Invalid Request"; // send response to client - ug_jsonrpc_response (jrpc, jres); + ug_jsonrpc_response(jrpc, jres); // clear response jres->error.message = NULL; - ug_jsonrpc_object_free (jres); + ug_jsonrpc_object_free(jres); return -1; } return type; } -int ug_jsonrpc_response (UgJsonrpc* jrpc, - UgJsonrpcObject* response) +int ug_jsonrpc_response(UgJsonrpc* jrpc, + UgJsonrpcObject* response) { int n; @@ -510,20 +510,20 @@ jrpc->error = 0; // write --- start --- - ug_json_begin_write (jrpc->json, 0, jrpc->buffer); - ug_json_write_rpc_object (jrpc->json, response); - ug_json_end_write (jrpc->json); + ug_json_begin_write(jrpc->json, 0, jrpc->buffer); + ug_json_write_rpc_object(jrpc->json, response); + ug_json_end_write(jrpc->json); // write --- end --- // send responses - n = jrpc->send.func (jrpc->send.data); + n = jrpc->send.func(jrpc->send.data); if (n == -1) return -1; return n; } -int ug_jsonrpc_response_batch (UgJsonrpc* jrpc, - UgJsonrpcArray* responses) +int ug_jsonrpc_response_batch(UgJsonrpc* jrpc, + UgJsonrpcArray* responses) { UgJsonrpcObject** cur; UgJsonrpcObject** end; @@ -536,8 +536,8 @@ if (responses->length == 0) return 0; // write --- start --- - ug_json_begin_write (jrpc->json, 0, jrpc->buffer); - ug_json_write_array_head (jrpc->json); + ug_json_begin_write(jrpc->json, 0, jrpc->buffer); + ug_json_write_array_head(jrpc->json); cur = responses->at; end = responses->at + responses->length; for (n = 0; cur < end; cur++) { @@ -545,11 +545,11 @@ if (cur[0] == NULL) continue; // output object and increase count - ug_json_write_rpc_object (jrpc->json, cur[0]); + ug_json_write_rpc_object(jrpc->json, cur[0]); n++; } - ug_json_write_array_tail (jrpc->json); - ug_json_end_write (jrpc->json); + ug_json_write_array_tail(jrpc->json); + ug_json_end_write(jrpc->json); // write --- end --- // if no object outputted, don't send response @@ -557,15 +557,15 @@ return 0; // send responses - n = jrpc->send.func (jrpc->send.data); + n = jrpc->send.func(jrpc->send.data); if (n == -1) return -1; return n; } -UgJsonError ug_json_parse_rpc_request (UgJson* json, - const char* name, const char* value, - void* jsonrpc, void* type) +UgJsonError ug_json_parse_rpc_request(UgJson* json, + const char* name, const char* value, + void* jsonrpc, void* type) { UgJsonrpc* jrpc = jsonrpc; @@ -574,18 +574,18 @@ *(int*)type = UG_JSON_OBJECT; if (jrpc->data.request.object == NULL) break; - ug_json_push (json, ug_json_parse_entry, + ug_json_push(json, ug_json_parse_entry, jrpc->data.request.object, (void*)UgJsonrpcObjectEntry); - return ug_json_parse_entry (json, name, value, + return ug_json_parse_entry(json, name, value, jrpc->data.request.object, (void*)UgJsonrpcObjectEntry); case UG_JSON_ARRAY: *(int*)type = UG_JSON_ARRAY; if (jrpc->data.request.array == NULL) break; - ug_json_push (json, ug_json_parse_rpc_array, + ug_json_push(json, ug_json_parse_rpc_array, jrpc->data.request.array, NULL); - return ug_json_parse_rpc_array (json, name, value, + return ug_json_parse_rpc_array(json, name, value, jrpc->data.request.array, NULL); default: diff -Nru uget-2.2.0/uglib/UgJsonrpcCurl.c uget-2.2.2/uglib/UgJsonrpcCurl.c --- uget-2.2.0/uglib/UgJsonrpcCurl.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgJsonrpcCurl.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgJsonrpcCurl.h uget-2.2.2/uglib/UgJsonrpcCurl.h --- uget-2.2.0/uglib/UgJsonrpcCurl.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgJsonrpcCurl.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgJsonrpc.h uget-2.2.2/uglib/UgJsonrpc.h --- uget-2.2.0/uglib/UgJsonrpc.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgJsonrpc.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -101,50 +101,50 @@ UgJsonrpcError error; }; -UgJsonrpcObject* ug_jsonrpc_object_new (void); -void ug_jsonrpc_object_free (UgJsonrpcObject* jrobj); +UgJsonrpcObject* ug_jsonrpc_object_new(void); +void ug_jsonrpc_object_free(UgJsonrpcObject* jrobj); -void ug_jsonrpc_object_init (UgJsonrpcObject* jrobj); -void ug_jsonrpc_object_clear (UgJsonrpcObject* jrobj); +void ug_jsonrpc_object_init(UgJsonrpcObject* jrobj); +void ug_jsonrpc_object_clear(UgJsonrpcObject* jrobj); -void ug_jsonrpc_object_clear_request (UgJsonrpcObject* jrobj); -void ug_jsonrpc_object_clear_response (UgJsonrpcObject* jrobj); +void ug_jsonrpc_object_clear_request(UgJsonrpcObject* jrobj); +void ug_jsonrpc_object_clear_response(UgJsonrpcObject* jrobj); // check request, and return error code. -//int ug_jsonrpc_object_check (UgJsonrpcObject* jrobj); +//int ug_jsonrpc_object_check(UgJsonrpcObject* jrobj); // parser: ug_json_parse_entry // writer: ug_json_write_entry will output all value in UgJsonrpcObject. // use below function to output JSON-RPC request and response object -void ug_json_write_rpc_object (UgJson* json, UgJsonrpcObject* jrobj); +void ug_json_write_rpc_object(UgJson* json, UgJsonrpcObject* jrobj); // ---------------------------------------------------------------------------- // UgJsonrpcArray: a UgJsonrpcObject array for batch -//void ug_jsonrpc_array_init (UgJsonrpcArray* joarray, int allocated_len); +//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); +void ug_jsonrpc_array_clear(UgJsonrpcArray* joarray, int free_objects); -UgJsonrpcObject* ug_jsonrpc_array_find (UgJsonrpcArray* joarray, UgValue* id, int* index); -UgJsonrpcObject* ug_jsonrpc_array_alloc (UgJsonrpcArray* joarray); +UgJsonrpcObject* ug_jsonrpc_array_find(UgJsonrpcArray* joarray, UgValue* id, int* index); +UgJsonrpcObject* ug_jsonrpc_array_alloc(UgJsonrpcArray* joarray); // ------------------------------------ -UgJsonError ug_json_parse_rpc_array (UgJson* json, - const char* name, const char* value, - void* jrarray, void* none); +UgJsonError ug_json_parse_rpc_array(UgJson* json, + const char* name, const char* value, + void* jrarray, void* none); // param noArrayIfPossible: TRUE or FALSE -void ug_json_write_rpc_array (UgJson* json, UgJsonrpcArray* objects, - int noArrayIfPossible); +void ug_json_write_rpc_array(UgJson* json, UgJsonrpcArray* objects, + int noArrayIfPossible); // If program doesn't known incoming data type, // this function can parse UgJsonrpcArray or UgJsonrpcObject. // This function used by server. -UgJsonError ug_json_parse_rpc_unknown (UgJson* json, - const char* name, const char* value, - void* jrarray, void* jrobject); +UgJsonError ug_json_parse_rpc_unknown(UgJson* json, + const char* name, const char* value, + void* jrarray, void* jrobject); // ---------------------------------------------------------------------------- // UgJsonrpc: JSON-RPC Client & Server @@ -185,20 +185,20 @@ } data; }; -void ug_jsonrpc_init (UgJsonrpc* jrpc, UgJson* json, UgBuffer* buffer); -void ug_jsonrpc_clear (UgJsonrpc* jrpc); +void ug_jsonrpc_init(UgJsonrpc* jrpc, UgJson* json, UgBuffer* buffer); +void ug_jsonrpc_clear(UgJsonrpc* jrpc); // ------------------------------------ // client API : set response == NULL if this is notify request // if error occurred, return -1 -int ug_jsonrpc_call (UgJsonrpc* jrpc, - UgJsonrpcObject* request, - UgJsonrpcObject* response); - -int ug_jsonrpc_call_batch (UgJsonrpc* jrpc, - UgJsonrpcArray* request, - UgJsonrpcArray* response); +int ug_jsonrpc_call(UgJsonrpc* jrpc, + UgJsonrpcObject* request, + UgJsonrpcObject* response); + +int ug_jsonrpc_call_batch(UgJsonrpc* jrpc, + UgJsonrpcArray* request, + UgJsonrpcArray* response); // ------------------------------------ // server API @@ -206,20 +206,20 @@ // return 0 if remote disconnected. // return -1 if error occurred. // if ok, return UG_JSON_ARRAY or UG_JSON_OBJECT and set jr_array or jr_object. -int ug_jsonrpc_receive (UgJsonrpc* jrpc, - UgJsonrpcObject* jr_object, - UgJsonrpcArray* jr_array); +int ug_jsonrpc_receive(UgJsonrpc* jrpc, + UgJsonrpcObject* jr_object, + UgJsonrpcArray* jr_array); -int ug_jsonrpc_response (UgJsonrpc* jrpc, - UgJsonrpcObject* jr_object); +int ug_jsonrpc_response(UgJsonrpc* jrpc, + UgJsonrpcObject* jr_object); -int ug_jsonrpc_response_batch (UgJsonrpc* jrpc, - UgJsonrpcArray* jr_array); +int ug_jsonrpc_response_batch(UgJsonrpc* jrpc, + UgJsonrpcArray* jr_array); // This function used by UgJsonrpc server mode. -UgJsonError ug_json_parse_rpc_request (UgJson* json, - const char* name, const char* value, - void* jsonrpc, void* type); +UgJsonError ug_json_parse_rpc_request(UgJson* json, + const char* name, const char* value, + void* jsonrpc, void* type); #ifdef __cplusplus } diff -Nru uget-2.2.0/uglib/UgJsonrpcSocket.c uget-2.2.2/uglib/UgJsonrpcSocket.c --- uget-2.2.0/uglib/UgJsonrpcSocket.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgJsonrpcSocket.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -209,7 +209,7 @@ UgThread thread; }; -static UG_THREAD_RETURN_TYPE jrpc_thread (struct UgJsonrpcSocketThread* jrst) +static UgThreadResult jrpc_thread (struct UgJsonrpcSocketThread* jrst) { UgSocketServer* server; UgJsonrpcServerFunc callback; @@ -221,7 +221,7 @@ ug_free (jrst); ug_socket_server_unref (server); // ref() on on_accepted() - return UG_THREAD_RETURN_VALUE; + return UG_THREAD_RESULT; } static void on_receiving (UgSocketServer* server, SOCKET client_fd, void* data) diff -Nru uget-2.2.0/uglib/UgJsonrpcSocket.h uget-2.2.2/uglib/UgJsonrpcSocket.h --- uget-2.2.0/uglib/UgJsonrpcSocket.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgJsonrpcSocket.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -64,10 +64,12 @@ struct UgJsonrpcSocket { UG_JSONRPC_SOCKET_MEMBERS; -// UgJson json; -// UgJsonrpc rpc; -// UgBuffer buffer; -// int socket; +/* // ------ UgJsonrpcSocket members ------ + UgJson json; + UgJsonrpc rpc; + UgBuffer buffer; + int socket; + */ }; void ug_jsonrpc_socket_init (UgJsonrpcSocket* jrsock); diff -Nru uget-2.2.0/uglib/UgList.c uget-2.2.2/uglib/UgList.c --- uget-2.2.0/uglib/UgList.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgList.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgList.h uget-2.2.2/uglib/UgList.h --- uget-2.2.0/uglib/UgList.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgList.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgNode.c uget-2.2.2/uglib/UgNode.c --- uget-2.2.0/uglib/UgNode.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgNode.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgNode.h uget-2.2.2/uglib/UgNode.h --- uget-2.2.0/uglib/UgNode.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgNode.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -60,13 +60,15 @@ struct UgNode { UG_NODE_MEMBERS (UgNode, void, data); -// void* data; -// UgNode* next; -// UgNode* prev; -// UgNode* parent; -// UgNode* children; -// UgNode* last; -// int n_children; +/* + void* data; + UgNode* next; + UgNode* prev; + UgNode* parent; + UgNode* children; + UgNode* last; + int n_children; + */ }; UgNode* ug_node_new (void); diff -Nru uget-2.2.0/uglib/UgOption.c uget-2.2.2/uglib/UgOption.c --- uget-2.2.0/uglib/UgOption.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgOption.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgOption.h uget-2.2.2/uglib/UgOption.h --- uget-2.2.0/uglib/UgOption.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgOption.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgRegistry.c uget-2.2.2/uglib/UgRegistry.c --- uget-2.2.0/uglib/UgRegistry.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgRegistry.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -37,103 +37,68 @@ #include #include -// ---------------------------------------------------------------------------- -// UgPairs - -void ug_registry_init (UgRegistry* reg) +void ug_registry_init(UgRegistry* reg) { - ug_array_init (reg, sizeof (UgPair), 16); + ug_array_init(reg, sizeof(UgPair), 16); reg->sorted = FALSE; } -void ug_registry_final (UgRegistry* reg) +void ug_registry_final(UgRegistry* reg) { - ug_array_clear (reg); + ug_array_clear(reg); } -void ug_registry_add (UgRegistry* reg, const UgDataInfo* info) +void ug_registry_add(UgRegistry* reg, const void* typeinfo) { UgPair* pair; int index; if (reg->sorted == FALSE || reg->length == 0) - pair = ug_array_alloc (reg, 1); + pair = ug_array_alloc(reg, 1); else { - pair = ug_registry_find (reg, info->name, &index); - if (pair == NULL) { - ug_array_alloc (reg, 1); - memmove (reg->at + index + 1, reg->at + index, - sizeof (UgPair) * (reg->length - index - 1)); - pair = reg->at + index; - } + pair = ug_registry_find(reg, ((UgTypeInfo*)typeinfo)->name, &index); + if (pair == NULL) + pair = ug_array_insert(reg, index, 1); } - pair->key = (void*) info->name; - pair->data = (void*) info; + pair->key = (void*) ((UgTypeInfo*)typeinfo)->name; + pair->data = (void*) typeinfo; } -void ug_registry_remove (UgRegistry* reg, const UgDataInfo* info) +void ug_registry_remove(UgRegistry* reg, const void* typeinfo) { UgPair* cur; + int index; - cur = ug_registry_find (reg, info->name, NULL); - if (cur) { - memmove (cur, cur +1, - sizeof (UgPair) * (reg->length - (cur - reg->at) -1)); - } + cur = ug_registry_find(reg, ((UgTypeInfo*)typeinfo)->name, &index); + if (cur) + ug_array_erase(reg, index, 1); } -UgPair* ug_registry_find (UgRegistry* reg, const char* key, int* inserted_index) +UgPair* ug_registry_find(UgRegistry* reg, const char* key, int* inserted_index) { - UgPair* low; UgPair* cur; - UgPair* high; - int diff; - - low = reg->at; - high = reg->at + reg->length; - cur = low; + UgPair* end; if (reg->sorted == FALSE) { - for (; low < high; low++) { - if (strcmp (low->key, key) == 0) { + cur = reg->at; + end = reg->at + reg->length; + for (; cur < end; cur++) { + if (strcmp(cur->key, key) == 0) { if (inserted_index) - inserted_index[0] = low - reg->at; - return low; + inserted_index[0] = cur - reg->at; + return cur; } } return NULL; } - while (low < high) { - cur = low + (high - low) / 2; - - diff = strcmp (cur->key, key); - if (diff == 0) { - if (inserted_index) - inserted_index[0] = cur - reg->at; - return cur; - } - else if (diff > 0) - high = cur; - else if (diff < 0) - low = cur + 1; - } - - if (inserted_index) { - if (cur < low) - cur++; - *inserted_index = cur - reg->at; - } - return NULL; -} - -static int compare_key_string (UgPair* pair1, UgPair* pair2) -{ - return strcmp (pair1->key, pair2->key); + return ug_array_find_sorted(reg, &key, + ug_array_compare_string, + inserted_index); } -void ug_registry_sort (UgRegistry* reg) +void ug_registry_sort(UgRegistry* reg) { - ug_array_sort (reg, (UgCompareFunc) compare_key_string); + ug_array_sort(reg, ug_array_compare_string); reg->sorted = TRUE; } diff -Nru uget-2.2.0/uglib/UgRegistry.h uget-2.2.2/uglib/UgRegistry.h --- uget-2.2.0/uglib/UgRegistry.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgRegistry.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -48,7 +48,7 @@ typedef struct UgRegistry UgRegistry; // ---------------------------------------------------------------------------- -// UgPair +// UgPair: key-data pair that is used by UgRegistry and UgInfo struct UgPair { @@ -56,34 +56,57 @@ void* data; }; -// ---------------------------------------------------------------------------- -// UgRegistry : store info and it's name. It search info by name. - -struct UgRegistry -{ - UG_ARRAY_MEMBERS (UgPair); -// UgPair** at; -// int length; -// int allocated; -// int element_size; - - int sorted; -}; +/* ---------------------------------------------------------------------------- + UgRegistry: store UgTypeInfo and it's name and search UgTypeInfo by name. + key pointer to UgTypeInfo.name + data pointer to UgTypeInfo + */ -void ug_registry_init (UgRegistry* reg); -void ug_registry_final (UgRegistry* reg); +// ---------------------------------------------------------------------------- +// UgRegistry functions -void ug_registry_add (UgRegistry* reg, const UgDataInfo* info); -void ug_registry_remove (UgRegistry* reg, const UgDataInfo* info); -UgPair* ug_registry_find (UgRegistry* reg, const char* key, int* index); +void ug_registry_init(UgRegistry* reg); +void ug_registry_final(UgRegistry* reg); -void ug_registry_sort (UgRegistry* reg); +void ug_registry_add(UgRegistry* reg, const void* type_info); +void ug_registry_remove(UgRegistry* reg, const void* type_info); +UgPair* ug_registry_find(UgRegistry* reg, const char* type_name, int* index); +void ug_registry_sort(UgRegistry* reg); #ifdef __cplusplus } #endif +// ---------------------------------------------------------------------------- +// UgRegistry structure + +struct UgRegistry +{ + UG_ARRAY_MEMBERS(UgPair); +/* // ------ UgArray members ------ + UgPair* at; + int length; + int allocated; + int element_size; + */ + + int sorted; + +#ifdef __cplusplus + inline void init(void) + { ug_registry_init(this); } + inline void final(void) + { ug_registry_final(this); } + + inline void add(const void* typeInfo) + { ug_registry_add(this, typeInfo); } + inline void remove(const void* typeInfo) + { ug_registry_remove(this, typeInfo); } + inline UgPair* find(const char* typeName, int* index = NULL) + { return ug_registry_find(this, typeName, index); } +#endif // __cplusplus +}; // ---------------------------------------------------------------------------- // C++11 standard-layout diff -Nru uget-2.2.0/uglib/UgSLink.c uget-2.2.2/uglib/UgSLink.c --- uget-2.2.0/uglib/UgSLink.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgSLink.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgSLink.h uget-2.2.2/uglib/UgSLink.h --- uget-2.2.0/uglib/UgSLink.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgSLink.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -69,13 +69,18 @@ struct UgSLinks { UG_SLINKS_MEMBERS; -// UgSLink* at; -// int length; -// int allocated; -// int element_size -// int n_links; -// UgSLink* used; -// UgSLink* freed; +/* + // ------ UgArray members ------ + UgSLink* at; + int length; + int allocated; + int element_size + + // ------ UgSLinks members ------ + int n_links; + UgSLink* used; + UgSLink* freed; + */ }; void ug_slinks_init (UgSLinks* slinks, int allocated_len); diff -Nru uget-2.2.0/uglib/UgSocket.c uget-2.2.2/uglib/UgSocket.c --- uget-2.2.0/uglib/UgSocket.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgSocket.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -241,7 +241,7 @@ // ------------------------------------ // UgSocketServer -static UG_THREAD_RETURN_TYPE server_thread (UgSocketServer* server); +static UgThreadResult server_thread (UgSocketServer* server); UgSocketServer* ug_socket_server_new (SOCKET server_fd) { @@ -348,7 +348,7 @@ } } -static UG_THREAD_RETURN_TYPE server_thread (UgSocketServer* server) +static UgThreadResult server_thread (UgSocketServer* server) { struct timeval timeout; int client_fd; @@ -383,5 +383,5 @@ server->stopping = FALSE; server->stopped = TRUE; ug_socket_server_unref (server); - return UG_THREAD_RETURN_VALUE; + return UG_THREAD_RESULT; } diff -Nru uget-2.2.0/uglib/UgSocket.h uget-2.2.2/uglib/UgSocket.h --- uget-2.2.0/uglib/UgSocket.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgSocket.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -110,25 +110,26 @@ int ug_socket_listen_unix (SOCKET fd, const char* path, int path_len, int backlog); #endif // ! (_WIN32 || _WIN64) +/* // ------------------------------------ // UgSocketServer -// sample code: -// -// UgSocketServer* server; -// SOCKET server_fd; -// -// server_fd = socket (AF_INET, SOCK_STREAM, 0); -// ug_socket_listen (server_fd, "127.0.0.1", "80", 5); -// -// server = ug_socket_server_new (server_fd); -// ug_socket_server_set_receiver (server, callback, callback_data); -// ug_socket_server_start (server); -// -// // --- now client can connect to server --- -// -// ug_socket_server_stop (server); -// ug_socket_server_unref (server); + // sample code: + UgSocketServer* server; + SOCKET server_fd; + + server_fd = socket (AF_INET, SOCK_STREAM, 0); + ug_socket_listen (server_fd, "127.0.0.1", "80", 5); + + server = ug_socket_server_new (server_fd); + ug_socket_server_set_receiver (server, callback, callback_data); + ug_socket_server_start (server); + + // --- now client can connect to server --- + + ug_socket_server_stop (server); + ug_socket_server_unref (server); + */ typedef struct UgSocketServer UgSocketServer; typedef void (*UgSocketServerFunc) (UgSocketServer* server, diff -Nru uget-2.2.0/uglib/UgStdio.c uget-2.2.2/uglib/UgStdio.c --- uget-2.2.0/uglib/UgStdio.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgStdio.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgStdio.h uget-2.2.2/uglib/UgStdio.h --- uget-2.2.0/uglib/UgStdio.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgStdio.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgString.c uget-2.2.2/uglib/UgString.c --- uget-2.2.0/uglib/UgString.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgString.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgString.h uget-2.2.2/uglib/UgString.h --- uget-2.2.0/uglib/UgString.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgString.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgThread.c uget-2.2.2/uglib/UgThread.c --- uget-2.2.0/uglib/UgThread.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgThread.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgThread.h uget-2.2.2/uglib/UgThread.h --- uget-2.2.0/uglib/UgThread.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgThread.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -46,25 +46,27 @@ #if defined _WIN32 || defined _WIN64 -typedef uintptr_t UgThread; -typedef void* UgMutex; - -typedef unsigned (*UgThreadFunc)(void*); - -#define UG_THREAD_RETURN_TYPE unsigned -#define UG_THREAD_RETURN_VALUE 0 -#define UG_THREAD_OK 0 - -int ug_thread_create (UgThread* thread, UgThreadFunc func, void* data); -int ug_thread_join (UgThread* thread); -void ug_thread_unjoin (UgThread* thread); -UgThread ug_thread_self (void); +typedef uintptr_t UgThread; +typedef void* UgMutex; +typedef unsigned UgThreadResult; + +// This function must return UG_THREAD_RESULT +typedef UgThreadResult (*UgThreadFunc)(void*); + +#define UG_THREAD_RESULT 0 +#define UG_THREAD_OK 0 + +// ug_thread_create() and ug_thread_join() return UG_THREAD_OK if successful +int ug_thread_create(UgThread* thread, UgThreadFunc func, void* data); +int ug_thread_join (UgThread* thread); +void ug_thread_unjoin(UgThread* thread); +UgThread ug_thread_self (void); // mutex ------ -void ug_mutex_init (UgMutex* mutex); +void ug_mutex_init (UgMutex* mutex); void ug_mutex_clear (UgMutex* mutex); -void ug_mutex_lock (UgMutex* mutex); -void ug_mutex_unlock (UgMutex* mutex); +void ug_mutex_lock (UgMutex* mutex); +void ug_mutex_unlock(UgMutex* mutex); //#elif defined(HAVE_PTHREAD) #else @@ -72,13 +74,15 @@ typedef pthread_t UgThread; typedef pthread_mutex_t UgMutex; +typedef void* UgThreadResult; -typedef void* (*UgThreadFunc)(void*); +// This function must return UG_THREAD_RESULT +typedef UgThreadResult (*UgThreadFunc)(void*); -#define UG_THREAD_RETURN_TYPE void* -#define UG_THREAD_RETURN_VALUE NULL -#define UG_THREAD_OK 0 +#define UG_THREAD_RESULT NULL +#define UG_THREAD_OK 0 +// ug_thread_create() and ug_thread_join() return UG_THREAD_OK if successful #define ug_thread_create(thread, func, data) \ pthread_create(thread, NULL, func, data) @@ -88,20 +92,20 @@ #define ug_thread_unjoin(thread) \ pthread_detach(*(thread)) -#define ug_thread_self() pthread_self() +#define ug_thread_self pthread_self // mutex ------ -// void ug_mutex_init (UgMutex* mutex); -#define ug_mutex_init(mutex) pthread_mutex_init (mutex, NULL) +// void ug_mutex_init(UgMutex* mutex); +#define ug_mutex_init(mutex) pthread_mutex_init(mutex, NULL) -// void ug_mutex_clear (UgMutex* mutex); -#define ug_mutex_clear(mutex) pthread_mutex_destroy (mutex) +// void ug_mutex_clear(UgMutex* mutex); +#define ug_mutex_clear(mutex) pthread_mutex_destroy(mutex) -// void ug_mutex_lock (UgMutex* mutex); -#define ug_mutex_lock(mutex) pthread_mutex_lock (mutex) +// void ug_mutex_lock(UgMutex* mutex); +#define ug_mutex_lock(mutex) pthread_mutex_lock(mutex) -// void ug_mutex_unlock (UgMutex* mutex); -#define ug_mutex_unlock(mutex) pthread_mutex_unlock (mutex) +// void ug_mutex_unlock(UgMutex* mutex); +#define ug_mutex_unlock(mutex) pthread_mutex_unlock(mutex) #endif // _WIN32 || _WIN64 diff -Nru uget-2.2.0/uglib/UgUri.c uget-2.2.2/uglib/UgUri.c --- uget-2.2.0/uglib/UgUri.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgUri.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -298,6 +298,17 @@ return ug_strndup (str, len); } +int ug_uri_is_file(UgUri* uuri) +{ + if (uuri->scheme_len == 4) { + if (strncmp(uuri->uri, "file", 4) != 0) + return FALSE; + } + else if (uuri->scheme_len != 0) + return FALSE; + return TRUE; +} + // ------------------------------------ // match uri functions diff -Nru uget-2.2.0/uglib/UgUri.h uget-2.2.2/uglib/UgUri.h --- uget-2.2.0/uglib/UgUri.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgUri.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -75,15 +75,17 @@ struct UgUri { UG_URI_MEMBERS; -// const char* uri; -// int16_t scheme_len; -// int16_t authority; -// int16_t host; -// int16_t port; -// int16_t path; -// int16_t file; -// int16_t query; -// int16_t fragment; +/* + const char* uri; + int16_t scheme_len; + int16_t authority; + int16_t host; + int16_t port; + int16_t path; + int16_t file; + int16_t query; + int16_t fragment; + */ }; int ug_uri_init (UgUri* uuri, const char* uri); @@ -111,6 +113,7 @@ int ug_uri_get_port (UgUri* uuri); char* ug_uri_get_file (UgUri* uuri); +int ug_uri_is_file (UgUri* uuri); // ------------------------------------ // match uri functions @@ -139,17 +142,17 @@ char* field_next; char* value_next; }; - -// param query_field can be NULL +/* + // e.g. + while (ug_uri_query_part(&uuquery, field) > 0) { + // your code here + field = uuquery->field_next; + } + */ +// return 0: if param 'query_field' is NULL. // return 0: no field (end of query) // return 1: field only // return 2: field & value -// -// while (ug_uri_query_part (&uuquery, field) > 0) { -// // your code here -// field = uuquery->next; -// } -// int ug_uri_query_part (UgUriQuery* uuquery, const char* query_field); // ------------------------------------ diff -Nru uget-2.2.0/uglib/UgUtil.c uget-2.2.2/uglib/UgUtil.c --- uget-2.2.0/uglib/UgUtil.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgUtil.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgUtil.h uget-2.2.2/uglib/UgUtil.h --- uget-2.2.0/uglib/UgUtil.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgUtil.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/uglib/UgValue.c uget-2.2.2/uglib/UgValue.c --- uget-2.2.0/uglib/UgValue.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgValue.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -45,60 +45,65 @@ #define strtoull _strtoui64 #endif -static UgValueArray* ug_value_array_new (int preAllocate); -static void ug_value_array_free (UgValueArray* varray); +static UgValueArray* ug_value_array_new(int preAllocate); +static void ug_value_array_free(UgValueArray* varray); #define ug_value_object_new ug_value_array_new #define ug_value_object_free ug_value_array_free // ---------------------------------------------------------------------------- // UgValue -void ug_value_init (UgValue* value) +void ug_value_init(UgValue* value) { value->type = UG_VALUE_NONE; value->name = NULL; } -void ug_value_clear (UgValue* value) +void ug_value_clear(UgValue* value) { switch (value->type) { case UG_VALUE_STRING: - ug_free (value->c.string); + ug_free(value->c.string); break; case UG_VALUE_OBJECT: case UG_VALUE_ARRAY: - ug_value_array_free (value->c.array); + ug_value_array_free(value->c.array); break; -#ifdef HAVE_UG_VALUE_CUSTOM - case UG_VALUE_CUSTOM: - ug_value_custom_free (value->c.custom); -#endif - default: break; } - ug_free (value->name); + ug_free(value->name); value->name = NULL; value->type = UG_VALUE_NONE; } -void ug_value_init_array (UgValue* value, int nElements) +void ug_value_init_type(UgValue* value, UgValueType type) { - value->type = UG_VALUE_ARRAY; + if (type == UG_VALUE_OBJECT) + value->c.object = ug_value_object_new(8); + else if (type == UG_VALUE_ARRAY) + value->c.array = ug_value_array_new(8); value->name = NULL; - value->c.array = ug_value_array_new (nElements); + value->type = type; } -void ug_value_init_object (UgValue* value, int nMembers) +void ug_value_init_array(UgValue* value, int nElements) +{ + value->name = NULL; + value->type = UG_VALUE_ARRAY; + value->c.array = ug_value_array_new(nElements); +} + +void ug_value_init_object(UgValue* value, int nMembers) { - value->type = UG_VALUE_OBJECT; value->name = NULL; - value->c.array = ug_value_object_new (nMembers); + value->type = UG_VALUE_OBJECT; + value->c.array = ug_value_object_new(nMembers); } -UgValue* ug_value_alloc (UgValue* uvalue, int nValue) +UgValue* ug_value_alloc(UgValue* uvalue, int nValue) { int len; UgValue* value; @@ -114,8 +119,8 @@ // if (len < 16) // len = 16; varray->allocated = len + 1; - uvalue->c.array = ug_realloc (varray, - sizeof (UgValueArray) + sizeof (UgValue[1]) * len); + uvalue->c.array = ug_realloc(varray, + sizeof(UgValueArray) + sizeof(UgValue[1]) * len); varray = uvalue->c.array; } len = varray->length; @@ -133,7 +138,7 @@ } #if 0 -UgValue* ug_value_alloc_front (UgValue* uvalue, int nValue) +UgValue* ug_value_alloc_front(UgValue* uvalue, int nValue) { int len; UgValue* value; @@ -149,13 +154,13 @@ // if (len < 16) // len = 16; varray->allocated = len + 1; - uvalue->c.array = ug_realloc (varray, - sizeof (UgValueArray) + sizeof (UgValue[1]) * len); + uvalue->c.array = ug_realloc(varray, + sizeof(UgValueArray) + sizeof(UgValue[1]) * len); varray = uvalue->c.array; } - memmove (varray->at + nValue, varray->at, - sizeof (UgValue) * varray->length); + memmove(varray->at + nValue, varray->at, + sizeof(UgValue) * varray->length); varray->length += nValue; value = varray->at; @@ -169,71 +174,71 @@ } #endif -UgValue* ug_value_find_name (UgValue* value, const char* name) +UgValue* ug_value_find_name(UgValue* value, const char* name) { UgValue temp; if (value->type == UG_VALUE_OBJECT) { temp.name = (char*)name; - return bsearch (&temp, value->c.object->at, value->c.object->length, - sizeof (UgValue), ug_value_compare_name); + return bsearch(&temp, value->c.object->at, value->c.object->length, + sizeof(UgValue), ug_value_compare_name); } return NULL; } -void ug_value_sort_recursive (UgValue* value, UgCompareFunc compare) +void ug_value_sort_recursive(UgValue* value, UgCompareFunc compare) { UgValue* end; if (value->type == UG_VALUE_OBJECT) { - ug_value_sort (value, compare); + ug_value_sort(value, compare); end = value->c.object->at + value->c.object->length; for (value = value->c.object->at; value < end; value++) - ug_value_sort_recursive (value, compare); + ug_value_sort_recursive(value, compare); } } -int ug_value_compare_name (const void* value1, const void* value2) +int ug_value_compare_name(const void* value1, const void* value2) { - return strcmp (((UgValue*)value1)->name, ((UgValue*)value2)->name); + return strcmp(((UgValue*)value1)->name, ((UgValue*)value2)->name); } -int ug_value_compare_string (const void* value1, const void* value2) +int ug_value_compare_string(const void* value1, const void* value2) { - return strcmp (((UgValue*)value1)->c.string, ((UgValue*)value2)->c.string); + return strcmp(((UgValue*)value1)->c.string, ((UgValue*)value2)->c.string); } -void ug_value_set_name (UgValue* value, void* data) +void ug_value_set_name(UgValue* value, void* data) { value->name = data; } -void ug_value_set_string (UgValue* value, void* data) +void ug_value_set_string(UgValue* value, void* data) { if (value->type == UG_VALUE_STRING) value->c.string = data; } -void ug_value_set_name_string (UgValue* value, void* data) +void ug_value_set_name_string(UgValue* value, void* data) { value->name = data; if (value->type == UG_VALUE_STRING) value->c.string = data; } -void ug_value_foreach (UgValue* value, UgValueForeachFunc func, void* data) +void ug_value_foreach(UgValue* value, UgValueForeachFunc func, void* data) { UgValue* end; - func (value, data); + func(value, data); if (value->type >= UG_VALUE_OBJECT) { end = value->c.object->at + value->c.object->length; for (value = value->c.object->at; value < end; value++) - ug_value_foreach (value, func, data); + ug_value_foreach(value, func, data); } } -int ug_value_get_int (UgValue* uvalue) +int ug_value_get_int(UgValue* uvalue) { switch (uvalue->type) { default: @@ -253,11 +258,11 @@ return (int) uvalue->c.fraction; case UG_VALUE_STRING: - return strtol (uvalue->c.string, NULL, 10); + return strtol(uvalue->c.string, NULL, 10); } } -int64_t ug_value_get_int64 (UgValue* uvalue) +int64_t ug_value_get_int64(UgValue* uvalue) { switch (uvalue->type) { case UG_VALUE_INT: @@ -277,11 +282,11 @@ return (int64_t) uvalue->c.fraction; case UG_VALUE_STRING: - return strtoll (uvalue->c.string, NULL, 10); + return strtoll(uvalue->c.string, NULL, 10); } } -uint64_t ug_value_get_uint64 (UgValue* uvalue) +uint64_t ug_value_get_uint64(UgValue* uvalue) { switch (uvalue->type) { case UG_VALUE_INT: @@ -301,33 +306,26 @@ return (uint64_t) uvalue->c.fraction; case UG_VALUE_STRING: - return strtoull (uvalue->c.string, NULL, 10); + return strtoull(uvalue->c.string, NULL, 10); } } -static UgJsonError ug_json_parse_value_array (UgJson* json, +static UgJsonError ug_json_parse_value_array(UgJson* json, const char* name, const char* value, void* uvalue, void* none); -UgJsonError ug_json_parse_value (UgJson* json, - const char* name, const char* value, - void* data, void* none) +UgJsonError ug_json_parse_value(UgJson* json, + const char* name, const char* value, + void* data, void* none) { UgValue* uvalue; uvalue = data; if (json->scope == UG_JSON_OBJECT) - uvalue->name = ug_strdup (name); + uvalue->name = ug_strdup(name); else uvalue->name = NULL; -#ifdef HAVE_UG_VALUE_CUSTOM - if (uvalue->type == UG_VALUE_CUSTOM) { - return uvalue->c.custom->parse (json, name, value, - uvalue->c.custom->data, uvalue->c.custom->data2); - } -#endif - switch (json->type) { case UG_JSON_NULL: uvalue->type = UG_VALUE_STRING; @@ -345,12 +343,12 @@ break; case UG_JSON_NUMBER: - if (strchr (value, '.')) { + if (strchr(value, '.')) { uvalue->type = UG_VALUE_DOUBLE; - uvalue->c.fraction = strtod (value, NULL); + uvalue->c.fraction = strtod(value, NULL); } else if (value[0] == '-') { - uvalue->c.integer64 = (int64_t) strtoll (value, NULL, 10); + uvalue->c.integer64 = (int64_t) strtoll(value, NULL, 10); if (uvalue->c.integer64 >= INT_MIN) { uvalue->c.integer = (int) uvalue->c.integer64; uvalue->type = UG_VALUE_INT; @@ -359,7 +357,7 @@ uvalue->type = UG_VALUE_INT64; } else { - uvalue->c.uinteger64 = (uint64_t) strtoull (value, NULL, 10); + uvalue->c.uinteger64 = (uint64_t) strtoull(value, NULL, 10); if (uvalue->c.uinteger64 <= INT_MAX) { uvalue->c.integer = (int) uvalue->c.uinteger64; uvalue->type = UG_VALUE_INT; @@ -379,19 +377,19 @@ case UG_JSON_STRING: uvalue->type = UG_VALUE_STRING; - uvalue->c.string = ug_strdup (value); + uvalue->c.string = ug_strdup(value); break; case UG_JSON_OBJECT: uvalue->type = UG_VALUE_OBJECT; - uvalue->c.object = ug_value_object_new (8); - ug_json_push (json, ug_json_parse_value_array, uvalue, NULL); + uvalue->c.object = ug_value_object_new(8); + ug_json_push(json, ug_json_parse_value_array, uvalue, NULL); break; case UG_JSON_ARRAY: uvalue->type = UG_VALUE_ARRAY; - uvalue->c.array = ug_value_array_new (8); - ug_json_push (json, ug_json_parse_value_array, uvalue, NULL); + uvalue->c.array = ug_value_array_new(8); + ug_json_push(json, ug_json_parse_value_array, uvalue, NULL); break; default: @@ -402,65 +400,58 @@ return UG_JSON_ERROR_NONE; } -static void ug_json_write_value_array (UgJson* json, UgValueArray* varray); +static void ug_json_write_value_array(UgJson* json, UgValueArray* varray); -void ug_json_write_value (UgJson* json, UgValue* uvalue) +void ug_json_write_value(UgJson* json, UgValue* uvalue) { if (uvalue->type == UG_VALUE_NONE) return; if (uvalue->name) - ug_json_write_string (json, uvalue->name); + ug_json_write_string(json, uvalue->name); switch (uvalue->type) { case UG_VALUE_BOOL: - ug_json_write_bool (json, uvalue->c.boolean); + ug_json_write_bool(json, uvalue->c.boolean); break; case UG_VALUE_INT: - ug_json_write_int (json, uvalue->c.integer); + ug_json_write_int(json, uvalue->c.integer); break; case UG_VALUE_UINT: - ug_json_write_uint (json, uvalue->c.uinteger); + ug_json_write_uint(json, uvalue->c.uinteger); break; case UG_VALUE_INT64: - ug_json_write_int64 (json, uvalue->c.integer64); + ug_json_write_int64(json, uvalue->c.integer64); break; case UG_VALUE_UINT64: - ug_json_write_uint64 (json, uvalue->c.uinteger64); + ug_json_write_uint64(json, uvalue->c.uinteger64); break; case UG_VALUE_DOUBLE: - ug_json_write_double (json, uvalue->c.fraction); + ug_json_write_double(json, uvalue->c.fraction); break; case UG_VALUE_STRING: if (uvalue->c.string) - ug_json_write_string (json, uvalue->c.string); + ug_json_write_string(json, uvalue->c.string); else - ug_json_write_null (json); + ug_json_write_null(json); break; case UG_VALUE_OBJECT: - ug_json_write_object_head (json); - ug_json_write_value_array (json, uvalue->c.array); - ug_json_write_object_tail (json); + ug_json_write_object_head(json); + ug_json_write_value_array(json, uvalue->c.array); + ug_json_write_object_tail(json); break; case UG_VALUE_ARRAY: - ug_json_write_array_head (json); - ug_json_write_value_array (json, uvalue->c.array); - ug_json_write_array_tail (json); - break; - -#ifdef HAVE_UG_VALUE_CUSTOM - case UG_VALUE_CUSTOM: - uvalue->c.custom->write (json, uvalue->c.custom->data, - uvalue->c.custom->data2); + ug_json_write_array_head(json); + ug_json_write_value_array(json, uvalue->c.array); + ug_json_write_array_tail(json); break; -#endif default: break; @@ -470,17 +461,17 @@ // ---------------------------------------------------------------------------- // UgValueArray = UgValueObject -static UgValueArray* ug_value_array_new (int preAllocate) +static UgValueArray* ug_value_array_new(int preAllocate) { UgValueArray* varray; - varray = ug_malloc (sizeof (UgValueArray) + sizeof (UgValue) * preAllocate); + varray = ug_malloc(sizeof(UgValueArray) + sizeof(UgValue) * preAllocate); varray->allocated = preAllocate + 1; varray->length = 0; return varray; } -static void ug_value_array_free (UgValueArray* varray) +static void ug_value_array_free(UgValueArray* varray) { UgValue* cur; UgValue* end; @@ -488,21 +479,21 @@ cur = varray->at; end = varray->at + varray->length; for (; cur < end; cur++) - ug_value_clear (cur); - ug_free (varray); + ug_value_clear(cur); + ug_free(varray); } -static UgJsonError ug_json_parse_value_array (UgJson* json, +static UgJsonError ug_json_parse_value_array(UgJson* json, const char* name, const char* value, void* uvalue, void* none) { UgValue* uvalue1; - uvalue1 = ug_value_alloc (uvalue, 1); - return ug_json_parse_value (json, name, value, uvalue1, none); + uvalue1 = ug_value_alloc(uvalue, 1); + return ug_json_parse_value(json, name, value, uvalue1, none); } -static void ug_json_write_value_array (UgJson* json, UgValueArray* varray) +static void ug_json_write_value_array(UgJson* json, UgValueArray* varray) { UgValue* cur; UgValue* end; @@ -510,31 +501,6 @@ cur = varray->at; end = varray->at + varray->length; for (; cur < end; cur++) - ug_json_write_value (json, cur); -} - -// ---------------------------------------------------------------------------- -// UgValueCustom - -#ifdef HAVE_UG_VALUE_CUSTOM - -UgValueCustom* ug_value_custom_new (void) -{ - UgValueCustom* custom; - - custom = ug_malloc0 (sizeof (UgValueCustom)); - custom->free_this = TRUE; - return custom; + ug_json_write_value(json, cur); } -void ug_value_custom_free (UgValueCustom* custom) -{ - if (custom->destroy.func) - custom->destroy.func (custom->destroy.data); - - if (custom->free_this) - ug_free (custom); -} - -#endif // HAVE_UG_VALUE_CUSTOM - diff -Nru uget-2.2.0/uglib/UgValue.h uget-2.2.2/uglib/UgValue.h --- uget-2.2.0/uglib/UgValue.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/uglib/UgValue.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -69,10 +69,6 @@ UG_VALUE_OBJECT, // JSON object, C UgValueObject (UgValueArray) UG_VALUE_ARRAY, // JSON array, C UgValueArray - -#ifdef HAVE_UG_VALUE_CUSTOM - UG_VALUE_CUSTOM, -#endif } UgValueType; // ---------------------------------------------------------------------------- @@ -91,77 +87,136 @@ UgValueArray* array; UgValueObject* object; -#ifdef HAVE_UG_VALUE_CUSTOM - UgValueCustom* custom; -#endif // void* pointer; }; // ---------------------------------------------------------------------------- -// UgValue +// UgValue functions -struct UgValue -{ - char* name; - UgValueType type; - UgValueC c; -}; +void ug_value_init(UgValue* value); +void ug_value_clear(UgValue* value); -void ug_value_init (UgValue* value); -void ug_value_clear (UgValue* value); - -void ug_value_init_array (UgValue* value, int nElements); -void ug_value_init_object (UgValue* value, int nMembers); +void ug_value_init_type(UgValue* value, UgValueType type); +void ug_value_init_array(UgValue* value, int nElements); +void ug_value_init_object(UgValue* value, int nMembers); // You can use this if UgValue.type == UG_VALUE_ARRAY or UG_VALUE_OBJECT. -UgValue* ug_value_alloc (UgValue* uvalue, int nValue); +UgValue* ug_value_alloc(UgValue* uvalue, int nValue); #if 0 -UgValue* ug_value_alloc_front (UgValue* uvalue, int nValue); +UgValue* ug_value_alloc_front(UgValue* uvalue, int nValue); #endif -// void ug_value_sort (UgValue* value, UgCompareFunc compare); -#define ug_value_sort(varray, compareFunc) \ - qsort ((varray)->c.array->at, (varray)->c.array->length, \ - sizeof (UgValue), compareFunc) - -// UgValue* ug_value_find (UgValue* value, UgValue* key, UgCompareFunc func); -#define ug_value_find(varray, key, compareFunc) \ - bsearch (key, (varray)->c.array->at, (varray)->c.array->length, \ - sizeof (UgValue), compareFunc) - -// void ug_value_sort_name (UgValue* value) -#define ug_value_sort_name(vobj) \ - qsort ((vobj)->c.object->at, (vobj)->c.object->length, \ - sizeof (UgValue), ug_value_compare_name) +// UgValue* ug_value_at(UgValue* value, UgValue* key, UgCompareFunc func); +#define ug_value_at(varray, index) \ + (varray)->c.array->at + (index) + +// int ug_value_length(UgValue* value); +#define ug_value_length(varray) \ + (varray)->c.array->length + +// void ug_value_sort(UgValue* value, UgCompareFunc compare); +#define ug_value_sort(varray, compareFunc) \ + qsort((varray)->c.array->at, (varray)->c.array->length, \ + sizeof(UgValue), compareFunc) + +// UgValue* ug_value_find(UgValue* value, UgValue* key, UgCompareFunc func); +#define ug_value_find(varray, key, compareFunc) \ + bsearch(key, (varray)->c.array->at, (varray)->c.array->length, \ + sizeof(UgValue), compareFunc) + +// void ug_value_sort_name(UgValue* value) +#define ug_value_sort_name(vobj) \ + qsort((vobj)->c.object->at, (vobj)->c.object->length, \ + sizeof(UgValue), ug_value_compare_name) -UgValue* ug_value_find_name (UgValue* value, const char* name); +UgValue* ug_value_find_name(UgValue* value, const char* name); // recursive functions -void ug_value_sort_recursive (UgValue* value, UgCompareFunc compare); -//void ug_value_sort_name_recursive (UgValue* value); -#define ug_value_sort_name_recursive(vobj) \ - ug_value_sort_recursive (vobj, ug_value_compare_name) +void ug_value_sort_recursive(UgValue* value, UgCompareFunc compare); +//void ug_value_sort_name_recursive(UgValue* value); +#define ug_value_sort_name_recursive(vobj) \ + ug_value_sort_recursive(vobj, ug_value_compare_name) -int ug_value_compare_name (const void* value1, const void* value2); -int ug_value_compare_string (const void* value1, const void* value2); +int ug_value_compare_name(const void* value1, const void* value2); +int ug_value_compare_string(const void* value1, const void* value2); // If you set static string in all UgValue.name or UgValue.c.string, // run ug_value_foreach() before you call ug_value_clear(). // e.g. -// ug_value_foreach (value, ug_value_set_name_string, NULL); -void ug_value_set_name (UgValue* value, void* data); -void ug_value_set_string (UgValue* value, void* data); -void ug_value_set_name_string (UgValue* value, void* data); -void ug_value_foreach (UgValue* value, UgValueForeachFunc func, void* data); - -int ug_value_get_int (UgValue* uvalue); -int64_t ug_value_get_int64 (UgValue* uvalue); -uint64_t ug_value_get_uint64 (UgValue* uvalue); - -UgJsonError ug_json_parse_value (UgJson* json, - const char* name, const char* value, - void* uvalue, void* none); -void ug_json_write_value (UgJson* json, UgValue* value); +// ug_value_foreach(value, ug_value_set_name_string, NULL); +void ug_value_set_name(UgValue* value, void* data); +void ug_value_set_string(UgValue* value, void* data); +void ug_value_set_name_string(UgValue* value, void* data); +void ug_value_foreach(UgValue* value, UgValueForeachFunc func, void* data); + +int ug_value_get_int(UgValue* uvalue); +int64_t ug_value_get_int64(UgValue* uvalue); +uint64_t ug_value_get_uint64(UgValue* uvalue); + +UgJsonError ug_json_parse_value(UgJson* json, + const char* name, const char* value, + void* uvalue, void* none); +void ug_json_write_value(UgJson* json, UgValue* value); + +#ifdef __cplusplus +} +#endif + +// ---------------------------------------------------------------------------- +// UgValue structure + +struct UgValue +{ + char* name; + UgValueType type; + UgValueC c; + +#ifdef __cplusplus + // C++11 standard-layout + inline UgValue(void) + { ug_value_init(this); } + inline UgValue(UgValueType type) + { ug_value_init_type(this, type); } + inline ~UgValue(void) + { ug_value_clear(this); } + + inline void init(void) + { ug_value_init(this); } + inline void init(UgValueType type) + { ug_value_init_type(this, type); } + inline void initObject(int nMember) + { ug_value_init_object(this, nMember); } + inline void initArray(int nElement) + { ug_value_init_array(this, nElement); } + inline void clear(void) + { ug_value_clear(this); } + + inline UgValue* alloc(int nValue) + { return ug_value_alloc(this, nValue); } + // get nth element at object or array + inline UgValue* at(int index); + // return length of object or array + inline int length(void); + + // find by object's member name + inline UgValue* find(const char* name) + { return ug_value_find_name(this, name); } + // find at object or array + inline UgValue* find(UgValue* key, UgCompareFunc func); + + // sort by object's member name + inline void sort(); + // sort at object or array + inline void sort(UgCompareFunc func); + + // sort by object's member name + inline void sortRecursive() + { ug_value_sort_recursive(this, ug_value_compare_name); } + // sort at object or array + inline void sortRecursive(UgCompareFunc func) + { ug_value_sort_recursive(this, func); } +#endif // __cplusplus +}; // ---------------------------------------------------------------------------- // UgValueArray = UgValueObject @@ -174,33 +229,34 @@ }; // ---------------------------------------------------------------------------- -// UgValueCustom: used by UG_VALUE_CUSTOM. It can't parse value in JSON array. +// C++ inline functions -#ifdef HAVE_UG_VALUE_CUSTOM -typedef struct UgValueCustom UgValueCustom; +#ifdef __cplusplus +inline UgValue* UgValue::at(int index) + { return ug_value_at(this, index); } +inline int UgValue::length(void) + { return ug_value_length(this); } +inline UgValue* UgValue::find(UgValue* key, UgCompareFunc func) + { return (UgValue*) ug_value_find(this, key, func); } +inline void UgValue::sort() + { ug_value_sort_name(this); } +inline void UgValue::sort(UgCompareFunc func) + { ug_value_sort(this, func); } +#endif // __cplusplus -struct UgValueCustom -{ - UgJsonParseFunc parse; - UgJsonWriteFunc write; - void* data; - void* data2; - - int free_this; - struct { - UgNotifyFunc func; - void* data; - } destroy; -}; +// ---------------------------------------------------------------------------- +// C++11 standard-layout -UgValueCustom* ug_value_custom_new (void); -void ug_value_custom_free (UgValueCustom* vcustom); +#ifdef __cplusplus -#endif // HAVE_UG_VALUE_CUSTOM +namespace Ug +{ +// This one is for directly use only. You can NOT derived it. +typedef struct UgValueArray ValueArray; +typedef struct UgValue Value; +}; // namespace Ug -#ifdef __cplusplus -} -#endif +#endif // __cplusplus #endif // UG_VALUE_H diff -Nru uget-2.2.0/ui-gtk/Makefile.in uget-2.2.2/ui-gtk/Makefile.in --- uget-2.2.0/ui-gtk/Makefile.in 2018-01-08 00:05:59.000000000 +0000 +++ uget-2.2.2/ui-gtk/Makefile.in 2019-05-19 16:51:35.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -145,7 +145,36 @@ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/uget_gtk-UgtkAboutDialog.Po \ + ./$(DEPDIR)/uget_gtk-UgtkApp-callback.Po \ + ./$(DEPDIR)/uget_gtk-UgtkApp-main.Po \ + ./$(DEPDIR)/uget_gtk-UgtkApp-timeout.Po \ + ./$(DEPDIR)/uget_gtk-UgtkApp-ui.Po \ + ./$(DEPDIR)/uget_gtk-UgtkApp.Po \ + ./$(DEPDIR)/uget_gtk-UgtkBanner.Po \ + ./$(DEPDIR)/uget_gtk-UgtkBatchDialog.Po \ + ./$(DEPDIR)/uget_gtk-UgtkCategoryForm.Po \ + ./$(DEPDIR)/uget_gtk-UgtkConfig.Po \ + ./$(DEPDIR)/uget_gtk-UgtkConfirmDialog.Po \ + ./$(DEPDIR)/uget_gtk-UgtkDownloadForm.Po \ + ./$(DEPDIR)/uget_gtk-UgtkMenubar-ui.Po \ + ./$(DEPDIR)/uget_gtk-UgtkMenubar.Po \ + ./$(DEPDIR)/uget_gtk-UgtkNodeDialog.Po \ + ./$(DEPDIR)/uget_gtk-UgtkNodeList.Po \ + ./$(DEPDIR)/uget_gtk-UgtkNodeTree.Po \ + ./$(DEPDIR)/uget_gtk-UgtkNodeView.Po \ + ./$(DEPDIR)/uget_gtk-UgtkProxyForm.Po \ + ./$(DEPDIR)/uget_gtk-UgtkScheduleForm.Po \ + ./$(DEPDIR)/uget_gtk-UgtkSelector.Po \ + ./$(DEPDIR)/uget_gtk-UgtkSequence.Po \ + ./$(DEPDIR)/uget_gtk-UgtkSetting.Po \ + ./$(DEPDIR)/uget_gtk-UgtkSettingDialog.Po \ + ./$(DEPDIR)/uget_gtk-UgtkSettingForm.Po \ + ./$(DEPDIR)/uget_gtk-UgtkSummary.Po \ + ./$(DEPDIR)/uget_gtk-UgtkTraveler.Po \ + ./$(DEPDIR)/uget_gtk-UgtkTrayIcon.Po \ + ./$(DEPDIR)/uget_gtk-UgtkUtil.Po am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -420,8 +449,8 @@ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -485,35 +514,41 @@ distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkAboutDialog.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkApp-callback.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkApp-main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkApp-timeout.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkApp-ui.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkApp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkBanner.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkBatchDialog.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkCategoryForm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkConfig.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkConfirmDialog.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkDownloadForm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkMenubar-ui.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkMenubar.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkNodeDialog.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkNodeList.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkNodeTree.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkNodeView.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkProxyForm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkScheduleForm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkSelector.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkSequence.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkSetting.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkSettingDialog.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkSettingForm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkSummary.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkTraveler.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkTrayIcon.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkUtil.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkAboutDialog.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkApp-callback.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkApp-main.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkApp-timeout.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkApp-ui.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkApp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkBanner.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkBatchDialog.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkCategoryForm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkConfig.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkConfirmDialog.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkDownloadForm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkMenubar-ui.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkMenubar.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkNodeDialog.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkNodeList.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkNodeTree.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkNodeView.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkProxyForm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkScheduleForm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkSelector.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkSequence.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkSetting.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkSettingDialog.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkSettingForm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkSummary.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkTraveler.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkTrayIcon.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk-UgtkUtil.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -987,7 +1022,10 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -1059,7 +1097,35 @@ clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/uget_gtk-UgtkAboutDialog.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkApp-callback.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkApp-main.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkApp-timeout.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkApp-ui.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkApp.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkBanner.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkBatchDialog.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkCategoryForm.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkConfig.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkConfirmDialog.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkDownloadForm.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkMenubar-ui.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkMenubar.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkNodeDialog.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkNodeList.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkNodeTree.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkNodeView.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkProxyForm.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkScheduleForm.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkSelector.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkSequence.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkSetting.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkSettingDialog.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkSettingForm.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkSummary.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkTraveler.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkTrayIcon.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkUtil.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -1105,7 +1171,35 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/uget_gtk-UgtkAboutDialog.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkApp-callback.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkApp-main.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkApp-timeout.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkApp-ui.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkApp.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkBanner.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkBatchDialog.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkCategoryForm.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkConfig.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkConfirmDialog.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkDownloadForm.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkMenubar-ui.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkMenubar.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkNodeDialog.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkNodeList.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkNodeTree.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkNodeView.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkProxyForm.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkScheduleForm.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkSelector.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkSequence.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkSetting.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkSettingDialog.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkSettingForm.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkSummary.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkTraveler.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkTrayIcon.Po + -rm -f ./$(DEPDIR)/uget_gtk-UgtkUtil.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -1125,7 +1219,7 @@ .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ diff -Nru uget-2.2.0/ui-gtk/UgtkAboutDialog.c uget-2.2.2/ui-gtk/UgtkAboutDialog.c --- uget-2.2.0/ui-gtk/UgtkAboutDialog.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkAboutDialog.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ static const char uget_license[] = { -" Copyright (C) 2005-2018 by C.H. Huang" "\n" +" Copyright (C) 2005-2019 by C.H. Huang" "\n" " plushuang.tw@gmail.com" "\n" "\n" "This library is free software; you can redistribute it and/or" "\n" diff -Nru uget-2.2.0/ui-gtk/UgtkAboutDialog.h uget-2.2.2/ui-gtk/UgtkAboutDialog.h --- uget-2.2.0/ui-gtk/UgtkAboutDialog.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkAboutDialog.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkApp.c uget-2.2.2/ui-gtk/UgtkApp.c --- uget-2.2.0/ui-gtk/UgtkApp.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkApp.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -71,10 +71,10 @@ // clipboard ugtk_clipboard_init (&app->clipboard, app->setting.clipboard.pattern); // plug-in initialize - uget_plugin_set (UgetPluginCurlInfo, UGET_PLUGIN_INIT, (void*) TRUE); - uget_plugin_set (UgetPluginAria2Info, UGET_PLUGIN_INIT, (void*) TRUE); - uget_plugin_set (UgetPluginMediaInfo, UGET_PLUGIN_INIT, (void*) TRUE); - uget_plugin_set (UgetPluginMegaInfo, UGET_PLUGIN_INIT, (void*) TRUE); + 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); // apply UgtkSetting ugtk_app_set_plugin_setting (app, &app->setting); ugtk_app_set_window_setting (app, &app->setting); @@ -87,7 +87,7 @@ ugtk_menubar_sync_category (&app->menubar, app, TRUE); app->recent.category_index = 0; - app->recent.infonode = uget_node_new (NULL); + app->recent.info = ug_info_new(8, 0); // RSS uget_rss_add_builtin (app->rss_builtin, UGET_RSS_STABLE); uget_rss_add_builtin (app->rss_builtin, UGET_RSS_NEWS); @@ -117,15 +117,16 @@ shutdown_now = app->setting.aria2.shutdown; else shutdown_now = FALSE; + ug_info_unref(app->recent.info); uget_rss_unref (app->rss_builtin); uget_app_final ((UgetApp*) app); // plug-in finalize - uget_plugin_set (UgetPluginAria2Info, UGET_PLUGIN_ARIA2_SHUTDOWN_NOW, + uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_ARIA2_GLOBAL_SHUTDOWN_NOW, (void*)(intptr_t) shutdown_now); - uget_plugin_set (UgetPluginCurlInfo, UGET_PLUGIN_INIT, (void*) FALSE); - uget_plugin_set (UgetPluginAria2Info, UGET_PLUGIN_INIT, (void*) FALSE); - uget_plugin_set (UgetPluginMediaInfo, UGET_PLUGIN_INIT, (void*) FALSE); - uget_plugin_set (UgetPluginMegaInfo, UGET_PLUGIN_INIT, (void*) FALSE); + 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); } void ugtk_app_save (UgtkApp* app) @@ -516,37 +517,36 @@ // set default plug-in uget_app_set_default_plugin ((UgetApp*) app, default_plugin); + // set agent plug-in (used by media and MEGA plug-in) + uget_plugin_agent_global_set(UGET_PLUGIN_AGENT_GLOBAL_PLUGIN, + (void*) default_plugin); // set media plug-in uget_app_add_plugin ((UgetApp*) app, UgetPluginMediaInfo); - uget_plugin_set (UgetPluginMediaInfo, UGET_PLUGIN_MEDIA_DEFAULT_PLUGIN, - (void*) default_plugin); - uget_plugin_set (UgetPluginMediaInfo, UGET_PLUGIN_MEDIA_MATCH_MODE, + uget_plugin_global_set(UgetPluginMediaInfo, UGET_PLUGIN_MEDIA_GLOBAL_MATCH_MODE, (void*)(intptr_t) setting->media.match_mode); - uget_plugin_set (UgetPluginMediaInfo, UGET_PLUGIN_MEDIA_QUALITY, + uget_plugin_global_set(UgetPluginMediaInfo, UGET_PLUGIN_MEDIA_GLOBAL_QUALITY, (void*)(intptr_t) setting->media.quality); - uget_plugin_set (UgetPluginMediaInfo, UGET_PLUGIN_MEDIA_TYPE, + uget_plugin_global_set(UgetPluginMediaInfo, UGET_PLUGIN_MEDIA_GLOBAL_TYPE, (void*)(intptr_t) setting->media.type); - // set agent plug-in (used by MEGA) - uget_plugin_agent_global_set (UGET_PLUGIN_AGENT_DEFAULT_PLUGIN, - (void*) default_plugin); + // set MEGA plug-in uget_app_add_plugin ((UgetApp*) app, UgetPluginMegaInfo); // set aria2 plug-in if (setting->plugin_order >= UGTK_PLUGIN_ORDER_ARIA2) { - uget_plugin_set (UgetPluginAria2Info, UGET_PLUGIN_ARIA2_URI, + uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_ARIA2_GLOBAL_URI, setting->aria2.uri); - uget_plugin_set (UgetPluginAria2Info, UGET_PLUGIN_ARIA2_PATH, + uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_ARIA2_GLOBAL_PATH, setting->aria2.path); - uget_plugin_set (UgetPluginAria2Info, UGET_PLUGIN_ARIA2_ARGUMENT, + uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_ARIA2_GLOBAL_ARGUMENT, setting->aria2.args); - uget_plugin_set (UgetPluginAria2Info, UGET_PLUGIN_ARIA2_TOKEN, + uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_ARIA2_GLOBAL_TOKEN, setting->aria2.token); - uget_plugin_set (UgetPluginAria2Info, UGET_PLUGIN_ARIA2_LAUNCH, + uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_ARIA2_GLOBAL_LAUNCH, (void*)(intptr_t) setting->aria2.launch); - uget_plugin_set (UgetPluginAria2Info, UGET_PLUGIN_ARIA2_SHUTDOWN, + uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_ARIA2_GLOBAL_SHUTDOWN, (void*)(intptr_t) setting->aria2.shutdown); limit[0] = setting->aria2.limit.download * 1024; limit[1] = setting->aria2.limit.upload * 1024; - uget_plugin_set (UgetPluginAria2Info, UGET_PLUGIN_SPEED_LIMIT, limit); + uget_plugin_global_set(UgetPluginAria2Info, UGET_PLUGIN_GLOBAL_SPEED_LIMIT, limit); } // app->aria2.remote_updated = FALSE; @@ -874,6 +874,8 @@ void ugtk_app_create_category (UgtkApp* app) { UgtkNodeDialog* ndialog; + UgetCommon* common_src; + UgetCommon* common; UgetNode* cnode_src; UgetNode* cnode; gchar* title; @@ -884,14 +886,18 @@ ugtk_download_form_set_folders (&ndialog->download, &app->setting); // category list - cnode_src = app->traveler.category.cursor.node->data; + cnode_src = app->traveler.category.cursor.node->base; if (cnode_src->parent != &app->real) cnode_src = app->real.children; + common_src = ug_info_get(cnode_src->info, UgetCommonInfo); cnode = uget_node_new (NULL); - cnode->name = ug_strdup_printf ("%s%s", _("Copy - "), cnode_src->name); - ug_info_assign (&cnode->info, &cnode_src->info, NULL); + common = ug_info_realloc(cnode->info, UgetCommonInfo); + ug_info_assign (cnode->info, cnode_src->info, NULL); + ug_free(common->name); + common->name = ug_strdup_printf("%s%s", _("Copy - "), + (common_src->name) ? common_src->name : NULL); - ugtk_node_dialog_set (ndialog, cnode); + ugtk_node_dialog_set (ndialog, cnode->info); ugtk_node_dialog_run (ndialog, UGTK_NODE_DIALOG_NEW_CATEGORY, cnode); } @@ -915,7 +921,7 @@ ugtk_download_form_set_folders (&ndialog->download, &app->setting); // category list - cnode = app->traveler.category.cursor.node->data; + cnode = app->traveler.category.cursor.node->base; if (cnode->parent != &app->real) cnode = app->real.children; @@ -944,7 +950,7 @@ } if (cnode) - cnode = cnode->data; + cnode = cnode->base; ugtk_node_dialog_set_category (ndialog, cnode); ugtk_node_dialog_run (ndialog, UGTK_NODE_DIALOG_NEW_DOWNLOAD, NULL); } @@ -957,7 +963,7 @@ UgetNode* cnode; int pos; - cnode = app->traveler.category.cursor.node->data; + cnode = app->traveler.category.cursor.node->base; pos = app->traveler.category.cursor.pos; // move cursor if (pos <= 0) @@ -999,11 +1005,11 @@ cursor = app->traveler.download.cursor.node; if (cursor) - cursor = cursor->data; + cursor = cursor->base; list = ugtk_traveler_get_selected (&app->traveler); for (link = list; link; link = link->next) { node = link->data; - node = node->data; + node = node->base; link->data = node; if (delete_files || mask & GDK_SHIFT_MASK) uget_app_delete_download ((UgetApp*) app, node, delete_files); @@ -1048,8 +1054,8 @@ ndialog = ugtk_node_dialog_new (title, app, TRUE); g_free (title); ugtk_download_form_set_folders (&ndialog->download, &app->setting); - ugtk_node_dialog_set (ndialog, node->data); - ugtk_node_dialog_run (ndialog, UGTK_NODE_DIALOG_EDIT_CATEGORY, node->data); + ugtk_node_dialog_set (ndialog, node->base->info); + ugtk_node_dialog_run (ndialog, UGTK_NODE_DIALOG_EDIT_CATEGORY, node->base); } void ugtk_app_edit_download (UgtkApp* app) @@ -1064,8 +1070,8 @@ ugtk_download_form_set_folders (&ndialog->download, &app->setting); node = app->traveler.download.cursor.node; - ugtk_node_dialog_set (ndialog, node->data); - ugtk_node_dialog_run (ndialog, UGTK_NODE_DIALOG_EDIT_DOWNLOAD, node->data); + ugtk_node_dialog_set (ndialog, node->base->info); + ugtk_node_dialog_run (ndialog, UGTK_NODE_DIALOG_EDIT_DOWNLOAD, node->base); } // ------------------------------------ @@ -1073,6 +1079,7 @@ void ugtk_app_queue_download (UgtkApp* app, gboolean keep_active) { + UgetRelation* relation; UgetNode* node; UgetNode* cursor; GList* list; @@ -1080,14 +1087,15 @@ cursor = app->traveler.download.cursor.node; if (cursor) - cursor = cursor->data; + cursor = cursor->base; list = ugtk_traveler_get_selected (&app->traveler); for (link = list; link; link = link->next) { node = link->data; - node = node->data; + node = node->base; link->data = node; - if (keep_active && node->state & UGET_STATE_ACTIVE) + relation = ug_info_realloc(node->info, UgetRelationInfo); + if (keep_active && relation->group & UGET_GROUP_ACTIVE) continue; uget_app_queue_download ((UgetApp*) app, node); } @@ -1112,12 +1120,12 @@ cursor = app->traveler.download.cursor.node; if (cursor) - cursor = cursor->data; + cursor = cursor->base; list = ugtk_traveler_get_selected (&app->traveler); for (link = list; link; link = link->next) { node = link->data; - node = node->data; + node = node->base; link->data = node; uget_app_pause_download ((UgetApp*) app, node); } @@ -1137,6 +1145,7 @@ void ugtk_app_switch_download_state (UgtkApp* app) { + UgetRelation* relation; UgetNode* node; UgetNode* cursor; GList* list; @@ -1144,16 +1153,17 @@ cursor = app->traveler.download.cursor.node; if (cursor) - cursor = cursor->data; + cursor = cursor->base; list = ugtk_traveler_get_selected (&app->traveler); for (link = list; link; link = link->next) { node = link->data; - node = node->data; + node = node->base; link->data = node; - if (node->state & UGET_STATE_PAUSED) + relation = ug_info_realloc(node->info, UgetRelationInfo); + if (relation->group & UGET_GROUP_PAUSED) uget_app_queue_download ((UgetApp*) app, node); - else if (node->state & UGET_STATE_ACTIVE) + else if (relation->group & UGET_GROUP_ACTIVE) uget_app_pause_download ((UgetApp*) app, node); } if (app->traveler.state.cursor.pos == 0) { @@ -1239,17 +1249,17 @@ GList* link; GList* list = NULL; - if (cnode == app->traveler.category.cursor.node->data) + if (cnode == app->traveler.category.cursor.node->base) return; list = ugtk_traveler_get_selected (&app->traveler); for (link = list; link; link = link->next) { node = link->data; - node = node->data; + node = node->base; if (node->parent == cnode) continue; uget_node_remove (node->parent, node); - uget_node_unref_fake (node); + uget_node_clear_fake (node); uget_node_append (cnode, node); } g_list_free (list); @@ -1379,7 +1389,7 @@ // file = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog)); gtk_widget_destroy (dialog); cnode = app->traveler.category.cursor.node; - if (uget_app_save_category ((UgetApp*) app, cnode->data, file, NULL) == FALSE) + if (uget_app_save_category ((UgetApp*) app, cnode->base, file, NULL) == FALSE) ugtk_app_show_message (app, GTK_MESSAGE_ERROR, _("Failed to save category file.")); g_free (file); } @@ -1478,7 +1488,7 @@ ugtk_download_form_set_folders (&bdialog->download, &app->setting); ugtk_batch_dialog_use_selector (bdialog); // category - cnode = app->traveler.category.cursor.node->data; + cnode = app->traveler.category.cursor.node->base; if (cnode->parent != &app->real) cnode = app->real.children; ugtk_batch_dialog_set_category (bdialog, cnode); @@ -1533,7 +1543,7 @@ ugtk_batch_dialog_use_selector (bdialog); ugtk_download_form_set_folders (&bdialog->download, &app->setting); // category - cnode = app->traveler.category.cursor.node->data; + cnode = app->traveler.category.cursor.node->base; if (cnode->parent != &app->real) cnode = app->real.children; ugtk_batch_dialog_set_category (bdialog, cnode); @@ -1563,9 +1573,9 @@ channel = g_io_channel_new_file (fname, "w", NULL); g_free (fname); - node = app->traveler.category.cursor.node->data; + node = app->traveler.category.cursor.node->base; for (node = node->children; node; node = node->next) { - common = ug_info_get (&node->data->info, UgetCommonInfo); + common = ug_info_get (node->info, UgetCommonInfo); if (common == NULL) continue; if (common->uri) { @@ -1641,7 +1651,7 @@ ugtk_download_form_set_folders (&bdialog->download, &app->setting); // category list - cnode = app->traveler.category.cursor.node->data; + cnode = app->traveler.category.cursor.node->base; if (cnode->parent != &app->real) cnode = app->real.children; ugtk_batch_dialog_set_category (bdialog, cnode); @@ -1686,7 +1696,7 @@ g_list_free (list); // category list - cnode = app->traveler.category.cursor.node->data; + cnode = app->traveler.category.cursor.node->base; if (cnode->parent != &app->real) cnode = app->real.children; ugtk_batch_dialog_set_category (bdialog, cnode); @@ -1763,10 +1773,10 @@ static int counts = 0; cnode = uget_node_new (NULL); - cnode->name = ug_strdup_printf ("%s %d", _("New"), counts++); - common = ug_info_realloc (&cnode->info, UgetCommonInfo); + common = ug_info_realloc (cnode->info, UgetCommonInfo); + common->name = ug_strdup_printf ("%s %d", _("New"), counts++); common->folder = ug_strdup (g_get_home_dir ()); - category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + category = ug_info_realloc (cnode->info, UgetCategoryInfo); *(char**)ug_array_alloc (&category->schemes, 1) = ug_strdup ("ftps"); *(char**)ug_array_alloc (&category->schemes, 1) = ug_strdup ("magnet"); *(char**)ug_array_alloc (&category->hosts, 1) = ug_strdup (".edu"); diff -Nru uget-2.2.0/ui-gtk/UgtkApp-callback.c uget-2.2.2/ui-gtk/UgtkApp-callback.c --- uget-2.2.0/ui-gtk/UgtkApp-callback.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkApp-callback.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -99,16 +99,16 @@ node = app->traveler.download.cursor.node; if (node) - node = node->data; + node = node->base; ugtk_summary_show (&app->summary, node); // UgtkMenubar.download.priority if (node == NULL) priority = UGET_PRIORITY_NORMAL; else { - relation = ug_info_get (&node->info, UgetRelationInfo); + relation = ug_info_get (node->info, UgetRelationInfo); if (relation) - priority = relation->task.priority; + priority = relation->priority; else priority = UGET_PRIORITY_NORMAL; } @@ -482,7 +482,7 @@ GtkTreeIter iter; UgtkApp* app; - app = node->notification->data; + app = node->control->notifier->data; if (node == (UgetNode*) app->traveler.category.model->root) { // category inserted path = gtk_tree_path_new_from_indices ( @@ -513,7 +513,7 @@ UgtkApp* app; int pos; - app = node->notification->data; + app = node->control->notifier->data; if (node == (UgetNode*) app->traveler.category.model->root) { // category removed if (sibling) @@ -549,7 +549,7 @@ UgtkApp* app; node = child->parent; - app = node->notification->data; + app = node->control->notifier->data; if (node == (UgetNode*) app->traveler.category.model->root) { // category changed path = gtk_tree_path_new_from_indices ( diff -Nru uget-2.2.0/ui-gtk/UgtkApp.h uget-2.2.2/ui-gtk/UgtkApp.h --- uget-2.2.0/ui-gtk/UgtkApp.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkApp.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -71,23 +71,25 @@ struct UgtkApp { UGET_APP_MEMBERS; -// UgetNode real; // root node for real category -// UgetNode split; -// UgetNode sorted; -// UgetNode sorted_split; -// UgetNode mix; -// UgetNode mix_split; -// UgRegistry infos; -// UgRegistry plugins; -// UgetPluginInfo* plugin; -// UgetTask task; -// UgArrayPtr nodes; -// void* uri_hash; -// char* config_dir; -// int n_error; // these n_xxxx increase by grow() -// int n_moved; -// int n_deleted; -// int n_completed; +/* // ------ UgetApp members ------ + UgetNode real; // real root node for real nodes + UgetNode split; // virtual root + UgetNode sorted; // virtual root + UgetNode sorted_split; // virtual root + UgetNode mix; // virtual root + UgetNode mix_split; // virtual root + UgRegistry infos; + UgRegistry plugins; + UgetPluginInfo* plugin_default; + UgetTask task; + UgArrayPtr nodes; + void* uri_hash; + char* config_dir; + int n_error; // uget_app_grow() will count these value: + int n_moved; // n_error, n_moved, n_deleted, and + int n_deleted; // n_completed + int n_completed; // + */ UgetRpc* rpc; UgtkSetting setting; @@ -95,7 +97,7 @@ // recent download settings struct { - UgetNode* infonode; + UgInfo* info; int category_index; int saved; } recent; diff -Nru uget-2.2.0/ui-gtk/UgtkApp-main.c uget-2.2.2/ui-gtk/UgtkApp-main.c --- uget-2.2.0/ui-gtk/UgtkApp-main.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkApp-main.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkApp-timeout.c uget-2.2.2/ui-gtk/UgtkApp-timeout.c --- uget-2.2.0/ui-gtk/UgtkApp-timeout.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkApp-timeout.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -280,13 +280,6 @@ app->task.speed.download, app->task.speed.upload); } - if (app->n_moved > 0) { - // refresh other data & status - gtk_widget_queue_draw ((GtkWidget*) app->traveler.download.view); - gtk_widget_queue_draw ((GtkWidget*) app->traveler.category.view); - gtk_widget_queue_draw ((GtkWidget*) app->traveler.state.view); - } - // if current status is "All" or "Active" if (app->traveler.state.cursor.pos == 0 || app->traveler.state.cursor.pos == 1) @@ -295,6 +288,14 @@ ugtk_traveler_restore_selection (&app->traveler); } + uget_app_trim((UgetApp*) app, NULL); + if (app->n_moved > 0) { + // refresh other data & status + gtk_widget_queue_draw ((GtkWidget*) app->traveler.download.view); + gtk_widget_queue_draw ((GtkWidget*) app->traveler.category.view); + gtk_widget_queue_draw ((GtkWidget*) app->traveler.state.view); + } + app->user_action = FALSE; app->n_moved = 0; // reset counter n_active_last = n_active; @@ -313,7 +314,7 @@ } static void ugtk_app_add_uris_quietly (UgtkApp* app, GList* list, - UgetNode* infonode, int nth_category) + UgInfo* node_info, int nth_category) { GList* link; UgUri uuri; @@ -340,16 +341,16 @@ ug_uri_init (&uuri, link->data); cnode = uget_app_match_category ((UgetApp*) app, &uuri, NULL); } - if (cnode == NULL && infonode) { + if (cnode == NULL && node_info) { // match category by filename - common = ug_info_realloc (&infonode->info, UgetCommonInfo); + common = ug_info_realloc(node_info, UgetCommonInfo); if (common && common->file) { ug_uri_init (&uuri, common->file); cnode = uget_app_match_category ((UgetApp*) app, &uuri, NULL); } } if (cnode == NULL) { - if (infonode == NULL) { + if (node_info == NULL) { cnode = uget_node_nth_child (&app->real, app->setting.clipboard.nth_category); } @@ -361,15 +362,15 @@ if (cnode == NULL) cnode = uget_node_nth_child (&app->real, 0); // add download - if (infonode == NULL) { + if (node_info == NULL) { // add and free URI uget_app_add_download_uri ((UgetApp*) app, link->data, cnode, TRUE); g_free (link->data); } else { dnode = uget_node_new (NULL); - ug_info_assign (&dnode->info, &infonode->info, NULL); - common = ug_info_realloc (&dnode->info, UgetCommonInfo); + ug_info_assign(dnode->info, node_info, NULL); + common = ug_info_realloc(dnode->info, UgetCommonInfo); common->uri = link->data; uget_app_add_download ((UgetApp*) app, dnode, cnode, TRUE); } @@ -378,7 +379,7 @@ } static void ugtk_app_add_uris_selected (UgtkApp* app, GList* list, - UgetNode* infonode, int nth_category) + UgInfo* node_info, int nth_category) { UgtkBatchDialog* bdialog; UgtkSelectorPage* page; @@ -394,7 +395,7 @@ } // choose title for clipboard or command-line - if (infonode == NULL) + if (node_info == NULL) title = g_strconcat (UGTK_APP_NAME " - ", _("New from Clipboard"), NULL); else title = g_strconcat (UGTK_APP_NAME " - ", _("New Download"), NULL); @@ -405,9 +406,9 @@ if (list->next == NULL) ugtk_batch_dialog_disable_batch (bdialog); // apply other setting - if (infonode) { - ugtk_download_form_set (&bdialog->download, infonode, FALSE); - ugtk_proxy_form_set (&bdialog->proxy, infonode, FALSE); + if (node_info) { + ugtk_download_form_set(&bdialog->download, node_info, FALSE); + ugtk_proxy_form_set(&bdialog->proxy, node_info, FALSE); } // add URIs if (list->next == NULL) { @@ -420,7 +421,7 @@ // all uris in list will be freed. ugtk_batch_dialog_use_selector (bdialog); ugtk_selector_hide_href (&bdialog->selector); - if (infonode == NULL) + if (node_info == NULL) page = ugtk_selector_add_page (&bdialog->selector, _("Clipboard")); else page = ugtk_selector_add_page (&bdialog->selector, _("Command line")); @@ -435,15 +436,15 @@ if (cnode == NULL && list->data) { // match category by URI ug_uri_init (&uuri, list->data); - if (infonode == NULL) + if (node_info == NULL) cnode = uget_app_match_category ((UgetApp*) app, &uuri, NULL); else { - common = ug_info_realloc (&infonode->info, UgetCommonInfo); + common = ug_info_realloc(node_info, UgetCommonInfo); cnode = uget_app_match_category ((UgetApp*) app, &uuri, common->file); } } if (cnode == NULL) { - if (infonode == NULL) { + if (node_info == NULL) { cnode = uget_node_nth_child (&app->real, app->setting.clipboard.nth_category); } @@ -507,7 +508,7 @@ { UgetRpcReq* req; UgetRpcCmd* cmd; - UgetNode* infonode; + UgInfo* node_info; for (;;) { if (uget_rpc_has_request(app->rpc) == FALSE) @@ -557,17 +558,17 @@ break; // add downloads - infonode = uget_node_new (NULL); - uget_option_value_to_info (&cmd->value, &infonode->info); + node_info = ug_info_new(8, 0); + uget_option_value_to_info(&cmd->value, node_info); if (cmd->value.quiet) { ugtk_app_add_uris_quietly (app, (GList*) cmd->uris.head, - infonode, cmd->value.category_index); + node_info, cmd->value.category_index); } else { ugtk_app_add_uris_selected (app, (GList*) cmd->uris.head, - infonode, cmd->value.category_index); + node_info, cmd->value.category_index); } - uget_node_unref (infonode); + ug_info_unref(node_info); break; default: @@ -777,7 +778,7 @@ #endif // HAVE_LIBNOTIFY #define NOTIFICATION_ERROR_TITLE _("Error Occurred") -#define NOTIFICATION_ERROR_STRING _("Error Occurred when downloading.") +#define NOTIFICATION_ERROR_STRING _("Error Occurred during downloading.") #define NOTIFICATION_STARTING_TITLE _("Download Starting") #define NOTIFICATION_STARTING_STRING _("Starting download queue.") #define NOTIFICATION_COMPLETED_TITLE _("Download Completed") diff -Nru uget-2.2.0/ui-gtk/UgtkApp-ui.c uget-2.2.2/ui-gtk/UgtkApp-ui.c --- uget-2.2.0/ui-gtk/UgtkApp-ui.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkApp-ui.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkBanner.c uget-2.2.2/ui-gtk/UgtkBanner.c --- uget-2.2.0/ui-gtk/UgtkBanner.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkBanner.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkBanner.h uget-2.2.2/ui-gtk/UgtkBanner.h --- uget-2.2.0/ui-gtk/UgtkBanner.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkBanner.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkBatchDialog.c uget-2.2.2/ui-gtk/UgtkBatchDialog.c --- uget-2.2.0/ui-gtk/UgtkBatchDialog.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkBatchDialog.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -198,7 +198,7 @@ uri = gtk_entry_get_text ((GtkEntry*)bdialog->download.uri_entry); if (ugtk_node_dialog_confirm_existing((UgtkNodeDialog*) bdialog, uri)) { dnode = uget_node_new (NULL); - ugtk_node_dialog_get ((UgtkNodeDialog*) bdialog, dnode); + ugtk_node_dialog_get ((UgtkNodeDialog*) bdialog, dnode->info); uget_app_add_download ((UgetApp*) app, dnode, cnode, FALSE); } } @@ -222,14 +222,13 @@ for (link = result.head; link; link = link->next) { dnode = uget_node_new (NULL); - common = ug_info_realloc (&dnode->info, UgetCommonInfo); - ugtk_node_dialog_get ((UgtkNodeDialog*) bdialog, dnode); + common = ug_info_realloc (dnode->info, UgetCommonInfo); + ugtk_node_dialog_get ((UgtkNodeDialog*) bdialog, dnode->info); common->uri = ug_strdup (link->data); uget_app_add_download ((UgetApp*) app, dnode, cnode, FALSE); } - ug_list_foreach_link (&result, (UgForeachFunc)ug_free, NULL); - ug_list_clear (&result, FALSE); + uget_sequence_clear_result(&result); } static void on_selector_response (UgtkBatchDialog* bdialog) @@ -250,8 +249,8 @@ for (link = uri_list; link; link = link->next) { dnode = uget_node_new (NULL); - common = ug_info_realloc (&dnode->info, UgetCommonInfo); - ugtk_node_dialog_get ((UgtkNodeDialog*) bdialog, dnode); + common = ug_info_realloc (dnode->info, UgetCommonInfo); + ugtk_node_dialog_get ((UgtkNodeDialog*) bdialog, dnode->info); #if 0 common->uri = link->data; link->data = NULL; diff -Nru uget-2.2.0/ui-gtk/UgtkBatchDialog.h uget-2.2.2/ui-gtk/UgtkBatchDialog.h --- uget-2.2.0/ui-gtk/UgtkBatchDialog.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkBatchDialog.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -53,20 +53,23 @@ struct UgtkBatchDialog { UGTK_NODE_DIALOG_MEMBERS; -// GtkDialog* self; -// GtkBox* hbox; -// GtkWidget* notebook; -// GtkTreeView* node_view; -// UgtkNodeTree* node_tree; -// gulong handler_id[3]; -// UgtkApp* app; -// UgetNode* node; -// UgtkProxyForm proxy; -// UgtkDownloadForm download; -// UgtkCategoryForm category; +/* // ------ UgtkNodeDialog members ------ + GtkDialog* self; + GtkBox* hbox; + GtkWidget* notebook; + GtkTreeView* node_view; + UgtkNodeTree* node_tree; + gulong handler_id[3]; + UgtkApp* app; + UgetNode* note; + UgData* node_data; + UgtkProxyForm proxy; + UgtkDownloadForm download; + UgtkCategoryForm category; + */ UgtkSelector selector; - UgtkSequence sequencer; + UgtkSequence sequencer; }; UgtkBatchDialog* ugtk_batch_dialog_new (const char* title, diff -Nru uget-2.2.0/ui-gtk/UgtkCategoryForm.c uget-2.2.2/ui-gtk/UgtkCategoryForm.c --- uget-2.2.0/ui-gtk/UgtkCategoryForm.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkCategoryForm.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -151,16 +151,18 @@ gtk_widget_show_all (GTK_WIDGET (top_grid)); } -void ugtk_category_form_get (UgtkCategoryForm* cform, UgetNode* cnode) +void ugtk_category_form_get (UgtkCategoryForm* cform, UgInfo* cnode_info) { UgetCategory* category; + UgetCommon* common; const gchar* text; - category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + category = ug_info_realloc(cnode_info, UgetCategoryInfo); + common = ug_info_realloc(cnode_info, UgetCommonInfo); if (gtk_widget_is_sensitive (cform->name_entry) == TRUE) { text = gtk_entry_get_text ((GtkEntry*) cform->name_entry); - ug_free (cnode->name); - cnode->name = (*text) ? ug_strdup (text) : NULL; + ug_free(common->name); + common->name = (*text) ? ug_strdup(text) : NULL; } category->active_limit = gtk_spin_button_get_value_as_int ( (GtkSpinButton*) cform->spin_active); @@ -187,15 +189,17 @@ &category->file_exts); } -void ugtk_category_form_set (UgtkCategoryForm* cform, UgetNode* cnode) +void ugtk_category_form_set (UgtkCategoryForm* cform, UgInfo* cnode_info) { + UgetCommon* common; UgetCategory* category; gchar* str; - category = ug_info_realloc (&cnode->info, UgetCategoryInfo); + category = ug_info_realloc(cnode_info, UgetCategoryInfo); + common = ug_info_get(cnode_info, UgetCommonInfo); if (gtk_widget_is_sensitive (cform->name_entry) == TRUE) { gtk_entry_set_text ((GtkEntry*) cform->name_entry, - (cnode->name) ? cnode->name : ""); + (common->name) ? common->name : ""); } gtk_spin_button_set_value ((GtkSpinButton*) cform->spin_active, (gdouble) category->active_limit); diff -Nru uget-2.2.0/ui-gtk/UgtkCategoryForm.h uget-2.2.2/ui-gtk/UgtkCategoryForm.h --- uget-2.2.0/ui-gtk/UgtkCategoryForm.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkCategoryForm.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -67,8 +67,8 @@ }; void ugtk_category_form_init (UgtkCategoryForm* cform); -void ugtk_category_form_get (UgtkCategoryForm* cform, UgetNode* cnode); -void ugtk_category_form_set (UgtkCategoryForm* cform, UgetNode* cnode); +void ugtk_category_form_get (UgtkCategoryForm* cform, UgInfo* cnode_info); +void ugtk_category_form_set (UgtkCategoryForm* cform, UgInfo* cnode_info); void ugtk_category_form_set_multiple (UgtkCategoryForm* cform, gboolean multiple_mode); diff -Nru uget-2.2.0/ui-gtk/UgtkConfig.c uget-2.2.2/ui-gtk/UgtkConfig.c --- uget-2.2.0/ui-gtk/UgtkConfig.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkConfig.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkConfig.h uget-2.2.2/ui-gtk/UgtkConfig.h --- uget-2.2.0/ui-gtk/UgtkConfig.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkConfig.h 2019-05-19 16:50:01.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -52,7 +52,7 @@ #endif #ifndef PACKAGE_VERSION -#define PACKAGE_VERSION "2.2.0" +#define PACKAGE_VERSION "2.2.2" #endif // ---------------------------------------------------------------------------- diff -Nru uget-2.2.0/ui-gtk/UgtkConfirmDialog.c uget-2.2.2/ui-gtk/UgtkConfirmDialog.c --- uget-2.2.0/ui-gtk/UgtkConfirmDialog.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkConfirmDialog.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkConfirmDialog.h uget-2.2.2/ui-gtk/UgtkConfirmDialog.h --- uget-2.2.0/ui-gtk/UgtkConfirmDialog.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkConfirmDialog.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkDownloadForm.c uget-2.2.2/ui-gtk/UgtkDownloadForm.c --- uget-2.2.0/ui-gtk/UgtkDownloadForm.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkDownloadForm.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -137,6 +137,8 @@ // File - entry widget = gtk_entry_new (); gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE); + gtk_entry_set_placeholder_text (GTK_ENTRY (widget), + _("Leave blank to use default filename ...")); g_object_set (widget, "margin", 1, "hexpand", TRUE, NULL); gtk_grid_attach (top_grid, widget, 1, 2, 2, 1); g_signal_connect (GTK_EDITABLE (widget), "changed", @@ -445,71 +447,74 @@ dform->timestamp = (GtkToggleButton*) widget; } -void ugtk_download_form_get (UgtkDownloadForm* dform, UgetNode* node) +void ugtk_download_form_get (UgtkDownloadForm* dform, UgInfo* node_info) { - UgetCommon* common; - UgetHttp* http; UgUri uuri; const gchar* text; gint number; + union { + UgetRelation* relation; + UgetCommon* common; + UgetHttp* http; + } temp; // ------------------------------------------ // UgetCommon - common = ug_info_realloc (&node->info, UgetCommonInfo); + temp.common = ug_info_realloc(node_info, UgetCommonInfo); // folder text = gtk_entry_get_text ((GtkEntry*)dform->folder_entry); - ug_free (common->folder); - common->folder = (*text) ? ug_strdup (text) : NULL; - ug_str_remove_crlf (common->folder, common->folder); + ug_free (temp.common->folder); + temp.common->folder = (*text) ? ug_strdup (text) : NULL; + ug_str_remove_crlf (temp.common->folder, temp.common->folder); // user text = gtk_entry_get_text ((GtkEntry*)dform->username_entry); - ug_free (common->user); - common->user = (*text) ? ug_strdup (text) : NULL; - ug_str_remove_crlf (common->user, common->user); + ug_free (temp.common->user); + temp.common->user = (*text) ? ug_strdup (text) : NULL; + ug_str_remove_crlf (temp.common->user, temp.common->user); // password text = gtk_entry_get_text ((GtkEntry*)dform->password_entry); - ug_free (common->password); - common->password = (*text) ? ug_strdup (text) : NULL; - ug_str_remove_crlf (common->password, common->password); + ug_free (temp.common->password); + temp.common->password = (*text) ? ug_strdup (text) : NULL; + ug_str_remove_crlf (temp.common->password, temp.common->password); // retry_limit number = gtk_spin_button_get_value_as_int ((GtkSpinButton*) dform->spin_retry); - common->retry_limit = number; + temp.common->retry_limit = number; // retry_delay number = gtk_spin_button_get_value_as_int ((GtkSpinButton*) dform->spin_delay); - common->retry_delay = number; + temp.common->retry_delay = number; // max_upload_speed number = gtk_spin_button_get_value_as_int ((GtkSpinButton*) dform->spin_upload_speed) * 1024; - common->max_upload_speed = number; + temp.common->max_upload_speed = number; // max_download_speed number = gtk_spin_button_get_value_as_int ((GtkSpinButton*) dform->spin_download_speed) * 1024; - common->max_download_speed = number; + temp.common->max_download_speed = number; // max_connections number = gtk_spin_button_get_value_as_int ((GtkSpinButton*) dform->spin_connections); - common->max_connections = number; + temp.common->max_connections = number; // timestamp - common->timestamp = gtk_toggle_button_get_active (dform->timestamp); + temp.common->timestamp = gtk_toggle_button_get_active (dform->timestamp); // URI if (gtk_widget_is_sensitive (dform->uri_entry) == TRUE) { text = gtk_entry_get_text ((GtkEntry*)dform->uri_entry); - ug_free (common->uri); - common->uri = (*text) ? ug_strdup (text) : NULL; - ug_str_remove_crlf (common->uri, common->uri); - if (common->uri) { - ug_uri_init (&uuri, common->uri); + ug_free (temp.common->uri); + temp.common->uri = (*text) ? ug_strdup (text) : NULL; + ug_str_remove_crlf (temp.common->uri, temp.common->uri); + if (temp.common->uri) { + ug_uri_init (&uuri, temp.common->uri); // set user number = ug_uri_user (&uuri, &text); if (number > 0) { - ug_free (common->user); - common->user = ug_strndup (text, number); + ug_free (temp.common->user); + temp.common->user = ug_strndup (text, number); } // set password number = ug_uri_password (&uuri, &text); if (number > 0) { - ug_free (common->password); - common->password = ug_strndup (text, number); + ug_free (temp.common->password); + temp.common->password = ug_strndup (text, number); } // Remove user & password from URL if (uuri.authority != uuri.host) { @@ -521,59 +526,61 @@ // mirrors if (gtk_widget_is_sensitive (dform->mirrors_entry) == TRUE) { text = gtk_entry_get_text ((GtkEntry*)dform->mirrors_entry); - ug_free (common->mirrors); - common->mirrors = (*text) ? ug_strdup (text) : NULL; - ug_str_remove_crlf (common->mirrors, common->mirrors); + ug_free (temp.common->mirrors); + temp.common->mirrors = (*text) ? ug_strdup (text) : NULL; + ug_str_remove_crlf (temp.common->mirrors, temp.common->mirrors); } // file if (gtk_widget_is_sensitive (dform->file_entry) == TRUE) { text = gtk_entry_get_text ((GtkEntry*)dform->file_entry); - ug_free (common->file); - common->file = (*text) ? ug_strdup (text) : NULL; - ug_str_remove_crlf (common->file, common->file); + ug_free (temp.common->file); + temp.common->file = (*text) ? ug_strdup (text) : NULL; + ug_str_remove_crlf (temp.common->file, temp.common->file); } // ------------------------------------------ // UgetHttp - http = ug_info_realloc (&node->info, UgetHttpInfo); + temp.http = ug_info_realloc(node_info, UgetHttpInfo); // referrer text = gtk_entry_get_text ((GtkEntry*) dform->referrer_entry); - ug_free (http->referrer); - http->referrer = (*text) ? ug_strdup (text) : NULL; - ug_str_remove_crlf (http->referrer, http->referrer); + ug_free (temp.http->referrer); + temp.http->referrer = (*text) ? ug_strdup (text) : NULL; + ug_str_remove_crlf (temp.http->referrer, temp.http->referrer); // cookie_file text = gtk_entry_get_text ((GtkEntry*) dform->cookie_entry); - ug_free (http->cookie_file); - http->cookie_file = (*text) ? ug_strdup (text) : NULL; - ug_str_remove_crlf (http->cookie_file, http->cookie_file); + ug_free (temp.http->cookie_file); + temp.http->cookie_file = (*text) ? ug_strdup (text) : NULL; + ug_str_remove_crlf (temp.http->cookie_file, temp.http->cookie_file); // post_file text = gtk_entry_get_text ((GtkEntry*) dform->post_entry); - ug_free (http->post_file); - http->post_file = (*text) ? ug_strdup (text) : NULL; - ug_str_remove_crlf (http->post_file, http->post_file); + ug_free (temp.http->post_file); + temp.http->post_file = (*text) ? ug_strdup (text) : NULL; + ug_str_remove_crlf (temp.http->post_file, temp.http->post_file); // user_agent text = gtk_entry_get_text ((GtkEntry*) dform->agent_entry); - ug_free (http->user_agent); - http->user_agent = (*text) ? ug_strdup (text) : NULL; - ug_str_remove_crlf (http->user_agent, http->user_agent); + ug_free (temp.http->user_agent); + temp.http->user_agent = (*text) ? ug_strdup (text) : NULL; + ug_str_remove_crlf (temp.http->user_agent, temp.http->user_agent); // ------------------------------------------ - // UgetNode + // UgetRelation if (gtk_widget_get_sensitive (dform->radio_pause)) { + temp.relation = ug_info_realloc(node_info, UgetRelationInfo); if (gtk_toggle_button_get_active ((GtkToggleButton*) dform->radio_pause)) - node->state |= UGET_STATE_PAUSED; + temp.relation->group |= UGET_GROUP_PAUSED; else - node->state &= ~UGET_STATE_PAUSED; + temp.relation->group &= ~UGET_GROUP_PAUSED; } } -void ugtk_download_form_set (UgtkDownloadForm* dform, UgetNode* node, gboolean keep_changed) +void ugtk_download_form_set (UgtkDownloadForm* dform, UgInfo* node_info, gboolean keep_changed) { + UgetRelation* relation; UgetCommon* common; UgetHttp* http; - common = ug_info_realloc (&node->info, UgetCommonInfo); - http = ug_info_get (&node->info, UgetHttpInfo); + common = ug_info_realloc(node_info, UgetCommonInfo); + http = ug_info_get(node_info, UgetHttpInfo); // disable changed flags dform->changed.enable = FALSE; @@ -684,9 +691,10 @@ } // ------------------------------------------ - // UgetNode + // UgetRelation if (gtk_widget_get_sensitive (dform->radio_pause)) { - if (node->state & UGET_STATE_PAUSED) + relation = ug_info_realloc(node_info, UgetRelationInfo); + if (relation->group & UGET_GROUP_PAUSED) gtk_toggle_button_set_active ((GtkToggleButton*) dform->radio_pause, TRUE); else gtk_toggle_button_set_active ((GtkToggleButton*) dform->radio_runnable, TRUE); diff -Nru uget-2.2.0/ui-gtk/UgtkDownloadForm.h uget-2.2.2/ui-gtk/UgtkDownloadForm.h --- uget-2.2.0/ui-gtk/UgtkDownloadForm.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkDownloadForm.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -143,8 +143,8 @@ void ugtk_download_form_init (UgtkDownloadForm* dform, UgtkProxyForm* proxy, GtkWindow* parent); -void ugtk_download_form_get (UgtkDownloadForm* dform, UgetNode* node); -void ugtk_download_form_set (UgtkDownloadForm* dform, UgetNode* node, gboolean keep_changed); +void ugtk_download_form_get (UgtkDownloadForm* dform, UgInfo* info); +void ugtk_download_form_set (UgtkDownloadForm* dform, UgInfo* info, gboolean keep_changed); void ugtk_download_form_set_multiple (UgtkDownloadForm* dform, gboolean multiple_mode); void ugtk_download_form_set_folders (UgtkDownloadForm* dform, UgtkSetting* setting); diff -Nru uget-2.2.0/ui-gtk/UgtkMenubar.c uget-2.2.2/ui-gtk/UgtkMenubar.c --- uget-2.2.0/ui-gtk/UgtkMenubar.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkMenubar.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -349,7 +349,7 @@ GtkTreeIter iter1, iter2; GtkTreePath *path1, *path2; - cnode = app->traveler.category.cursor.node->data; + cnode = app->traveler.category.cursor.node->base; if (cnode == NULL || cnode->prev == NULL) return; @@ -380,7 +380,7 @@ GtkTreeIter iter1, iter2; GtkTreePath *path1, *path2; - cnode = app->traveler.category.cursor.node->data; + cnode = app->traveler.category.cursor.node->base; if (cnode == NULL || cnode->next == NULL) return; @@ -445,8 +445,7 @@ node = app->traveler.download.cursor.node; if (node == NULL) return; - node = node->data; - common = ug_info_get (&node->info, UgetCommonInfo); + common = ug_info_get (node->info, UgetCommonInfo); if (common == NULL || common->folder == NULL || common->file == NULL) return; @@ -475,8 +474,7 @@ node = app->traveler.download.cursor.node; if (node == NULL) return; - node = node->data; - common = ug_info_get (&node->info, UgetCommonInfo); + common = ug_info_get (node->info, UgetCommonInfo); if (common == NULL || common->folder == NULL) return; @@ -555,12 +553,12 @@ GList* link; list = ugtk_traveler_get_selected (&app->traveler); - cursor = app->traveler.download.cursor.node->data; + cursor = app->traveler.download.cursor.node->base; for (link = list; link; link = link->next) { node = link->data; - node = node->data; + node = node->base; link->data = node; - uget_app_activate_download ((UgetApp*) app, node->data); + uget_app_activate_download ((UgetApp*) app, node->base); } if (app->traveler.state.cursor.pos == 0) { ugtk_traveler_set_cursor (&app->traveler, cursor); @@ -597,7 +595,7 @@ } } - if (cnode == NULL || cnode == app->traveler.category.cursor.node->data) + if (cnode == NULL || cnode == app->traveler.category.cursor.node->base) return; // if current category is "All" @@ -607,8 +605,8 @@ list = ugtk_traveler_get_selected (&app->traveler); for (link = list; link; link = link->next) { dnode = link->data; - dnode = dnode->data; - uget_app_move_download_to ((UgetApp*) app, dnode, cnode->data); + dnode = dnode->base; + uget_app_move_download_to ((UgetApp*) app, dnode, cnode->base); } g_list_free (list); // refresh @@ -639,9 +637,9 @@ list = ugtk_traveler_get_selected (&app->traveler); for (link = list; link; link = link->next) { node = link->data; - node = node->data; - relation = ug_info_realloc (&node->info, UgetRelationInfo); - relation->task.priority = priority; + node = node->base; + relation = ug_info_realloc (node->info, UgetRelationInfo); + relation->priority = priority; } g_list_free (list); } @@ -889,6 +887,7 @@ void ugtk_menubar_sync_category (UgtkMenubar* menubar, UgtkApp* app, gboolean reset) { UgetNode* cnode; + UgetCommon* common; GtkWidget* menu_item; GtkWidget* image; GPtrArray* array; @@ -907,7 +906,11 @@ // add new item for (cnode = app->real.children; cnode; cnode = cnode->next) { // create menu item - menu_item = gtk_image_menu_item_new_with_label (cnode->name); + common = ug_info_get(cnode->info, UgetCommonInfo); + if (common && common->name) + menu_item = gtk_image_menu_item_new_with_label (common->name); + else + menu_item = gtk_image_menu_item_new_with_label (""); image = gtk_image_new_from_stock (GTK_STOCK_DND_MULTIPLE, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image ((GtkImageMenuItem*) menu_item, @@ -927,7 +930,7 @@ for (index = 0; index < array->len; index += 2) { menu_item = g_ptr_array_index (array, index); cnode = g_ptr_array_index (array, index +1); - if (cnode == app->traveler.category.cursor.node->data) + if (cnode == app->traveler.category.cursor.node->base) gtk_widget_set_sensitive (menu_item, FALSE); else gtk_widget_set_sensitive (menu_item, TRUE); diff -Nru uget-2.2.0/ui-gtk/UgtkMenubar.h uget-2.2.2/ui-gtk/UgtkMenubar.h --- uget-2.2.0/ui-gtk/UgtkMenubar.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkMenubar.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkMenubar-ui.c uget-2.2.2/ui-gtk/UgtkMenubar-ui.c --- uget-2.2.0/ui-gtk/UgtkMenubar-ui.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkMenubar-ui.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkNodeDialog.c uget-2.2.2/ui-gtk/UgtkNodeDialog.c --- uget-2.2.0/ui-gtk/UgtkNodeDialog.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkNodeDialog.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -153,7 +153,8 @@ { if (node) { ndialog->node = node; - uget_node_ref (node); + ndialog->node_info = node->info; + ug_info_ref(node->info); } switch (mode) { @@ -244,7 +245,7 @@ app->recent.category_index = nth; gtk_tree_path_free (path); } - ugtk_download_form_get (&ndialog->download, app->recent.infonode); + ugtk_download_form_get(&ndialog->download, app->recent.info); } void ugtk_node_dialog_apply_recent (UgtkNodeDialog* ndialog, UgtkApp* app) @@ -256,8 +257,8 @@ gtk_tree_view_set_cursor (ndialog->node_view, path, NULL, FALSE); gtk_tree_path_free (path); ndialog->download.changed.uri = TRUE; - ugtk_download_form_set (&ndialog->download, - app->recent.infonode, TRUE); + ugtk_download_form_set(&ndialog->download, + app->recent.info, TRUE); } } @@ -310,20 +311,20 @@ return nth; } -void ugtk_node_dialog_set (UgtkNodeDialog* ndialog, UgetNode* node) +void ugtk_node_dialog_set (UgtkNodeDialog* ndialog, UgInfo* node_info) { - ugtk_proxy_form_set (&ndialog->proxy, node, FALSE); - ugtk_download_form_set (&ndialog->download, node, FALSE); + ugtk_proxy_form_set(&ndialog->proxy, node_info, FALSE); + ugtk_download_form_set(&ndialog->download, node_info, FALSE); if (ndialog->category.self) - ugtk_category_form_set (&ndialog->category, node); + ugtk_category_form_set(&ndialog->category, node_info); } -void ugtk_node_dialog_get (UgtkNodeDialog* ndialog, UgetNode* node) +void ugtk_node_dialog_get (UgtkNodeDialog* ndialog, UgInfo* node_info) { - ugtk_proxy_form_get (&ndialog->proxy, node); - ugtk_download_form_get (&ndialog->download, node); + ugtk_proxy_form_get(&ndialog->proxy, node_info); + ugtk_download_form_get(&ndialog->download, node_info); if (ndialog->category.self) - ugtk_category_form_get (&ndialog->category, node); + ugtk_category_form_get(&ndialog->category, node_info); } // ---------------------------------------------------------------------------- @@ -439,8 +440,8 @@ gtk_tree_model_get_iter (model, &iter, path); gtk_tree_path_free (path); node = iter.user_data; - ugtk_proxy_form_set (&ndialog->proxy, node, TRUE); - ugtk_download_form_set (&ndialog->download, node, TRUE); + ugtk_proxy_form_set(&ndialog->proxy, node->info, TRUE); + ugtk_download_form_set(&ndialog->download, node->info, TRUE); } static void after_uri_entry_changed (GtkEditable *editable, @@ -457,14 +458,14 @@ if (response_id == GTK_RESPONSE_OK) { cnode = uget_node_new (NULL); - ugtk_node_dialog_get (ndialog, cnode); + ugtk_node_dialog_get(ndialog, cnode->info); uget_app_add_category ((UgetApp*) ndialog->app, cnode, TRUE); ugtk_app_decide_category_sensitive (ndialog->app); ugtk_download_form_get_folders (&ndialog->download, &ndialog->app->setting); } - if (ndialog->node) - uget_node_unref (ndialog->node); + if (ndialog->node_info) + ug_info_unref(ndialog->node_info); ugtk_node_dialog_free (ndialog); } @@ -478,7 +479,7 @@ if (response_id == GTK_RESPONSE_OK) { ugtk_node_dialog_store_recent (ndialog, ndialog->app); dnode = uget_node_new (NULL); - ugtk_node_dialog_get (ndialog, dnode); + ugtk_node_dialog_get(ndialog, dnode->info); ugtk_node_dialog_get_category (ndialog, &cnode); uri = gtk_entry_get_text ((GtkEntry*) ndialog->download.uri_entry); if (ugtk_node_dialog_confirm_existing (ndialog, uri)) { @@ -487,8 +488,8 @@ &ndialog->app->setting); } } - if (ndialog->node) - uget_node_unref (ndialog->node); + if (ndialog->node_info) + ug_info_unref(ndialog->node_info); ugtk_node_dialog_free (ndialog); } @@ -497,11 +498,13 @@ { UgtkApp* app; - if (response_id == GTK_RESPONSE_OK && ndialog->node) { + if (response_id == GTK_RESPONSE_OK && ndialog->node_info) { app = ndialog->app; - ugtk_node_dialog_get (ndialog, ndialog->node); - ugtk_app_category_changed (app, ndialog->node); - uget_node_unref (ndialog->node); + ugtk_node_dialog_get(ndialog, ndialog->node_info); + // if ndialog->node_info->ref_count == 1, ndialog->node is freed by App + if (ndialog->node_info->ref_count > 1) + ugtk_app_category_changed(app, ndialog->node); + ug_info_unref(ndialog->node_info); ugtk_download_form_get_folders (&ndialog->download, &app->setting); } @@ -513,15 +516,18 @@ { UgtkApp* app; - if (response_id == GTK_RESPONSE_OK && ndialog->node) { + if (response_id == GTK_RESPONSE_OK && ndialog->node_info) { app = ndialog->app; - uget_uri_hash_remove_download (app->uri_hash, ndialog->node); - ugtk_node_dialog_get (ndialog, ndialog->node); - uget_uri_hash_add_download (app->uri_hash, ndialog->node); - ugtk_traveler_reserve_selection (&app->traveler); - uget_app_reset_download_name ((UgetApp*) app, ndialog->node); - ugtk_traveler_restore_selection (&app->traveler); - uget_node_unref (ndialog->node); + uget_uri_hash_remove_download(app->uri_hash, ndialog->node_info); + ugtk_node_dialog_get(ndialog, ndialog->node_info); + uget_uri_hash_add_download(app->uri_hash, ndialog->node_info); + // if ndialog->node_info->ref_count == 1, ndialog->node is freed by App + if (ndialog->node_info->ref_count > 1) { + ugtk_traveler_reserve_selection (&app->traveler); + uget_app_reset_download_name((UgetApp*) app, ndialog->node); + ugtk_traveler_restore_selection (&app->traveler); + } + ug_info_unref(ndialog->node_info); ugtk_download_form_get_folders (&ndialog->download, &app->setting); } diff -Nru uget-2.2.0/ui-gtk/UgtkNodeDialog.h uget-2.2.2/ui-gtk/UgtkNodeDialog.h --- uget-2.2.0/ui-gtk/UgtkNodeDialog.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkNodeDialog.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -66,6 +66,7 @@ gulong handler_id[3]; \ UgtkApp* app; \ UgetNode* node; \ + UgInfo* node_info; \ UgtkProxyForm proxy; \ UgtkDownloadForm download; \ UgtkCategoryForm category @@ -73,17 +74,20 @@ struct UgtkNodeDialog { UGTK_NODE_DIALOG_MEMBERS; -// GtkDialog* self; -// GtkBox* hbox; -// GtkWidget* notebook; -// GtkTreeView* node_view; -// UgtkNodeTree* node_tree; -// gulong handler_id[3]; -// UgtkApp* app; -// UgetNode* node; -// UgtkProxyForm proxy; -// UgtkDownloadForm download; -// UgtkCategoryForm category; +/* // ------ UgtkNodeDialog members ------ + GtkDialog* self; + GtkBox* hbox; + GtkWidget* notebook; + GtkTreeView* node_view; + UgtkNodeTree* node_tree; + gulong handler_id[3]; + UgtkApp* app; + UgetNode* note; + UgInfo* node_info; + UgtkProxyForm proxy; + UgtkDownloadForm download; + UgtkCategoryForm category; + */ // handler_id[0] : "row-changed" // handler_id[1] : "row-deleted" @@ -102,8 +106,8 @@ void ugtk_node_dialog_set_category (UgtkNodeDialog* ndialog, UgetNode* cnode); // set/get node's info to/from UgtkNodeDialog -void ugtk_node_dialog_get (UgtkNodeDialog* ndialog, UgetNode* node); -void ugtk_node_dialog_set (UgtkNodeDialog* ndialog, UgetNode* node); +void ugtk_node_dialog_get (UgtkNodeDialog* ndialog, UgInfo* node_info); +void ugtk_node_dialog_set (UgtkNodeDialog* ndialog, UgInfo* node_info); void ugtk_node_dialog_run (UgtkNodeDialog* ndialog, UgtkNodeDialogMode mode, diff -Nru uget-2.2.0/ui-gtk/UgtkNodeList.c uget-2.2.2/ui-gtk/UgtkNodeList.c --- uget-2.2.0/ui-gtk/UgtkNodeList.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkNodeList.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkNodeList.h uget-2.2.2/ui-gtk/UgtkNodeList.h --- uget-2.2.0/ui-gtk/UgtkNodeList.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkNodeList.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkNodeTree.c uget-2.2.2/ui-gtk/UgtkNodeTree.c --- uget-2.2.0/ui-gtk/UgtkNodeTree.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkNodeTree.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkNodeTree.h uget-2.2.2/ui-gtk/UgtkNodeTree.h --- uget-2.2.0/ui-gtk/UgtkNodeTree.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkNodeTree.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkNodeView.c uget-2.2.2/ui-gtk/UgtkNodeView.c --- uget-2.2.0/ui-gtk/UgtkNodeView.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkNodeView.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -49,26 +49,26 @@ #if GTK_MAJOR_VERSION >= 3 && GTK_MINOR_VERSION >= 10 static const UgPair state_icon_pair[] = { - {(void*)(intptr_t) UGET_STATE_FINISHED, "go-last"}, - {(void*)(intptr_t) UGET_STATE_RECYCLED, "list-remove"}, - {(void*)(intptr_t) UGET_STATE_PAUSED, "media-playback-pause"}, - {(void*)(intptr_t) UGET_STATE_ERROR, "dialog-error"}, - {(void*)(intptr_t) UGET_STATE_UPLOADING, "go-up"}, - {(void*)(intptr_t) UGET_STATE_COMPLETED, "gtk-yes"}, - {(void*)(intptr_t) UGET_STATE_QUEUING, "text-x-generic"}, - {(void*)(intptr_t) UGET_STATE_ACTIVE, "media-playback-start"}, + {(void*)(intptr_t) UGET_GROUP_FINISHED, "go-last"}, + {(void*)(intptr_t) UGET_GROUP_RECYCLED, "list-remove"}, + {(void*)(intptr_t) UGET_GROUP_PAUSED, "media-playback-pause"}, + {(void*)(intptr_t) UGET_GROUP_ERROR, "dialog-error"}, + {(void*)(intptr_t) UGET_GROUP_UPLOADING, "go-up"}, + {(void*)(intptr_t) UGET_GROUP_COMPLETED, "gtk-yes"}, + {(void*)(intptr_t) UGET_GROUP_QUEUING, "text-x-generic"}, + {(void*)(intptr_t) UGET_GROUP_ACTIVE, "media-playback-start"}, }; #else static const UgPair state_icon_pair[] = { - {(void*)(intptr_t) UGET_STATE_FINISHED, GTK_STOCK_GOTO_LAST}, - {(void*)(intptr_t) UGET_STATE_RECYCLED, GTK_STOCK_DELETE}, - {(void*)(intptr_t) UGET_STATE_PAUSED, GTK_STOCK_MEDIA_PAUSE}, - {(void*)(intptr_t) UGET_STATE_ERROR, GTK_STOCK_DIALOG_ERROR}, - {(void*)(intptr_t) UGET_STATE_UPLOADING, GTK_STOCK_GO_UP}, - {(void*)(intptr_t) UGET_STATE_COMPLETED, GTK_STOCK_YES}, - {(void*)(intptr_t) UGET_STATE_QUEUING, GTK_STOCK_FILE}, - {(void*)(intptr_t) UGET_STATE_ACTIVE, GTK_STOCK_MEDIA_PLAY}, + {(void*)(intptr_t) UGET_GROUP_FINISHED, GTK_STOCK_GOTO_LAST}, + {(void*)(intptr_t) UGET_GROUP_RECYCLED, GTK_STOCK_DELETE}, + {(void*)(intptr_t) UGET_GROUP_PAUSED, GTK_STOCK_MEDIA_PAUSE}, + {(void*)(intptr_t) UGET_GROUP_ERROR, GTK_STOCK_DIALOG_ERROR}, + {(void*)(intptr_t) UGET_GROUP_UPLOADING, GTK_STOCK_GO_UP}, + {(void*)(intptr_t) UGET_GROUP_COMPLETED, GTK_STOCK_YES}, + {(void*)(intptr_t) UGET_GROUP_QUEUING, GTK_STOCK_FILE}, + {(void*)(intptr_t) UGET_GROUP_ACTIVE, GTK_STOCK_MEDIA_PLAY}, }; #endif static const int state_icon_pair_len = sizeof (state_icon_pair) / sizeof (UgPair); @@ -80,6 +80,7 @@ gpointer data) { UgetNode* node; + UgetRelation* relation; const gchar* icon_name; int key, index; @@ -89,7 +90,7 @@ if (node == NULL) return; - node = node->data; + node = node->base; #if GTK_MAJOR_VERSION >= 3 && GTK_MINOR_VERSION >= 10 icon_name = "text-x-generic"; #else @@ -98,7 +99,8 @@ // select icon_name for (index = 0; index < state_icon_pair_len; index++) { key = (intptr_t)state_icon_pair[index].key; - if ((key & node->state) == key) { + relation = ug_info_realloc(node->info, UgetRelationInfo); + if ((key & relation->group) == key) { icon_name = state_icon_pair[index].data; break; } @@ -139,13 +141,14 @@ // } // } - node = node->data; + node = node->base; name = _("unnamed"); + common = ug_info_get(node->info, UgetCommonInfo); - if (node->name) - name = node->name; + if (common && common->name) + name = common->name; else { - common = ug_info_get (&node->info, UgetCommonInfo); + common = ug_info_get (node->info, UgetCommonInfo); if (common) { if (common->file) name = common->file; @@ -171,9 +174,9 @@ // avoid crash in GTK3 if (node == NULL) return; - node = node->data; + node = node->base; - progress = ug_info_get (&node->info, UgetProgressInfo); + progress = ug_info_get (node->info, UgetProgressInfo); if (progress && progress->total) string = ug_str_from_int_unit (progress->complete, NULL); else @@ -198,9 +201,9 @@ // avoid crash in GTK3 if (node == NULL) return; - node = node->data; + node = node->base; - progress = ug_info_get (&node->info, UgetProgressInfo); + progress = ug_info_get (node->info, UgetProgressInfo); if (progress && progress->total) string = ug_str_from_int_unit (progress->total, NULL); else @@ -225,9 +228,9 @@ // avoid crash in GTK3 if (node == NULL) return; - node = node->data; + node = node->base; - progress = ug_info_get (&node->info, UgetProgressInfo); + progress = ug_info_get (node->info, UgetProgressInfo); if (progress && progress->total) { string = ug_strdup_printf ("%d%c", progress->percent, '%'); g_object_set (cell, "visible", TRUE, NULL); @@ -258,9 +261,9 @@ // avoid crash in GTK3 if (node == NULL) return; - node = node->data; + node = node->base; - progress = ug_info_get (&node->info, UgetProgressInfo); + progress = ug_info_get (node->info, UgetProgressInfo); if (progress) string = ug_str_from_seconds ((int) progress->elapsed, TRUE); else @@ -287,12 +290,12 @@ // avoid crash in GTK3 if (node == NULL) return; - node = node->data; + node = node->base; - progress = ug_info_get (&node->info, UgetProgressInfo); - relation = ug_info_get (&node->info, UgetRelationInfo); + progress = ug_info_get (node->info, UgetProgressInfo); + relation = ug_info_get (node->info, UgetRelationInfo); - if (progress && relation && relation->task.plugin) + if (progress && relation && relation->task) string = ug_str_from_seconds ((int) progress->left, TRUE); else string = NULL; @@ -317,12 +320,12 @@ // avoid crash in GTK3 if (node == NULL) return; - node = node->data; + node = node->base; - progress = ug_info_get (&node->info, UgetProgressInfo); - relation = ug_info_get (&node->info, UgetRelationInfo); + progress = ug_info_get (node->info, UgetProgressInfo); + relation = ug_info_get (node->info, UgetRelationInfo); - if (progress && relation && relation->task.plugin) + if (progress && relation && relation->task) string = ug_str_from_int_unit (progress->download_speed, "/s"); else string = NULL; @@ -347,12 +350,12 @@ // avoid crash in GTK3 if (node == NULL) return; - node = node->data; + node = node->base; - progress = ug_info_get (&node->info, UgetProgressInfo); - relation = ug_info_get (&node->info, UgetRelationInfo); + progress = ug_info_get (node->info, UgetProgressInfo); + relation = ug_info_get (node->info, UgetRelationInfo); - if (progress && relation && relation->task.plugin && progress->upload_speed) + if (progress && relation && relation->task && progress->upload_speed) string = ug_str_from_int_unit (progress->upload_speed, "/s"); else string = NULL; @@ -376,9 +379,9 @@ // avoid crash in GTK3 if (node == NULL) return; - node = node->data; + node = node->base; - progress = ug_info_get (&node->info, UgetProgressInfo); + progress = ug_info_get (node->info, UgetProgressInfo); if (progress && progress->uploaded) string = ug_str_from_int_unit (progress->uploaded, NULL); else @@ -403,9 +406,9 @@ // avoid crash in GTK3 if (node == NULL) return; - node = node->data; + node = node->base; - progress = ug_info_get (&node->info, UgetProgressInfo); + progress = ug_info_get (node->info, UgetProgressInfo); if (progress && progress->ratio) string = ug_strdup_printf ("%.2f", progress->ratio); else @@ -430,9 +433,9 @@ // avoid crash in GTK3 if (node == NULL) return; - node = node->data; + node = node->base; - common = ug_info_get (&node->info, UgetCommonInfo); + common = ug_info_get (node->info, UgetCommonInfo); if (common == NULL || common->retry_count == 0) string = NULL; else if (common->retry_count < 100) @@ -452,6 +455,7 @@ GtkTreeIter *iter, gpointer data) { + UgetCommon* common; UgetNode* node; char* string; @@ -460,10 +464,15 @@ // avoid crash in GTK3 if (node == NULL) return; - node = node->data; + node = node->base; - if (node->parent) - string = node->parent->name; + if (node->parent) { + common = ug_info_get(node->parent->info, UgetCommonInfo); + if (common) + string = common->name; + else + string = NULL; + } else string = NULL; @@ -485,9 +494,9 @@ // avoid crash in GTK3 if (node == NULL) return; - node = node->data; + node = node->base; - common = ug_info_get (&node->info, UgetCommonInfo); + common = ug_info_get (node->info, UgetCommonInfo); if (common) string = common->uri; else @@ -511,9 +520,9 @@ // avoid crash in GTK3 if (node == NULL) return; - node = node->data; + node = node->base; - ulog = ug_info_get (&node->info, UgetLogInfo); + ulog = ug_info_get (node->info, UgetLogInfo); if (ulog && ulog->added_time) string = ug_str_from_time (ulog->added_time, FALSE); else @@ -538,9 +547,9 @@ // avoid crash in GTK3 if (node == NULL) return; - node = node->data; + node = node->base; - ulog = ug_info_get (&node->info, UgetLogInfo); + ulog = ug_info_get (node->info, UgetLogInfo); if (ulog && ulog->completed_time) string = ug_str_from_time (ulog->completed_time, FALSE); else @@ -582,6 +591,7 @@ GtkTreeIter *iter, gpointer data) { + UgetCommon* common; UgetNode* node; char* name; @@ -601,9 +611,10 @@ // } // } - node = node->data; - if (node->name) - name = node->name; + node = node->base; + common = ug_info_get(node->info, UgetCommonInfo); + if (common && common->name) + name = common->name; else name = _("unnamed"); @@ -620,12 +631,12 @@ node = iter->user_data; #if GTK_MAJOR_VERSION >= 3 && GTK_MINOR_VERSION >= 10 - if (node->state & UGET_STATE_PAUSED) + if (uget_node_get_group(node) & UGET_GROUP_PAUSED) g_object_set (cell, "icon-name", "media-playback-pause", NULL); else g_object_set (cell, "icon-name", "gtk-dnd-multiple", NULL); #else - if (node->state & UGET_STATE_PAUSED) + if (uget_node_get_group(node) & UGET_GROUP_PAUSED) g_object_set (cell, "stock-id", GTK_STOCK_MEDIA_PAUSE, NULL); else g_object_set (cell, "stock-id", GTK_STOCK_DND_MULTIPLE, NULL); @@ -637,14 +648,14 @@ static const UgPair state_name_pair[] = { - {(void*)(intptr_t) UGET_STATE_ERROR, N_("Error")}, - {(void*)(intptr_t) UGET_STATE_PAUSED, N_("Paused")}, - {(void*)(intptr_t) UGET_STATE_UPLOADING, N_("Uploading")}, - {(void*)(intptr_t) UGET_STATE_COMPLETED, N_("Completed")}, - {(void*)(intptr_t) UGET_STATE_FINISHED, N_("Finished")}, - {(void*)(intptr_t) UGET_STATE_RECYCLED, N_("Recycled")}, - {(void*)(intptr_t) UGET_STATE_QUEUING, N_("Queuing")}, - {(void*)(intptr_t) UGET_STATE_ACTIVE, N_("Active")}, + {(void*)(intptr_t) UGET_GROUP_ERROR, N_("Error")}, + {(void*)(intptr_t) UGET_GROUP_PAUSED, N_("Paused")}, + {(void*)(intptr_t) UGET_GROUP_UPLOADING, N_("Uploading")}, + {(void*)(intptr_t) UGET_GROUP_COMPLETED, N_("Completed")}, + {(void*)(intptr_t) UGET_GROUP_FINISHED, N_("Finished")}, + {(void*)(intptr_t) UGET_GROUP_RECYCLED, N_("Recycled")}, + {(void*)(intptr_t) UGET_GROUP_QUEUING, N_("Queuing")}, + {(void*)(intptr_t) UGET_GROUP_ACTIVE, N_("Active")}, }; static const int state_name_pair_len = sizeof (state_name_pair) / sizeof (UgPair); @@ -658,6 +669,7 @@ char* name; int key; int index; + int group; // gtk_tree_model_get (model, iter, 0, &node, -1); node = iter->user_data; @@ -667,9 +679,10 @@ name = _("All Status"); if (node->real) { + group = uget_node_get_group(node); for (index = 0; index < state_name_pair_len; index++) { key = (intptr_t)state_name_pair[index].key; - if ((key & node->state) == key) { + if ((key & group) == key) { name = gettext (state_name_pair[index].data); break; } @@ -687,6 +700,7 @@ UgetNode* node; const gchar* icon_name; int key, index; + int group; // gtk_tree_model_get (model, iter, 0, &node, -1); node = iter->user_data; @@ -701,9 +715,10 @@ icon_name = GTK_STOCK_DND_MULTIPLE; #endif if (node->real) { + group = uget_node_get_group(node); for (index = 0; index < state_icon_pair_len; index++) { key = (intptr_t)state_icon_pair[index].key; - if ((key & node->state) == key) { + if ((key & group) == key) { icon_name = state_icon_pair[index].data; break; } diff -Nru uget-2.2.0/ui-gtk/UgtkNodeView.h uget-2.2.2/ui-gtk/UgtkNodeView.h --- uget-2.2.0/ui-gtk/UgtkNodeView.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkNodeView.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkProxyForm.c uget-2.2.2/ui-gtk/UgtkProxyForm.c --- uget-2.2.0/ui-gtk/UgtkProxyForm.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkProxyForm.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -181,14 +181,14 @@ gtk_widget_show_all (pform->std); } -void ugtk_proxy_form_get (UgtkProxyForm* pform, UgetNode* node) +void ugtk_proxy_form_get (UgtkProxyForm* pform, UgInfo* node_info) { UgetProxy* proxy; gint index; const gchar* text; index = gtk_combo_box_get_active ((GtkComboBox*) pform->type); - proxy = ug_info_realloc (&node->info, UgetProxyInfo); + proxy = ug_info_realloc (node_info, UgetProxyInfo); proxy->type = index; // user text = gtk_entry_get_text ((GtkEntry*)pform->user); @@ -221,11 +221,11 @@ #endif // HAVE_LIBPWMD } -void ugtk_proxy_form_set (UgtkProxyForm* pform, UgetNode* node, gboolean keep_changed) +void ugtk_proxy_form_set (UgtkProxyForm* pform, UgInfo* node_info, gboolean keep_changed) { UgetProxy* proxy; - proxy = ug_info_get (&node->info, UgetProxyInfo); + proxy = ug_info_get (node_info, UgetProxyInfo); // if no proxy data if (proxy == NULL) { pform->changed.enable = FALSE; // disable changed flags diff -Nru uget-2.2.0/ui-gtk/UgtkProxyForm.h uget-2.2.2/ui-gtk/UgtkProxyForm.h --- uget-2.2.0/ui-gtk/UgtkProxyForm.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkProxyForm.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -104,8 +104,8 @@ }; void ugtk_proxy_form_init (UgtkProxyForm* pform); -void ugtk_proxy_form_get (UgtkProxyForm* pform, UgetNode* node); -void ugtk_proxy_form_set (UgtkProxyForm* pform, UgetNode* node, gboolean keep_changed); +void ugtk_proxy_form_get (UgtkProxyForm* pform, UgInfo* info); +void ugtk_proxy_form_set (UgtkProxyForm* pform, UgInfo* info, gboolean keep_changed); #ifdef __cplusplus diff -Nru uget-2.2.0/ui-gtk/UgtkScheduleForm.c uget-2.2.2/ui-gtk/UgtkScheduleForm.c --- uget-2.2.0/ui-gtk/UgtkScheduleForm.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkScheduleForm.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkScheduleForm.h uget-2.2.2/ui-gtk/UgtkScheduleForm.h --- uget-2.2.0/ui-gtk/UgtkScheduleForm.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkScheduleForm.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkSelector.c uget-2.2.2/ui-gtk/UgtkSelector.c --- uget-2.2.0/ui-gtk/UgtkSelector.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkSelector.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkSelector.h uget-2.2.2/ui-gtk/UgtkSelector.h --- uget-2.2.0/ui-gtk/UgtkSelector.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkSelector.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkSequence.c uget-2.2.2/ui-gtk/UgtkSequence.c --- uget-2.2.0/ui-gtk/UgtkSequence.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkSequence.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -323,8 +323,7 @@ gtk_list_store_append (seq->preview.store, &iter); gtk_list_store_set (seq->preview.store, &iter, 0, link->data, -1); } - ug_list_foreach_link (&result, (UgForeachFunc)ug_free, NULL); - ug_list_clear (&result, FALSE); + uget_sequence_clear_result(&result); // notify if (seq->notify.func) seq->notify.func (seq->notify.data, TRUE); diff -Nru uget-2.2.0/ui-gtk/UgtkSequence.h uget-2.2.2/ui-gtk/UgtkSequence.h --- uget-2.2.0/ui-gtk/UgtkSequence.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkSequence.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkSetting.c uget-2.2.2/ui-gtk/UgtkSetting.c --- uget-2.2.0/ui-gtk/UgtkSetting.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkSetting.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkSettingDialog.c uget-2.2.2/ui-gtk/UgtkSettingDialog.c --- uget-2.2.0/ui-gtk/UgtkSettingDialog.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkSettingDialog.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkSettingDialog.h uget-2.2.2/ui-gtk/UgtkSettingDialog.h --- uget-2.2.0/ui-gtk/UgtkSettingDialog.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkSettingDialog.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkSettingForm.c uget-2.2.2/ui-gtk/UgtkSettingForm.c --- uget-2.2.0/ui-gtk/UgtkSettingForm.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkSettingForm.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkSettingForm.h uget-2.2.2/ui-gtk/UgtkSettingForm.h --- uget-2.2.0/ui-gtk/UgtkSettingForm.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkSettingForm.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkSetting.h uget-2.2.2/ui-gtk/UgtkSetting.h --- uget-2.2.0/ui-gtk/UgtkSetting.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkSetting.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkSummary.c uget-2.2.2/ui-gtk/UgtkSummary.c --- uget-2.2.0/ui-gtk/UgtkSummary.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkSummary.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -91,14 +91,13 @@ } iter.stamp = 0; // used by ugtk_summary_store_realloc_next() - node = node->data; - temp.common = ug_info_get (&node->info, UgetCommonInfo); + temp.common = ug_info_get (node->info, UgetCommonInfo); // Summary Name if (summary->visible.name) { - if (node->name) { + if (temp.common && temp.common->name) { name = g_strconcat (_("Name"), ":", NULL); - value = node->name; + value = temp.common->name; } else { name = g_strconcat (_("File"), ":", NULL); @@ -129,7 +128,13 @@ // Summary Category if (summary->visible.category) { name = g_strconcat (_("Category"), ":", NULL); - value = (node->parent) ? node->parent->name : NULL; + if (node->parent) { + temp.common = ug_info_get (node->parent->info, UgetCommonInfo); + value = (temp.common) ? temp.common->name : NULL; + temp.common = ug_info_get (node->info, UgetCommonInfo); + } + else + value = NULL; ugtk_summary_store_realloc_next (summary->store, &iter); gtk_list_store_set (summary->store, &iter, UGTK_SUMMARY_COLUMN_ICON , GTK_STOCK_DND_MULTIPLE, @@ -151,7 +156,7 @@ g_free (name); } // Summary Message - temp.log = ug_info_get (&node->info, UgetLogInfo); + temp.log = ug_info_get (node->info, UgetLogInfo); if (temp.log) temp.event = (UgetEvent*) temp.log->messages.head; if (summary->visible.message) { diff -Nru uget-2.2.0/ui-gtk/UgtkSummary.h uget-2.2.2/ui-gtk/UgtkSummary.h --- uget-2.2.0/ui-gtk/UgtkSummary.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkSummary.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkTraveler.c uget-2.2.2/ui-gtk/UgtkTraveler.c --- uget-2.2.0/ui-gtk/UgtkTraveler.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkTraveler.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -227,23 +227,14 @@ GList* list; GList* link; - g_list_free_full (traveler->reserved.list, - (GDestroyNotify) uget_node_unref); - if (traveler->reserved.node) - uget_node_unref (traveler->reserved.node); - list = ugtk_traveler_get_selected (traveler); - for (link = list; link; link = link->next) { - link->data = ((UgetNode*)link->data)->data; - uget_node_ref (link->data); - } + for (link = list; link; link = link->next) + link->data = ((UgetNode*)link->data)->base; traveler->reserved.list = list; traveler->reserved.node = traveler->download.cursor.node; - if (traveler->reserved.node) { - traveler->reserved.node = traveler->reserved.node->data; - uget_node_ref (traveler->reserved.node); - } + if (traveler->reserved.node) + traveler->reserved.node = traveler->reserved.node->base; return list; } @@ -256,9 +247,6 @@ node = traveler->reserved.node; ugtk_traveler_set_cursor (traveler, node); ugtk_traveler_set_selected (traveler, list); - if (node) - uget_node_unref (node); - g_list_free_full (list, (GDestroyNotify) uget_node_unref); traveler->reserved.list = NULL; traveler->reserved.node = NULL; } diff -Nru uget-2.2.0/ui-gtk/UgtkTraveler.h uget-2.2.2/ui-gtk/UgtkTraveler.h --- uget-2.2.0/ui-gtk/UgtkTraveler.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkTraveler.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2012-2018 by C.H. Huang + * Copyright (C) 2012-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkTrayIcon.c uget-2.2.2/ui-gtk/UgtkTrayIcon.c --- uget-2.2.0/ui-gtk/UgtkTrayIcon.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkTrayIcon.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkTrayIcon.h uget-2.2.2/ui-gtk/UgtkTrayIcon.h --- uget-2.2.0/ui-gtk/UgtkTrayIcon.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkTrayIcon.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkUtil.c uget-2.2.2/ui-gtk/UgtkUtil.c --- uget-2.2.0/ui-gtk/UgtkUtil.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkUtil.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk/UgtkUtil.h uget-2.2.2/ui-gtk/UgtkUtil.h --- uget-2.2.0/ui-gtk/UgtkUtil.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk/UgtkUtil.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk-1to2/main.c uget-2.2.2/ui-gtk-1to2/main.c --- uget-2.2.0/ui-gtk-1to2/main.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/main.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2013-2018 by C.H. Huang + * Copyright (C) 2013-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk-1to2/Makefile.am uget-2.2.2/ui-gtk-1to2/Makefile.am --- uget-2.2.0/ui-gtk-1to2/Makefile.am 2017-11-16 13:26:18.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/Makefile.am 2019-05-19 16:49:07.000000000 +0000 @@ -1,4 +1,4 @@ -AUTOMAKE_OPTIONS = subdir-objects +AUTOMAKE_OPTIONS = subdir-objects no-dependencies bin_PROGRAMS = uget-gtk-1to2 diff -Nru uget-2.2.0/ui-gtk-1to2/Makefile.in uget-2.2.2/ui-gtk-1to2/Makefile.in --- uget-2.2.0/ui-gtk-1to2/Makefile.in 2018-01-08 00:05:58.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/Makefile.in 2019-05-19 16:51:34.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -130,9 +130,8 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f +depcomp = +am__maybe_remake_depfiles = AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -176,7 +175,7 @@ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -326,7 +325,7 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -AUTOMAKE_OPTIONS = subdir-objects +AUTOMAKE_OPTIONS = subdir-objects no-dependencies uget_gtk_1to2_CPPFLAGS = \ -DDATADIR='"$(datadir)"' \ -I$(top_srcdir)/ui-gtk \ @@ -385,8 +384,8 @@ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -442,11 +441,8 @@ ../ui-gtk/$(am__dirstamp): @$(MKDIR_P) ../ui-gtk @: > ../ui-gtk/$(am__dirstamp) -../ui-gtk/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) ../ui-gtk/$(DEPDIR) - @: > ../ui-gtk/$(DEPDIR)/$(am__dirstamp) ../ui-gtk/uget_gtk_1to2-UgtkSetting.$(OBJEXT): \ - ../ui-gtk/$(am__dirstamp) ../ui-gtk/$(DEPDIR)/$(am__dirstamp) + ../ui-gtk/$(am__dirstamp) uget-gtk-1to2$(EXEEXT): $(uget_gtk_1to2_OBJECTS) $(uget_gtk_1to2_DEPENDENCIES) $(EXTRA_uget_gtk_1to2_DEPENDENCIES) @rm -f uget-gtk-1to2$(EXEEXT) @@ -459,172 +455,71 @@ distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@../ui-gtk/$(DEPDIR)/uget_gtk_1to2-UgtkSetting.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk_1to2-UgCategory.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk_1to2-UgData-download.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk_1to2-UgData1.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk_1to2-UgDataset.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk_1to2-UgMarkup.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk_1to2-UgRegistry1.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk_1to2-UgSetting.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk_1to2-Ugtk1to2.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uget_gtk_1to2-main.Po@am__quote@ - .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + $(AM_V_CC)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + $(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` uget_gtk_1to2-UgCategory.o: UgCategory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-UgCategory.o -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-UgCategory.Tpo -c -o uget_gtk_1to2-UgCategory.o `test -f 'UgCategory.c' || echo '$(srcdir)/'`UgCategory.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-UgCategory.Tpo $(DEPDIR)/uget_gtk_1to2-UgCategory.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgCategory.c' object='uget_gtk_1to2-UgCategory.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgCategory.o `test -f 'UgCategory.c' || echo '$(srcdir)/'`UgCategory.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgCategory.o `test -f 'UgCategory.c' || echo '$(srcdir)/'`UgCategory.c uget_gtk_1to2-UgCategory.obj: UgCategory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-UgCategory.obj -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-UgCategory.Tpo -c -o uget_gtk_1to2-UgCategory.obj `if test -f 'UgCategory.c'; then $(CYGPATH_W) 'UgCategory.c'; else $(CYGPATH_W) '$(srcdir)/UgCategory.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-UgCategory.Tpo $(DEPDIR)/uget_gtk_1to2-UgCategory.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgCategory.c' object='uget_gtk_1to2-UgCategory.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgCategory.obj `if test -f 'UgCategory.c'; then $(CYGPATH_W) 'UgCategory.c'; else $(CYGPATH_W) '$(srcdir)/UgCategory.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgCategory.obj `if test -f 'UgCategory.c'; then $(CYGPATH_W) 'UgCategory.c'; else $(CYGPATH_W) '$(srcdir)/UgCategory.c'; fi` uget_gtk_1to2-UgData1.o: UgData1.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-UgData1.o -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-UgData1.Tpo -c -o uget_gtk_1to2-UgData1.o `test -f 'UgData1.c' || echo '$(srcdir)/'`UgData1.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-UgData1.Tpo $(DEPDIR)/uget_gtk_1to2-UgData1.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgData1.c' object='uget_gtk_1to2-UgData1.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgData1.o `test -f 'UgData1.c' || echo '$(srcdir)/'`UgData1.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgData1.o `test -f 'UgData1.c' || echo '$(srcdir)/'`UgData1.c uget_gtk_1to2-UgData1.obj: UgData1.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-UgData1.obj -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-UgData1.Tpo -c -o uget_gtk_1to2-UgData1.obj `if test -f 'UgData1.c'; then $(CYGPATH_W) 'UgData1.c'; else $(CYGPATH_W) '$(srcdir)/UgData1.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-UgData1.Tpo $(DEPDIR)/uget_gtk_1to2-UgData1.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgData1.c' object='uget_gtk_1to2-UgData1.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgData1.obj `if test -f 'UgData1.c'; then $(CYGPATH_W) 'UgData1.c'; else $(CYGPATH_W) '$(srcdir)/UgData1.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgData1.obj `if test -f 'UgData1.c'; then $(CYGPATH_W) 'UgData1.c'; else $(CYGPATH_W) '$(srcdir)/UgData1.c'; fi` uget_gtk_1to2-UgData-download.o: UgData-download.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-UgData-download.o -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-UgData-download.Tpo -c -o uget_gtk_1to2-UgData-download.o `test -f 'UgData-download.c' || echo '$(srcdir)/'`UgData-download.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-UgData-download.Tpo $(DEPDIR)/uget_gtk_1to2-UgData-download.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgData-download.c' object='uget_gtk_1to2-UgData-download.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgData-download.o `test -f 'UgData-download.c' || echo '$(srcdir)/'`UgData-download.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgData-download.o `test -f 'UgData-download.c' || echo '$(srcdir)/'`UgData-download.c uget_gtk_1to2-UgData-download.obj: UgData-download.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-UgData-download.obj -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-UgData-download.Tpo -c -o uget_gtk_1to2-UgData-download.obj `if test -f 'UgData-download.c'; then $(CYGPATH_W) 'UgData-download.c'; else $(CYGPATH_W) '$(srcdir)/UgData-download.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-UgData-download.Tpo $(DEPDIR)/uget_gtk_1to2-UgData-download.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgData-download.c' object='uget_gtk_1to2-UgData-download.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgData-download.obj `if test -f 'UgData-download.c'; then $(CYGPATH_W) 'UgData-download.c'; else $(CYGPATH_W) '$(srcdir)/UgData-download.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgData-download.obj `if test -f 'UgData-download.c'; then $(CYGPATH_W) 'UgData-download.c'; else $(CYGPATH_W) '$(srcdir)/UgData-download.c'; fi` uget_gtk_1to2-UgDataset.o: UgDataset.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-UgDataset.o -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-UgDataset.Tpo -c -o uget_gtk_1to2-UgDataset.o `test -f 'UgDataset.c' || echo '$(srcdir)/'`UgDataset.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-UgDataset.Tpo $(DEPDIR)/uget_gtk_1to2-UgDataset.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgDataset.c' object='uget_gtk_1to2-UgDataset.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgDataset.o `test -f 'UgDataset.c' || echo '$(srcdir)/'`UgDataset.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgDataset.o `test -f 'UgDataset.c' || echo '$(srcdir)/'`UgDataset.c uget_gtk_1to2-UgDataset.obj: UgDataset.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-UgDataset.obj -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-UgDataset.Tpo -c -o uget_gtk_1to2-UgDataset.obj `if test -f 'UgDataset.c'; then $(CYGPATH_W) 'UgDataset.c'; else $(CYGPATH_W) '$(srcdir)/UgDataset.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-UgDataset.Tpo $(DEPDIR)/uget_gtk_1to2-UgDataset.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgDataset.c' object='uget_gtk_1to2-UgDataset.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgDataset.obj `if test -f 'UgDataset.c'; then $(CYGPATH_W) 'UgDataset.c'; else $(CYGPATH_W) '$(srcdir)/UgDataset.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgDataset.obj `if test -f 'UgDataset.c'; then $(CYGPATH_W) 'UgDataset.c'; else $(CYGPATH_W) '$(srcdir)/UgDataset.c'; fi` uget_gtk_1to2-UgMarkup.o: UgMarkup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-UgMarkup.o -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-UgMarkup.Tpo -c -o uget_gtk_1to2-UgMarkup.o `test -f 'UgMarkup.c' || echo '$(srcdir)/'`UgMarkup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-UgMarkup.Tpo $(DEPDIR)/uget_gtk_1to2-UgMarkup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgMarkup.c' object='uget_gtk_1to2-UgMarkup.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgMarkup.o `test -f 'UgMarkup.c' || echo '$(srcdir)/'`UgMarkup.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgMarkup.o `test -f 'UgMarkup.c' || echo '$(srcdir)/'`UgMarkup.c uget_gtk_1to2-UgMarkup.obj: UgMarkup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-UgMarkup.obj -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-UgMarkup.Tpo -c -o uget_gtk_1to2-UgMarkup.obj `if test -f 'UgMarkup.c'; then $(CYGPATH_W) 'UgMarkup.c'; else $(CYGPATH_W) '$(srcdir)/UgMarkup.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-UgMarkup.Tpo $(DEPDIR)/uget_gtk_1to2-UgMarkup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgMarkup.c' object='uget_gtk_1to2-UgMarkup.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgMarkup.obj `if test -f 'UgMarkup.c'; then $(CYGPATH_W) 'UgMarkup.c'; else $(CYGPATH_W) '$(srcdir)/UgMarkup.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgMarkup.obj `if test -f 'UgMarkup.c'; then $(CYGPATH_W) 'UgMarkup.c'; else $(CYGPATH_W) '$(srcdir)/UgMarkup.c'; fi` uget_gtk_1to2-UgRegistry1.o: UgRegistry1.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-UgRegistry1.o -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-UgRegistry1.Tpo -c -o uget_gtk_1to2-UgRegistry1.o `test -f 'UgRegistry1.c' || echo '$(srcdir)/'`UgRegistry1.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-UgRegistry1.Tpo $(DEPDIR)/uget_gtk_1to2-UgRegistry1.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgRegistry1.c' object='uget_gtk_1to2-UgRegistry1.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgRegistry1.o `test -f 'UgRegistry1.c' || echo '$(srcdir)/'`UgRegistry1.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgRegistry1.o `test -f 'UgRegistry1.c' || echo '$(srcdir)/'`UgRegistry1.c uget_gtk_1to2-UgRegistry1.obj: UgRegistry1.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-UgRegistry1.obj -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-UgRegistry1.Tpo -c -o uget_gtk_1to2-UgRegistry1.obj `if test -f 'UgRegistry1.c'; then $(CYGPATH_W) 'UgRegistry1.c'; else $(CYGPATH_W) '$(srcdir)/UgRegistry1.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-UgRegistry1.Tpo $(DEPDIR)/uget_gtk_1to2-UgRegistry1.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgRegistry1.c' object='uget_gtk_1to2-UgRegistry1.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgRegistry1.obj `if test -f 'UgRegistry1.c'; then $(CYGPATH_W) 'UgRegistry1.c'; else $(CYGPATH_W) '$(srcdir)/UgRegistry1.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgRegistry1.obj `if test -f 'UgRegistry1.c'; then $(CYGPATH_W) 'UgRegistry1.c'; else $(CYGPATH_W) '$(srcdir)/UgRegistry1.c'; fi` uget_gtk_1to2-UgSetting.o: UgSetting.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-UgSetting.o -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-UgSetting.Tpo -c -o uget_gtk_1to2-UgSetting.o `test -f 'UgSetting.c' || echo '$(srcdir)/'`UgSetting.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-UgSetting.Tpo $(DEPDIR)/uget_gtk_1to2-UgSetting.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgSetting.c' object='uget_gtk_1to2-UgSetting.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgSetting.o `test -f 'UgSetting.c' || echo '$(srcdir)/'`UgSetting.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgSetting.o `test -f 'UgSetting.c' || echo '$(srcdir)/'`UgSetting.c uget_gtk_1to2-UgSetting.obj: UgSetting.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-UgSetting.obj -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-UgSetting.Tpo -c -o uget_gtk_1to2-UgSetting.obj `if test -f 'UgSetting.c'; then $(CYGPATH_W) 'UgSetting.c'; else $(CYGPATH_W) '$(srcdir)/UgSetting.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-UgSetting.Tpo $(DEPDIR)/uget_gtk_1to2-UgSetting.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='UgSetting.c' object='uget_gtk_1to2-UgSetting.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgSetting.obj `if test -f 'UgSetting.c'; then $(CYGPATH_W) 'UgSetting.c'; else $(CYGPATH_W) '$(srcdir)/UgSetting.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-UgSetting.obj `if test -f 'UgSetting.c'; then $(CYGPATH_W) 'UgSetting.c'; else $(CYGPATH_W) '$(srcdir)/UgSetting.c'; fi` uget_gtk_1to2-Ugtk1to2.o: Ugtk1to2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-Ugtk1to2.o -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-Ugtk1to2.Tpo -c -o uget_gtk_1to2-Ugtk1to2.o `test -f 'Ugtk1to2.c' || echo '$(srcdir)/'`Ugtk1to2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-Ugtk1to2.Tpo $(DEPDIR)/uget_gtk_1to2-Ugtk1to2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='Ugtk1to2.c' object='uget_gtk_1to2-Ugtk1to2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-Ugtk1to2.o `test -f 'Ugtk1to2.c' || echo '$(srcdir)/'`Ugtk1to2.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-Ugtk1to2.o `test -f 'Ugtk1to2.c' || echo '$(srcdir)/'`Ugtk1to2.c uget_gtk_1to2-Ugtk1to2.obj: Ugtk1to2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-Ugtk1to2.obj -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-Ugtk1to2.Tpo -c -o uget_gtk_1to2-Ugtk1to2.obj `if test -f 'Ugtk1to2.c'; then $(CYGPATH_W) 'Ugtk1to2.c'; else $(CYGPATH_W) '$(srcdir)/Ugtk1to2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-Ugtk1to2.Tpo $(DEPDIR)/uget_gtk_1to2-Ugtk1to2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='Ugtk1to2.c' object='uget_gtk_1to2-Ugtk1to2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-Ugtk1to2.obj `if test -f 'Ugtk1to2.c'; then $(CYGPATH_W) 'Ugtk1to2.c'; else $(CYGPATH_W) '$(srcdir)/Ugtk1to2.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-Ugtk1to2.obj `if test -f 'Ugtk1to2.c'; then $(CYGPATH_W) 'Ugtk1to2.c'; else $(CYGPATH_W) '$(srcdir)/Ugtk1to2.c'; fi` ../ui-gtk/uget_gtk_1to2-UgtkSetting.o: ../ui-gtk/UgtkSetting.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT ../ui-gtk/uget_gtk_1to2-UgtkSetting.o -MD -MP -MF ../ui-gtk/$(DEPDIR)/uget_gtk_1to2-UgtkSetting.Tpo -c -o ../ui-gtk/uget_gtk_1to2-UgtkSetting.o `test -f '../ui-gtk/UgtkSetting.c' || echo '$(srcdir)/'`../ui-gtk/UgtkSetting.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../ui-gtk/$(DEPDIR)/uget_gtk_1to2-UgtkSetting.Tpo ../ui-gtk/$(DEPDIR)/uget_gtk_1to2-UgtkSetting.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../ui-gtk/UgtkSetting.c' object='../ui-gtk/uget_gtk_1to2-UgtkSetting.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o ../ui-gtk/uget_gtk_1to2-UgtkSetting.o `test -f '../ui-gtk/UgtkSetting.c' || echo '$(srcdir)/'`../ui-gtk/UgtkSetting.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o ../ui-gtk/uget_gtk_1to2-UgtkSetting.o `test -f '../ui-gtk/UgtkSetting.c' || echo '$(srcdir)/'`../ui-gtk/UgtkSetting.c ../ui-gtk/uget_gtk_1to2-UgtkSetting.obj: ../ui-gtk/UgtkSetting.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT ../ui-gtk/uget_gtk_1to2-UgtkSetting.obj -MD -MP -MF ../ui-gtk/$(DEPDIR)/uget_gtk_1to2-UgtkSetting.Tpo -c -o ../ui-gtk/uget_gtk_1to2-UgtkSetting.obj `if test -f '../ui-gtk/UgtkSetting.c'; then $(CYGPATH_W) '../ui-gtk/UgtkSetting.c'; else $(CYGPATH_W) '$(srcdir)/../ui-gtk/UgtkSetting.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../ui-gtk/$(DEPDIR)/uget_gtk_1to2-UgtkSetting.Tpo ../ui-gtk/$(DEPDIR)/uget_gtk_1to2-UgtkSetting.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../ui-gtk/UgtkSetting.c' object='../ui-gtk/uget_gtk_1to2-UgtkSetting.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o ../ui-gtk/uget_gtk_1to2-UgtkSetting.obj `if test -f '../ui-gtk/UgtkSetting.c'; then $(CYGPATH_W) '../ui-gtk/UgtkSetting.c'; else $(CYGPATH_W) '$(srcdir)/../ui-gtk/UgtkSetting.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o ../ui-gtk/uget_gtk_1to2-UgtkSetting.obj `if test -f '../ui-gtk/UgtkSetting.c'; then $(CYGPATH_W) '../ui-gtk/UgtkSetting.c'; else $(CYGPATH_W) '$(srcdir)/../ui-gtk/UgtkSetting.c'; fi` uget_gtk_1to2-main.o: main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-main.o -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-main.Tpo -c -o uget_gtk_1to2-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-main.Tpo $(DEPDIR)/uget_gtk_1to2-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='uget_gtk_1to2-main.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c uget_gtk_1to2-main.obj: main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -MT uget_gtk_1to2-main.obj -MD -MP -MF $(DEPDIR)/uget_gtk_1to2-main.Tpo -c -o uget_gtk_1to2-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/uget_gtk_1to2-main.Tpo $(DEPDIR)/uget_gtk_1to2-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='uget_gtk_1to2-main.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi` + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(uget_gtk_1to2_CPPFLAGS) $(CPPFLAGS) $(uget_gtk_1to2_CFLAGS) $(CFLAGS) -c -o uget_gtk_1to2-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique @@ -678,7 +573,10 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -741,7 +639,6 @@ distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f ../ui-gtk/$(DEPDIR)/$(am__dirstamp) -rm -f ../ui-gtk/$(am__dirstamp) maintainer-clean-generic: @@ -752,7 +649,6 @@ clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am - -rm -rf ../ui-gtk/$(DEPDIR) ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -798,7 +694,6 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ../ui-gtk/$(DEPDIR) ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff -Nru uget-2.2.0/ui-gtk-1to2/UgCategory.c uget-2.2.2/ui-gtk-1to2/UgCategory.c --- uget-2.2.0/ui-gtk-1to2/UgCategory.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/UgCategory.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk-1to2/UgCategory.h uget-2.2.2/ui-gtk-1to2/UgCategory.h --- uget-2.2.0/ui-gtk-1to2/UgCategory.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/UgCategory.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk-1to2/UgData1.c uget-2.2.2/ui-gtk-1to2/UgData1.c --- uget-2.2.0/ui-gtk-1to2/UgData1.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/UgData1.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk-1to2/UgData1.h uget-2.2.2/ui-gtk-1to2/UgData1.h --- uget-2.2.0/ui-gtk-1to2/UgData1.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/UgData1.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -49,7 +49,7 @@ typedef struct UgData1 UgData1; typedef struct UgDatalist UgDatalist; -typedef enum UgType UgType; +typedef enum UgType1 UgType1; // UgData1Interface typedef void (*UgInitFunc) (void* instance); @@ -64,7 +64,7 @@ // notify callback typedef void (*UgNotifyFunc) (void* user_data); -enum UgType +enum UgType1 { UG_TYPE_NONE, UG_TYPE_STRING, @@ -110,7 +110,7 @@ { char* name; // tag name int offset; - UgType type; + UgType1 type; const void* parser; // How to parse data. const void* writer; // How to write data. diff -Nru uget-2.2.0/ui-gtk-1to2/UgData-download.c uget-2.2.2/ui-gtk-1to2/UgData-download.c --- uget-2.2.0/ui-gtk-1to2/UgData-download.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/UgData-download.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk-1to2/UgData-download.h uget-2.2.2/ui-gtk-1to2/UgData-download.h --- uget-2.2.0/ui-gtk-1to2/UgData-download.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/UgData-download.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk-1to2/UgDataset.c uget-2.2.2/ui-gtk-1to2/UgDataset.c --- uget-2.2.0/ui-gtk-1to2/UgDataset.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/UgDataset.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk-1to2/UgDataset.h uget-2.2.2/ui-gtk-1to2/UgDataset.h --- uget-2.2.0/ui-gtk-1to2/UgDataset.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/UgDataset.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk-1to2/UgMarkup.c uget-2.2.2/ui-gtk-1to2/UgMarkup.c --- uget-2.2.0/ui-gtk-1to2/UgMarkup.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/UgMarkup.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk-1to2/UgMarkup.h uget-2.2.2/ui-gtk-1to2/UgMarkup.h --- uget-2.2.0/ui-gtk-1to2/UgMarkup.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/UgMarkup.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk-1to2/UgRegistry1.c uget-2.2.2/ui-gtk-1to2/UgRegistry1.c --- uget-2.2.0/ui-gtk-1to2/UgRegistry1.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/UgRegistry1.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk-1to2/UgRegistry1.h uget-2.2.2/ui-gtk-1to2/UgRegistry1.h --- uget-2.2.0/ui-gtk-1to2/UgRegistry1.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/UgRegistry1.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk-1to2/UgSetting.c uget-2.2.2/ui-gtk-1to2/UgSetting.c --- uget-2.2.0/ui-gtk-1to2/UgSetting.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/UgSetting.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk-1to2/UgSetting.h uget-2.2.2/ui-gtk-1to2/UgSetting.h --- uget-2.2.0/ui-gtk-1to2/UgSetting.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/UgSetting.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2005-2018 by C.H. Huang + * Copyright (C) 2005-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/ui-gtk-1to2/Ugtk1to2.c uget-2.2.2/ui-gtk-1to2/Ugtk1to2.c --- uget-2.2.0/ui-gtk-1to2/Ugtk1to2.c 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/Ugtk1to2.c 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2013-2018 by C.H. Huang + * Copyright (C) 2013-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or @@ -194,6 +194,7 @@ union { UgetProgress* progress; + UgetRelation* relation; UgetCommon* common; UgetProxy* proxy; UgetHttp* http; @@ -202,28 +203,29 @@ old.relation = ug_dataset_get (dataset, UgRelationInfo, 0); if (old.relation) { + new.relation = ug_info_realloc (node->info, UgetRelationInfo); if (old.relation->hints & UG_HINT_PAUSED) - node->state |= UGET_STATE_PAUSED; + new.relation->group |= UGET_GROUP_PAUSED; if (old.relation->hints & UG_HINT_ERROR) - node->state |= UGET_STATE_ERROR; + new.relation->group |= UGET_GROUP_ERROR; if (old.relation->hints & UG_HINT_COMPLETED) - node->state |= UGET_STATE_COMPLETED; + new.relation->group |= UGET_GROUP_COMPLETED; if (old.relation->hints & UG_HINT_FINISHED) - node->state |= UGET_STATE_FINISHED; + new.relation->group |= UGET_GROUP_FINISHED; else if (old.relation->hints & UG_HINT_RECYCLED) - node->state |= UGET_STATE_RECYCLED; + new.relation->group |= UGET_GROUP_RECYCLED; else - node->state |= UGET_STATE_QUEUING; + new.relation->group |= UGET_GROUP_QUEUING; } old.common = ug_dataset_get (dataset, UgCommonInfo, 0); if (old.common) { - node->name = old.common->name; + new.common = ug_info_realloc (node->info, UgetCommonInfo); + new.common->name = old.common->name; old.common->name = NULL; - if (node->name == NULL && old.common->file) - node->name = ug_strdup (old.common->file); - new.common = ug_info_realloc (&node->info, UgetCommonInfo); + if (new.common->name == NULL && old.common->file) + new.common->name = ug_strdup (old.common->file); new.common->uri = old.common->url; old.common->url = NULL; new.common->mirrors = old.common->mirrors; @@ -249,7 +251,7 @@ old.proxy = ug_dataset_get (dataset, UgProxyInfo, 0); if (old.proxy) { - new.proxy = ug_info_realloc (&node->info, UgetProxyInfo); + new.proxy = ug_info_realloc (node->info, UgetProxyInfo); new.proxy->host = old.proxy->host; old.proxy->host = NULL; new.proxy->port = old.proxy->port; @@ -262,7 +264,7 @@ old.http = ug_dataset_get (dataset, UgHttpInfo, 0); if (old.http) { - new.http = ug_info_realloc (&node->info, UgetHttpInfo); + new.http = ug_info_realloc (node->info, UgetHttpInfo); new.http->user = old.http->user; old.http->user = NULL; new.http->password = old.http->password; @@ -285,7 +287,7 @@ old.ftp = ug_dataset_get (dataset, UgFtpInfo, 0); if (old.ftp) { - new.ftp = ug_info_realloc (&node->info, UgetFtpInfo); + new.ftp = ug_info_realloc (node->info, UgetFtpInfo); new.ftp->user = old.ftp->user; old.ftp->user = NULL; new.ftp->password = old.ftp->password; @@ -295,7 +297,7 @@ old.progress = ug_dataset_get (dataset, UgProgressInfo, 0); if (old.progress) { - new.progress = ug_info_realloc (&node->info, UgetProgressInfo); + new.progress = ug_info_realloc (node->info, UgetProgressInfo); new.progress->complete = old.progress->complete; new.progress->total = old.progress->total; new.progress->complete = old.progress->complete; @@ -312,16 +314,17 @@ GList* link; UgetNode* node; UgetNode* dnode; + UgetCommon* common; UgetCategory* category; node = uget_node_new (NULL); uget_node_set_by_dataset (node, category1->defaults); - category = ug_info_realloc (&node->info, UgetCategoryInfo); + category = ug_info_realloc (node->info, UgetCategoryInfo); category->active_limit = category1->active_limit; category->finished_limit = category1->finished_limit; category->recycled_limit = category1->recycled_limit; - node->type = UGET_NODE_CATEGORY; - node->name = category1->name; + common = ug_info_realloc(node->info, UgetCommonInfo); + common->name = category1->name; category1->name = NULL; // other *(char**)ug_array_alloc (&category->schemes, 1) = ug_strdup ("http"); @@ -333,7 +336,6 @@ // for (link = category1->indices; link; link = link->next) { dnode = uget_node_new (NULL); - dnode->type = UGET_NODE_DOWNLOAD; uget_node_set_by_dataset (dnode, (UgDataset*) link->data); uget_node_append (node, dnode); } diff -Nru uget-2.2.0/ui-gtk-1to2/Ugtk1to2.h uget-2.2.2/ui-gtk-1to2/Ugtk1to2.h --- uget-2.2.0/ui-gtk-1to2/Ugtk1to2.h 2018-01-08 00:04:26.000000000 +0000 +++ uget-2.2.2/ui-gtk-1to2/Ugtk1to2.h 2019-05-19 16:49:07.000000000 +0000 @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2013-2018 by C.H. Huang + * Copyright (C) 2013-2019 by C.H. Huang * plushuang.tw@gmail.com * * This library is free software; you can redistribute it and/or diff -Nru uget-2.2.0/Windows/CodeBlocks/test-info.cbp uget-2.2.2/Windows/CodeBlocks/test-info.cbp --- uget-2.2.0/Windows/CodeBlocks/test-info.cbp 2017-11-16 13:26:20.000000000 +0000 +++ uget-2.2.2/Windows/CodeBlocks/test-info.cbp 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ - - - - - - diff -Nru uget-2.2.0/Windows/CodeBlocks/test-uget-cxx.cbp uget-2.2.2/Windows/CodeBlocks/test-uget-cxx.cbp --- uget-2.2.0/Windows/CodeBlocks/test-uget-cxx.cbp 2017-11-16 13:26:19.000000000 +0000 +++ uget-2.2.2/Windows/CodeBlocks/test-uget-cxx.cbp 2019-05-19 16:49:05.000000000 +0000 @@ -35,8 +35,8 @@ - + @@ -46,6 +46,7 @@ + diff -Nru uget-2.2.0/Windows/CodeBlocks/uget.cbp uget-2.2.2/Windows/CodeBlocks/uget.cbp --- uget-2.2.0/Windows/CodeBlocks/uget.cbp 2018-01-06 06:32:35.000000000 +0000 +++ uget-2.2.2/Windows/CodeBlocks/uget.cbp 2019-05-19 16:49:05.000000000 +0000 @@ -68,6 +68,10 @@