From 4e4b995657d03984bac9ab96873b9d4070664a5a Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 28 Jul 2025 10:22:43 +0200 Subject: [PATCH] examples: Add hello-ocaml example. * gettext-tools/examples/hello-ocaml/INSTALL: New file. * gettext-tools/examples/hello-ocaml/autogen.sh: New file. * gettext-tools/examples/hello-ocaml/autoclean.sh: New file. * gettext-tools/examples/hello-ocaml/dune.in: New file. * gettext-tools/examples/hello-ocaml/dune-project.in: New file. * gettext-tools/examples/hello-ocaml/hello.ml.in: New file. * gettext-tools/examples/hello-ocaml/Makefile.am: New file. * gettext-tools/examples/hello-ocaml/configure.ac: New file. * gettext-tools/examples/hello-ocaml/m4/Makefile.am: New file. * gettext-tools/examples/hello-ocaml/po/LINGUAS: New file. * gettext-tools/examples/hello-ocaml/po/Makefile.am: New file. * gettext-tools/examples/Makefile.am (EXAMPLESFILES, EXAMPLESDIRS): Add hello-ocaml. * gettext-tools/examples/po/Makefile.am (POTFILES, SMALLPOTS): Update for hello-ocaml. (hello-ocaml.pot): New target. (SMALLPOFILES_FOR_lang): Update for hello-ocaml. ($(srcdir)/../hello-ocaml/po/$(LL).po): New rule. * gettext-tools/examples/check-examples (func_check__hello_ocaml): New function. * gettext-tools/examples/README: Mention hello-ocaml. * gettext-tools/doc/lang-ocaml.texi: Likewise. * NEWS: Likewise. --- NEWS | 1 + gettext-tools/doc/lang-ocaml.texi | 2 +- gettext-tools/examples/Makefile.am | 12 + gettext-tools/examples/README | 2 + gettext-tools/examples/check-examples | 6 + gettext-tools/examples/hello-ocaml/INSTALL | 23 + .../examples/hello-ocaml/Makefile.am | 51 ++ .../examples/hello-ocaml/autoclean.sh | 32 ++ gettext-tools/examples/hello-ocaml/autogen.sh | 44 ++ .../examples/hello-ocaml/configure.ac | 41 ++ .../examples/hello-ocaml/dune-project.in | 2 + gettext-tools/examples/hello-ocaml/dune.in | 3 + .../examples/hello-ocaml/hello.ml.in | 27 ++ .../examples/hello-ocaml/m4/Makefile.am | 2 + gettext-tools/examples/hello-ocaml/po/LINGUAS | 5 + .../examples/hello-ocaml/po/Makefile.am | 434 ++++++++++++++++++ gettext-tools/examples/po/Makefile.am | 9 + 17 files changed, 695 insertions(+), 1 deletion(-) create mode 100644 gettext-tools/examples/hello-ocaml/INSTALL create mode 100644 gettext-tools/examples/hello-ocaml/Makefile.am create mode 100755 gettext-tools/examples/hello-ocaml/autoclean.sh create mode 100755 gettext-tools/examples/hello-ocaml/autogen.sh create mode 100644 gettext-tools/examples/hello-ocaml/configure.ac create mode 100644 gettext-tools/examples/hello-ocaml/dune-project.in create mode 100644 gettext-tools/examples/hello-ocaml/dune.in create mode 100644 gettext-tools/examples/hello-ocaml/hello.ml.in create mode 100644 gettext-tools/examples/hello-ocaml/m4/Makefile.am create mode 100644 gettext-tools/examples/hello-ocaml/po/LINGUAS create mode 100644 gettext-tools/examples/hello-ocaml/po/Makefile.am diff --git a/NEWS b/NEWS index 2fa1524e6..2fb058f0a 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ Version 0.27 - September 2025 - xgettext now supports OCaml. - 'msgfmt -c' now verifies the syntax of translations of OCaml format strings. + - A new example 'hello-ocaml' has been added. Version 0.26 - July 2025 diff --git a/gettext-tools/doc/lang-ocaml.texi b/gettext-tools/doc/lang-ocaml.texi index 9e900bdfd..905f8ff0e 100644 --- a/gettext-tools/doc/lang-ocaml.texi +++ b/gettext-tools/doc/lang-ocaml.texi @@ -62,4 +62,4 @@ fully portable --- @end table -@c An example is available in the @file{examples} directory: @code{hello-ocaml}. +An example is available in the @file{examples} directory: @code{hello-ocaml}. diff --git a/gettext-tools/examples/Makefile.am b/gettext-tools/examples/Makefile.am index 41e0c2108..96c86fb99 100644 --- a/gettext-tools/examples/Makefile.am +++ b/gettext-tools/examples/Makefile.am @@ -420,6 +420,17 @@ EXAMPLESFILES = \ hello-d/m4/Makefile.am \ hello-d/po/Makefile.am \ \ + hello-ocaml/INSTALL \ + hello-ocaml/autogen.sh \ + hello-ocaml/autoclean.sh \ + hello-ocaml/dune.in \ + hello-ocaml/dune-project.in \ + hello-ocaml/hello.ml.in \ + hello-ocaml/Makefile.am \ + hello-ocaml/configure.ac \ + hello-ocaml/m4/Makefile.am \ + hello-ocaml/po/Makefile.am \ + \ hello-smalltalk/INSTALL \ hello-smalltalk/autogen.sh \ hello-smalltalk/autoclean.sh \ @@ -513,6 +524,7 @@ EXAMPLESDIRS = \ hello-pascal \ hello-modula2 \ hello-d \ + hello-ocaml \ hello-smalltalk \ hello-tcl \ hello-tcl-tk \ diff --git a/gettext-tools/examples/README b/gettext-tools/examples/README index 16bbfb395..46d3f87a1 100644 --- a/gettext-tools/examples/README +++ b/gettext-tools/examples/README @@ -38,6 +38,7 @@ environment. hello-pascal Pascal hello-modula2 Modula-2 hello-d D + hello-ocaml OCaml hello-smalltalk Smalltalk hello-tcl Tcl hello-tcl-tk Tcl Tk @@ -87,6 +88,7 @@ Makefile types: hello-pascal .gmo Makefile.am hello-modula2 .gmo Makefile.am hello-d .gmo Makefile.am + hello-ocaml .gmo Makefile.am hello-smalltalk .gmo Makefile.am hello-perl .gmo Makefile.am hello-php .gmo Makefile.am diff --git a/gettext-tools/examples/check-examples b/gettext-tools/examples/check-examples index 6e001db04..c63ff5ba5 100755 --- a/gettext-tools/examples/check-examples +++ b/gettext-tools/examples/check-examples @@ -732,6 +732,11 @@ func_check__hello_d () func_check hello-d } +func_check__hello_ocaml () +{ + func_check hello-ocaml +} + func_check__hello_smalltalk () { func_check hello-smalltalk @@ -810,6 +815,7 @@ func_check__hello_gawk # 32 s func_check__hello_pascal # 33 s func_check__hello_modula2 # 46 s func_check__hello_d # 70 s +func_check__hello_ocaml # 33 s func_check__hello_smalltalk # 32 s func_check__hello_tcl # 36 s func_check__hello_tcl_tk # 36 s diff --git a/gettext-tools/examples/hello-ocaml/INSTALL b/gettext-tools/examples/hello-ocaml/INSTALL new file mode 100644 index 000000000..f44874c47 --- /dev/null +++ b/gettext-tools/examples/hello-ocaml/INSTALL @@ -0,0 +1,23 @@ +This example relies on + - OCaml, + - 'opam', the OCaml package manager. +The following get installed through 'opam': + - 'dune', part of the OCaml build system, + - the opam package 'gettext-stub' + + + + +Preparation: Define environment variable for use of 'opam': + $ eval $(opam env) + $ opam install dune + $ opam install gettext-stub + +Installation: + ./autogen.sh + ./configure --prefix=/some/prefix + make + make install +Cleanup: + make distclean + ./autoclean.sh diff --git a/gettext-tools/examples/hello-ocaml/Makefile.am b/gettext-tools/examples/hello-ocaml/Makefile.am new file mode 100644 index 000000000..e75ad3295 --- /dev/null +++ b/gettext-tools/examples/hello-ocaml/Makefile.am @@ -0,0 +1,51 @@ +# Example for use of GNU gettext. +# This file is in the public domain. +# +# Makefile configuration - processed by automake. + +# General automake options. +AUTOMAKE_OPTIONS = foreign +ACLOCAL_AMFLAGS = -I m4 + +# The list of subdirectories containing Makefiles. +SUBDIRS = m4 po + +# The list of OCaml programs that are built. +bin_OCAMLPROGRAMS = hello + +# The source files of the 'hello' program. +hello_SOURCES = hello.ml + +DISTCLEANFILES = + +# Additional files to be distributed. +EXTRA_DIST = autogen.sh autoclean.sh + + +# ----------------- General rules for compiling OCaml programs ----------------- + +# Support for VPATH builds. +DUNE_BUILD = @DUNE@ build --root=. + +EXTRA_DIST += dune.in dune-project.in + + +# Rules for compiling OCaml programs. + +all-local: _build/default/hello.exe + +_build/default/hello.exe: dune dune-project $(hello_SOURCES) + $(DUNE_BUILD) hello.exe + +mostlyclean-local: + rm -rf _build + +install-exec-local: all-local + $(MKDIR_P) $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) _build/default/hello.exe $(DESTDIR)$(bindir)/hello + +installdirs-local: + $(MKDIR_P) $(DESTDIR)$(bindir) + +uninstall-local: + rm -f $(DESTDIR)$(bindir)/hello diff --git a/gettext-tools/examples/hello-ocaml/autoclean.sh b/gettext-tools/examples/hello-ocaml/autoclean.sh new file mode 100755 index 000000000..191fd55c3 --- /dev/null +++ b/gettext-tools/examples/hello-ocaml/autoclean.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# Example for use of GNU gettext. +# This file is in the public domain. +# +# Script for cleaning all autogenerated files. + +test ! -f Makefile || make distclean +# Do the equivalent of "make maintainer-clean", even without the Makefile. +rm -rf _build +rm -rf autom4te.cache + +# Brought in by explicit copy. +rm -f m4/nls.m4 +rm -f m4/po.m4 +rm -f m4/progtest.m4 +rm -f po/remove-potcdate.sed + +# Generated by aclocal. +rm -f aclocal.m4 + +# Generated by autoconf. +rm -f configure + +# Generated or brought in by automake. +rm -f Makefile.in +rm -f m4/Makefile.in +rm -f po/Makefile.in +rm -f install-sh +rm -f missing +rm -f po/*.pot +rm -f po/stamp-po +rm -f po/*.gmo diff --git a/gettext-tools/examples/hello-ocaml/autogen.sh b/gettext-tools/examples/hello-ocaml/autogen.sh new file mode 100755 index 000000000..a972da804 --- /dev/null +++ b/gettext-tools/examples/hello-ocaml/autogen.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# Example for use of GNU gettext. +# This file is in the public domain. +# +# Script for regenerating all autogenerated files. + +if test -r ../Makefile.am; then + # Inside the gettext source directory. + GETTEXT_TOPSRCDIR=../../.. +else + if test -r ../Makefile; then + # Inside a gettext build directory. + GETTEXT_TOOLS_SRCDIR=`sed -n -e 's,^top_srcdir *= *\(.*\)$,\1,p' ../Makefile` + # Adjust a relative top_srcdir. + case $GETTEXT_TOOLS_SRCDIR in + /*) ;; + *) GETTEXT_TOOLS_SRCDIR=../$GETTEXT_TOOLS_SRCDIR ;; + esac + GETTEXT_TOPSRCDIR=$GETTEXT_TOOLS_SRCDIR/../.. + else + # Installed under ${prefix}/share/doc/gettext/examples. + . ../installpaths + fi +fi + +cp -p ${ACLOCALDIR-$GETTEXT_TOPSRCDIR/gettext-runtime/m4}/nls.m4 m4/nls.m4 +cp -p ${ACLOCALDIR-$GETTEXT_TOPSRCDIR/gettext-runtime/m4}/po.m4 m4/po.m4 +cp -p ${ACLOCALDIR-$GETTEXT_TOPSRCDIR/gettext-runtime/m4}/progtest.m4 m4/progtest.m4 +cp -p ${GETTEXTSRCPODIR-$GETTEXT_TOPSRCDIR/gettext-runtime/po}/remove-potcdate.sed po/remove-potcdate.sed + +aclocal -I m4 + +autoconf + +automake -a -c + +cd po +for f in *.po; do + if test -r "$f"; then + lang=`echo $f | sed -e 's,\.po$,,'` + msgfmt -c -o $lang.gmo $lang.po + fi +done +cd .. diff --git a/gettext-tools/examples/hello-ocaml/configure.ac b/gettext-tools/examples/hello-ocaml/configure.ac new file mode 100644 index 000000000..9cbc4a783 --- /dev/null +++ b/gettext-tools/examples/hello-ocaml/configure.ac @@ -0,0 +1,41 @@ +dnl Example for use of GNU gettext. +dnl This file is in the public domain. +dnl +dnl Configuration file - processed by autoconf. + +AC_INIT([hello-ocaml], [0]) +AC_CONFIG_SRCDIR([hello.ml.in]) +AM_INIT_AUTOMAKE([1.11]) + +dnl Check for availability of the 'dune' program. +AC_CHECK_PROGS([DUNE], [dune]) +if test -z "$DUNE"; then + echo "*** Essential program dune not found" 1>&2 + exit 1 +fi + +dnl The installed program must know where to find its message catalogs. +dnl Unfortunately, prefix gets only finally determined at the end of configure. +if test "X$prefix" = "XNONE"; then + final_prefix="$ac_default_prefix" +else + final_prefix="$prefix" +fi +save_prefix="$prefix" +prefix="$final_prefix" +eval "datarootdir=\"${datarootdir}\"" +eval "localedir=\"${datarootdir}/locale\"" +prefix="$save_prefix" +AC_SUBST([localedir]) + +dnl Support for the po directory. +AM_PO_SUBDIRS + +AC_CONFIG_FILES([Makefile hello.ml]) +dnl Support for VPATH builds: +dnl We need a copy of dune and dune-project in the build directory. Otherwise +dnl "dune build ..." creates its '_build' directory in the source directory. +AC_CONFIG_FILES([dune dune-project]) +AC_CONFIG_FILES([m4/Makefile]) +AC_CONFIG_FILES([po/Makefile], [AM_POSTPROCESS_PO_MAKEFILE]) +AC_OUTPUT diff --git a/gettext-tools/examples/hello-ocaml/dune-project.in b/gettext-tools/examples/hello-ocaml/dune-project.in new file mode 100644 index 000000000..0fb49fb04 --- /dev/null +++ b/gettext-tools/examples/hello-ocaml/dune-project.in @@ -0,0 +1,2 @@ +(lang dune 3.19) +(name hello) diff --git a/gettext-tools/examples/hello-ocaml/dune.in b/gettext-tools/examples/hello-ocaml/dune.in new file mode 100644 index 000000000..d8f08a350 --- /dev/null +++ b/gettext-tools/examples/hello-ocaml/dune.in @@ -0,0 +1,3 @@ +(executable + (name hello) + (libraries gettext.base gettext-stub unix)) diff --git a/gettext-tools/examples/hello-ocaml/hello.ml.in b/gettext-tools/examples/hello-ocaml/hello.ml.in new file mode 100644 index 000000000..25c23a396 --- /dev/null +++ b/gettext-tools/examples/hello-ocaml/hello.ml.in @@ -0,0 +1,27 @@ +(* Example for use of GNU gettext. + This file is in the public domain. + + Source code of the OCaml program. *) + + +module ConfiguredGettext = + (* See https://gildor478.github.io/ocaml-gettext/gettext/Gettext/Program/index.html *) + Gettext.Program + (* See https://gildor478.github.io/ocaml-gettext/gettext/GettextTypes/module-type-INIT_TYPE/index.html *) + (struct + let textdomain = "hello-ocaml" + let codeset = None + let dir = Some "@localedir@" + let dependencies = [] + end) + (* See https://github.com/gildor478/ocaml-gettext/blob/master/doc/reference-manual.md *) + (GettextStub.Native) + +open ConfiguredGettext;; +open Printf;; +open Unix;; (* works also on Windows *) + +let () = + print_endline (s_ "Hello, world!"); + print_endline (sprintf (f_ "This program is running as process number %d.") + (getpid ())); diff --git a/gettext-tools/examples/hello-ocaml/m4/Makefile.am b/gettext-tools/examples/hello-ocaml/m4/Makefile.am new file mode 100644 index 000000000..8a841b31f --- /dev/null +++ b/gettext-tools/examples/hello-ocaml/m4/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST = \ + nls.m4 po.m4 diff --git a/gettext-tools/examples/hello-ocaml/po/LINGUAS b/gettext-tools/examples/hello-ocaml/po/LINGUAS new file mode 100644 index 000000000..dc4a82afb --- /dev/null +++ b/gettext-tools/examples/hello-ocaml/po/LINGUAS @@ -0,0 +1,5 @@ +# Example for use of GNU gettext. +# This file is in the public domain. +# +# Set of available languages. +af ast bg ca cs da de el eo es fi fr ga gl hr hu id it ja ka ky lv ms mt nb nl nn pl pt pt_BR ro ru sk sl sq sr sv ta tr uk vi zh_CN zh_HK zh_TW diff --git a/gettext-tools/examples/hello-ocaml/po/Makefile.am b/gettext-tools/examples/hello-ocaml/po/Makefile.am new file mode 100644 index 000000000..55056aec5 --- /dev/null +++ b/gettext-tools/examples/hello-ocaml/po/Makefile.am @@ -0,0 +1,434 @@ +# Example for use of GNU gettext. +# This file is in the public domain. +# +# Makefile configuration - processed by automake. + +# List of files which contain translatable strings. +POTFILES = \ + hello.ml.in + +# Usually the message domain is the same as the package name. +DOMAIN = $(PACKAGE) + +# These options get passed to xgettext. +XGETTEXT_OPTIONS = + +# This is the copyright holder that gets inserted into the header of the +# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding +# package. (Note that the msgid strings, extracted from the package's +# sources, belong to the copyright holder of the package.) Translators are +# expected to transfer the copyright for their translations to this person +# or entity, or to disclaim their copyright. The empty string stands for +# the public domain; in this case the translators are expected to disclaim +# their copyright. +COPYRIGHT_HOLDER = Yoyodyne, Inc. + +# This tells whether or not to prepend "GNU " prefix to the package +# name that gets inserted into the header of the $(DOMAIN).pot file. +# Possible values are "yes", "no", or empty. If it is empty, try to +# detect it automatically by scanning the files in $(top_srcdir) for +# "GNU packagename" string. +PACKAGE_GNU = no + +# This is the email address or URL to which the translators shall report +# bugs in the untranslated strings: +# - Strings which are not entire sentences, see the maintainer guidelines +# in the GNU gettext documentation, section 'Preparing Strings'. +# - Strings which use unclear terms or require additional context to be +# understood. +# - Strings which make invalid assumptions about notation of date, time or +# money. +# - Pluralisation problems. +# - Incorrect English spelling. +# - Incorrect formatting. +# It can be your email address, or a mailing list address where translators +# can write to without being subscribed, or the URL of a web page through +# which the translators can contact you. +MSGID_BUGS_ADDRESS = bug-gettext@gnu.org + +# This is the list of locale categories, beyond LC_MESSAGES, for which the +# message catalogs shall be used. It is usually empty. +EXTRA_LOCALE_CATEGORIES = + +# These options get passed to msgmerge. +# Useful options are in particular: +# --previous to keep previous msgids of translated messages +MSGMERGE_OPTIONS = + +# These options get passed to msginit. +# If you want to disable line wrapping when writing PO files, add +# --no-wrap to MSGMERGE_OPTIONS, XGETTEXT_OPTIONS, and +# MSGINIT_OPTIONS. +MSGINIT_OPTIONS = + +MSGMERGE = @MSGMERGE@ +MSGMERGE_UPDATE = @MSGMERGE@ --update +MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ +MSGINIT = msginit +MSGCONV = msgconv +MSGFILTER = msgfilter + +# This is computed as $(foreach file, $(POTFILES), $(top_srcdir)/$(file)) +POTFILES_DEPS != for file in $(POTFILES); do echo $(top_srcdir)/$$file; done + +# The set of available translations. +ALL_LINGUAS != if test -f $(srcdir)/LINGUAS; then \ + sed -e '/^\#/d' < $(srcdir)/LINGUAS; \ + else \ + echo $(LINGUAS); \ + fi +# This is computed as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) +POFILES != for lang in $(ALL_LINGUAS); do echo $(srcdir)/$$lang.po; done +# This is computed as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) +GMOFILES != for lang in $(ALL_LINGUAS); do echo $(srcdir)/$$lang.gmo; done +# This is computed as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) +UPDATEPOFILES != for lang in $(ALL_LINGUAS); do echo $$lang.po-update; done +# This is computed as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) +DUMMYPOFILES != for lang in $(ALL_LINGUAS); do echo $$lang.nop; done + +# The set of desired translations, as specified by the installer or distributor. +DESIRED_LINGUAS = @DESIRED_LINGUAS@ +# The set of translations to install. This is computed based on $(ALL_LINGUAS) +# and $(DESIRED_LINGUAS). It is a subset of $(ALL_LINGUAS). +# We use the presentlang catalog if desiredlang is +# a. equal to presentlang, or +# b. a variant of presentlang (because in this case, presentlang can be used +# as a fallback for messages which are not translated in the desiredlang +# catalog). +INST_LINGUAS != for presentlang in $(ALL_LINGUAS); do \ + useit=false; \ + for desiredlang in $(DESIRED_LINGUAS); do \ + case "$$desiredlang" in \ + "$$presentlang" | "$$presentlang"_* | "$$presentlang".* | "$$presentlang"@*) \ + useit=true ;; \ + esac; \ + done; \ + if $$useit; then echo $$presentlang; fi; \ + done +# This is computed as $(foreach lang, $(INST_LINGUAS), $(lang).gmo) +CATALOGS != for lang in $(INST_LINGUAS); do echo $$lang.gmo; done + +SUFFIXES = .po .gmo .nop .po-create .po-update + +# The .pot file, stamp-po, .po files, and .gmo files appear in release tarballs. +# The GNU Coding Standards say in +# : +# "GNU distributions usually contain some files which are not source files +# ... . Since these files normally appear in the source directory, they +# should always appear in the source directory, not in the build directory. +# So Makefile rules to update them should put the updated files in the +# source directory." +# Therefore we put these files in the source directory, not the build directory. + +# During .po -> .gmo conversion, take into account the most recent changes to +# the .pot file. This eliminates the need to update the .po files when the +# .pot file has changed, which would be troublesome if the .po files are put +# under version control. +$(GMOFILES): $(srcdir)/$(DOMAIN).pot +.po.gmo: + @lang=`echo $* | sed -e 's,.*/,,'`; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}rm -f $${lang}.gmo && $(MSGMERGE) $(MSGMERGE_FOR_MSGFMT_OPTION) -o $${lang}.1po $${lang}.po $(DOMAIN).pot && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.1po && rm -f $${lang}.1po"; \ + cd $(srcdir) && \ + rm -f $${lang}.gmo && \ + $(MSGMERGE) $(MSGMERGE_FOR_MSGFMT_OPTION) -o $${lang}.1po $${lang}.po $(DOMAIN).pot && \ + $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.1po && \ + mv t-$${lang}.gmo $${lang}.gmo && \ + rm -f $${lang}.1po + + +all-local: all-local-@USE_NLS@ + +all-local-yes: $(srcdir)/stamp-po +all-local-no: + +# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no +# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because +# we don't want to bother translators with empty POT files). We assume that +# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. +# In this case, $(srcdir)/stamp-po is a nop (i.e. a phony target). + +# $(srcdir)/stamp-po is a timestamp denoting the last time at which the CATALOGS +# have been loosely updated. Its purpose is that when a developer or translator +# checks out the package from a version control system, and the $(DOMAIN).pot +# file is not under version control, "make" will update the $(DOMAIN).pot and +# the $(CATALOGS), but subsequent invocations of "make" will do nothing. This +# timestamp would not be necessary if updating the $(CATALOGS) would always +# touch them; however, the rule for $(POFILES) has been designed to not touch +# files that don't need to be changed. +$(srcdir)/stamp-po: $(srcdir)/$(DOMAIN).pot + test ! -f $(srcdir)/$(DOMAIN).pot || \ + test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) + @test ! -f $(srcdir)/$(DOMAIN).pot || { \ + echo "touch $(srcdir)/stamp-po" && \ + echo timestamp > $(srcdir)/stamp-poT && \ + mv $(srcdir)/stamp-poT $(srcdir)/stamp-po; \ + } + +# This target rebuilds $(DOMAIN).pot; it is an expensive operation. +# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. +# The determination of whether the package xyz is a GNU one is based on the +# heuristic whether some file in the top level directory mentions "GNU xyz". +# If GNU 'find' is available, we avoid grepping through monster files. +$(DOMAIN).pot-update: $(POTFILES_DEPS) + package_gnu="$(PACKAGE_GNU)"; \ + test -n "$$package_gnu" || { \ + if { if (LC_ALL=C find --version) 2>/dev/null | grep GNU >/dev/null; then \ + LC_ALL=C find -L $(top_srcdir) -maxdepth 1 -type f -size -10000000c -exec grep -i 'GNU $(PACKAGE)' /dev/null '{}' ';' 2>/dev/null; \ + else \ + LC_ALL=C grep -i 'GNU $(PACKAGE)' $(top_srcdir)/* 2>/dev/null; \ + fi; \ + } | grep -v 'libtool:' >/dev/null; then \ + package_gnu=yes; \ + else \ + package_gnu=no; \ + fi; \ + }; \ + if test "$$package_gnu" = "yes"; then \ + package_prefix='GNU '; \ + else \ + package_prefix=''; \ + fi; \ + if test -n '$(MSGID_BUGS_ADDRESS)'; then \ + msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \ + else \ + msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ + fi; \ + case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ + $(POTFILES) \ + ;; \ + *) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --package-name="$${package_prefix}$(PACKAGE)" \ + --package-version='$(VERSION)' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ + $(POTFILES) \ + ;; \ + esac + test ! -f $(DOMAIN).po || { \ + if test -f $(srcdir)/$(DOMAIN).pot-header; then \ + sed -e '1,/^#$$/d' < $(DOMAIN).po > $(DOMAIN).1po && \ + cat $(srcdir)/$(DOMAIN).pot-header $(DOMAIN).1po > $(DOMAIN).po && \ + rm -f $(DOMAIN).1po \ + || exit 1; \ + fi; \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + sed -f $(srcdir)/remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ + sed -f $(srcdir)/remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ + if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ + else \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + else \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + } + +# This rule has no dependencies: we don't need to update $(DOMAIN).pot at +# every "make" invocation, only create it when it is missing. +# Only "make $(DOMAIN).pot-update" or "make dist" will force an update. +$(srcdir)/$(DOMAIN).pot: + $(MAKE) $(DOMAIN).pot-update + +# This target rebuilds a PO file if $(DOMAIN).pot has changed. +# Note that a PO file is not touched if it doesn't need to be changed. +$(POFILES): $(srcdir)/$(DOMAIN).pot + @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ + if test -f "$(srcdir)/$${lang}.po"; then \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE_UPDATE) --quiet $(MSGMERGE_OPTIONS) --lang=$${lang} --previous $${lang}.po $(DOMAIN).pot"; \ + cd $(srcdir) \ + && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.10 | 0.10.*) \ + $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \ + 0.1[1-5] | 0.1[1-5].*) \ + $(MSGMERGE_UPDATE) --quiet $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \ + 0.1[6-7] | 0.1[6-7].*) \ + $(MSGMERGE_UPDATE) --quiet $(MSGMERGE_OPTIONS) --previous $${lang}.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE_UPDATE) --quiet $(MSGMERGE_OPTIONS) --lang=$${lang} --previous $${lang}.po $(DOMAIN).pot;; \ + esac; \ + }; \ + else \ + $(MAKE) $${lang}.po-create; \ + fi + + +install-data-local: install-data-local-@USE_NLS@ +install-data-local-no: all-local +install-data-local-yes: all-local + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(MKDIR_P) $(DESTDIR)$$dir; \ + if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ + $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ + echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ + fi; \ + done; \ + done + +installdirs-local: installdirs-local-@USE_NLS@ +installdirs-local-no: +installdirs-local-yes: + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(MKDIR_P) $(DESTDIR)$$dir; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + fi; \ + done; \ + done + +uninstall-local: uninstall-local-@USE_NLS@ +uninstall-local-no: +uninstall-local-yes: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + done; \ + done + +html ID: + +MOSTLYCLEANFILES = +MOSTLYCLEANFILES += stamp-poT +MOSTLYCLEANFILES += core core.* *.stackdump $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po +MOSTLYCLEANFILES += *.o + +MAINTAINERCLEANFILES = $(DOMAIN).pot stamp-po $(GMOFILES) + +EXTRA_DIST = remove-potcdate.sed LINGUAS $(POFILES) $(GMOFILES) + +# Hidden from automake, but really activated. Works around an automake-1.5 bug. +#distdir: distdir1 +distdir1: + $(MAKE) update-po + $(MAKE) $(srcdir)/stamp-po + @if test -f $(srcdir)/$(DOMAIN).pot; then \ + for file in $(DOMAIN).pot stamp-po; do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + cp -p $$d/$$file $(distdir)/$$file || exit 1; \ + done; \ + else \ + case $(XGETTEXT) in \ + :) echo "Warning: Creating a tarball without '$(DOMAIN).pot', because a suitable 'xgettext' program was not found in PATH." 1>&2;; \ + *) echo "Warning: Creating a tarball without '$(DOMAIN).pot', because 'xgettext' found no strings to extract. Check the POTFILES and the XGETTEXT_OPTIONS in the Makefile.am file." 1>&2;; \ + esac; \ + fi + +update-po: Makefile + $(MAKE) $(DOMAIN).pot-update + test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) + $(MAKE) update-gmo + +# General rule for creating PO files. + +.nop.po-create: + @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ + echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ + exit 1 + +# General rule for updating PO files. + +.nop.po-update: + @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ + tmpdir=`pwd`; \ + echo "$$lang:"; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE) --quiet $(MSGMERGE_OPTIONS) --lang=$$lang --previous $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ + cd $(srcdir); \ + if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.10 | 0.10.*) \ + $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + 0.1[1-5] | 0.1[1-5].*) \ + $(MSGMERGE) --quiet $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + 0.1[6-7] | 0.1[6-7].*) \ + $(MSGMERGE) --quiet $(MSGMERGE_OPTIONS) --previous -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE) --quiet $(MSGMERGE_OPTIONS) --lang=$$lang --previous -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + esac; \ + }; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "msgmerge for $$lang.po failed!" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi + +$(DUMMYPOFILES): + +update-gmo: Makefile $(GMOFILES) + @: diff --git a/gettext-tools/examples/po/Makefile.am b/gettext-tools/examples/po/Makefile.am index ef3c9247a..76eadc4b3 100644 --- a/gettext-tools/examples/po/Makefile.am +++ b/gettext-tools/examples/po/Makefile.am @@ -72,6 +72,7 @@ POTFILES = \ hello-pascal/hello.pas \ hello-modula2/hello.mod.in \ hello-d/hello.d.in \ + hello-ocaml/hello.ml.in \ hello-smalltalk/hello.st.in \ hello-tcl/hello.tcl \ hello-tcl-tk/hello.tcl \ @@ -115,6 +116,7 @@ SMALLPOTS = \ hello-pascal.pot \ hello-modula2.pot \ hello-d.pot \ + hello-ocaml.pot \ hello-smalltalk.pot \ hello-tcl.pot \ hello-tcl-tk.pot \ @@ -364,6 +366,9 @@ hello-modula2.pot : $(POTFILES_DEPS) hello-d.pot : $(POTFILES_DEPS) $(USE_BUILT_PROGS) $(SHELL) '$(srcdir)/xsmallpot.sh' '$(srcdir)' hello-d +hello-ocaml.pot : $(POTFILES_DEPS) + $(USE_BUILT_PROGS) $(SHELL) '$(srcdir)/xsmallpot.sh' '$(srcdir)' hello-ocaml + hello-smalltalk.pot : $(POTFILES_DEPS) $(USE_BUILT_PROGS) $(SHELL) '$(srcdir)/xsmallpot.sh' '$(srcdir)' hello-smalltalk @@ -491,6 +496,7 @@ SMALLPOFILES_FOR_lang = \ $(srcdir)/../hello-pascal/po/$$lang.po \ $(srcdir)/../hello-modula2/po/$$lang.po \ $(srcdir)/../hello-d/po/$$lang.po \ + $(srcdir)/../hello-ocaml/po/$$lang.po \ $(srcdir)/../hello-smalltalk/po/$$lang.po \ $(srcdir)/../hello-tcl/po/$$lang.po \ $(srcdir)/../hello-tcl-tk/po/$$lang.po \ @@ -597,6 +603,9 @@ $(srcdir)/../hello-modula2/po/$(LL).po: $(srcdir)/hello-modula2.pot $(srcdir)/$( $(srcdir)/../hello-d/po/$(LL).po: $(srcdir)/hello-d.pot $(srcdir)/$(LL).po $(USE_BUILT_PROGS) cd $(srcdir) && $(SHELL) mmsmallpo.sh hello-d $(LL) +$(srcdir)/../hello-ocaml/po/$(LL).po: $(srcdir)/hello-ocaml.pot $(srcdir)/$(LL).po + $(USE_BUILT_PROGS) cd $(srcdir) && $(SHELL) mmsmallpo.sh hello-ocaml $(LL) + $(srcdir)/../hello-smalltalk/po/$(LL).po: $(srcdir)/hello-smalltalk.pot $(srcdir)/$(LL).po $(USE_BUILT_PROGS) cd $(srcdir) && $(SHELL) mmsmallpo.sh hello-smalltalk $(LL) -- 2.47.3