# Copyright (C) 2002-2023 Free Software Foundation, Inc.
#
# This program 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 program 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 program.  If not, see <https://www.gnu.org/licenses/>.

#===============================================================================
# Define global imports
#===============================================================================
import os
import re
import codecs
import subprocess as sp
from . import constants
from .GLInfo import GLInfo
from .GLConfig import GLConfig
from .GLModuleSystem import GLModule
from .GLModuleSystem import GLModuleTable
from .GLMakefileTable import GLMakefileTable
from .GLFileSystem import GLFileAssistant


#===============================================================================
# Define module information
#===============================================================================
__author__ = constants.__author__
__license__ = constants.__license__
__copyright__ = constants.__copyright__


#===============================================================================
# Define global constants
#===============================================================================
TESTS = constants.TESTS
joinpath = constants.joinpath
relinverse = constants.relinverse
isfile = os.path.isfile
normpath = os.path.normpath


#===============================================================================
# Define GLEmiter class
#===============================================================================
class GLEmiter(object):
    '''This class is used to emit the contents of necessary files.'''

    def __init__(self, config):
        '''GLEmiter.__init__(config) -> GLEmiter

        Create GLEmiter instance.'''
        self.info = GLInfo()
        if type(config) is not GLConfig:
            raise TypeError('config must be a GLConfig, not %s'
                            % type(config).__name__)
        self.config = config

    def __repr__(self):
        '''x.__repr__() <==> repr(x)'''
        result = '<pygnulib.GLEmiter %s>' % hex(id(self))
        return result

    def copyright_notice(self):
        '''GLEmiter.copyright_notice() -> str

        Emit a header for a generated file.'''
        emit = "# %s" % self.info.copyright()
        emit += """
#
# 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 <https://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.\n"""
        return emit

    def autoconfSnippet(self, module, toplevel,
                        disable_libtool, disable_gettext, replace_auxdir, indentation):
        '''GLEmiter.autoconfSnippet(module, toplevel,
          disable_libtool, disable_gettext, replace_auxdir, indentation) -> str

        Emit the autoconf snippet of a module.
        GLConfig: include_guard_prefix.

        module is a GLModule instance, which is processed.
        toplevel is a bool variable, False means a subordinate use of pygnulib.
        disable_libtool is a bool variable; it tells whether to disable libtool
          handling even if it has been specified through the GLConfig class.
        disable_gettext is a bool variable; it tells whether to disable
          AM_GNU_GETTEXT invocations.
        replace_auxdir is a bool variable; it tells whether to replace
          'build-aux' directory in AC_CONFIG_FILES.
        indentation is a string which contain spaces to prepend on each line.'''
        if type(module) is not GLModule:
            raise TypeError('module must be a GLModule, not %s'
                            % type(module).__name__)
        if type(toplevel) is not bool:
            raise TypeError('toplevel must be a bool, not %s'
                            % type(toplevel).__name__)
        if type(disable_libtool) is not bool:
            raise TypeError('disable_libtool must be a bool, not %s'
                            % type(disable_libtool).__name__)
        if type(disable_gettext) is not bool:
            raise TypeError('disable_gettext must be a bool, not %s'
                            % type(disable_gettext).__name__)
        if type(indentation) is not str:
            raise TypeError('indentation must be a string, not %s'
                            % type(indentation).__name__)
        if not indentation.isspace():
            raise ValueError('indentation must contain only whitespaces')
        auxdir = self.config['auxdir']
        libtool = self.config['libtool']
        include_guard_prefix = self.config['include_guard_prefix']
        emit = ''
        if str(module) in ['gnumakefile', 'maintainer-makefile']:
            # These modules are meant to be used only in the top-level directory.
            flag = toplevel
        else:  # if not str(module) in ['gnumakefile', 'maintainer-makefile']
            flag = True
        if flag:
            snippet = module.getAutoconfSnippet()
            snippet = snippet.replace('${gl_include_guard_prefix}',
                                      include_guard_prefix)
            lines = [ line
                      for line in snippet.split('\n')
                      if line.strip() ]
            snippet = '%s\n' % '\n'.join(lines)
            pattern = re.compile('^(.*)$', re.M)
            snippet = pattern.sub('%s\\1' % indentation, snippet)
            if disable_libtool:
                snippet = snippet.replace('$gl_cond_libtool', 'false')
                snippet = snippet.replace('gl_libdeps', 'gltests_libdeps')
                snippet = snippet.replace('gl_ltlibdeps', 'gltests_ltlibdeps')
            if disable_gettext:
                snippet = snippet.replace('AM_GNU_GETTEXT([external])',
                                          'dnl you must add AM_GNU_GETTEXT([external]) or similar to configure.ac.')
            else:
                # Don't indent AM_GNU_GETTEXT_VERSION line, as that confuses
                # autopoint through at least GNU gettext version 0.18.2.
                snippet = re.compile('^ *AM_GNU_GETTEXT_VERSION', re.M).sub('AM_GNU_GETTEXT_VERSION', snippet)
            emit += snippet
            if str(module) == 'alloca' and libtool and not disable_libtool:
                emit += 'changequote(,)dnl\n'
                emit += "LTALLOCA=`echo \"$ALLOCA\" | sed -e 's/\\.[^.]* /.lo /g;s/\\.[^.]*$/.lo/'`\n"
                emit += 'changequote([, ])dnl\n'
                emit += 'AC_SUBST([LTALLOCA])'
            if replace_auxdir:
                regex = 'AC_CONFIG_FILES\\(\\[(.*)\\:build-aux/(.*)\\]\\)'
                repl = 'AC_CONFIG_FILES([\\1:%s/\\2])' % auxdir
                pattern = re.compile(regex, re.M)
                emit = pattern.sub(repl, emit)
        lines = [ line
                  for line in emit.split('\n')
                  if line.strip() ]
        emit = '%s\n' % '\n'.join(lines)
        return emit

    def autoconfSnippets(self, modules, moduletable,
                         verifier, toplevel, disable_libtool, disable_gettext, replace_auxdir):
        '''GLEmiter.autoconfSnippets(modules,
          verifier, toplevel, disable_libtool, disable_gettext, replace_auxdir) -> str

        Collect and emit the autoconf snippets of a set of modules.
        GLConfig: conddeps.

        basemodules argument represents list of modules; every module in this list
          must be a GLModule instance; this list of modules is used to sort all
          modules after they were processed.
        modules argument represents list of modules; every module in this list must
          be a GLModule instance.
        moduletable is a GLModuleTable instance, which contains necessary
          information about dependencies of the modules.
        verifier is an integer, which can be 0, 1 or 2.
          if verifier == 0, then process every module;
          if verifier == 1, then process only non-tests modules;
          if verifier == 2, then process only tests modules.
        toplevel is a bool variable, False means a subordinate use of pygnulib.
        disable_libtool is a bool variable; it tells whether to disable libtool
          handling even if it has been specified through the GLConfig class.
        disable_gettext is a bool variable; it tells whether to disable
          AM_GNU_GETTEXT invocations.
        replace_auxdir is a bool variable; it tells whether to replace
          'build-aux' directory in AC_CONFIG_FILES.'''
        for module in modules:
            if type(module) is not GLModule:
                raise TypeError('each module must be a GLModule instance')
        if type(moduletable) is not GLModuleTable:
            raise TypeError('moduletable must be a GLFileAssistant, not %s'
                            % type(moduletable).__name__)
        if type(verifier) is not int:
            raise TypeError('verifier must be an int, not %s'
                            % type(verifier).__name__)
        if not (0 <= verifier <= 2):
            raise ValueError('verifier must be 0, 1 or 2, not %d' % verifier)
        if type(toplevel) is not bool:
            raise TypeError('toplevel must be a bool, not %s'
                            % type(toplevel).__name__)
        if type(disable_libtool) is not bool:
            raise TypeError('disable_libtool must be a bool, not %s'
                            % type(disable_libtool).__name__)
        if type(disable_gettext) is not bool:
            raise TypeError('disable_gettext must be a bool, not %s'
                            % type(disable_gettext).__name__)
        if type(replace_auxdir) is not bool:
            raise TypeError('replace_auxdir must be a bool, not %s'
                            % type(replace_auxdir).__name__)
        auxdir = self.config['auxdir']
        conddeps = self.config['conddeps']
        macro_prefix = self.config['macro_prefix']
        emit = ''
        if not conddeps:
            # Ignore the conditions, and enable all modules unconditionally.
            for module in modules:
                if verifier == 0:
                    solution = True
                elif verifier == 1:
                    solution = module.isNonTests()
                elif verifier == 2:
                    solution = module.isTests()
                if solution:
                    emit += self.autoconfSnippet(module, toplevel,
                                                 disable_libtool, disable_gettext, replace_auxdir, '  ')
        else:  # if conddeps
            # Emit the autoconf code for the unconditional modules.
            for module in modules:
                if verifier == 0:
                    solution = True
                elif verifier == 1:
                    solution = module.isNonTests()
                elif verifier == 2:
                    solution = module.isTests()
                if solution:
                    if not moduletable.isConditional(module):
                        emit += self.autoconfSnippet(module, toplevel,
                                                     disable_libtool, disable_gettext, replace_auxdir, '  ')
            # Initialize the shell variables indicating that the modules are enabled.
            for module in modules:
                if verifier == 0:
                    solution = True
                elif verifier == 1:
                    solution = module.isNonTests()
                elif verifier == 2:
                    solution = module.isTests()
                if solution:
                    if moduletable.isConditional(module):
                        shellvar = module.getShellVar()
                        emit += '  %s=false\n' % module.getShellVar()
            # Emit the autoconf code for the conditional modules, each in a separate
            # function. This makes it possible to support cycles among conditional
            # modules.
            for module in modules:
                if verifier == 0:
                    solution = True
                elif verifier == 1:
                    solution = module.isNonTests()
                elif verifier == 2:
                    solution = module.isTests()
                if solution:
                    if moduletable.isConditional(module):
                        shellfunc = module.getShellFunc()
                        shellvar = module.getShellVar()
                        emit += '  %s ()\n' % shellfunc
                        emit += '  {\n'
                        emit += '    if ! $%s; then\n' % shellvar
                        emit += self.autoconfSnippet(module, toplevel,
                                                     disable_libtool, disable_gettext, replace_auxdir, '      ')
                        emit += '      %s=true\n' % shellvar
                        depmodules = module.getDependenciesWithoutConditions()
                        # Intersect dependencies with the modules list.
                        depmodules = [ dep
                                       for dep in depmodules
                                       if dep in modules ]   # TODO should this be basemodules or modules?
                        for depmodule in depmodules:
                            if moduletable.isConditional(depmodule):
                                shellfunc = depmodule.getShellFunc()
                                condition = moduletable.getCondition(module, depmodule)
                                if condition != None:
                                    emit += '  if %s; then\n' % condition
                                    emit += '    %s\n' % shellfunc
                                    emit += '  fi\n'
                                else:  # if condition == None
                                    emit += '  %s\n' % shellfunc
                            # if not moduletable.isConditional(depmodule)
                            else:
                                # The autoconf code for $dep has already been emitted above and
                                # therefore is already executed when this code is run.
                                pass
                        emit += '    fi\n'
                        emit += '  }\n'
            # Emit the dependencies from the unconditional to the conditional modules.
            for module in modules:
                if verifier == 0:
                    solution = True
                elif verifier == 1:
                    solution = module.isNonTests()
                elif verifier == 2:
                    solution = module.isTests()
                if solution:
                    if not moduletable.isConditional(module):
                        depmodules = module.getDependenciesWithoutConditions()
                        # Intersect dependencies with the modules list.
                        depmodules = [ dep
                                       for dep in depmodules
                                       if dep in modules ]   # TODO should this be basemodules or modules?
                        for depmodule in depmodules:
                            if moduletable.isConditional(depmodule):
                                shellfunc = depmodule.getShellFunc()
                                condition = moduletable.getCondition(module, depmodule)
                                if condition != None:
                                    emit += '  if %s; then\n' % condition
                                    emit += '    %s\n' % shellfunc
                                    emit += '  fi\n'
                                else:  # if condition == None
                                    emit += '  %s\n' % shellfunc
                            # if not moduletable.isConditional(depmodule)
                            else:
                                # The autoconf code for $dep has already been emitted above and
                                # therefore is already executed when this code is run.
                                pass
            # Define the Automake conditionals.
            emit += '  m4_pattern_allow([^%s_GNULIB_ENABLED_])\n' % macro_prefix
            for module in modules:
                if verifier == 0:
                    solution = True
                elif verifier == 1:
                    solution = module.isNonTests()
                elif verifier == 2:
                    solution = module.isTests()
                if solution:
                    if moduletable.isConditional(module):
                        condname = module.getConditionalName()
                        shellvar = module.getShellVar()
                        emit += '  AM_CONDITIONAL([%s], [$%s])\n' % (condname, shellvar)
        lines = [ line
                  for line in emit.split('\n')
                  if line.strip() ]
        emit = '%s\n' % '\n'.join(lines)
        return emit

    def preEarlyMacros(self, require, indentation, modules):
        '''GLEmiter.preEarlyMacros(require, indentation, modules) -> str

        Collect and emit the pre-early section.

        require parameter can be True (AC_REQUIRE) or False (direct call).
        indentation parameter is a string.
        modules argument represents list of modules; every module in this list must
          be a GLModule instance.'''
        emit = '\n' + indentation + '# Pre-early section.\n'
        # We need to call gl_USE_SYSTEM_EXTENSIONS before gl_PROG_AR_RANLIB.
        # Doing AC_REQUIRE in configure-ac.early is not early enough.
        if any(str(module) == 'extensions' for module in modules):
            if require:
                emit += indentation + 'AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])\n'
            else:
                emit += indentation + 'gl_USE_SYSTEM_EXTENSIONS\n'
        if require:
            emit += indentation + 'AC_REQUIRE([gl_PROG_AR_RANLIB])\n'
        else:
            emit += indentation + 'gl_PROG_AR_RANLIB\n'
        emit += '\n'
        return emit

    def po_Makevars(self):
        '''GLEmiter.po_Makevars() -> str

        Emit the contents of po/ makefile parameterization.
        GLConfig: pobase, podomain.'''
        pobase = self.config['pobase']
        podomain = self.config['podomain']
        emit = ''
        emit += "## DO NOT EDIT! GENERATED AUTOMATICALLY!\n"
        emit += "%s\n" % self.copyright_notice()
        emit += "# Usually the message domain is the same as the package name.\n"
        emit += "# But here it has a '-gnulib' suffix.\n"
        emit += "DOMAIN = %s-gnulib\n\n" % podomain
        emit += "# These two variables depend on the location of this directory.\n"
        emit += "subdir = %s\n" % pobase
        emit += "top_builddir = %s\n" % relinverse(pobase)
        emit += """
# 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. See the gettext manual, section Names."' \\
  --keyword='proper_name_utf8:1,"This is a proper name. 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\n"""
        return emit

    def po_POTFILES_in(self, files):
        '''GLEmiter.po_POTFILES_in(files) -> str

        Emit the file list to be passed to xgettext.
        GLConfig: sourcebase.'''
        sourcebase = self.config['sourcebase'] + os.path.sep
        emit = ''
        emit += "## DO NOT EDIT! GENERATED AUTOMATICALLY!\n"
        emit += "%s\n" % self.copyright_notice()
        emit += "# List of files which contain translatable strings.\n"
        for file in files:
            if file.startswith('lib/'):
                emit += '%s\n' % constants.substart('lib/', sourcebase, file)
        return emit

    def initmacro_start(self, macro_prefix_arg):
        '''GLEmiter.initmacro_start(macro_prefix_arg) -> str

        Emit the first few statements of the gl_INIT macro.'''
        if type(macro_prefix_arg) is not str:
            raise TypeError('macro_prefix_arg must be a string, not %s'
                            % type(macro_prefix_arg).__name__)
        module_indicator_prefix = self.config.getModuleIndicatorPrefix()
        emit = ''
        # 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.
        emit += "  m4_pushdef([AC_LIBOBJ], m4_defn([%s_LIBOBJ]))\n" % macro_prefix_arg
        emit += "  m4_pushdef([AC_REPLACE_FUNCS], m4_defn([%s_REPLACE_FUNCS]))\n" % macro_prefix_arg
        # 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.
        emit += "  m4_pushdef([AC_LIBSOURCES], m4_defn([%s_LIBSOURCES]))\n" % macro_prefix_arg
        # 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.
        emit += "  m4_pushdef([%s_LIBSOURCES_LIST], [])\n" % macro_prefix_arg
        emit += "  m4_pushdef([%s_LIBSOURCES_DIR], [])\n" % macro_prefix_arg
        # Scope for m4 macros.
        emit += "  m4_pushdef([GL_MACRO_PREFIX], [%s])\n" % macro_prefix_arg
        # Scope the GNULIB_<modulename> variables.
        emit += "  m4_pushdef([GL_MODULE_INDICATOR_PREFIX], [%s])\n" % module_indicator_prefix
        emit += "  gl_COMMON\n"
        return emit

    def initmacro_end(self, macro_prefix_arg):
        '''GLEmiter.initmacro_end(macro_prefix_arg) -> str

        Emit the last few statements of the gl_INIT macro.'''
        if type(macro_prefix_arg) is not str:
            raise TypeError('macro_prefix_arg must be a string, not %s'
                            % type(macro_prefix_arg).__name__)
        emit = ''
        # 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.
        emit += r"""\
  m4_ifval(%V1%_LIBSOURCES_LIST, [
    m4_syscmd([test ! -d ]m4_defn([%V1%_LIBSOURCES_DIR])[ ||
      for gl_file in ]%V1%_LIBSOURCES_LIST[ ; do
        if test ! -r ]m4_defn([%V1%_LIBSOURCES_DIR])[/$gl_file ; then
          echo "missing file ]m4_defn([%V1%_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([GL_MODULE_INDICATOR_PREFIX])
  m4_popdef([GL_MACRO_PREFIX])
  m4_popdef([%V1%_LIBSOURCES_DIR])
  m4_popdef([%V1%_LIBSOURCES_LIST])
  m4_popdef([AC_LIBSOURCES])
  m4_popdef([AC_REPLACE_FUNCS])
  m4_popdef([AC_LIBOBJ])
  AC_CONFIG_COMMANDS_PRE([
    %V1%_libobjs=
    %V1%_ltlibobjs=
    if test -n "$%V1%_LIBOBJS"; then
      # Remove the extension.
      sed_drop_objext='s/\.o$//;s/\.obj$//'
      for i in `for i in $%V1%_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do
        %V1%_libobjs="$%V1%_libobjs $i.$ac_objext"
        %V1%_ltlibobjs="$%V1%_ltlibobjs $i.lo"
      done
    fi
    AC_SUBST([%V1%_LIBOBJS], [$%V1%_libobjs])
    AC_SUBST([%V1%_LTLIBOBJS], [$%V1%_ltlibobjs])
  ])\n"""
        emit = emit.replace('%V1%', macro_prefix_arg)
        return emit

    def initmacro_done(self, macro_prefix_arg, sourcebase_arg):
        '''GLEmiter.initmacro_done(macro_prefix_arg, sourcebase_arg) -> str

        Emit a few statements after the gl_INIT macro.
        GLConfig: sourcebase.'''
        if type(macro_prefix_arg) is not str:
            raise TypeError('macro_prefix_arg must be a string, not %s'
                            % type(macro_prefix_arg).__name__)
        if type(sourcebase_arg) is not str:
            raise TypeError('sourcebase_arg must be a string, not %s'
                            % type(sourcebase_arg).__name__)
        emit = ''
        emit += """\

# Like AC_LIBOBJ, except that the module name goes
# into %V1%_LIBOBJS instead of into LIBOBJS.
AC_DEFUN([%V1%_LIBOBJ], [
  AS_LITERAL_IF([$1], [%V1%_LIBSOURCES([$1.c])])dnl
  %V1%_LIBOBJS="$%V1%_LIBOBJS $1.$ac_objext"
])

# Like AC_REPLACE_FUNCS, except that the module name goes
# into %V1%_LIBOBJS instead of into LIBOBJS.
AC_DEFUN([%V1%_REPLACE_FUNCS], [
  m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl
  AC_CHECK_FUNCS([$1], , [%V1%_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([%V1%_LIBSOURCES], [
  m4_foreach([_gl_NAME], [$1], [
    m4_if(_gl_NAME, [alloca.c], [], [
      m4_define([%V1%_LIBSOURCES_DIR], [%V2%])
      m4_append([%V1%_LIBSOURCES_LIST], _gl_NAME, [ ])
    ])
  ])
])\n"""
        emit = emit.replace('%V1%', macro_prefix_arg)
        emit = emit.replace('%V2%', sourcebase_arg)
        return emit

    def lib_Makefile_am(self, destfile, modules,
                        moduletable, makefiletable, actioncmd, for_test):
        '''GLEmiter.lib_Makefile_am(destfile, modules, moduletable, makefiletable,
             actioncmd, for_test) -> tuple of str and bool

        Emit the contents of the library Makefile. Returns str and a bool
        variable which shows if subdirectories are used.
        GLConfig: localpath, sourcebase, libname, pobase, auxdir, makefile_name, libtool,
        macro_prefix, podomain, conddeps, witness_c_macro.

        destfile is a filename relative to destdir of Makefile being generated.
        modules is a list of GLModule instances.
        moduletable is a GLModuleTable instance.
        makefiletable is a GLMakefileTable instance.
        actioncmd is a string variable, which represents the actioncmd; it can be
          an empty string e.g. when user wants to generate files for GLTestDir.
        for_test is a bool variable; it must be set to True if creating a package
          for testing, False otherwise.'''
        if type(destfile) is not str:
            raise TypeError('destfile must be a string, not %s'
                            % type(destfile).__name__)
        for module in modules:
            if type(module) is not GLModule:
                raise TypeError('each module must be a GLModule instance')
        if type(moduletable) is not GLModuleTable:
            raise TypeError('moduletable must be a GLModuleTable, not %s'
                            % type(moduletable).__name__)
        if type(makefiletable) is not GLMakefileTable:
            raise TypeError('makefiletable must be a GLMakefileTable, not %s'
                            % type(makefiletable).__name__)
        if type(actioncmd) is not str:
            raise TypeError('actioncmd must be a string, not %s'
                            % type(actioncmd).__name__)
        if type(for_test) is not bool:
            raise TypeError('for_test must be a bool, not %s'
                            % type(for_test).__name__)
        sourcebase = self.config['sourcebase']
        libname = self.config['libname']
        pobase = self.config['pobase']
        auxdir = self.config['auxdir']
        makefile_name = self.config['makefile_name']
        libtool = self.config['libtool']
        macro_prefix = self.config['macro_prefix']
        podomain = self.config['podomain']
        conddeps = self.config['conddeps']
        witness_c_macro = self.config['witness_c_macro']
        include_guard_prefix = self.config['include_guard_prefix']
        module_indicator_prefix = self.config.getModuleIndicatorPrefix()
        ac_version = self.config['ac_version']
        destfile = os.path.normpath(destfile)
        emit = ''

        # When creating an includable Makefile.am snippet, augment variables with
        # += instead of assigning them.
        if makefile_name:
            assign = '+='
        else:  # if not makefile_name
            assign = '='
        if libtool:
            libext = 'la'
            perhapsLT = 'LT'
            eliminate_LDFLAGS = False
        else:  # if not libtool
            libext = 'a'
            perhapsLT = ''
            eliminate_LDFLAGS = True
        if for_test:
            # When creating a package for testing: Attempt to provoke failures,
            # especially link errors, already during "make" rather than during
            # "make check", because "make check" is not possible in a cross-compiling
            # situation. Turn check_PROGRAMS into noinst_PROGRAMS.
            edit_check_PROGRAMS = True
        else:  # if not for_test
            edit_check_PROGRAMS = False
        emit += "## DO NOT EDIT! GENERATED AUTOMATICALLY!\n"
        emit += "## Process this file with automake to produce Makefile.in.\n"
        emit += self.copyright_notice()
        if actioncmd:
            # The maximum line length (excluding the terminating newline) of
            # any file that is to be preprocessed by config.status is 3070.
            # config.status uses awk, and the HP-UX 11.00 awk fails if a line
            # has length >= 3071; similarly, the IRIX 6.5 awk fails if a line
            # has length >= 3072.
            if len(actioncmd) <= 3000:
                emit += "# Reproduce by: %s\n" % actioncmd
        emit += '\n'
        uses_subdirs = False

        # Compute allsnippets variable.
        allsnippets = ''
        for module in modules:
            if not module.isTests():
                # Get conditional snippet, edit it and save to amsnippet1.
                amsnippet1 = module.getAutomakeSnippet_Conditional()
                amsnippet1 = amsnippet1.replace('lib_LIBRARIES', 'lib%_LIBRARIES')
                amsnippet1 = amsnippet1.replace('lib_LTLIBRARIES', 'lib%_LTLIBRARIES')
                if eliminate_LDFLAGS:
                    pattern = re.compile('^(lib_LDFLAGS[\t ]*\\+=.*$\n)', re.M)
                    amsnippet1 = pattern.sub('', amsnippet1)
                pattern = re.compile('lib_([A-Z][A-Z]*)', re.M)
                amsnippet1 = pattern.sub('%s_%s_\\1' % (libname, libext),
                                         amsnippet1)
                amsnippet1 = amsnippet1.replace('$(GNULIB_', '$(' + module_indicator_prefix + '_GNULIB_')
                amsnippet1 = amsnippet1.replace('lib%_LIBRARIES', 'lib_LIBRARIES')
                amsnippet1 = amsnippet1.replace('lib%_LTLIBRARIES', 'lib_LTLIBRARIES')
                if edit_check_PROGRAMS:
                    amsnippet1 = amsnippet1.replace('check_PROGRAMS', 'noinst_PROGRAMS')
                amsnippet1 = amsnippet1.replace('${gl_include_guard_prefix}',
                                                include_guard_prefix)
                if str(module) == 'alloca':
                    amsnippet1 += '%s_%s_LIBADD += @%sALLOCA@\n' % (libname, libext, perhapsLT)
                    amsnippet1 += '%s_%s_DEPENDENCIES += @%sALLOCA@\n' % (libname, libext, perhapsLT)
                amsnippet1 = constants.combine_lines_matching(re.compile('%s_%s_SOURCES' % (libname, libext)),
                                                              amsnippet1)

                # Get unconditional snippet, edit it and save to amsnippet2.
                amsnippet2 = module.getAutomakeSnippet_Unconditional()
                pattern = re.compile('lib_([A-Z][A-Z]*)', re.M)
                amsnippet2 = pattern.sub('%s_%s_\\1' % (libname, libext),
                                         amsnippet2)
                amsnippet2 = amsnippet2.replace('$(GNULIB_',
                                                '$(' + module_indicator_prefix + '_GNULIB_')
                # Skip the contents if it's entirely empty.
                if not (amsnippet1 + amsnippet2).isspace():
                    allsnippets += '## begin gnulib module %s\n\n' % str(module)
                    if conddeps:
                        if moduletable.isConditional(module):
                            name = module.getConditionalName()
                            allsnippets += 'if %s\n' % name
                    allsnippets += amsnippet1
                    if conddeps:
                        if moduletable.isConditional(module):
                            allsnippets += 'endif\n'
                    allsnippets += amsnippet2
                    allsnippets += '## end   gnulib module %s\n\n' % str(module)

                    # Test whether there are some source files in subdirectories.
                    for file in module.getFiles():
                        if (file.startswith('lib/')
                                and file.endswith('.c')
                                and file.count('/') > 1):
                            uses_subdirs = True
                            break

        if not makefile_name:
            subdir_options = ''
            # If there are source files in subdirectories, prevent collision of the
            # object files (example: hash.c and libxml/hash.c).
            if uses_subdirs:
                subdir_options = ' subdir-objects'
            emit += 'AUTOMAKE_OPTIONS = 1.9.6 gnits%s\n' % subdir_options
        emit += '\n'
        if not makefile_name:
            emit += 'SUBDIRS =\n'
            emit += 'noinst_HEADERS =\n'
            emit += 'noinst_LIBRARIES =\n'
            emit += 'noinst_LTLIBRARIES =\n'
            # Automake versions < 1.11.4 create an empty pkgdatadir at
            # installation time if you specify pkgdata_DATA to empty.
            # See automake bugs #10997 and #11030:
            #  * https://debbugs.gnu.org/10997
            #  * https://debbugs.gnu.org/11030
            # So we need this workaround.
            pattern = re.compile('^pkgdata_DATA *\\+=', re.M)
            if pattern.findall(allsnippets):
                emit += 'pkgdata_DATA =\n'
            emit += 'EXTRA_DIST =\n'
            emit += 'BUILT_SOURCES =\n'
            emit += 'SUFFIXES =\n'
        emit += 'MOSTLYCLEANFILES %s core *.stackdump\n' % assign
        if not makefile_name:
            emit += 'MOSTLYCLEANDIRS =\n'
            emit += 'CLEANFILES =\n'
            emit += 'DISTCLEANFILES =\n'
            emit += 'MAINTAINERCLEANFILES =\n'

        # Execute edits that apply to the Makefile.am being generated.
        for current_edit in range(0, makefiletable.count()):
            dictionary = makefiletable[current_edit]
            if dictionary['var']:
                if destfile == joinpath(dictionary['dir'], 'Makefile.am'):
                    emit += '%s += %s\n' % (dictionary['var'], dictionary['val'])
                    dictionary.pop('var')

        # Define two parts of cppflags variable.
        cppflags_part1 = ''
        if witness_c_macro:
            cppflags_part1 = ' -D%s=1' % witness_c_macro
        cppflags_part2 = ''
        if for_test:
            cppflags_part2 = ' -DGNULIB_STRICT_CHECKING=1'
        cppflags = '%s%s' % (cppflags_part1, cppflags_part2)
        if not makefile_name:
            emit += '\n'
            emit += 'AM_CPPFLAGS =%s\n' % cppflags
            emit += 'AM_CFLAGS =\n'
        else:  # if makefile_name
            if cppflags:
                emit += '\n'
                emit += 'AM_CPPFLAGS +=%s\n' % cppflags
        emit += '\n'

        # Test if one of the snippets or the user's Makefile.am already specifies an
        # installation location for the library. Don't confuse automake by saying
        # it should not be installed.
        # First test if allsnippets already specify an installation location.
        lib_gets_installed = False
        regex = '^[a-zA-Z0-9_]*_%sLIBRARIES *\\+{0,1}= *%s\\.%s' % (perhapsLT, libname, libext)
        pattern = re.compile(regex, re.M)
        if pattern.findall(allsnippets):
            lib_gets_installed = True
        else:
            # Then test if $sourcebase/Makefile.am (if it exists) specifies it.
            if makefile_name:
                path = joinpath(sourcebase, 'Makefile.am')
                if isfile(path):
                    with codecs.open(path, 'rb', 'UTF-8') as file:
                        data = file.read()
                    if pattern.findall(data):
                        lib_gets_installed = True
        if not lib_gets_installed:
            # By default, the generated library should not be installed.
            emit += 'noinst_%sLIBRARIES += %s.%s\n' % (perhapsLT, libname, libext)

        emit += '\n'
        emit += '%s_%s_SOURCES =\n' % (libname, libext)
        # Here we use $(LIBOBJS), not @LIBOBJS@. The value is the same. However,
        # automake during its analysis looks for $(LIBOBJS), not for @LIBOBJS@.
        emit += '%s_%s_LIBADD = $(%s_%sLIBOBJS)\n' % (libname, libext, macro_prefix, perhapsLT)
        emit += '%s_%s_DEPENDENCIES = $(%s_%sLIBOBJS)\n' % (libname, libext, macro_prefix, perhapsLT)
        emit += 'EXTRA_%s_%s_SOURCES =\n' % (libname, libext)
        if libtool:
            emit += '%s_%s_LDFLAGS = $(AM_LDFLAGS)\n' % (libname, libext)
            emit += '%s_%s_LDFLAGS += -no-undefined\n' % (libname, libext)
            # Synthesize an ${libname}_${libext}_LDFLAGS augmentation by combining
            # the link dependencies of all modules.
            links = [ module.getLink()
                      for module in modules
                      if not module.isTests() ]
            lines = [ line
                      for link in links
                      for line in link.split('\n')
                      if line != '' ]
            pattern = re.compile(' when linking with libtool.*')
            lines = [ pattern.sub('', line)
                      for line in lines ]
            lines = sorted(set(lines))
            for line in lines:
                emit += '%s_%s_LDFLAGS += %s\n' % (libname, libext, line)
        emit += '\n'
        if pobase:
            emit += 'AM_CPPFLAGS += -DDEFAULT_TEXT_DOMAIN=\\"%s-gnulib\\"\n' % podomain
            emit += '\n'
        allsnippets = allsnippets.replace('$(top_srcdir)/build-aux/',
                                          '$(top_srcdir)/%s/' % auxdir)
        emit += allsnippets
        emit += '\n'
        emit += 'mostlyclean-local: mostlyclean-generic\n'
        emit += '\t@for dir in \'\' $(MOSTLYCLEANDIRS); do \\\n'
        emit += '\t  if test -n "$$dir" && test -d $$dir; then \\\n'
        emit += '\t    echo "rmdir $$dir"; rmdir $$dir; \\\n'
        emit += '\t  fi; \\\n'
        emit += '\tdone; \\\n'
        emit += '\t:\n'
        result = tuple([emit, uses_subdirs])
        return result

    def tests_Makefile_am(self, destfile, modules, makefiletable,
                          witness_macro, for_test):
        '''GLEmiter.tests_Makefile_am(destfile, modules, makefiletable,
             witness_c_macro, for_test) -> tuple of string and bool

        Emit the contents of the tests Makefile. Returns str and a bool variable
        which shows if subdirectories are used.
        GLConfig: localpath, modules, libname, auxdir, makefile_name, libtool,
        sourcebase, m4base, testsbase, macro_prefix, witness_c_macro,
        single_configure, libtests.

        destfile is a filename relative to destdir of Makefile being generated.
        witness_macro is a string which represents witness_c_macro with the suffix.
        modules is a list of GLModule instances.
        moduletable is a GLModuleTable instance.
        makefiletable is a GLMakefileTable instance.
        actioncmd is a string variable, which represents the actioncmd; it can be
          an empty string e.g. when user wants to generate files for GLTestDir.
        for_test is a bool variable; it must be set to True if creating a package
          for testing, False otherwise.'''
        if type(destfile) is not str:
            raise TypeError('destfile must be a string, not %s'
                            % type(destfile).__name__)
        for module in modules:
            if type(module) is not GLModule:
                raise TypeError('each module must be a GLModule instance')
        if type(makefiletable) is not GLMakefileTable:
            raise TypeError('makefiletable must be a GLMakefileTable, not %s'
                            % type(makefiletable).__name__)
        if type(witness_macro) is not str:
            raise TypeError('witness_macro must be a string, not %s'
                            % type(witness_macro).__name__)
        if type(for_test) is not bool:
            raise TypeError('for_test must be a bool, not %s'
                            % type(for_test).__name__)
        auxdir = self.config['auxdir']
        sourcebase = self.config['sourcebase']
        libname = self.config['libname']
        m4base = self.config['m4base']
        pobase = self.config['pobase']
        testsbase = self.config['testsbase']
        makefile_name = self.config['makefile_name']
        libtool = self.config['libtool']
        macro_prefix = self.config['macro_prefix']
        podomain = self.config['podomain']
        conddeps = self.config['conddeps']
        witness_c_macro = self.config['witness_c_macro']
        include_guard_prefix = self.config['include_guard_prefix']
        module_indicator_prefix = self.config.getModuleIndicatorPrefix()
        ac_version = self.config['ac_version']
        libtests = self.config['libtests']
        single_configure = self.config['single_configure']
        emit = ''

        if libtool:
            libext = 'la'
            perhapsLT = 'LT'
            eliminate_LDFLAGS = False
        else:  # if not libtool
            libext = 'a'
            perhapsLT = ''
            eliminate_LDFLAGS = True
        if for_test:
            # When creating a package for testing: Attempt to provoke failures,
            # especially link errors, already during "make" rather than during
            # "make check", because "make check" is not possible in a cross-compiling
            # situation. Turn check_PROGRAMS into noinst_PROGRAMS.
            edit_check_PROGRAMS = True
        else:  # if not for_test
            edit_check_PROGRAMS = False

        # Compute testsbase_inverse
        testsbase_inverse = relinverse(testsbase)

        # Begin the generation.
        emit += "## DO NOT EDIT! GENERATED AUTOMATICALLY!\n"
        emit += "## Process this file with automake to produce Makefile.in.\n"
        emit += '%s\n' % self.copyright_notice()

        uses_subdirs = False
        main_snippets = ''
        longrun_snippets = ''
        for module in modules:
            if for_test and not single_configure:
                accept = module.isTests()
            else:  # if for_test and not single_configure
                accept = True
            if accept:
                snippet = module.getAutomakeSnippet()
                snippet = snippet.replace('lib_LIBRARIES', 'lib%_LIBRARIES')
                snippet = snippet.replace('lib_LTLIBRARIES', 'lib%_LTLIBRARIES')
                if eliminate_LDFLAGS:
                    pattern = re.compile('^(lib_LDFLAGS[\t ]*\\+=.*$\n)', re.M)
                    amsnippet1 = pattern.sub('', snippet)
                pattern = re.compile('lib_([A-Z][A-Z]*)', re.M)
                snippet = pattern.sub('libtests_a_\\1', snippet)
                snippet = snippet.replace('$(GNULIB_', '$(' + module_indicator_prefix + '_GNULIB_')
                snippet = snippet.replace('lib%_LIBRARIES', 'lib_LIBRARIES')
                snippet = snippet.replace('lib%_LTLIBRARIES', 'lib_LTLIBRARIES')
                if edit_check_PROGRAMS:
                    snippet = snippet.replace('check_PROGRAMS', 'noinst_PROGRAMS')
                snippet = snippet.replace('${gl_include_guard_prefix}',
                                          include_guard_prefix)
                # Check if module is 'alloca'.
                if libtests and str(module) == 'alloca':
                    snippet += 'libtests_a_LIBADD += @%sALLOCA@\n' % perhapsLT
                    snippet += 'libtests_a_DEPENDENCIES += @%sALLOCA@\n' % perhapsLT

                # Skip the contents if it's entirely empty.
                if not snippet.isspace():
                    snippet = ('## begin gnulib module %s\n\n' % str(module)
                               + snippet
                               + '## end   gnulib module %s\n\n' % str(module))
                    # Mention long-running tests at the end.
                    if 'longrunning-test' in module.getStatuses():
                        longrun_snippets += snippet
                    else:
                        main_snippets += snippet

                    # Test whether there are some source files in subdirectories.
                    for file in module.getFiles():
                        if ((file.startswith('lib/') or file.startswith('tests/'))
                                and file.endswith('.c')
                                and file.count('/') > 1):
                            uses_subdirs = True
                            break

        # Generate dependencies here, since it eases the debugging of test failures.
        # If there are source files in subdirectories, prevent collision of the
        # object files (example: hash.c and libxml/hash.c).
        subdir_options = ''
        if uses_subdirs:
            subdir_options = ' subdir-objects'
        emit += 'AUTOMAKE_OPTIONS = 1.9.6 foreign%s\n\n' % subdir_options
        if for_test and not single_configure:
            emit += 'ACLOCAL_AMFLAGS = -I %s/%s\n\n' % (testsbase_inverse, m4base)

        # Nothing is being added to SUBDIRS; nevertheless the existence of this
        # variable is needed to avoid an error from automake:
        #   "AM_GNU_GETTEXT used but SUBDIRS not defined"
        emit += 'SUBDIRS = .\n'
        emit += 'TESTS =\n'
        emit += 'XFAIL_TESTS =\n'
        emit += 'TESTS_ENVIRONMENT =\n'
        emit += 'noinst_PROGRAMS =\n'
        if not for_test:
            emit += 'check_PROGRAMS =\n'
        emit += 'noinst_HEADERS =\n'
        emit += 'noinst_LIBRARIES =\n'
        if libtests:
            if for_test:
                emit += 'noinst_LIBRARIES += libtests.a\n'
            else:  # if not for_test
                emit += 'check_LIBRARIES = libtests.a\n'

        # Automake versions < 1.11.4 create an empty pkgdatadir at
        # installation time if you specify pkgdata_DATA to empty.
        # See automake bugs #10997 and #11030:
        #  * https://debbugs.gnu.org/10997
        #  * https://debbugs.gnu.org/11030
        # So we need this workaround.
        pattern = re.compile('^pkgdata_DATA *\\+=', re.M)
        if pattern.findall(main_snippets) or pattern.findall(longrun_snippets):
            emit += 'pkgdata_DATA =\n'

        emit += 'EXTRA_DIST =\n'
        emit += 'BUILT_SOURCES =\n'
        emit += 'SUFFIXES =\n'
        emit += 'MOSTLYCLEANFILES = core *.stackdump\n'
        emit += 'MOSTLYCLEANDIRS =\n'
        emit += 'CLEANFILES =\n'
        emit += 'DISTCLEANFILES =\n'
        emit += 'MAINTAINERCLEANFILES =\n'

        # Execute edits that apply to the Makefile.am being generated.
        for current_edit in range(0, makefiletable.count()):
            dictionary = makefiletable[current_edit]
            if dictionary['var']:
                if destfile == joinpath(dictionary['dir'], 'Makefile.am'):
                    emit += '%s += %s\n' % (dictionary['var'], dictionary['val'])
                    dictionary.pop('var')

        emit += '\nAM_CPPFLAGS = \\\n'
        if for_test:
            emit += '  -DGNULIB_STRICT_CHECKING=1 \\\n'
        if witness_c_macro:
            emit += '  -D%s=1 \\\n' % witness_c_macro
        if witness_macro:
            emit += '  -D@%s@=1 \\\n' % witness_macro
        emit += '  -I. -I$(srcdir) \\\n'
        emit += '  -I%s -I$(srcdir)/%s \\\n' % (testsbase_inverse, testsbase_inverse)
        emit += '  -I%s/%s -I$(srcdir)/%s/%s\n' % (testsbase_inverse, sourcebase, testsbase_inverse, sourcebase)
        emit += '\n'

        ldadd_before = ''
        ldadd_after = ''
        if libtests:
            # All test programs need to be linked with libtests.a.
            # It needs to be passed to the linker before ${libname}.${libext},
            # since the tests-related modules depend on the main modules.
            # It also needs to be passed to the linker after ${libname}.${libext}
            # because the latter might contain incomplete modules (such as the
            # 'version-etc' module whose dependency to 'version-etc-fsf' is
            # voluntarily omitted).
            # The LIBTESTS_LIBDEPS can be passed to the linker once or twice, it
            # does not matter.
            ldadd_before = ' libtests.a'
            ldadd_after = ' libtests.a $(LIBTESTS_LIBDEPS)'
        emit += 'LDADD =%s %s/%s/%s.%s libtests.a %s/%s/%s.%s%s\n\n' \
                % (ldadd_before,
                   testsbase_inverse, sourcebase, libname, libext,
                   testsbase_inverse, sourcebase, libname, libext,
                   ldadd_after)
        if libtests:
            emit += 'libtests_a_SOURCES =\n'
            # Here we use $(LIBOBJS), not @LIBOBJS@. The value is the same. However,
            # automake during its analysis looks for $(LIBOBJS), not for @LIBOBJS@.
            emit += 'libtests_a_LIBADD = $(%stests_LIBOBJS)\n' % macro_prefix
            emit += 'libtests_a_DEPENDENCIES = $(%stests_LIBOBJS)\n' % macro_prefix
            emit += 'EXTRA_libtests_a_SOURCES =\n'
            # The circular dependency in LDADD requires this.
            emit += 'AM_LIBTOOLFLAGS = --preserve-dup-deps\n\n'
        # Many test scripts use ${EXEEXT} or ${srcdir}.
        # EXEEXT is defined by AC_PROG_CC through autoconf.
        # srcdir is defined by autoconf and automake.
        emit += "TESTS_ENVIRONMENT += EXEEXT='@EXEEXT@' srcdir='$(srcdir)'\n\n"
        all_snippets = main_snippets + longrun_snippets
        all_snippets = all_snippets.replace('$(top_srcdir)/build-aux/',
                                            '$(top_srcdir)/%s/' % auxdir)
        emit += all_snippets
        emit += '# Clean up after Solaris cc.\n'
        emit += 'clean-local:\n'
        emit += '\trm -rf SunWS_cache\n\n'
        emit += 'mostlyclean-local: mostlyclean-generic\n'
        emit += '\t@for dir in \'\' $(MOSTLYCLEANDIRS); do \\\n'
        emit += '\t  if test -n "$$dir" && test -d $$dir; then \\\n'
        emit += '\t    echo "rmdir $$dir"; rmdir $$dir; \\\n'
        emit += '\t  fi; \\\n'
        emit += '\tdone; \\\n'
        emit += '\t:\n'
        result = tuple([emit, uses_subdirs])
        return result
