From: Bruno Haible Date: Tue, 15 Oct 2024 00:37:28 +0000 (+0200) Subject: its: Add ability to check *.its and *.loc files with XML Schema 1.1. X-Git-Tag: v0.23~51 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b286a63d8bc034c92fcc994710aa30ff01f03a2a;p=thirdparty%2Fgettext.git its: Add ability to check *.its and *.loc files with XML Schema 1.1. * gettext-tools/src/its.xsd10: Renamed from gettext-tools/src/its.xsd. (RulesType): Enumerate all possible rules in the ITS namespace, instead of using a wildcard. (OtherRuleType): New element. * gettext-tools/src/its.xsd11: Copied from gettext-tools/src/its.xsd. (LocNoteRuleType): Enable assertion. * gettext-tools/src/locating-rules.xsd10: Renamed from gettext-tools/src/locating-rules.xsd. * gettext-tools/src/locating-rules.xsd11: Copied from gettext-tools/src/locating-rules.xsd. (LocatingRuleType): Enable assertion. * gettext-tools/src/Makefile.am (schema_DATA): Add its.xsd10, its.xsd11, locating-rules.xsd10, locating-rules.xsd11. Remove its.xsd, locating-rules.xsd. * gettext-tools/build-aux/xml-validate-10.in: New file. * gettext-tools/build-aux/xml-validate-11.in: New file. * gettext-tools/configure.ac: Substitute HAVE_JAVAEXEC. (AC_CONFIG_FILES): Create build-aux/xml-validate-10, build-aux/xml-validate-11. * gettext-tools/Makefile.am (DISTCLEANFILES): Add build-aux/xml-validate-10, build-aux/xml-validate-11. * gettext-tools/its/Makefile.am: Revert last commit. (check-local): Check each file both using the XML Schema 1.0 and the XML Schema 1.1. * gettext-tools/doc/gettext.texi (ITS Rules): Mention the two versions of its.xsd. (Location Rules): Mention the two versions of locating-rules.xsd. * HACKING: Mention Xerces2-J. --- diff --git a/.gitignore b/.gitignore index dd22d459a..c0645b229 100644 --- a/.gitignore +++ b/.gitignore @@ -642,6 +642,8 @@ autom4te.cache/ /gettext-tools/javaexec.sh /gettext-tools/libtool /gettext-tools/stamp-h1 +/gettext-tools/build-aux/xml-validate-10 +/gettext-tools/build-aux/xml-validate-11 /gettext-tools/doc/Makefile /gettext-tools/emacs/Makefile /gettext-tools/examples/Makefile diff --git a/HACKING b/HACKING index b29b4ab88..60225417c 100644 --- a/HACKING +++ b/HACKING @@ -147,6 +147,10 @@ are skipped. To this effect, you need to install also: - On Debian and Debian-based systems: libxml2-utils, - On Red Hat distributions: libxml2. - Other: https://repology.org/project/libxml2/versions + * The Xerces2 Java XML parser (binary distribution named 'xml-schema-1.1') + + Homepage: https://xerces.apache.org/xerces2-j/ + + Pre-built package name: -- + + See gettext-tools/build-aux/xml-validate-11.in for more details. * A C++ compiler + Homepage: https://gcc.gnu.org/ diff --git a/gettext-tools/Makefile.am b/gettext-tools/Makefile.am index 1d6c665a7..274b9d41a 100644 --- a/gettext-tools/Makefile.am +++ b/gettext-tools/Makefile.am @@ -23,6 +23,7 @@ SUBDIRS = gnulib-lib libgrep src libgettextpo po its projects styles emacs misc EXTRA_DIST = misc/DISCLAIM MOSTLYCLEANFILES = core *.stackdump +DISTCLEANFILES = build-aux/xml-validate-10 build-aux/xml-validate-11 # Files installed for use by gettextize. diff --git a/gettext-tools/build-aux/xml-validate-10.in b/gettext-tools/build-aux/xml-validate-10.in new file mode 100644 index 000000000..609279ffb --- /dev/null +++ b/gettext-tools/build-aux/xml-validate-10.in @@ -0,0 +1,104 @@ +#!/bin/sh +# Validating an XML document against an XML Schema 1.0. + +# Copyright (C) 2024 Free Software Foundation, Inc. +# +# This file is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# This file 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 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 . + +# Written by Bruno Haible , 2024. + +# func_usage +# outputs to stdout the --help usage message. +func_usage () +{ + echo "\ +Usage: xml-validate-10 [OPTION]... SCHEMA DOCUMENT + +Invokes an XML Schema 1.0 validator, validating the given XML document +against the given XML schema. + +The exit code is 0 for valid, 1 for invalid. + +Options: + --help print this help and exit + --version print version information and exit + +Send patches and bug reports to ." +} + +# func_version +# outputs to stdout the --version message. +func_version () +{ + echo "xml-validate-10 (GNU gettext)" + echo "Copyright (C) 2024 Free Software Foundation, Inc. +License GPLv3+: GNU GPL version 3 or later +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law." + echo + printf 'Written by %s.\n' "Bruno Haible" +} + +# func_fatal_error message +# outputs to stderr a fatal error message, and terminates the program. +func_fatal_error () +{ + echo "xml-validate-10: *** $1" 1>&2 + echo "xml-validate-10: *** Stop." 1>&2 + exit 1 +} + +# Outputs a command and runs it. +func_verbose () +{ + # Make it easy to copy&paste the printed command into a shell in most cases, + # by escaping '\\', '"', and '$'. This is not perfect, just good enough. + echo "$@" | sed -e 's/\([\\"$]\)/\\\1/g' + "$@" +} + +# Command-line option processing. +while test $# -gt 0; do + case "$1" in + --help | --hel | --he | --h ) + func_usage + exit 0 ;; + --version | --versio | --versi | --vers | --ver | --ve | --v ) + func_version + exit 0 ;; + -- ) # Stop option processing + shift; break ;; + -* ) + func_fatal_error "unrecognized option: $1" + ;; + * ) + break ;; + esac +done + +if test $# -lt 2; then + func_fatal_error "too few arguments" +fi +if test $# -gt 2; then + func_fatal_error "too many arguments" +fi + +schema="$1" +document="$2" +shift +shift + +if test '@XMLLINT@' != ':'; then + func_verbose @XMLLINT@ --noout --schema "$schema" "$document" || exit 1 +fi diff --git a/gettext-tools/build-aux/xml-validate-11.in b/gettext-tools/build-aux/xml-validate-11.in new file mode 100644 index 000000000..c7d08e623 --- /dev/null +++ b/gettext-tools/build-aux/xml-validate-11.in @@ -0,0 +1,189 @@ +#!/bin/sh +# Validating an XML document against an XML Schema 1.1. + +# Copyright (C) 2024 Free Software Foundation, Inc. +# +# This file is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# This file 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 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 . + +# Written by Bruno Haible , 2024. + +# The major advantages of XML Schema 1.1, compared to XML Schema 1.0, are: +# * It fixes an ill-designed "Unique Particle Attribution" rule +# +# +# that makes +# +# elements practically useless. See +# +# . +# * It allows to check that, for example, a specific child element and a +# specific attribute are not used together in the same XML element. +# This is a special case of . +# +# The major drawback of XML Schema 1.1, compared to XML Schema 1.0, are: +# * (As of 2024) There is only one Free Software implementation of it: +# Apache Xerces in version 2.12 or newer, in the "xml-schema-1.1" variant. +# * The error messages emitted by Apache Xerces are regularly mysterious / +# unintelligible. + +# func_usage +# outputs to stdout the --help usage message. +func_usage () +{ + echo "\ +Usage: xml-validate-11 [OPTION]... SCHEMA DOCUMENT + +Invokes an XML Schema 1.1 validator, validating the given XML document +against the given XML schema. + +The exit code is 0 for valid, 1 for invalid. + +Options: + --help print this help and exit + --version print version information and exit + +The environment variable XERCES_J_DIR should point to a directory that +contains a binary distribution of Xerces-J version 2.12 (or newer), +in xml-schema-1.1 variant. Download location: +https://dlcdn.apache.org//xerces/j/binaries/Xerces-J-bin.2.12.2-xml-schema-1.1.tar.gz + +Send patches and bug reports to ." +} + +# func_version +# outputs to stdout the --version message. +func_version () +{ + echo "xml-validate-11 (GNU gettext)" + echo "Copyright (C) 2024 Free Software Foundation, Inc. +License GPLv3+: GNU GPL version 3 or later +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law." + echo + printf 'Written by %s.\n' "Bruno Haible" +} + +# func_fatal_error message +# outputs to stderr a fatal error message, and terminates the program. +func_fatal_error () +{ + echo "xml-validate-11: *** $1" 1>&2 + echo "xml-validate-11: *** Stop." 1>&2 + exit 1 +} + +# Outputs a command and runs it. +func_verbose () +{ + # Make it easy to copy&paste the printed command into a shell in most cases, + # by escaping '\\', '"', and '$'. This is not perfect, just good enough. + echo "$@" | sed -e 's/\([\\"$]\)/\\\1/g' + "$@" +} + +# func_tmpdir +# creates a temporary directory. +# Sets variable +# - tmp pathname of freshly created temporary directory +func_tmpdir () +{ + # Use the environment variable TMPDIR, falling back to /tmp. This allows + # users to specify a different temporary directory, for example, if their + # /tmp is filled up or too small. + : "${TMPDIR=/tmp}" + { + # Use the mktemp program if available. If not available, hide the error + # message. + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/gtXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" + } || + { + # Use a simple mkdir command. It is guaranteed to fail if the directory + # already exists. $RANDOM is bash specific and expands to empty in shells + # other than bash, ksh and zsh. Its use does not increase security; + # rather, it minimizes the probability of failure in a very cluttered /tmp + # directory. + tmp=$TMPDIR/gt$$-$RANDOM + (umask 077 && mkdir "$tmp") + } || + { + echo "$0: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } + } +} + +# Command-line option processing. +while test $# -gt 0; do + case "$1" in + --help | --hel | --he | --h ) + func_usage + exit 0 ;; + --version | --versio | --versi | --vers | --ver | --ve | --v ) + func_version + exit 0 ;; + -- ) # Stop option processing + shift; break ;; + -* ) + func_fatal_error "unrecognized option: $1" + ;; + * ) + break ;; + esac +done + +if test $# -lt 2; then + func_fatal_error "too few arguments" +fi +if test $# -gt 2; then + func_fatal_error "too many arguments" +fi + +schema="$1" +document="$2" +shift +shift + +if test -n '@HAVE_JAVAEXEC@' \ + && test -n "$XERCES_J_DIR" \ + && test -d "$XERCES_J_DIR" \ + && test -f "$XERCES_J_DIR/xercesSamples.jar" \ + && test -f "$XERCES_J_DIR/xercesImpl.jar" \ + && test -f "$XERCES_J_DIR/org.eclipse.wst.xml.xpath2.processor_1.2.1.jar" \ + && test -f "$XERCES_J_DIR/cupv10k-runtime.jar"; then + # We don't need to write our own Java program that invokes the validator, + # like + # or , + # because the Xerces-J FAQ + # says: + # "You can also refer to the JAXP sample, SourceValidator, where you can + # validate XML documents against 1.1 schemas by specifying an option + # "-xsd11" when running the sample." + # Documentation of this sample: + # + func_tmpdir + echo "sh ../javaexec.sh jaxp.SourceValidator -xsd11 -f -a $schema -i $document" + CLASSPATH="$XERCES_J_DIR/xercesSamples.jar:$XERCES_J_DIR/xercesImpl.jar:$XERCES_J_DIR/org.eclipse.wst.xml.xpath2.processor_1.2.1.jar:$XERCES_J_DIR/cupv10k-runtime.jar" \ + sh ../javaexec.sh jaxp.SourceValidator -xsd11 -f -a "$schema" -i "$document" \ + > "$tmp"/out 2> "$tmp"/err + # The exit code is usually 0, even if there were errors. + if test $? != 0 || grep '\[Error\]' "$tmp"/err >/dev/null; then + exitcode=1 + else + exitcode=0 + fi + cat "$tmp"/err 1>&2 + cat "$tmp"/out + rm -f "$tmp"/out "$tmp"/err + exit $exitcode +fi diff --git a/gettext-tools/configure.ac b/gettext-tools/configure.ac index b9c131170..86e4f1725 100644 --- a/gettext-tools/configure.ac +++ b/gettext-tools/configure.ac @@ -618,6 +618,7 @@ AM_CONDITIONAL([TEST_SYSTEM_LIBINTL], [test $USE_INCLUDED_LIBINTL = no]) dnl Checks for optional programs for the its/* tests. AC_PATH_PROGS([XMLLINT], [xmllint], [:]) +AC_SUBST([HAVE_JAVAEXEC]) AC_CONFIG_SUBDIRS([examples]) @@ -664,4 +665,9 @@ AC_CONFIG_FILES([system-tests/Makefile]) AC_CONFIG_FILES([gnulib-tests/Makefile]) +AC_CONFIG_FILES([build-aux/xml-validate-10], + [chmod a+x build-aux/xml-validate-10]) +AC_CONFIG_FILES([build-aux/xml-validate-11], + [chmod a+x build-aux/xml-validate-11]) + AC_OUTPUT diff --git a/gettext-tools/doc/gettext.texi b/gettext-tools/doc/gettext.texi index a2cbb3c11..6a644b127 100644 --- a/gettext-tools/doc/gettext.texi +++ b/gettext-tools/doc/gettext.texi @@ -10879,8 +10879,9 @@ second ("A non-translatable string"), the following ITS rules can be used: @end example ITS rules files must have the @file{.its} file extension and obey -the XML schema encoded by -@code{its.xsd} and its auxiliary schema @code{its-extensions.xsd}. +the XML schema version 1.0 encoded by @code{its.xsd10} or +the XML schema version 1.1 encoded by @code{its.xsd11} +and its auxiliary schema @code{its-extensions.xsd}. @node Locating Rules @subsubsection Specifying where to find the ITS Rules @@ -10924,7 +10925,8 @@ of @code{locatingRule} or @code{documentRule}. If it is specified in a have the @code{target} attribute. Locating rules files must have the @file{.loc} file extension and obey -the XML schema encoded by @code{locating-rules.xsd}. +the XML schema version 1.0 encoded by @code{locating-rules.xsd10} or +the XML schema version 1.1 encoded by @code{locating-rules.xsd11}. Both ITS rules files and locating rules files must be installed in the @file{$prefix/share/gettext/its} directory. Once those files are properly installed, @code{xgettext} can extract translatable strings diff --git a/gettext-tools/its/Makefile.am b/gettext-tools/its/Makefile.am index e372a4311..9066e7bfd 100644 --- a/gettext-tools/its/Makefile.am +++ b/gettext-tools/its/Makefile.am @@ -38,15 +38,17 @@ dist_its_DATA = $(ITS_FILES) $(LOC_FILES) # Checks the XML files against their schemas. # Work around . check-local: - @if echo '' | $(XMLLINT) --noout --schema $(top_srcdir)/src/its.xsd - >/dev/null 2>&1; then \ - for file in $(ITS_FILES); do \ - echo "Checking $$file..."; \ - echo "$(XMLLINT) --noout --schema $(top_srcdir)/src/its.xsd $(srcdir)/$$file"; \ - $(XMLLINT) --noout --schema $(top_srcdir)/src/its.xsd $(srcdir)/$$file || exit 1; \ - done; \ - fi + @for file in $(ITS_FILES); do \ + echo "Checking $$file..."; \ + echo "$(top_builddir)/build-aux/xml-validate-10 $(top_srcdir)/src/its.xsd10 $(srcdir)/$$file"; \ + $(top_builddir)/build-aux/xml-validate-10 $(top_srcdir)/src/its.xsd10 $(srcdir)/$$file || exit 1; \ + echo "$(top_builddir)/build-aux/xml-validate-11 $(top_srcdir)/src/its.xsd11 $(srcdir)/$$file"; \ + $(top_builddir)/build-aux/xml-validate-11 $(top_srcdir)/src/its.xsd11 $(srcdir)/$$file || exit 1; \ + done @for file in $(LOC_FILES); do \ echo "Checking $$file..."; \ - echo "$(XMLLINT) --noout --schema $(top_srcdir)/src/locating-rules.xsd $(srcdir)/$$file"; \ - $(XMLLINT) --noout --schema $(top_srcdir)/src/locating-rules.xsd $(srcdir)/$$file || exit 1; \ + echo "$(top_builddir)/build-aux/xml-validate-10 $(top_srcdir)/src/locating-rules.xsd10 $(srcdir)/$$file"; \ + $(top_builddir)/build-aux/xml-validate-10 $(top_srcdir)/src/locating-rules.xsd10 $(srcdir)/$$file || exit 1; \ + echo "$(top_builddir)/build-aux/xml-validate-11 $(top_srcdir)/src/locating-rules.xsd11 $(srcdir)/$$file"; \ + $(top_builddir)/build-aux/xml-validate-11 $(top_srcdir)/src/locating-rules.xsd11 $(srcdir)/$$file || exit 1; \ done diff --git a/gettext-tools/src/Makefile.am b/gettext-tools/src/Makefile.am index cd94c3895..9dd79b266 100644 --- a/gettext-tools/src/Makefile.am +++ b/gettext-tools/src/Makefile.am @@ -796,8 +796,8 @@ uninstall-tcl: # Special rules for XML schemas. schema_DATA = \ - its.xsd its-extensions.xsd \ - locating-rules.xsd + its.xsd10 its.xsd11 its-extensions.xsd \ + locating-rules.xsd10 locating-rules.xsd11 EXTRA_DIST += $(schema_DATA) diff --git a/gettext-tools/src/its.xsd10 b/gettext-tools/src/its.xsd10 new file mode 100644 index 000000000..326edfbe1 --- /dev/null +++ b/gettext-tools/src/its.xsd10 @@ -0,0 +1,139 @@ + + + + + XML schema 1.0 of *.its files, as understood by GNU gettext. + +Copyright (C) 2015-2024 Free Software Foundation, Inc. + +This file is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published +by the Free Software Foundation, either version 3 of the License, +or (at your option) any later version. + +This file 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 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 <https://www.gnu.org/licenses/>. + +Written by Bruno Haible <bruno@clisp.org>, 2024. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Note: An instance should not have both the 'locNotePointer' attribute and a 'locNote' child at the same time. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gettext-tools/src/its.xsd b/gettext-tools/src/its.xsd11 similarity index 96% rename from gettext-tools/src/its.xsd rename to gettext-tools/src/its.xsd11 index 21cd7f454..5280bbaf3 100644 --- a/gettext-tools/src/its.xsd +++ b/gettext-tools/src/its.xsd11 @@ -2,7 +2,7 @@ - XML schema of *.its files, as understood by GNU gettext. + XML schema 1.1 of *.its files, as understood by GNU gettext. Copyright (C) 2015-2024 Free Software Foundation, Inc. @@ -82,9 +82,8 @@ Written by Bruno Haible <bruno@clisp.org>, 2024. - + + diff --git a/gettext-tools/src/locating-rules.xsd b/gettext-tools/src/locating-rules.xsd10 similarity index 97% rename from gettext-tools/src/locating-rules.xsd rename to gettext-tools/src/locating-rules.xsd10 index 3bb86fd13..1795e6ea4 100644 --- a/gettext-tools/src/locating-rules.xsd +++ b/gettext-tools/src/locating-rules.xsd10 @@ -2,7 +2,7 @@ - XML schema of *.loc files, as understood by GNU gettext. + XML schema 1.0 of *.loc files, as understood by GNU gettext. Copyright (C) 2015-2024 Free Software Foundation, Inc. diff --git a/gettext-tools/src/locating-rules.xsd11 b/gettext-tools/src/locating-rules.xsd11 new file mode 100644 index 000000000..d4bac98bb --- /dev/null +++ b/gettext-tools/src/locating-rules.xsd11 @@ -0,0 +1,87 @@ + + + + + XML schema 1.1 of *.loc files, as understood by GNU gettext. + +Copyright (C) 2015-2024 Free Software Foundation, Inc. + +This file is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published +by the Free Software Foundation, either version 3 of the License, +or (at your option) any later version. + +This file 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 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 <https://www.gnu.org/licenses/>. + +Written by Bruno Haible <bruno@clisp.org>, 2024. + + + + + + + + + + + Example: +<locatingRules> + <locatingRule name="Glade" pattern="*.glade"> + <documentRule localName="GTK-Interface" target="glade1.its"/> + <documentRule localName="glade-interface" target="glade2.its"/> + <documentRule localName="interface" target="gtkbuilder.its"/> + </locatingRule> + <locatingRule name="Glade" pattern="*.glade2"> + <documentRule localName="glade-interface" target="glade2.its"/> + </locatingRule> + <locatingRule name="Glade" pattern="*.ui"> + <documentRule localName="interface" target="gtkbuilder.its"/> + </locatingRule> +</locatingRules> + + + + + + + + + + + + Example: +&lt;locatingRule name=&quot;Glade&quot; pattern=&quot;*.glade&quot;&gt; + &lt;documentRule localName=&quot;GTK-Interface&quot; target=&quot;glade1.its&quot;/&gt; + &lt;documentRule localName=&quot;glade-interface&quot; target=&quot;glade2.its&quot;/&gt; + &lt;documentRule localName=&quot;interface&quot; target=&quot;gtkbuilder.its&quot;/&gt; +&lt;/locatingRule&gt; + +Note: An instance should not have both the 'target' attribute and a 'documentRule' child at the same time. + + + + + + + + + + + + + + Example: +<documentRule localName="GTK-Interface" target="glade1.its"/> + + + + + + +