Imported Upstream version 2.0.7 upstream upstream/2.0.7
authorDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 16 Dec 2021 00:18:58 +0000 (09:18 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 16 Dec 2021 00:18:58 +0000 (09:18 +0900)
13 files changed:
ChangeLog
Makefile.in
NEWS
aclocal.m4
configure
configure.ac
install-sh
its/Makefile.in
itstool
itstool.1
itstool.in
missing
setup.py

index 1b681d4..7002159 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,81 @@
+commit e21be796ad7c274674aa62817b405569039f669f
+Merge: db42353 f1c747a
+Author: Shaun McCance <shaunm@redhat.com>
+Date:   Sat Dec 26 22:36:28 2020 -0500
+
+    Merge pull request #40 from ptoscano/update-gitignore
+    
+    Update .gitignore
+
+commit db42353587f48f3885f55f1998e4cabbb4c359e2
+Author: Shaun McCance <shaunm@redhat.com>
+Date:   Sat Dec 26 15:50:32 2020 -0500
+
+    Fix errors from accidental global variable removal
+    
+    In a recent commit for profiling, I moved the __main__ code to a main()
+    function. This broke some stuff that relied on an accidentally global
+    variable. Now the variable gets passed as a param, as it should.
+
+ itstool.in | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+commit decbd0e50e824ee0241b36c07c5652b1af47ff20
+Author: Shaun McCance <shaunm@redhat.com>
+Date:   Sat Dec 12 10:40:30 2020 -0500
+
+    Cache computed values for translate, localefilter, and locnote
+    
+    If these aren't explicitly set for a node with a selector or local markup,
+    then we have to chain up, often all the way to the root. But we were doing
+    this over and over again, chaining up across the same nodes. This change
+    stores the computed value, so chaining up usually hits that cache. I was
+    careful to clear the cache if new rules are applied.
+
+ itstool.in | 41 +++++++++++++++++++++++++++++++++++------
+ 1 file changed, 35 insertions(+), 6 deletions(-)
+
+commit 366dbb36b897dc223b41a1855ea1f3075ad565ba
+Author: Shaun McCance <shaunm@redhat.com>
+Date:   Sun Dec 6 13:44:24 2020 -0500
+
+    Don't re-lookup ITS params for every single rule
+    
+    We have to create a new XPath context for every rule, and we have
+    to freshly apply any ITS params to that context. But what we were
+    also doing is looking thru the children of the parent ITS rules
+    element for param element each time. This was inefficient. Looking
+    for param elements only once per ruleset gives a small but measurable
+    speed boost.
+
+ itstool.in | 65 +++++++++++++++++++++++++++++++++++++-------------------------
+ 1 file changed, 39 insertions(+), 26 deletions(-)
+
+commit f1c747ae846e7d54fc8e3facd020a7d080560d76
+Author: Pino Toscano <ptoscano@redhat.com>
+Date:   Tue May 19 07:38:33 2020 +0200
+
+    Update .gitignore
+    
+    - remove entries referring to non-existing stuff
+    - prefix files appearing in the top-level directory with '/'
+    - add '/' as suffix for directories
+    - add '*.mo' for files created during the test run
+    - sort the entries
+
+ .gitignore | 27 ++++++++++++---------------
+ 1 file changed, 12 insertions(+), 15 deletions(-)
+
+commit 60f3a955ca047b1d62a1d952beec74afaff7cbbf
+Author: Shaun McCance <shaunm@redhat.com>
+Date:   Sat Apr 6 14:55:49 2019 -0400
+
+    Version 2.0.6
+
+ NEWS         | 5 +++++
+ configure.ac | 2 +-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
 commit ce3e235efbe251083f257e0b1cfdaa11e4f7b01c
 Author: Shaun McCance <shaunm@redhat.com>
 Date:   Sun Dec 30 16:31:05 2018 -0500
index 3474509..338aa9e 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 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 @@ am__recursive_targets = \
   $(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)
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
@@ -306,6 +306,7 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -350,8 +351,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
            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)
@@ -553,7 +554,10 @@ distclean-tags:
        -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'`; \
@@ -632,6 +636,10 @@ dist-xz: distdir
        tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
        $(am__post_remove_distdir)
 
+dist-zstd: distdir
+       tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
+       $(am__post_remove_distdir)
+
 dist-tarZ: distdir
        @echo WARNING: "Support for distribution archives compressed with" \
                       "legacy program 'compress' is deprecated." >&2
@@ -674,6 +682,8 @@ distcheck: dist
          eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
        *.zip*) \
          unzip $(distdir).zip ;;\
+       *.tar.zst*) \
+         zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
        esac
        chmod -R a-w $(distdir)
        chmod u+w $(distdir)
@@ -855,7 +865,7 @@ uninstall-man: uninstall-man1
        am--refresh check check-am clean clean-cscope clean-generic \
        cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
        dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
-       distcheck distclean distclean-generic distclean-tags \
+       dist-zstd distcheck distclean distclean-generic distclean-tags \
        distcleancheck distdir distuninstallcheck dvi dvi-am html \
        html-am info info-am install install-am install-binSCRIPTS \
        install-data install-data-am install-dvi install-dvi-am \
diff --git a/NEWS b/NEWS
index bd0f482..6678184 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+2.0.7
+=====
+* Performance improvements when chaining up on certain ITS rules
+* Performance improvements when using ITS params.
+
 2.0.6
 =====
 * Make DocBook keyword element within text
index 83ef91d..e7aaf4f 100644 (file)
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
 
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,7 @@ You have another version of autoconf.  It may work, but is not guaranteed to.
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-# Copyright (C) 2002-2017 Free Software Foundation, Inc.
+# Copyright (C) 2002-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
 # 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.2], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # 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.2])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -197,8 +197,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
 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:
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 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.
@@ -265,7 +265,7 @@ END
 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: <http://www.gnu.org/software/coreutils/>.
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
 
 If you want to complete the configuration process using your problematic
 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@@ -307,7 +307,7 @@ for _am_header in $config_headers :; do
 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-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -328,7 +328,7 @@ if test x"${install_sh+set}" != xset; then
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2017 Free Software Foundation, Inc.
+# Copyright (C) 2003-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -349,7 +349,7 @@ AC_SUBST([am__leading_dot])])
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2017 Free Software Foundation, Inc.
+# Copyright (C) 1997-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -388,7 +388,7 @@ fi
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -417,7 +417,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -450,10 +450,12 @@ AC_DEFUN([AM_PATH_PYTHON],
  [
   dnl Find a Python interpreter.  Python versions prior to 2.0 are not
   dnl supported. (2.0 was released on October 16, 2000).
-  dnl FIXME: Remove the need to hard-code Python versions here.
   m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
-[python python2 python3 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 dnl
- python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0])
+[python python2 python3 dnl
+ python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 dnl
+ python3.2 python3.1 python3.0 dnl
+ python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 dnl
+ python2.0])
 
   AC_ARG_VAR([PYTHON], [the Python interpreter])
 
@@ -498,12 +500,14 @@ AC_DEFUN([AM_PATH_PYTHON],
     m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])])
   else
 
-  dnl Query Python for its version number.  Getting [:3] seems to be
-  dnl the best way to do this; it's what "site.py" does in the standard
-  dnl library.
+  dnl Query Python for its version number.  Although site.py simply uses
+  dnl sys.version[:3], printing that failed with Python 3.10, since the
+  dnl trailing zero was eliminated. So now we output just the major
+  dnl and minor version numbers, as numbers. Apparently the tertiary
+  dnl version is not of interest.
 
   AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version],
-    [am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`])
+    [am_cv_python_version=`$PYTHON -c "import sys; print('%u.%u' % sys.version_info[[:2]])"`])
   AC_SUBST([PYTHON_VERSION], [$am_cv_python_version])
 
   dnl Use the values of $prefix and $exec_prefix for the corresponding
@@ -653,7 +657,7 @@ for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
 sys.exit(sys.hexversion < minverhex)"
   AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -672,7 +676,7 @@ AC_DEFUN([AM_RUN_LOG],
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -753,7 +757,7 @@ AC_CONFIG_COMMANDS_PRE(
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2017 Free Software Foundation, Inc.
+# Copyright (C) 2009-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -813,7 +817,7 @@ AC_SUBST([AM_BACKSLASH])dnl
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -841,7 +845,7 @@ fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2017 Free Software Foundation, Inc.
+# Copyright (C) 2006-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -860,7 +864,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2017 Free Software Foundation, Inc.
+# Copyright (C) 2004-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
index a1f046d..864cf74 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for itstool 2.0.6.
+# Generated by GNU Autoconf 2.69 for itstool 2.0.7.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -576,8 +576,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='itstool'
 PACKAGE_TARNAME='itstool'
-PACKAGE_VERSION='2.0.6'
-PACKAGE_STRING='itstool 2.0.6'
+PACKAGE_VERSION='2.0.7'
+PACKAGE_STRING='itstool 2.0.7'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -639,6 +639,7 @@ infodir
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -705,6 +706,7 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -957,6 +959,15 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1094,7 +1105,7 @@ fi
 for ac_var in  exec_prefix prefix bindir sbindir libexecdir datarootdir \
                datadir sysconfdir sharedstatedir localstatedir includedir \
                oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-               libdir localedir mandir
+               libdir localedir mandir runstatedir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1207,7 +1218,7 @@ if test "$ac_init_help" = "long"; then
   # 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 itstool 2.0.6 to adapt to many kinds of systems.
+\`configure' configures itstool 2.0.7 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1247,6 +1258,7 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -1273,7 +1285,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of itstool 2.0.6:";;
+     short | recursive ) echo "Configuration of itstool 2.0.7:";;
    esac
   cat <<\_ACEOF
 
@@ -1353,7 +1365,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-itstool configure 2.0.6
+itstool configure 2.0.7
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1370,7 +1382,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by itstool $as_me 2.0.6, which was
+It was created by itstool $as_me 2.0.7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -1718,7 +1730,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-am__api_version='1.15'
+am__api_version='1.16'
 
 ac_aux_dir=
 for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
@@ -2233,7 +2245,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='itstool'
- VERSION='2.0.6'
+ VERSION='2.0.7'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -2263,8 +2275,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
 
 # For better backward compatibility.  To be removed once Automake 1.9.x
 # dies out for good.  For more background, see:
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 mkdir_p='$(MKDIR_P)'
 
 # We need awk for the "check" target (and possibly the TAP driver).  The
@@ -2315,7 +2327,7 @@ END
 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: <http://www.gnu.org/software/coreutils/>.
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
 
 If you want to complete the configuration process using your problematic
 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@@ -2377,7 +2389,7 @@ if ${am_cv_pathless_PYTHON+:} false; then :
   $as_echo_n "(cached) " >&6
 else
 
-       for am_cv_pathless_PYTHON in python python2 python3 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7  python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do
+       for am_cv_pathless_PYTHON in python python2 python3  python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3  python3.2 python3.1 python3.0  python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1  python2.0 none; do
          test "$am_cv_pathless_PYTHON" = none && break
          prog="import sys
 # split strings by '.' and convert to numeric.  Append some zeros
@@ -2458,7 +2470,7 @@ $as_echo_n "checking for $am_display_PYTHON version... " >&6; }
 if ${am_cv_python_version+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"`
+  am_cv_python_version=`$PYTHON -c "import sys; print('%u.%u' % sys.version_info[:2])"`
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5
 $as_echo "$am_cv_python_version" >&6; }
@@ -3165,7 +3177,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by itstool $as_me 2.0.6, which was
+This file was extended by itstool $as_me 2.0.7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -3218,7 +3230,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-itstool config.status 2.0.6
+itstool config.status 2.0.7
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
index a46c4c9..9d04372 100644 (file)
@@ -1,4 +1,4 @@
-AC_INIT([itstool], [2.0.6], [])
+AC_INIT([itstool], [2.0.7], [])
 AM_INIT_AUTOMAKE([1.9 no-dist-gzip dist-bzip2])
 
 DATADIR=`(
index 0360b79..20d8b2e 100755 (executable)
@@ -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 @@ do
     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 @@ do
     fi
   fi
 
+  case $dstdir in
+    */) dstdirslash=$dstdir;;
+    *)  dstdirslash=$dstdir/;;
+  esac
+
   obsolete_mkdir_used=false
 
   if test $dstdir_status != 0; then
@@ -324,34 +332,43 @@ do
             # 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,14 +444,25 @@ do
   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
 
     # Copy the file name to the temp name.
-    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+    (umask $cp_umask &&
+     { test -z "$stripcmd" || {
+        # Create $dsttmp read-write so that cp doesn't create it read-only,
+        # which would cause strip to fail.
+        if test -z "$doit"; then
+          : >"$dsttmp" # No need to fork-exec 'touch'.
+        else
+          $doit touch "$dsttmp"
+        fi
+       }
+     } &&
+     $doit_exec $cpprog "$src" "$dsttmp") &&
 
     # and set any options; do chmod last to preserve setuid bits.
     #
@@ -493,7 +521,7 @@ do
 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"
index 04ab346..7ef7588 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -221,6 +221,7 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -252,8 +253,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
          *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)
@@ -292,7 +293,10 @@ ctags CTAGS:
 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 --git a/itstool b/itstool
index a1f0627..d213c7d 100644 (file)
--- a/itstool
+++ b/itstool
@@ -19,7 +19,7 @@
 from __future__ import print_function
 from __future__ import unicode_literals
 
-VERSION="2.0.6"
+VERSION="2.0.7"
 DATADIR="/usr/local/share"
 
 import gettext
@@ -554,6 +554,8 @@ class Document (object):
         self._itst_credits = None
         self._its_externals = {}
 
+        self._clear_cache()
+
     def __del__ (self):
         self._doc.freeDoc()
 
@@ -561,17 +563,27 @@ class Document (object):
         if self._xml_err:
             raise libxml2.parserError(self._xml_err)
 
-    def register_its_params(self, xpath, rules, params={}):
+    def _clear_cache(self):
+        self._its_translate_nodes_cache = {}
+        self._its_locale_filters_cache = {}
+        self._its_loc_notes_cache = {}
+
+    def get_its_params(self, rules):
+        params = {}
         for child in xml_child_iter(rules):
             if xml_is_ns_name(child, NS_ITS, 'param'):
-                name = child.nsProp('name', None)
-                if name in params:
-                    value = params[name]
-                else:
-                    value = child.getContent()
-                xpath.xpathRegisterVariable(name, None, value)
+                params[child.nsProp('name', None)] = child.getContent()
+        return params
+
+    def register_its_params(self, xpath, params, userparams={}):
+        for param in params:
+            if param in userparams:
+                xpath.xpathRegisterVariable(name, None, userparams[param])
+            else:
+                xpath.xpathRegisterVariable(name, None, params[param])
 
     def apply_its_rule(self, rule, xpath):
+        self._clear_cache()
         if rule.type != 'element':
             return
         if xml_is_ns_name(rule, NS_ITS, 'translateRule'):
@@ -733,7 +745,8 @@ class Document (object):
                         self._its_externals[node] = res[0].content
                     xpath.setContextNode(oldnode)
 
-    def apply_its_rules(self, builtins, params={}):
+    def apply_its_rules(self, builtins, userparams={}):
+        self._clear_cache()
         if builtins:
             dirs = []
             ddir = os.getenv('XDG_DATA_HOME', '')
@@ -754,11 +767,12 @@ class Document (object):
                 for dfile in os.listdir(itsdir):
                     if dfile.endswith('.its'):
                         if not ddone.get(dfile, False):
-                            self.apply_its_file(os.path.join(itsdir, dfile), params=params)
+                            self.apply_its_file(os.path.join(itsdir, dfile), userparams=userparams)
                             ddone[dfile] = True
-        self.apply_local_its_rules(params=params)
+        self.apply_local_its_rules(userparams=userparams)
 
-    def apply_its_file(self, filename, params={}):
+    def apply_its_file(self, filename, userparams={}):
+        self._clear_cache()
         doc = libxml2.parseFile(filename)
         root = doc.getRootElement()
         if not xml_is_ns_name(root, NS_ITS, 'rules'):
@@ -795,6 +809,7 @@ class Document (object):
                         break
         if matched == False:
             return
+        params = self.get_its_params(root)
         for rule in xml_child_iter(root):
             xpath = self._doc.xpathNewContext()
             par = match
@@ -808,10 +823,11 @@ class Document (object):
                             xpath.xpathRegisterNs(nsdef.name, nsdef.content)
                     nsdef = nsdef.next
                 par = par.parent
-            self.register_its_params(xpath, root, params=params)
+            self.register_its_params(xpath, params, userparams=userparams)
             self.apply_its_rule(rule, xpath)
 
-    def apply_local_its_rules(self, params={}):
+    def apply_local_its_rules(self, userparams={}):
+        self._clear_cache()
         for rules in self._localrules:
             def reg_ns(xpath, node):
                 if node.parent is not None:
@@ -823,14 +839,15 @@ class Document (object):
                     nsdef = nsdef.next
             xpath = self._doc.xpathNewContext()
             reg_ns(xpath, rules)
-            self.register_its_params(xpath, rules, params=params)
+            params = self.get_its_params(rules)
+            self.register_its_params(xpath, params, userparams=userparams)
             for rule in xml_child_iter(rules):
                 if rule.type != 'element':
                     continue
                 if rule.nsDefs() is not None:
                     rule_xpath = self._doc.xpathNewContext()
                     reg_ns(rule_xpath, rule)
-                    self.register_its_params(rule_xpath, rules, params=params)
+                    self.register_its_params(rule_xpath, params, userparams=userparams)
                 else:
                     rule_xpath = xpath
                 self.apply_its_rule(rule, rule_xpath)
@@ -1111,7 +1128,7 @@ class Document (object):
                 self.generate_message(child, None, comments=comments)
                 break
 
-    def generate_message (self, node, msg, comments=True, path=None):
+    def generate_message(self, node, msg, comments=True, path=None):
         if node.type in ('text', 'cdata') and msg is not None:
             msg.add_text(node.content)
             return
@@ -1261,6 +1278,8 @@ class Document (object):
         return False
 
     def get_its_translate(self, node):
+        if node in self._its_translate_nodes_cache:
+            return self._its_translate_nodes_cache[node]
         val = None
         if node.hasNsProp('translate', NS_ITS):
             val = node.nsProp('translate', NS_ITS)
@@ -1269,11 +1288,14 @@ class Document (object):
         elif node in self._its_translate_nodes:
             val = self._its_translate_nodes[node]
         if val is not None:
+            self._its_translate_nodes_cache[node] = val
             return val
         if node.type == 'attribute':
             return 'no'
         if node.parent.type == 'element':
-            return self.get_its_translate(node.parent)
+            parval = self.get_its_translate(node.parent)
+            self._its_translate_nodes_cache[node] = parval
+            return parval
         return 'yes'
 
     def get_its_within_text(self, node):
@@ -1288,6 +1310,8 @@ class Document (object):
         return 'no'
 
     def get_its_locale_filter(self, node):
+        if node in self._its_locale_filters_cache:
+            return self._its_locale_filters_cache[node]
         if node.hasNsProp('localeFilterList', NS_ITS) or node.hasNsProp('localeFilterType', NS_ITS):
             if node.hasNsProp('localeFilterList', NS_ITS):
                 lst = node.nsProp('localeFilterList', NS_ITS)
@@ -1312,7 +1336,9 @@ class Document (object):
         if node in self._its_locale_filters:
             return self._its_locale_filters[node]
         if node.parent.type == 'element':
-            return self.get_its_locale_filter(node.parent)
+            parval = self.get_its_locale_filter(node.parent)
+            self._its_locale_filters_cache[node] = parval
+            return parval
         return ('*', 'include')
 
     def get_itst_drop(self, node):
@@ -1328,15 +1354,21 @@ class Document (object):
         return self._its_id_values.get(node, None)
 
     def get_its_loc_notes(self, node, inherit=True):
+        if node in self._its_loc_notes_cache:
+            return self._its_loc_notes_cache[node]
         ret = []
-        if node.hasNsProp('locNote', NS_ITS) or node.hasNsProp('locNoteRef', NS_ITS) or node.hasNsProp('locNoteType', NS_ITS):
+        if ( node.hasNsProp('locNote', NS_ITS)     or
+             node.hasNsProp('locNoteRef', NS_ITS)  or
+             node.hasNsProp('locNoteType', NS_ITS) ):
             notetype = node.nsProp('locNoteType', NS_ITS)
             if node.hasNsProp('locNote', NS_ITS):
                 ret.append(LocNote(locnote=node.nsProp('locNote', NS_ITS), locnotetype=notetype))
             elif node.hasNsProp('locNoteRef', NS_ITS):
                 ret.append(LocNote(locnoteref=node.nsProp('locNoteRef', NS_ITS), locnotetype=notetype))
         elif  xml_is_ns_name(node, NS_ITS, 'span'):
-            if node.hasNsProp('locNote', None) or node.hasNsProp('locNoteRef', None) or node.hasNsProp('locNoteType', None):
+            if ( node.hasNsProp('locNote', None)     or
+                 node.hasNsProp('locNoteRef', None)  or
+                 node.hasNsProp('locNoteType', None) ):
                 notetype = node.nsProp('locNoteType', None)
                 if node.hasNsProp('locNote', None):
                     ret.append(LocNote(locnote=node.nsProp('locNote', None), locnotetype=notetype))
@@ -1346,7 +1378,10 @@ class Document (object):
             ret.append(locnote)
         if (len(ret) == 0 and inherit and
             node.type != 'attribute' and node.parent is not None and node.parent.type == 'element'):
-            return self.get_its_loc_notes(node.parent)
+            parval = self.get_its_loc_notes(node.parent)
+            self._its_loc_notes_cache[node] = parval
+            return parval
+        self._its_loc_notes_cache[node] = ret
         return ret
 
     def output_test_data(self, category, out, node=None):
@@ -1460,6 +1495,7 @@ def convert_locale (locale):
     return ret
 
 
+#def main():
 if __name__ == '__main__':
     options = optparse.OptionParser()
     options.set_usage('\n  itstool [OPTIONS] [XMLFILES]\n' +
@@ -1516,7 +1552,7 @@ if __name__ == '__main__':
                        help='Keep entity reference unexpanded')
     options.add_option('-p', '--param',
                        action='append',
-                       dest='params',
+                       dest='userparams',
                        default=[],
                        nargs=2,
                        metavar='NAME VALUE',
@@ -1537,18 +1573,18 @@ if __name__ == '__main__':
         print('itstool %s' % VERSION)
         sys.exit(0)
 
-    params = {}
-    for name, value in opts.params:
-        params[name] = value
+    userparams = {}
+    for name, value in opts.userparams:
+        userparams[name] = value
 
     if opts.merge is None and opts.join is None:
         messages = MessageList()
         for filename in args[1:]:
             doc = Document(filename, messages, load_dtd=opts.load_dtd, keep_entities=opts.keep_entities)
-            doc.apply_its_rules(not(opts.nobuiltins), params=params)
+            doc.apply_its_rules(not(opts.nobuiltins), userparams=userparams)
             if opts.itsfile is not None:
                 for itsfile in opts.itsfile:
-                    doc.apply_its_file(itsfile, params=params)
+                    doc.apply_its_file(itsfile, userparams=userparams)
             if opts.test is None:
                 doc.generate_messages()
         if opts.output is None or opts.output == '-':
@@ -1590,10 +1626,10 @@ if __name__ == '__main__':
         for filename in args[1:]:
             messages = MessageList()
             doc = Document(filename, messages, load_dtd=opts.load_dtd, keep_entities=opts.keep_entities)
-            doc.apply_its_rules(not(opts.nobuiltins), params=params)
+            doc.apply_its_rules(not(opts.nobuiltins), userparams=userparams)
             if opts.itsfile is not None:
                 for itsfile in opts.itsfile:
-                    doc.apply_its_file(itsfile, params=params)
+                    doc.apply_its_file(itsfile, userparams=userparams)
             try:
                 doc.merge_translations(translations, opts.lang, strict=opts.strict)
             except Exception as e:
@@ -1634,10 +1670,10 @@ if __name__ == '__main__':
             out = open(opts.output, 'wb')
         messages = MessageList()
         doc = Document(opts.join, messages)
-        doc.apply_its_rules(not(opts.nobuiltins), params=params)
+        doc.apply_its_rules(not(opts.nobuiltins), userparams=userparams)
         if opts.itsfile is not None:
             for itsfile in opts.itsfile:
-                doc.apply_its_file(itsfile, params=params)
+                doc.apply_its_file(itsfile, userparams=userparams)
         doc.join_translations(translations, strict=opts.strict)
         serialized = doc._doc.serialize('utf-8')
         if PY3:
@@ -1646,3 +1682,10 @@ if __name__ == '__main__':
             serialized = serialized.encode('utf-8')
         out.write(serialized)
         out.flush()
+
+#if __name__ == '__main__':
+#    if os.getenv('ITSTOOL_PROFILE') is not None:
+#        import cProfile
+#        cProfile.run('main()')
+#    else:
+#        main()
index 1ed1b93..5db613d 100644 (file)
--- a/itstool.1
+++ b/itstool.1
@@ -1,4 +1,4 @@
-.TH "ITSTOOL" "1" "December 2013" "itstool 2.0.6"
+.TH "ITSTOOL" "1" "December 2013" "itstool 2.0.7"
 
 .SH "NAME"
 itstool \- convert between XML and PO using ITS
index e64cd34..c21ad4b 100755 (executable)
@@ -554,6 +554,8 @@ class Document (object):
         self._itst_credits = None
         self._its_externals = {}
 
+        self._clear_cache()
+
     def __del__ (self):
         self._doc.freeDoc()
 
@@ -561,17 +563,27 @@ class Document (object):
         if self._xml_err:
             raise libxml2.parserError(self._xml_err)
 
-    def register_its_params(self, xpath, rules, params={}):
+    def _clear_cache(self):
+        self._its_translate_nodes_cache = {}
+        self._its_locale_filters_cache = {}
+        self._its_loc_notes_cache = {}
+
+    def get_its_params(self, rules):
+        params = {}
         for child in xml_child_iter(rules):
             if xml_is_ns_name(child, NS_ITS, 'param'):
-                name = child.nsProp('name', None)
-                if name in params:
-                    value = params[name]
-                else:
-                    value = child.getContent()
-                xpath.xpathRegisterVariable(name, None, value)
+                params[child.nsProp('name', None)] = child.getContent()
+        return params
+
+    def register_its_params(self, xpath, params, userparams={}):
+        for param in params:
+            if param in userparams:
+                xpath.xpathRegisterVariable(name, None, userparams[param])
+            else:
+                xpath.xpathRegisterVariable(name, None, params[param])
 
     def apply_its_rule(self, rule, xpath):
+        self._clear_cache()
         if rule.type != 'element':
             return
         if xml_is_ns_name(rule, NS_ITS, 'translateRule'):
@@ -733,7 +745,8 @@ class Document (object):
                         self._its_externals[node] = res[0].content
                     xpath.setContextNode(oldnode)
 
-    def apply_its_rules(self, builtins, params={}):
+    def apply_its_rules(self, builtins, userparams={}):
+        self._clear_cache()
         if builtins:
             dirs = []
             ddir = os.getenv('XDG_DATA_HOME', '')
@@ -754,11 +767,12 @@ class Document (object):
                 for dfile in os.listdir(itsdir):
                     if dfile.endswith('.its'):
                         if not ddone.get(dfile, False):
-                            self.apply_its_file(os.path.join(itsdir, dfile), params=params)
+                            self.apply_its_file(os.path.join(itsdir, dfile), userparams=userparams)
                             ddone[dfile] = True
-        self.apply_local_its_rules(params=params)
+        self.apply_local_its_rules(userparams=userparams)
 
-    def apply_its_file(self, filename, params={}):
+    def apply_its_file(self, filename, userparams={}):
+        self._clear_cache()
         doc = libxml2.parseFile(filename)
         root = doc.getRootElement()
         if not xml_is_ns_name(root, NS_ITS, 'rules'):
@@ -795,6 +809,7 @@ class Document (object):
                         break
         if matched == False:
             return
+        params = self.get_its_params(root)
         for rule in xml_child_iter(root):
             xpath = self._doc.xpathNewContext()
             par = match
@@ -808,10 +823,11 @@ class Document (object):
                             xpath.xpathRegisterNs(nsdef.name, nsdef.content)
                     nsdef = nsdef.next
                 par = par.parent
-            self.register_its_params(xpath, root, params=params)
+            self.register_its_params(xpath, params, userparams=userparams)
             self.apply_its_rule(rule, xpath)
 
-    def apply_local_its_rules(self, params={}):
+    def apply_local_its_rules(self, userparams={}):
+        self._clear_cache()
         for rules in self._localrules:
             def reg_ns(xpath, node):
                 if node.parent is not None:
@@ -823,14 +839,15 @@ class Document (object):
                     nsdef = nsdef.next
             xpath = self._doc.xpathNewContext()
             reg_ns(xpath, rules)
-            self.register_its_params(xpath, rules, params=params)
+            params = self.get_its_params(rules)
+            self.register_its_params(xpath, params, userparams=userparams)
             for rule in xml_child_iter(rules):
                 if rule.type != 'element':
                     continue
                 if rule.nsDefs() is not None:
                     rule_xpath = self._doc.xpathNewContext()
                     reg_ns(rule_xpath, rule)
-                    self.register_its_params(rule_xpath, rules, params=params)
+                    self.register_its_params(rule_xpath, params, userparams=userparams)
                 else:
                     rule_xpath = xpath
                 self.apply_its_rule(rule, rule_xpath)
@@ -1111,7 +1128,7 @@ class Document (object):
                 self.generate_message(child, None, comments=comments)
                 break
 
-    def generate_message (self, node, msg, comments=True, path=None):
+    def generate_message(self, node, msg, comments=True, path=None):
         if node.type in ('text', 'cdata') and msg is not None:
             msg.add_text(node.content)
             return
@@ -1261,6 +1278,8 @@ class Document (object):
         return False
 
     def get_its_translate(self, node):
+        if node in self._its_translate_nodes_cache:
+            return self._its_translate_nodes_cache[node]
         val = None
         if node.hasNsProp('translate', NS_ITS):
             val = node.nsProp('translate', NS_ITS)
@@ -1269,11 +1288,14 @@ class Document (object):
         elif node in self._its_translate_nodes:
             val = self._its_translate_nodes[node]
         if val is not None:
+            self._its_translate_nodes_cache[node] = val
             return val
         if node.type == 'attribute':
             return 'no'
         if node.parent.type == 'element':
-            return self.get_its_translate(node.parent)
+            parval = self.get_its_translate(node.parent)
+            self._its_translate_nodes_cache[node] = parval
+            return parval
         return 'yes'
 
     def get_its_within_text(self, node):
@@ -1288,6 +1310,8 @@ class Document (object):
         return 'no'
 
     def get_its_locale_filter(self, node):
+        if node in self._its_locale_filters_cache:
+            return self._its_locale_filters_cache[node]
         if node.hasNsProp('localeFilterList', NS_ITS) or node.hasNsProp('localeFilterType', NS_ITS):
             if node.hasNsProp('localeFilterList', NS_ITS):
                 lst = node.nsProp('localeFilterList', NS_ITS)
@@ -1312,7 +1336,9 @@ class Document (object):
         if node in self._its_locale_filters:
             return self._its_locale_filters[node]
         if node.parent.type == 'element':
-            return self.get_its_locale_filter(node.parent)
+            parval = self.get_its_locale_filter(node.parent)
+            self._its_locale_filters_cache[node] = parval
+            return parval
         return ('*', 'include')
 
     def get_itst_drop(self, node):
@@ -1328,15 +1354,21 @@ class Document (object):
         return self._its_id_values.get(node, None)
 
     def get_its_loc_notes(self, node, inherit=True):
+        if node in self._its_loc_notes_cache:
+            return self._its_loc_notes_cache[node]
         ret = []
-        if node.hasNsProp('locNote', NS_ITS) or node.hasNsProp('locNoteRef', NS_ITS) or node.hasNsProp('locNoteType', NS_ITS):
+        if ( node.hasNsProp('locNote', NS_ITS)     or
+             node.hasNsProp('locNoteRef', NS_ITS)  or
+             node.hasNsProp('locNoteType', NS_ITS) ):
             notetype = node.nsProp('locNoteType', NS_ITS)
             if node.hasNsProp('locNote', NS_ITS):
                 ret.append(LocNote(locnote=node.nsProp('locNote', NS_ITS), locnotetype=notetype))
             elif node.hasNsProp('locNoteRef', NS_ITS):
                 ret.append(LocNote(locnoteref=node.nsProp('locNoteRef', NS_ITS), locnotetype=notetype))
         elif  xml_is_ns_name(node, NS_ITS, 'span'):
-            if node.hasNsProp('locNote', None) or node.hasNsProp('locNoteRef', None) or node.hasNsProp('locNoteType', None):
+            if ( node.hasNsProp('locNote', None)     or
+                 node.hasNsProp('locNoteRef', None)  or
+                 node.hasNsProp('locNoteType', None) ):
                 notetype = node.nsProp('locNoteType', None)
                 if node.hasNsProp('locNote', None):
                     ret.append(LocNote(locnote=node.nsProp('locNote', None), locnotetype=notetype))
@@ -1346,7 +1378,10 @@ class Document (object):
             ret.append(locnote)
         if (len(ret) == 0 and inherit and
             node.type != 'attribute' and node.parent is not None and node.parent.type == 'element'):
-            return self.get_its_loc_notes(node.parent)
+            parval = self.get_its_loc_notes(node.parent)
+            self._its_loc_notes_cache[node] = parval
+            return parval
+        self._its_loc_notes_cache[node] = ret
         return ret
 
     def output_test_data(self, category, out, node=None):
@@ -1460,6 +1495,7 @@ def convert_locale (locale):
     return ret
 
 
+#def main():
 if __name__ == '__main__':
     options = optparse.OptionParser()
     options.set_usage('\n  itstool [OPTIONS] [XMLFILES]\n' +
@@ -1516,7 +1552,7 @@ if __name__ == '__main__':
                        help='Keep entity reference unexpanded')
     options.add_option('-p', '--param',
                        action='append',
-                       dest='params',
+                       dest='userparams',
                        default=[],
                        nargs=2,
                        metavar='NAME VALUE',
@@ -1537,18 +1573,18 @@ if __name__ == '__main__':
         print('itstool %s' % VERSION)
         sys.exit(0)
 
-    params = {}
-    for name, value in opts.params:
-        params[name] = value
+    userparams = {}
+    for name, value in opts.userparams:
+        userparams[name] = value
 
     if opts.merge is None and opts.join is None:
         messages = MessageList()
         for filename in args[1:]:
             doc = Document(filename, messages, load_dtd=opts.load_dtd, keep_entities=opts.keep_entities)
-            doc.apply_its_rules(not(opts.nobuiltins), params=params)
+            doc.apply_its_rules(not(opts.nobuiltins), userparams=userparams)
             if opts.itsfile is not None:
                 for itsfile in opts.itsfile:
-                    doc.apply_its_file(itsfile, params=params)
+                    doc.apply_its_file(itsfile, userparams=userparams)
             if opts.test is None:
                 doc.generate_messages()
         if opts.output is None or opts.output == '-':
@@ -1590,10 +1626,10 @@ if __name__ == '__main__':
         for filename in args[1:]:
             messages = MessageList()
             doc = Document(filename, messages, load_dtd=opts.load_dtd, keep_entities=opts.keep_entities)
-            doc.apply_its_rules(not(opts.nobuiltins), params=params)
+            doc.apply_its_rules(not(opts.nobuiltins), userparams=userparams)
             if opts.itsfile is not None:
                 for itsfile in opts.itsfile:
-                    doc.apply_its_file(itsfile, params=params)
+                    doc.apply_its_file(itsfile, userparams=userparams)
             try:
                 doc.merge_translations(translations, opts.lang, strict=opts.strict)
             except Exception as e:
@@ -1634,10 +1670,10 @@ if __name__ == '__main__':
             out = open(opts.output, 'wb')
         messages = MessageList()
         doc = Document(opts.join, messages)
-        doc.apply_its_rules(not(opts.nobuiltins), params=params)
+        doc.apply_its_rules(not(opts.nobuiltins), userparams=userparams)
         if opts.itsfile is not None:
             for itsfile in opts.itsfile:
-                doc.apply_its_file(itsfile, params=params)
+                doc.apply_its_file(itsfile, userparams=userparams)
         doc.join_translations(translations, strict=opts.strict)
         serialized = doc._doc.serialize('utf-8')
         if PY3:
@@ -1646,3 +1682,10 @@ if __name__ == '__main__':
             serialized = serialized.encode('utf-8')
         out.write(serialized)
         out.flush()
+
+#if __name__ == '__main__':
+#    if os.getenv('ITSTOOL_PROFILE') is not None:
+#        import cProfile
+#        cProfile.run('main()')
+#    else:
+#        main()
diff --git a/missing b/missing
index b7e571e..8d0eaad 100755 (executable)
--- a/missing
+++ b/missing
@@ -1,9 +1,9 @@
-#!/bin/sh
+#! /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-2020 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@ scriptversion=2016-01-11.22; # UTC
 # 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 <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # 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 @@ else
   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 @@ give_advice "$1" | sed -e '1s/^/WARNING: /' \
 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"
index d5aab09..cf4236e 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -8,7 +8,7 @@
 from distutils.core import setup
 
 setup(name='itstool',
-      version='2.0.6',
+      version='2.0.7',
       description='XML to PO and back again using W3C ITS rules',
       author='Shaun McCance',
       author_email='shaunm@gnome.org',