2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-17 01:32:12 +00:00
Files
build/v2/tools/gettext.jam
Vladimir Prus 533abcaadd Bugfix: the main target rules did not work unless called from Jamfile.
The used 'CALLER_MODULE' to determine the project where the main target
is to be declared, which did not work if the rule is called from another
module.

Thanks to Zbynek Winkler for the bug report.

* build/project.jam (current): New rule
* test/wrapper.py: New test
* other files: Use 'project.current'.


[SVN r22569]
2004-03-31 06:53:56 +00:00

227 lines
7.2 KiB
Plaintext

# Copyright (C) Vladimir Prus 2003. Permission to copy, use, modify, sell and
# distribute this software is granted provided this copyright notice appears in
# all copies. This software is provided "as is" without express or implied
# warranty, and with no claim as to its suitability for any purpose.
# This module support GNU gettext internationalization utilities.
#
# It provides two main target rules: 'gettext.catalog', used for
# creating machine-readable catalogs from translations files, and
# 'gettext.update', used for update translation files from modified
# sources.
#
# To add i18n support to your application you should follow these
# steps.
#
# - Decide on a file name which will contain translations and
# what main target name will be used to update it. For example::
#
# gettext.update update-russian : russian.po a.cpp my_app ;
#
# - Create the initial translation file by running::
#
# bjam update-russian
#
# - Edit russian.po. For example, you might change fields like LastTranslator.
#
# - Create a main target for final message catalog::
#
# gettext.catalog russian : russian.po ;
#
# The machine-readable catalog will be updated whenever you update
# "russian.po". The "russian.po" file will be updated only on explicit
# request. When you're ready to update translations, you should
#
# - Run::
#
# bjam update-russian
#
# - Edit "russian.po" in appropriate editor.
#
# The next bjam run will convert "russian.po" into machine-readable form.
#
# By default, translations are marked by 'i18n' call. The 'gettext.keyword'
# feature can be used to alter this.
import targets ;
import property-set ;
import virtual-target ;
import "class" : new ;
import project ;
import type ;
import generators ;
import errors ;
import feature : feature ;
import toolset : flags ;
import regex ;
.path = "" ;
# Initializes the gettext module.
rule init ( path ? # Path where all tools are located. If not specified,
# they should be in PATH.
)
{
if $(.initialized) && $(.path) != $(path)
{
errors.error "Attempt to reconfigure with different path" ;
}
.initialized = true ;
if $(path)
{
.path = $(path)/ ;
}
}
# Creates a main target 'name', which, when updated, will cause
# file 'existing-translation' to be updated with translations
# extracted from 'sources'. It's possible to specify main target
# in sources --- it which case all target from dependency graph
# of those main targets will be scanned, provided they are of
# appropricate type. The 'gettext.types' feature can be used to
# control the types.
#
# The target will be updated only if explicitly requested on the
# command line.
rule update ( name : existing-translation sources + : requirements * )
{
local project = [ project.current ] ;
targets.main-target-alternative
[ new update-translations-class $(name) : $(project) :
$(existing-translation) $(sources)
: [ targets.main-target-requirements $(requirements) : $(project) ]
] ;
local project-target = [ project.target $(project) ] ;
$(project-target).mark-target-as-explicit $(name) ;
}
# The human editable source, containing translation.
type.register gettext.PO : po ;
# The machine readable message catalog.
type.register gettext.catalog : mo : : main ;
# Intermediate type produce by extracting translations from
# sources.
type.register gettext.POT : pot ;
# Identifies the keyword that should be used when scanning sources.
# Default: i18n
feature gettext.keyword : : free ;
# Contains space-separated list of sources types which should be scanned.
# Default: "C CPP"
feature gettext.types : : free ;
generators.register-standard gettext.compile : gettext.PO : gettext.catalog ;
class update-translations-class : basic-target
{
import regex : split ;
rule __init__ ( name : project : sources * : requirements )
{
basic-target.__init__ $(name) : $(project) : $(sources) : $(requirements)
: $(default-build) ;
}
rule construct ( source-targets * : property-set )
{
local types = [ $(property-set).get <gettext.types> ] ;
types ?= "C CPP" ;
types = [ regex.split $(types) " " ] ;
property-set = [ property-set.empty ] ;
if ! $(.constructed)
{
# First deterime the list of sources that must be scanned to
# messages.
local all-sources ;
for local s in $(source-targets[2-])
{
all-sources += [ virtual-target.traverse $(s) : : include-sources ] ;
}
local right-sources ;
for local s in $(all-sources)
{
if [ $(s).type ] in $(types)
{
right-sources += $(s) ;
}
}
if $(right-sources)
{
local new-messages = [ new file-target $(self.name) : gettext.POT : $(self.project) ] ;
local extract =
[ new action $(new-messages) : $(right-sources) : gettext.extract ] ;
$(new-messages).action $(extract) ;
local r = [ new notfile-target $(self.name) : $(self.project) ] ;
local a = [ new action $(r) : $(source-targets[1]) $(new-messages)
: gettext.update-po-dispatch ] ;
$(r).action $(a) ;
.constructed = [ virtual-target.register $(r) ] ;
}
else
{
errors.error "No source could be scanned by gettext tools" ;
}
}
return $(.constructed) ;
}
rule check-for-unused-sources ( result * : sources * )
{
}
}
flags gettext.extract KEYWORD <gettext.keyword> ;
actions extract
{
$(.path)xgettext -k$(KEYWORD:E=i18n) -o $(<) $(>)
}
# Does realy updating of po file. The tricky part is that
# we're actually updating one of the sources:
# $(<) is the NOTFILE target we're updating
# $(>[1]) is the PO file to be really updated.
# $(>[2]) is the PO file created from sources.
#
# When file to be updated does not exist (during the
# first run), we need to copy the file created from sources.
# In all other cases, we need to update the file.
rule update-po-dispatch
{
NOCARE $(>[1]) ;
gettext.create-po $(<) : $(>) ;
gettext.update-po $(<) : $(>) ;
_ on $(<) = " " ;
ok on $(<) = "" ;
EXISTING_PO on $(<) = $(>[1]) ;
}
# Due to fancy interaction of existing and updated, this rule
# can be called with with one source, in which case we copy
# the lonely source into EXISTING_PO, or with two sources,
# in which case the action body expands to nothing.
# I'd really like to have "missing" action modifier.
actions quietly existing updated create-po bind EXISTING_PO
{
cp$(_)"$(>[1])"$(_)"$(EXISTING_PO)"$($(>[2]:E=ok))
}
actions updated update-po bind EXISTING_PO
{
$(.path)msgmerge$(_)-U$(_)"$(EXISTING_PO)"$(_)"$(>[1])"
}
actions gettext.compile
{
$(.path)msgfmt -o $(<) $(>)
}
IMPORT $(__name__) : update : : gettext.update ;