2016-03-26 15:32:11 +03:00
#!/usr/bin/env python
# encoding: utf-8
2018-01-31 12:48:43 +03:00
# Thomas Nagy, 2006-2018 (ita)
2016-03-26 15:32:11 +03:00
"""
Support for translation tools such as msgfmt and intltool
Usage : :
def configure ( conf ) :
conf . load ( ' gnu_dirs intltool ' )
def build ( bld ) :
# process the .po files into .gmo files, and install them in LOCALEDIR
bld ( features = ' intltool_po ' , appname = ' myapp ' , podir = ' po ' , install_path = " $ {LOCALEDIR} " )
# process an input file, substituting the translations from the po dir
bld (
features = " intltool_in " ,
podir = " ../po " ,
style = " desktop " ,
flags = [ " -u " ] ,
source = ' kupfer.desktop.in ' ,
install_path = " $ {DATADIR} /applications " ,
)
Usage of the : py : mod : ` waflib . Tools . gnu_dirs ` is recommended , but not obligatory .
"""
2018-01-31 12:48:43 +03:00
from __future__ import with_statement
2016-03-26 15:32:11 +03:00
import os , re
from waflib import Context , Task , Utils , Logs
import waflib . Tools . ccroot
from waflib . TaskGen import feature , before_method , taskgen_method
from waflib . Logs import error
from waflib . Configure import conf
_style_flags = {
' ba ' : ' -b ' ,
' desktop ' : ' -d ' ,
' keys ' : ' -k ' ,
' quoted ' : ' --quoted-style ' ,
' quotedxml ' : ' --quotedxml-style ' ,
' rfc822deb ' : ' -r ' ,
' schemas ' : ' -s ' ,
' xml ' : ' -x ' ,
}
@taskgen_method
def ensure_localedir ( self ) :
"""
Expands LOCALEDIR from DATAROOTDIR / locale if possible , or falls back to PREFIX / share / locale
"""
# use the tool gnu_dirs to provide options to define this
if not self . env . LOCALEDIR :
if self . env . DATAROOTDIR :
self . env . LOCALEDIR = os . path . join ( self . env . DATAROOTDIR , ' locale ' )
else :
self . env . LOCALEDIR = os . path . join ( self . env . PREFIX , ' share ' , ' locale ' )
@before_method ( ' process_source ' )
@feature ( ' intltool_in ' )
def apply_intltool_in_f ( self ) :
"""
Creates tasks to translate files by intltool - merge : :
def build ( bld ) :
bld (
features = " intltool_in " ,
podir = " ../po " ,
style = " desktop " ,
flags = [ " -u " ] ,
source = ' kupfer.desktop.in ' ,
install_path = " $ {DATADIR} /applications " ,
)
: param podir : location of the . po files
: type podir : string
: param source : source files to process
: type source : list of string
: param style : the intltool - merge mode of operation , can be one of the following values :
` ` ba ` ` , ` ` desktop ` ` , ` ` keys ` ` , ` ` quoted ` ` , ` ` quotedxml ` ` , ` ` rfc822deb ` ` , ` ` schemas ` ` and ` ` xml ` ` .
See the ` ` intltool - merge ` ` man page for more information about supported modes of operation .
: type style : string
: param flags : compilation flags ( " -quc " by default )
: type flags : list of string
: param install_path : installation path
: type install_path : string
"""
2018-01-31 12:48:43 +03:00
try :
self . meths . remove ( ' process_source ' )
except ValueError :
pass
2016-03-26 15:32:11 +03:00
self . ensure_localedir ( )
podir = getattr ( self , ' podir ' , ' . ' )
podirnode = self . path . find_dir ( podir )
if not podirnode :
error ( " could not find the podir %r " % podir )
return
cache = getattr ( self , ' intlcache ' , ' .intlcache ' )
self . env . INTLCACHE = [ os . path . join ( str ( self . path . get_bld ( ) ) , podir , cache ) ]
self . env . INTLPODIR = podirnode . bldpath ( )
self . env . append_value ( ' INTLFLAGS ' , getattr ( self , ' flags ' , self . env . INTLFLAGS_DEFAULT ) )
if ' -c ' in self . env . INTLFLAGS :
self . bld . fatal ( ' Redundant -c flag in intltool task %r ' % self )
style = getattr ( self , ' style ' , None )
if style :
try :
style_flag = _style_flags [ style ]
except KeyError :
self . bld . fatal ( ' intltool_in style " %s " is not valid ' % style )
self . env . append_unique ( ' INTLFLAGS ' , [ style_flag ] )
for i in self . to_list ( self . source ) :
node = self . path . find_resource ( i )
task = self . create_task ( ' intltool ' , node , node . change_ext ( ' ' ) )
inst = getattr ( self , ' install_path ' , None )
if inst :
self . add_install_files ( install_to = inst , install_from = task . outputs )
@feature ( ' intltool_po ' )
def apply_intltool_po ( self ) :
"""
Creates tasks to process po files : :
def build ( bld ) :
bld ( features = ' intltool_po ' , appname = ' myapp ' , podir = ' po ' , install_path = " $ {LOCALEDIR} " )
The relevant task generator arguments are :
: param podir : directory of the . po files
: type podir : string
: param appname : name of the application
: type appname : string
: param install_path : installation directory
: type install_path : string
The file LINGUAS must be present in the directory pointed by * podir * and list the translation files to process .
"""
2018-01-31 12:48:43 +03:00
try :
self . meths . remove ( ' process_source ' )
except ValueError :
pass
2016-03-26 15:32:11 +03:00
self . ensure_localedir ( )
appname = getattr ( self , ' appname ' , getattr ( Context . g_module , Context . APPNAME , ' set_your_app_name ' ) )
podir = getattr ( self , ' podir ' , ' . ' )
inst = getattr ( self , ' install_path ' , ' $ {LOCALEDIR} ' )
linguas = self . path . find_node ( os . path . join ( podir , ' LINGUAS ' ) )
if linguas :
# scan LINGUAS file for locales to process
2018-01-31 12:48:43 +03:00
with open ( linguas . abspath ( ) ) as f :
langs = [ ]
for line in f . readlines ( ) :
# ignore lines containing comments
if not line . startswith ( ' # ' ) :
langs + = line . split ( )
2016-03-26 15:32:11 +03:00
re_linguas = re . compile ( ' [-a-zA-Z_@.]+ ' )
for lang in langs :
# Make sure that we only process lines which contain locales
if re_linguas . match ( lang ) :
node = self . path . find_resource ( os . path . join ( podir , re_linguas . match ( lang ) . group ( ) + ' .po ' ) )
task = self . create_task ( ' po ' , node , node . change_ext ( ' .mo ' ) )
if inst :
filename = task . outputs [ 0 ] . name
( langname , ext ) = os . path . splitext ( filename )
inst_file = inst + os . sep + langname + os . sep + ' LC_MESSAGES ' + os . sep + appname + ' .mo '
self . add_install_as ( install_to = inst_file , install_from = task . outputs [ 0 ] ,
chmod = getattr ( self , ' chmod ' , Utils . O644 ) )
else :
Logs . pprint ( ' RED ' , " Error no LINGUAS file found in po directory " )
class po ( Task . Task ) :
"""
Compiles . po files into . gmo files
"""
run_str = ' $ {MSGFMT} -o $ {TGT} $ {SRC} '
color = ' BLUE '
class intltool ( Task . Task ) :
"""
Calls intltool - merge to update translation files
"""
run_str = ' $ {INTLTOOL} $ {INTLFLAGS} $ { INTLCACHE_ST:INTLCACHE} $ {INTLPODIR} $ {SRC} $ {TGT} '
color = ' BLUE '
@conf
def find_msgfmt ( conf ) :
"""
Detects msgfmt and sets the ` ` MSGFMT ` ` variable
"""
conf . find_program ( ' msgfmt ' , var = ' MSGFMT ' )
@conf
def find_intltool_merge ( conf ) :
"""
Detects intltool - merge
"""
if not conf . env . PERL :
conf . find_program ( ' perl ' , var = ' PERL ' )
conf . env . INTLCACHE_ST = ' --cache= %s '
conf . env . INTLFLAGS_DEFAULT = [ ' -q ' , ' -u ' ]
conf . find_program ( ' intltool-merge ' , interpreter = ' PERL ' , var = ' INTLTOOL ' )
def configure ( conf ) :
"""
Detects the program * msgfmt * and set * conf . env . MSGFMT * .
Detects the program * intltool - merge * and set * conf . env . INTLTOOL * .
It is possible to set INTLTOOL in the environment , but it must not have spaces in it : :
$ INTLTOOL = " /path/to/the program/intltool " waf configure
If a C / C + + compiler is present , execute a compilation test to find the header * locale . h * .
"""
conf . find_msgfmt ( )
conf . find_intltool_merge ( )
if conf . env . CC or conf . env . CXX :
conf . check ( header_name = ' locale.h ' )
2018-01-31 12:48:43 +03:00