# Copyright 2003, 2004, 2005, 2006 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)

#  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 typed-target $(name) : $(project) : gettext.UPDATE :
        $(existing-translation) $(sources)
        : [ targets.main-target-requirements $(requirements) : $(project) ]
      ] ;
    $(project).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 ;
# Intermediate type produce by extracting translations from
# sources.
type.register gettext.POT : pot ;
# Pseudo type used to invoke update-translations generator
type.register gettext.UPDATE ;

# 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-generator : generator
{
    import regex : split ;
    import property-set ;

    rule __init__ ( * : * )
    {
        generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
    }

    # The rule should be called with at least two sources. The first source
    # is the translation (.po) file to update. The remaining sources are targets
    # which should be scanned for new messages. All sources files for those targets
    # will be found and passed to the 'xgettext' utility, which extracts the
    # messages for localization. Those messages will be merged to the .po file.
    rule run ( project name ? : property-set : sources * : multiple ? )
    {
        local types = [ $(property-set).get <gettext.types> ] ;
        types ?= "C CPP" ;
        types = [ regex.split $(types) " " ] ;

        local keywords = [ $(property-set).get <gettext.keyword> ] ;
        property-set = [ property-set.create $(keywords:G=<gettext.keyword>) ] ;

        # First deterime the list of sources that must be scanned for
        # messages.
        local all-sources ;
        # CONSIDER: I'm not sure if the logic should be the same as for 'stage':
        # i.e. following dependency properties as well.
        for local s in $(sources[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) ;
            }
        }

        local .constructed ;
        if $(right-sources)
        {
            # Create the POT file, which will contain list of messages extracted
            # from the sources.
            local extract =
              [ new action $(right-sources) : gettext.extract : $(property-set) ] ;
            local new-messages = [ new file-target $(name) : gettext.POT
              : $(project) : $(extract) ] ;

            # Create a notfile target which will update the existing translation file
            # with new messages.
            local a = [ new action $(sources[1]) $(new-messages)
              : gettext.update-po-dispatch ] ;
            local r = [ new notfile-target $(name) : $(project) : $(a) ] ;
            .constructed = [ virtual-target.register $(r) ] ;
        }
        else
        {
            errors.error "No source could be scanned by gettext tools" ;
        }
        return $(.constructed) ;
    }
}
generators.register [ new update-translations-generator gettext.update : : gettext.UPDATE ] ;

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
# 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 ;
