Mercurial > gnulib
view pygnulib/generator.py @ 38933:e896a3753833
generator: do not export private class members into inherited classes
author | Dmitry Selyutin <ghostmansd@gmail.com> |
---|---|
date | Sat, 09 Sep 2017 19:42:55 +0300 |
parents | 8ee46377bd5f |
children | 19139a91b9e1 |
line wrap: on
line source
#!/usr/bin/python # encoding: UTF-8 import os from .config import Config from .module import Module class Generator: """gnulib file content generator""" _TEMPLATE_ = ( "## DO NOT EDIT! GENERATED AUTOMATICALLY!", "#", "# 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 file. If not, see <http://www.gnu.org/licenses/>.", "#", "# As a special exception to the GNU General Public License,", "# this file may be distributed as part of a program that", "# contains a configuration script generated by Autoconf, under", "# the same distribution terms as the rest of that program.", "#", "# Generated by gnulib-tool.", ) def __repr__(self): return "pygnulib.generator.Generator" def __str__(self): return "\n".join([_ for _ in self]) def __iter__(self): for line in Generator._TEMPLATE_: yield line class POMakefile(Generator): """PO Makefile parameterization""" _TEMPLATE_ = ( "# These options get passed to xgettext.", "XGETTEXT_OPTIONS = \\", " --keyword=_ --flag=_:1:pass-c-format \\", " --keyword=N_ --flag=N_:1:pass-c-format \\", " --keyword='proper_name:1,\"This is a proper name." # comma omitted " See the gettext manual, section Names.\"' \\", " --keyword='proper_name_utf8:1,\"This is a proper name." # comma omitted " See the gettext manual, section Names.\"' \\", " --flag=error:3:c-format --flag=error_at_line:5:c-format", "", "# This is the copyright holder that gets inserted into the header of the", "# $(DOMAIN).pot file. gnulib is copyrighted by the FSF.", "COPYRIGHT_HOLDER = Free Software Foundation, Inc.", "", "# 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-gnulib@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 =", "", "# This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt'", "# context. Possible values are \"yes\" and \"no\". Set this to yes if the", "# package uses functions taking also a message context, like pgettext(), or", "# if in $(XGETTEXT_OPTIONS) you define keywords with a context argument.", "USE_MSGCTXT = no" ) def __init__(self, config): if not isinstance(config, Config): raise TypeError("config must be of pygnulib.Config type") super().__init__() self.__config = config @property def po_base(self): """directory relative to ROOT where *.po files are placed; defaults to 'po'""" return self.__config.po_base @property def po_domain(self): """the prefix of the i18n domain""" return self.__config.po_domain def __repr__(self): fmt = "pygnulib.generator.POMakefile(po_base=%r, po_domain=%r)" return fmt % (self.po_base, self.po_domain) def __iter__(self): for line in super().__iter__(): yield line yield "# Usually the message domain is the same as the package name." yield "# But here it has a '-gnulib' suffix." yield "DOMAIN = %s-gnulib" % self.po_domain yield "" yield "# These two variables depend on the location of this directory." yield "subdir = %s" % self.po_domain yield "top_subdir = %s" % "/".join([".." for _ in self.po_base.split(os.path.sep)]) for line in POMakefile._TEMPLATE_: yield line class POTFILES(Generator): """file list to be passed to xgettext""" def __init__(self, config, files): if not isinstance(config, Config): raise TypeError("config must be of pygnulib.Config type") super().__init__() self.__config = config self.__files = tuple(files) @property def files(self): """list of files""" return tuple(self.files) def __repr__(self): fmt = "pygnulib.generator.POTFILES(files=%r)" return fmt % self.files def __iter__(self): for line in super().__iter__(): yield line yield "# List of files which contain translatable strings." for file in [_ for _ in self.files if _.startswith("lib/")]: yield os.path.join(self.__config.source_base, file[4:]) class AutoconfSnippet(Generator): """autoconf snippet generator for standalone module""" def __init__(self, config, module, toplevel, no_libtool, no_gettext): """ config: gnulib configuration module: gnulib module instance toplevel: make a subordinate use of gnulib if False no_libtool: disable libtool (regardless of configuration) no_gettext: disable AM_GNU_GETTEXT invocations if True """ if not isinstance(config, Config): raise TypeError("config must be of pygnulib.config.Config type") if not isinstance(module, Module): raise TypeError("module must be of pygnulib.module.Module type") if not isinstance(toplevel, bool): raise TypeError("toplevel must be of bool type") if not isinstance(no_libtool, bool): raise TypeError("no_libtool must be of bool type") if not isinstance(no_gettext, bool): raise TypeError("no_gettext must be of bool type") super().__init__() self.__config = config self.__module = module self.__toplevel = toplevel self.__no_libtool = no_libtool self.__no_gettext = no_gettext @property def toplevel(self): """top level indicator; subordinate use of pygnulib""" return self.__toplevel @property def libtool(self): """libtool switch, disabling libtool configuration parameter""" return self.__config.libtool and not self.__no_libtool @property def gettext(self): """gettext switch, disabling AM_GNU_GETTEXT invocations""" return not self.__no_gettext def __repr__(self): flags = [] if self.toplevel: flags += ["toplevel"] if self.libtool: flags += ["libtool"] if self.gettext: flags += ["gettext"] fmt = "pygnulib.generator.AutoconfSnippet(include_guard_prefix=%r, flags=%s)" include_guard_prefix = self.__config.include_guard_prefix return fmt % (include_guard_prefix, "|".join(flags)) def __iter__(self): module = self.__module if module.name not in ("gnumakefile", "maintainer-makefile") or self.toplevel: snippet = module.configure_ac_snippet include_guard_prefix = self.__config.include_guard_prefix snippet.replace(r"${gl_include_guard_prefix}", include_guard_prefix) if not self.libtool: table = ( (r"$gl_cond_libtool", "false"), ("gl_libdeps", "gltests_libdeps"), ("gl_ltlibdeps", "gltests_ltlibdeps"), ) for (src, dst) in table: snippet = snippet.replace(src, dst) if not self.gettext: src = "AM_GNU_GETTEXT([external])" dst = "dnl you must add AM_GNU_GETTEXT([external]) or similar to configure.ac.'" snippet = snippet.replace(src, dst) lines = (_ for _ in snippet.split("\n") if _) for line in lines: yield line if module.name == "alloca" and self.libtool: yield "changequote(,)dnl" yield "LTALLOCA=`echo \"$ALLOCA\" | sed -e 's/\\.[^.]* /.lo /g;s/\\.[^.]*$/.lo/'`" yield "changequote([, ])dnl" yield "AC_SUBST([LTALLOCA])" class InitMacro(Generator): """basic gl_INIT macro generator""" def __init__(self, config, macro_prefix=None): """ config: gnulib configuration macro_prefix: macro prefix; if None, consider configuration """ if not isinstance(config, Config): raise TypeError("config must be of pygnulib.config.Config type") if macro_prefix is None: macro_prefix = config.macro_prefix if not isinstance(macro_prefix, str): raise TypeError("macro_prefix must be of str type") self.__macro_prefix = macro_prefix @property def macro_prefix(self): """the prefix of the macros 'gl_EARLY' and 'gl_INIT'""" return self.__macro_prefix def __repr__(self): fmt = "pygnulib.generator.InitMacro(macro_prefix=%r)" return fmt % self.macro_prefix class InitMacroHeader(InitMacro): """the first few statements of the gl_INIT macro""" def __init__(self, config, macro_prefix=None): """ config: gnulib configuration macro_prefix: macro prefix; if None, consider configuration """ super().__init__(config=config, macro_prefix=macro_prefix) def __repr__(self): fmt = "pygnulib.generator.InitMacroHeader(macro_prefix=%r)" return fmt % self.macro_prefix def __iter__(self): # Overriding AC_LIBOBJ and AC_REPLACE_FUNCS has the effect of storing # platform-dependent object files in ${macro_prefix_arg}_LIBOBJS instead # of LIBOBJS. The purpose is to allow several gnulib instantiations under # a single configure.ac file. (AC_CONFIG_LIBOBJ_DIR does not allow this # flexibility). # Furthermore it avoids an automake error like this when a Makefile.am # that uses pieces of gnulib also uses $(LIBOBJ): # automatically discovered file `error.c' should not be explicitly # mentioned. yield " m4_pushdef([AC_LIBOBJ], m4_defn([%s_LIBOBJ]))" % self.macro_prefix yield " m4_pushdef([AC_REPLACE_FUNCS], m4_defn([%s_REPLACE_FUNCS]))" % self.macro_prefix # Overriding AC_LIBSOURCES has the same purpose of avoiding the automake # error when a Makefile.am that uses pieces of gnulib also uses $(LIBOBJ): # automatically discovered file `error.c' should not be explicitly # mentioned # We let automake know about the files to be distributed through the # EXTRA_lib_SOURCES variable. yield " m4_pushdef([AC_LIBSOURCES], m4_defn([%s_LIBSOURCES]))" % self.macro_prefix # Create data variables for checking the presence of files that are # mentioned as AC_LIBSOURCES arguments. These are m4 variables, not shell # variables, because we want the check to happen when the configure file is # created, not when it is run. ${macro_prefix_arg}_LIBSOURCES_LIST is the # list of files to check for. ${macro_prefix_arg}_LIBSOURCES_DIR is the # subdirectory in which to expect them. yield " m4_pushdef([%s_LIBSOURCES_LIST], [])" % self.macro_prefix yield " m4_pushdef([%s_LIBSOURCES_DIR], [])" % self.macro_prefix yield " gl_COMMON" class InitMacroFooter(InitMacro): """the last few statements of the gl_INIT macro""" _TEMPLATE_ = ( " m4_ifval({macro_prefix}_LIBSOURCES_LIST, [", " m4_syscmd([test ! -d ]m4_defn([{macro_prefix}_LIBSOURCES_DIR])[ ||", " for gl_file in ]{macro_prefix}_LIBSOURCES_LIST[ ; do", " if test ! -r ]m4_defn([{macro_prefix}_LIBSOURCES_DIR])[/$gl_file ; then", " echo \"missing file ]m4_defn([{macro_prefix}_LIBSOURCES_DIR])[/$gl_file\" >&2", " exit 1", " fi", " done])dnl", " m4_if(m4_sysval, [0], [],", " [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])])", " ])", " m4_popdef([{macro_prefix}_LIBSOURCES_DIR])", " m4_popdef([{macro_prefix}_LIBSOURCES_LIST])", " m4_popdef([AC_LIBSOURCES])", " m4_popdef([AC_REPLACE_FUNCS])", " m4_popdef([AC_LIBOBJ])", " AC_CONFIG_COMMANDS_PRE([", " {macro_prefix}_libobjs=", " {macro_prefix}_ltlibobjs=", " if test -n \"${macro_prefix}_LIBOBJS\"; then", " # Remove the extension.", " sed_drop_objext='s/\\.o$//;s/\\.obj$//'", " for i in `for i in ${macro_prefix}_LIBOBJS; " # comma omitted "do echo \"$i\"; done | sed -e \"$sed_drop_objext\" | sort | uniq`; do", " {macro_prefix}_libobjs=\"${macro_prefix}_libobjs $i.$ac_objext\"", " {macro_prefix}_ltlibobjs=\"${macro_prefix}_ltlibobjs $i.lo\"", " done", " fi", " AC_SUBST([{macro_prefix}_LIBOBJS], [${macro_prefix}_libobjs])", " AC_SUBST([{macro_prefix}_LTLIBOBJS], [${macro_prefix}_ltlibobjs])", " ])", ) def __init__(self, config, macro_prefix=None): """ config: gnulib configuration macro_prefix: macro prefix; if None, consider configuration """ super().__init__(config=config, macro_prefix=macro_prefix) def __repr__(self): fmt = "pygnulib.generator.InitMacroFooter(macro_prefix=%r)" return fmt % self.macro_prefix def __iter__(self): # Check the presence of files that are mentioned as AC_LIBSOURCES # arguments. The check is performed only when autoconf is run from the # directory where the configure.ac resides; if it is run from a different # directory, the check is skipped. for line in InitMacroFooter._TEMPLATE_: yield line.format(macro_prefix=self.macro_prefix) class InitMacroDone(InitMacro): """few statements AFTER the gl_INIT macro""" _TEMPLATE_ = ( "", "# Like AC_LIBOBJ, except that the module name goes", "# into {macro_prefix}_LIBOBJS instead of into LIBOBJS.", "AC_DEFUN([{macro_prefix}_LIBOBJ], [", " AS_LITERAL_IF([$1], [{macro_prefix}_LIBSOURCES([$1.c])])dnl", " {macro_prefix}_LIBOBJS=\"${macro_prefix}_LIBOBJS $1.$ac_objext\"", "])", "", "# Like AC_REPLACE_FUNCS, except that the module name goes", "# into {macro_prefix}_LIBOBJS instead of into LIBOBJS.", "AC_DEFUN([{macro_prefix}_REPLACE_FUNCS], [", " m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl", " AC_CHECK_FUNCS([$1], , [{macro_prefix}_LIBOBJ($ac_func)])", "])", "", "# Like AC_LIBSOURCES, except the directory where the source file is", "# expected is derived from the gnulib-tool parameterization,", "# and alloca is special cased (for the alloca-opt module).", "# We could also entirely rely on EXTRA_lib..._SOURCES.", "AC_DEFUN([{macro_prefix}_LIBSOURCES], [", " m4_foreach([_gl_NAME], [$1], [", " m4_if(_gl_NAME, [alloca.c], [], [", " m4_define([{macro_prefix}_LIBSOURCES_DIR], [{source_base}])", " m4_append([{macro_prefix}_LIBSOURCES_LIST], _gl_NAME, [ ])", " ])", " ])", "])", ) def __init__(self, config, source_base=None, macro_prefix=None): if source_base is None: source_base = config.source_base if not isinstance(source_base, str): raise TypeError("source_base must be of str type") super().__init__(config=config, macro_prefix=macro_prefix) self.__source_base = source_base @property def source_base(self): """directory relative to ROOT where source code is placed; defaults to 'lib'""" return self.__source_base def __repr__(self): fmt = "pygnulib.generator.InitMacroDone(source_base=%r, macro_prefix=%r)" return fmt % (self.source_base, self.macro_prefix) def __iter__(self): for line in InitMacroDone._TEMPLATE_: yield line.format(source_base=self.__source_base, macro_prefix=self.macro_prefix)