changeset 38811:5cdae0d43261

[pygnulib] initial merge (including some small bug fixes)
author Dmitry Selyutin <ghostmansd@gmail.com>
date Sun, 20 Aug 2017 11:17:58 +0300
parents 131725ebe293
children e4197b976364
files gnulib-tool.py pygnulib/GLConfig.py pygnulib/GLEmiter.py pygnulib/GLError.py pygnulib/GLFileSystem.py pygnulib/GLImport.py pygnulib/GLInfo.py pygnulib/GLMakefileTable.py pygnulib/GLModuleSystem.py pygnulib/GLTestDir.py pygnulib/__init__.py pygnulib/classes.py pygnulib/constants.py
diffstat 13 files changed, 8475 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnulib-tool.py	Sun Aug 20 11:17:58 2017 +0300
@@ -0,0 +1,987 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2002-2012 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 <http://www.gnu.org/licenses/>.
+#
+
+# This program is meant for authors or maintainers which want to import
+# modules from gnulib into their packages.
+
+
+#===============================================================================
+# Define global imports
+#===============================================================================
+import os
+import re
+import sys
+import codecs
+import random
+import shutil
+import argparse
+import subprocess as sp
+from pprint import pprint
+from pygnulib import constants
+from pygnulib import classes
+
+
+#===============================================================================
+# Define global constants
+#===============================================================================
+PYTHON3 = constants.PYTHON3
+APP = constants.APP
+DIRS = constants.DIRS
+ENCS = constants.ENCS
+UTILS = constants.UTILS
+FILES = constants.FILES
+MODES = constants.MODES
+TESTS = constants.TESTS
+compiler = constants.compiler
+joinpath = constants.joinpath
+cleaner = constants.cleaner
+string = constants.string
+isabs = os.path.isabs
+isdir = os.path.isdir
+isfile = os.path.isfile
+normpath = os.path.normpath
+relpath = os.path.relpath
+
+
+#===============================================================================
+# Define main part
+#===============================================================================
+def main():
+  # Reset arguments
+  mode = None
+  destdir = None
+  localdir = None
+  modcache = None
+  verbose = None
+  auxdir = None
+  modules = None
+  avoids = None
+  sourcebase = None
+  m4base = None
+  pobase = None
+  docbase = None
+  testsbase = None
+  tests = None
+  libname = None
+  lgpl = None
+  makefile = None
+  libtool = None
+  conddeps = None
+  macro_prefix = None
+  podomain = None
+  witness_c_macro = None
+  vc_files = None
+  dryrun = None
+  errors = None
+  
+  info = classes.GLInfo()
+  parser = argparse.ArgumentParser(
+    prog=constants.APP['name'],
+    usage='gnulib-tool.py --help',
+    add_help=False)
+  # help
+  parser.add_argument('-h', '--help', '--hel', '--he', '--h',
+    dest='help',
+    default=None,
+    action='store_true')
+  # version
+  parser.add_argument('--version', '--versio', '--versi', '--vers',
+    dest='version',
+    default=None,
+    action='store_true')
+  # list
+  parser.add_argument('-l', '--list', '--lis',
+    dest='mode_list',
+    default=None,
+    action='store_true')
+  # find
+  parser.add_argument('-f', '--find', '--fin', '--fi', '--f',
+    dest='mode_find',
+    default=None,
+    nargs='*')
+  # import
+  parser.add_argument('-i', '--import',
+    dest='mode_import',
+    default=None,
+    nargs='+')
+  # add-import
+  parser.add_argument('-a', '--add-import',
+    dest='mode_add_import',
+    default=None,
+    nargs='+')
+  # remove-import
+  parser.add_argument('-r', '--remove-import',
+    dest='mode_remove_import',
+    default=None,
+    nargs='+')
+  # update
+  parser.add_argument('-u', '--update',
+    dest='mode_update',
+    default=None,
+    action='store_true')
+  # create-testdir
+  parser.add_argument('-td', '--create-testdir',
+    dest='mode_create_testdir',
+    default=None,
+    nargs='*')
+  # create-megatestdir
+  parser.add_argument('-mtd', '--create-megatestdir',
+    dest='mode_create_megatestdir',
+    default=None,
+    nargs='*')
+  # test
+  parser.add_argument('-t', '--test',
+    dest='mode_test',
+    default=None,
+    nargs='*')
+  # megatest
+  parser.add_argument('-mt', '--megatest', '--megates', '--megate', '--megat',
+    '--mega', '--meg', '--me', '--m',
+    dest='mode_megatest',
+    default=None,
+    nargs='*')
+  # copy-file
+  parser.add_argument('-c', '--copy-file',
+    dest='mode_copy_file',
+    default=None,
+    nargs='+')
+  # extract-*
+  parser.add_argument('-xD', '--extract-description',
+    dest='mode_xdescription',
+    default=None,
+    nargs='*')
+  parser.add_argument('-xc', '--extract-comment',
+    dest='mode_xcomment',
+    default=None,
+    nargs='*')
+  parser.add_argument('-xs', '--extract-status',
+    dest='mode_xstatus',
+    default=None,
+    nargs='*')
+  parser.add_argument('-xn', '--extract-notice',
+    dest='mode_xnotice',
+    default=None,
+    nargs='*')
+  parser.add_argument('-xa', '--extract-applicability',
+    dest='mode_xapplicability',
+    default=None,
+    nargs='*')
+  parser.add_argument('-xf', '--extract-filelist',
+    dest='mode_xfilelist',
+    default=None,
+    nargs='*')
+  parser.add_argument('-xd', '--extract-dependencies',
+    dest='mode_xdependencies',
+    default=None,
+    nargs='*')
+  parser.add_argument('-xac', '--extract-autoconf-snippet',
+    dest='mode_xautoconf',
+    default=None,
+    nargs='*')
+  parser.add_argument('-xam', '--extract-automake-snippet',
+    dest='mode_xautomake',
+    default=None,
+    nargs='*')
+  parser.add_argument('-xi', '--extract-include-directive',
+    dest='mode_xinclude',
+    default=None,
+    nargs='*')
+  parser.add_argument('-xl', '--extract-link-directive',
+    dest='mode_xlink',
+    default=None,
+    nargs='*')
+  parser.add_argument('-xL', '--extract-license',
+    dest='mode_xlicense',
+    default=None,
+    nargs='*')
+  parser.add_argument('-xm', '--extract-maintainer',
+    dest='mode_xmaintainer',
+    default=None,
+    nargs='*')
+  # destdir
+  parser.add_argument('-d', '--destdir',
+    dest='destdir',
+    default=None,
+    nargs=1)
+  # localdir
+  parser.add_argument('-ld', '--local-dir',
+    dest='localdir',
+    default=None,
+    nargs=1)
+  # verbose
+  parser.add_argument('-v', '--verbose',
+    default=0,
+    action='count')
+  # quiet
+  parser.add_argument('-q', '--quiet',
+    default=0,
+    action='count')
+  # dryrun
+  parser.add_argument('--dry-run',
+    dest='dryrun',
+    default=None,
+    action='store_true')
+  # inctests
+  parser.add_argument('--with-tests',
+    dest='inctests',
+    default=None,
+    action='store_true')
+  # obsolete
+  parser.add_argument('--with-obsolete',
+    dest='obsolete',
+    default=None,
+    action='store_true')
+  # c++-tests
+  parser.add_argument('--with-c++-tests',
+    dest='cxx',
+    default=None,
+    action='store_true')
+  # longrunning-tests
+  parser.add_argument('--with-longrunning-tests',
+    dest='longrunning',
+    default=None,
+    action='store_true')
+  # privileged-tests
+  parser.add_argument('--with-privileged-tests',
+    dest='privileged',
+    default=None,
+    action='store_true')
+  # unportable-tests
+  parser.add_argument('--with-unportable-tests',
+    dest='unportable',
+    default=None,
+    action='store_true')
+  # all-tests
+  parser.add_argument('--with-all-tests',
+    dest='alltests',
+    default=None,
+    action='store_true')
+  # auxdir
+  parser.add_argument('--aux-dir',
+    dest='auxdir',
+    default=None,
+    nargs=1)
+  # libname
+  parser.add_argument('--lib',
+    dest='libname',
+    default=None,
+    nargs=1)
+  # sourcebase
+  parser.add_argument('-sb', '--source-base',
+    dest='sourcebase',
+    default=None,
+    nargs=1)
+  # m4base
+  parser.add_argument('-mb', '--m4-base',
+    dest='m4base',
+    default=None,
+    nargs=1)
+  # pobase
+  parser.add_argument('-pb', '--po-base',
+    dest='pobase',
+    default=None,
+    nargs=1)
+  # docbase
+  parser.add_argument('-db', '--doc-base',
+    dest='docbase',
+    default=None,
+    nargs=1)
+  # testsbase
+  parser.add_argument('-tb', '--tests-base',
+    dest='testsbase',
+    default=None,
+    nargs=1)
+  # lgpl
+  parser.add_argument('--lgpl',
+    dest='lgpl',
+    default=False,
+    type=int,
+    nargs='?')
+  # avoids
+  parser.add_argument('--avoid',
+    dest='avoids',
+    default=None,
+    nargs='+')
+  
+  # Parse the given arguments.
+  cmdargs = parser.parse_args()
+  
+  # Determine when user tries to combine modes.
+  args = [
+    cmdargs.mode_list,
+    cmdargs.mode_import,
+    cmdargs.mode_add_import,
+    cmdargs.mode_remove_import,
+    cmdargs.mode_update,
+    cmdargs.mode_create_testdir,
+    cmdargs.mode_create_megatestdir,
+    cmdargs.mode_test,
+    cmdargs.mode_megatest,
+    cmdargs.mode_copy_file,
+    cmdargs.mode_xdescription,
+    cmdargs.mode_xcomment,
+    cmdargs.mode_xstatus,
+    cmdargs.mode_xnotice,
+    cmdargs.mode_xapplicability,
+    cmdargs.mode_xfilelist,
+    cmdargs.mode_xdependencies,
+    cmdargs.mode_xautoconf,
+    cmdargs.mode_xautomake,
+    cmdargs.mode_xinclude,
+    cmdargs.mode_xlink,
+    cmdargs.mode_xlicense,
+    cmdargs.mode_xmaintainer,
+  ]
+  overflow = [arg for arg in args if arg]
+  if len(overflow) > 1:
+    message = 'gnulib-tool: Unable to combine different modes of work.\n'
+    message += 'Try \'gnulib-tool --help\' for more information.\n'
+    sys.stderr.write(message)
+    sys.exit(1)
+  
+  # Determine selected mode.
+  if cmdargs.help != None:
+    print(info.usage())
+    sys.exit(0)
+  if cmdargs.version != None:
+    message = '''gnulib-tool (%s %s)%s\n%s\n%s\n\nWritten by %s.''' % \
+      (info.package(), info.date(), info.version(), info.copyright(),
+        info.license(), info.authors())
+    print(message)
+    sys.exit(0)
+  if cmdargs.mode_list != None:
+    mode = 'list'
+  if cmdargs.mode_import != None:
+    mode = 'import'
+    modules = list(cmdargs.mode_import)
+  if cmdargs.mode_add_import != None:
+    mode = 'add-import'
+    modules = list(cmdargs.mode_add_import)
+  if cmdargs.mode_remove_import != None:
+    mode = 'remove-import'
+    modules = list(cmdargs.mode_remove_import)
+  if cmdargs.mode_update != None:
+    mode = 'update'
+  if cmdargs.mode_create_testdir != None:
+    mode = 'create-testdir'
+    modules = list(cmdargs.mode_create_testdir)
+  if cmdargs.mode_create_megatestdir != None:
+    mode = 'create-megatestdir'
+    modules = list(cmdargs.mode_create_megatestdir)
+  if cmdargs.mode_test != None:
+    mode = 'test'
+    modules = list(cmdargs.mode_test)
+  if cmdargs.mode_megatest != None:
+    mode = 'megatest'
+    modules = list(cmdargs.mode_megatest)
+  if cmdargs.mode_xdescription != None:
+    mode = 'extract-description'
+    modules = list(cmdargs.mode_xdescription)
+  if cmdargs.mode_xcomment != None:
+    mode = 'extract-comment'
+    modules = list(cmdargs.mode_xcomment)
+  if cmdargs.mode_xstatus != None:
+    mode = 'extract-status'
+    modules = list(cmdargs.mode_xstatus)
+  if cmdargs.mode_xnotice != None:
+    mode = 'extract-notice'
+    modules = list(cmdargs.mode_xnotice)
+  if cmdargs.mode_xapplicability != None:
+    mode = 'extract-applicability'
+    modules = list(cmdargs.mode_xapplicability)
+  if cmdargs.mode_xfilelist != None:
+    mode = 'extract-filelist'
+    modules = list(cmdargs.mode_xfilelist)
+  if cmdargs.mode_xautoconf != None:
+    mode = 'extract-autoconf-snippet'
+    modules = list(cmdargs.mode_xautoconf)
+  if cmdargs.mode_xautomake != None:
+    mode = 'extract-automake-snippet'
+    modules = list(cmdargs.mode_xautomake)
+  if cmdargs.mode_xdependencies != None:
+    mode = 'extract-dependencies'
+    modules = list(cmdargs.mode_xdependencies)
+  if cmdargs.mode_xinclude != None:
+    mode = 'extract-include-directive'
+    modules = list(cmdargs.mode_xinclude)
+  if cmdargs.mode_xlink != None:
+    mode = 'extract-link-directive'
+    modules = list(cmdargs.mode_xlink)
+  if cmdargs.mode_xlicense != None:
+    mode = 'extract-license'
+    modules = list(cmdargs.mode_xlicense)
+  if cmdargs.mode_xmaintainer != None:
+    mode = 'extract-maintainer'
+    modules = list(cmdargs.mode_xmaintainer)
+  if cmdargs.mode_copy_file != None:
+    mode = 'copy-file'
+    if len(cmdargs.mode_copy_file) > 2:
+      message = '%s: *** ' % constants.APP['name']
+      message += 'invalid number of arguments for --%s' % mode
+      message += '\n%s: *** Exit.\n' % constants.APP['name']
+      sys.stderr.write(message)
+      sys.exit(1)
+    files = list(cmdargs.mode_copy_file)
+  
+  # Determine specific settings.
+  destdir = cmdargs.destdir
+  if destdir != None:
+    destdir = cmdargs.destdir[0]
+  localdir = cmdargs.localdir
+  if localdir != None:
+    localdir = cmdargs.localdir[0]
+  libname = cmdargs.libname
+  if libname != None:
+    libname = cmdargs.libname[0]
+  auxdir = cmdargs.auxdir
+  if auxdir != None:
+    auxdir = cmdargs.auxdir[0]
+  sourcebase = cmdargs.sourcebase
+  if sourcebase != None:
+    sourcebase = cmdargs.sourcebase[0]
+  m4base = cmdargs.m4base
+  if m4base != None:
+    m4base = cmdargs.m4base[0]
+  pobase = cmdargs.pobase
+  if pobase != None:
+    pobase = cmdargs.pobase[0]
+  testsbase = cmdargs.testsbase
+  if testsbase != None:
+    testsbase = cmdargs.testsbase[0]
+  dryrun = cmdargs.dryrun
+  verbose = -cmdargs.quiet +cmdargs.verbose
+  inctests = cmdargs.inctests
+  flags = [cmdargs.inctests, cmdargs.obsolete, cmdargs.cxx,
+    cmdargs.longrunning, cmdargs.privileged, cmdargs.unportable,
+    cmdargs.alltests]
+  testflags = list()
+  for flag in flags:
+    index = flags.index(flag)
+    if flag != None:
+      if flag:
+        if index == 0:
+          testflags += [constants.TESTS['tests']]
+        elif index == 1:
+          testflags += [constants.TESTS['obsolete']]
+        elif index == 2:
+          testflags += [constants.TESTS['cxx-tests']]
+        elif index == 3:
+          testflags += [constants.TESTS['longrunning-tests']]
+        elif index == 4:
+          testflags += [constants.TESTS['privileged-tests']]
+        elif index == 5:
+          testflags += [constants.TESTS['unportable-tests']]
+        elif index == 6:
+          testflags += [constants.TESTS['all-tests']]
+  lgpl = cmdargs.lgpl
+  if lgpl == None:
+    lgpl = True
+  avoids = cmdargs.avoids
+  
+  # Create pygnulib configuration.
+  config = classes.GLConfig\
+  (
+    destdir=destdir,
+    localdir=localdir,
+    m4base=m4base,
+    auxdir=auxdir,
+    modules=modules,
+    avoids=avoids,
+    sourcebase=sourcebase,
+    pobase=pobase,
+    docbase=docbase,
+    testsbase=testsbase,
+    testflags=testflags,
+    libname=libname,
+    lgpl=lgpl,
+    makefile=makefile,
+    libtool=libtool,
+    conddeps=conddeps,
+    macro_prefix=macro_prefix,
+    podomain=podomain,
+    witness_c_macro=witness_c_macro,
+    vc_files=vc_files,
+    modcache=modcache,
+    verbose=verbose,
+    dryrun=dryrun,
+  )
+  
+  # Canonicalize the inctests variable.
+  if inctests == None:
+    if mode in ['import', 'add-import', 'remove-import', 'update']:
+      config.disableTestFlag(TESTS['tests'])
+    elif mode in ['create-testdir', 'create-megatestdir', 'test', 'megatest']:
+      config.enableTestFlag(TESTS['tests'])
+  
+  # Work in the given mode.
+  if mode in ['list']:
+    modulesystem = classes.GLModuleSystem(config)
+    listing = modulesystem.list()
+    result = '\n'.join(listing)
+    os.rmdir(config['tempdir'])
+    print(result)
+    
+  elif mode in ['import', 'add-import', 'remove-import', 'update']:
+    mode = MODES[mode]
+    if not destdir:
+      destdir = '.'
+    config.setDestDir(destdir)
+    
+    if mode == MODES['import']:
+      # Set variables to default values.
+      if not sourcebase:
+        sourcebase = 'lib'
+      if not m4base:
+        m4base = 'm4'
+      if not docbase:
+        docbase = 'doc'
+      if not testsbase:
+        testsbase = 'tests'
+      if not macro_prefix:
+        macro_prefix = 'gl'
+      config.setSourceBase(sourcebase)
+      config.setM4Base(m4base)
+      config.setDocBase(docbase)
+      config.setTestsBase(testsbase)
+      config.setMacroPrefix(macro_prefix)
+      
+      # Perform GLImport actions.
+      importer = classes.GLImport(config, mode)
+      filetable, transformers = importer.prepare()
+      importer.execute(filetable, transformers)
+    
+    else: # if mode != MODE['--import']
+      if m4base:
+        if not isfile(joinpath(destdir, m4base, 'gnulib-cache.m4')):
+          if not sourcebase:
+            sourcebase = 'lib'
+          if not docbase:
+            docbase = 'doc'
+          if not testsbase:
+            testsbase = 'tests'
+          if not macro_prefix:
+            macro_prefix = 'gl'
+          config.setSourceBase(sourcebase)
+          config.setM4Base(m4base)
+          config.setDocBase(docbase)
+          config.setTestsBase(testsbase)
+          config.setMacroPrefix(macro_prefix)
+        # Perform GLImport actions.
+        importer = classes.GLImport(config, mode)
+        filetable, transformers = importer.prepare()
+        importer.execute(filetable, transformers)
+      else: # if not m4base
+        m4dirs = list()
+        dirisnext = bool()
+        filepath = joinpath(destdir, 'Makefile.am')
+        if isfile(filepath):
+          with codecs.open(filepath, 'rb', 'UTF-8') as file:
+            data = file.read()
+            data = data.split('ACLOCAL_AMFLAGS')[1]
+            data = data[data.find('=')+1:data.find('\n')]
+          aclocal_amflags = data.split()
+          for aclocal_amflag in aclocal_amflags:
+            if dirisnext:
+              if not isabs(aclocal_amflag):
+                m4dirs += [aclocal_amflag]
+            else: # if not dirisnext
+              if aclocal_amflag == '-I':
+                dirisnext = True
+              else: # if aclocal_amflag != '-I'
+                dirisnext = False
+        else: # if not isfile(filepath)
+          filepath = joinpath(destdir, 'aclocal.m4')
+          if isfile(filepath):
+            pattern = constants.compiler(r'm4_include\(\[(.*?)\]\)')
+            with codecs.open(filepath, 'rb', 'UTF-8') as file:
+              m4dirs = pattern.findall(file.read())
+            m4dirs = [os.path.dirname(m4dir) for m4dir in m4dirs]
+            m4dirs = \
+            [ # Begin filtering
+              m4dir for m4dir in m4dirs \
+              if isfile(joinpath(destdir, m4dir, 'gnulib-cache.m4'))
+            ] # Finish filtering
+            m4dirs = sorted(set(m4dirs))
+        if len(m4dirs) == 0:
+          # First use of gnulib in a package.
+          # Any number of additional modules can be given.
+          if not sourcebase:
+            sourcebase = 'lib'
+          m4base = 'm4'
+          if not docbase:
+            docbase = 'doc'
+          if not testsbase:
+            testsbase = 'tests'
+          if not macro_prefix:
+            macro_prefix = 'gl'
+          config.setSourceBase(sourcebase)
+          config.setM4Base(m4base)
+          config.setDocBase(docbase)
+          config.setTestsBase(testsbase)
+          config.setMacroPrefix(macro_prefix)
+          # Perform GLImport actions.
+          importer = classes.GLImport(config, mode)
+          filetable, transformers = importer.prepare()
+          importer.execute(filetable, transformers)
+        elif len(m4dirs) == 1:
+          m4base = m4dirs[-1]
+          config.setM4Base(m4base)
+          # Perform GLImport actions.
+          importer = classes.GLImport(config, mode)
+          filetable, transformers = importer.prepare()
+          importer.execute(filetable, transformers)
+        else: # if len(m4dirs) > 1
+          for m4base in m4dirs:
+            config.setM4Base(m4base)
+            # Perform GLImport actions.
+            importer = classes.GLImport(config, mode)
+            filetable, transformers = importer.prepare()
+            importer.execute(filetable, transformers)
+  
+  elif mode == 'create-testdir':
+    if not destdir:
+      message = '%s: *** ' % constants.APP['name']
+      message += 'please specify --dir option'
+      message += '\n%s: *** Exit.\n' % constants.APP['name']
+      sys.stderr.write(message)
+      sys.exit(1)
+    if not auxdir:
+      auxdir = 'build-aux'
+    config.setAuxDir(auxdir)
+    testdir = classes.GLTestDir(config, destdir)
+    testdir.execute()
+  
+  elif mode == 'create-megatestdir':
+    if not destdir:
+      message = '%s: *** ' % constants.APP['name']
+      message += 'please specify --dir option'
+      message += '\n%s: *** Exit.\n' % constants.APP['name']
+      sys.stderr.write(message)
+      sys.exit(1)
+    if not auxdir:
+      auxdir = 'build-aux'
+    config.setAuxDir(auxdir)
+    testdir = classes.GLMegaTestDir(config, destdir)
+    testdir.execute()
+  
+  elif mode == 'test':
+    if not destdir:
+      destdir = 'testdir %04d' % random.randrange(0, 9999)
+    if not auxdir:
+      auxdir = 'build-aux'
+    config.setAuxDir(auxdir)
+    testdir = classes.GLTestDir(config, destdir)
+    testdir.execute()
+    os.chdir(destdir)
+    os.mkdir('build')
+    os.chdir('build')
+    try: # Try to execute commands
+      sp.call(['../configure'])
+      sp.call([UTILS['make']])
+      sp.call([UTILS['make'], 'check'])
+      sp.call([UTILS['make'], 'distclean'])
+    except Exception as error:
+      sys.exit(1)
+    args = ['find', '.', '-type', 'f', '-print']
+    remaining = sp.check_output(args).decode(ENCS['shell'])
+    lines = [line.strip() for line in remaining.split('\n') if line.strip()]
+    remaining = ' '.join(lines)
+    if remaining:
+      message = 'Remaining files: %s\n' % remaining
+      message += 'gnulib-tool: *** Stop.\n'
+      sys.stderr.write(message)
+      sys.exit(1)
+    os.chdir('../..')
+    sp.call(['rm', '-rf', destdir], shell=False)
+    
+  elif mode == 'megatest':
+    if not destdir:
+      destdir = 'testdir %04d' % random.randrange(0, 9999)
+    if not auxdir:
+      auxdir = 'build-aux'
+    config.setAuxDir(auxdir)
+    testdir = classes.GLMegaTestDir(config, destdir)
+    testdir.execute()
+    os.chdir(destdir)
+    os.mkdir('build')
+    os.chdir('build')
+    sp.call(['../configure'])
+    sp.call([UTILS['make']])
+    sp.call([UTILS['make'], 'check'])
+    sp.call([UTILS['make'], 'distclean'])
+    args = ['find', '.', '-type', 'f', '-print']
+    remaining = sp.check_output(args).decode(ENCS['shell'])
+    lines = [line.strip() for line in remaining.split('\n') if line.strip()]
+    remaining = ' '.join(lines)
+    if remaining:
+      message = 'Remaining files: %s\n' % remaining
+      message += 'gnulib-tool: *** Stop.\n'
+      sys.stderr.write(message)
+      sys.exit(1)
+    os.chdir('../..')
+    sp.call(['rm', '-rf', destdir], shell=False)
+  
+  elif mode == 'extract-description':
+    modulesystem = classes.GLModuleSystem(config)
+    modules = [modulesystem.find(module) for module in modules]
+    for module in modules:
+      print(module.getDescription())
+    
+  elif mode == 'extract-comment':
+    modulesystem = classes.GLModuleSystem(config)
+    modules = [modulesystem.find(module) for module in modules]
+    for module in modules:
+      print(module.getComment())
+    
+  elif mode == 'extract-status':
+    modulesystem = classes.GLModuleSystem(config)
+    modules = [modulesystem.find(module) for module in modules]
+    for module in modules:
+      status = module.getStatus()
+      print('\n'.join(status))
+    
+  elif mode == 'extract-notice':
+    modulesystem = classes.GLModuleSystem(config)
+    modules = [modulesystem.find(module) for module in modules]
+    for module in modules:
+      print(module.getNotice())
+    
+  elif mode == 'extract-applicability':
+    modulesystem = classes.GLModuleSystem(config)
+    modules = [modulesystem.find(module) for module in modules]
+    for module in modules:
+      print(module.getApplicability())
+    
+  elif mode == 'extract-filelist':
+    modulesystem = classes.GLModuleSystem(config)
+    modules = [modulesystem.find(module) for module in modules]
+    for module in modules:
+      files = module.getFiles()
+      print('\n'.join(files))
+    
+  elif mode == 'extract-dependencies':
+    result = string()
+    if avoids:
+      message = '%s: *** ' % constants.APP['name']
+      message += 'cannot combine --avoid and --extract-dependencies\n'
+      message += '%s: *** Exit.\n' % constants.APP['name']
+      sys.stderr.write(message)
+      sys.exit(1)
+    modulesystem = classes.GLModuleSystem(config)
+    modules = [modulesystem.find(module) for module in modules]
+    for module in modules:
+      dependencies = module.getDependencies()
+      if dependencies:
+        for depmodule, condition in dependencies:
+          if condition == None:
+            result += '%s\n' % str(depmodule)
+          else: # if condition != None
+            result += '%s\t%s' % (str(depmodule), condition)
+    print(result)
+    
+  elif mode == 'extract-autoconf-snippet':
+    modulesystem = classes.GLModuleSystem(config)
+    modules = [modulesystem.find(module) for module in modules]
+    for module in modules:
+      print(module.getAutoconfSnippet())
+    
+  elif mode == 'extract-automake-snippet':
+    modulesystem = classes.GLModuleSystem(config)
+    modules = [modulesystem.find(module) for module in modules]
+    for module in modules:
+      print(module.getAutomakeSnippet())
+    
+  elif mode == 'extract-include-directive':
+    modulesystem = classes.GLModuleSystem(config)
+    modules = [modulesystem.find(module) for module in modules]
+    for module in modules:
+      print(module.getInclude())
+    
+  elif mode == 'extract-link-directive':
+    modulesystem = classes.GLModuleSystem(config)
+    modules = [modulesystem.find(module) for module in modules]
+    for module in modules:
+      print(module.getLink())
+    
+  elif mode == 'extract-license':
+    modulesystem = classes.GLModuleSystem(config)
+    modules = [modulesystem.find(module) for module in modules]
+    for module in modules:
+      print(module.getLicense())
+    
+  elif mode == 'extract-maintainer':
+    modulesystem = classes.GLModuleSystem(config)
+    modules = [modulesystem.find(module) for module in modules]
+    for module in modules:
+      print(module.getMaintainer())
+    
+  elif mode == 'extract-tests-module':
+    modulesystem = classes.GLModuleSystem(config)
+    modules = [modulesystem.find(module) for module in modules]
+    for module in modules:
+      if module.getTestsModule():
+        print(module.getTestsName())
+    
+  elif mode == 'copy-file':
+    srcpath = files[0]
+    if len(files) == 2:
+      dest = files[1]
+    else: # if len(files) != 2
+      dest = '.'
+    if type(srcpath) is bytes:
+      srcpath = srcpath.decode(ENCS['default'])
+    if type(dest) is bytes:
+      dest = dest.decode(ENCS['default'])
+    if not auxdir:
+      auxdir = 'build-aux'
+    if not sourcebase:
+      sourcebase = 'lib'
+    if not m4base:
+      m4base = 'm4'
+    if not docbase:
+      docbase = 'doc'
+    if not testsbase:
+      testsbase = 'tests'
+    config.setAuxDir(auxdir)
+    config.setSourceBase(sourcebase)
+    config.setM4Base(m4base)
+    config.setDocBase(docbase)
+    config.setTestsBase(testsbase)
+    filesystem = classes.GLFileSystem(config)
+    lookedup, flag = filesystem.lookup(srcpath)
+    if isdir(dest):
+      destdir = string(dest)
+      if srcpath.startswith('build-aux/'):
+        destpath = constants.substart('build-aux/', '%s/' % auxdir, srcpath)
+      elif srcpath.startswith('doc/'):
+        destpath = constants.substart('doc/', '%s/' % docbase, srcpath)
+      elif srcpath.startswith('lib/'):
+        destpath = constants.substart('lib/', '%s/' % sourcebase, srcpath)
+      elif srcpath.startswith('m4/'):
+        destpath = constants.substart('m4/', '%s/' % m4base, srcpath)
+      elif srcpath.startswith('tests/'):
+        destpath = constants.substart('tests/', '%s/' % testsbase, srcpath)
+      elif srcpath.startswith('tests=lib/'):
+        destpath = constants.substart('tests=lib/', '%s/' % testsbase, srcpath)
+      elif srcpath.startswith('top/'):
+        destpath = constants.substart('top/', '', srcpath)
+      else: # either case
+        destpath = srcpath
+    else: # if not isdir(destpath)
+      destdir = os.path.dirname(destpath)
+      destpath = os.path.basename(destpath)
+    # Create the directory for destfile.
+    dirname = os.path.dirname(joinpath(destdir, destpath))
+    if not config['dryrun']:
+      if dirname and not isdir(dirname):
+        try: # Try to create directories
+          os.makedirs(dirname)
+        except Exception as error:
+          pass
+    # Copy the file.
+    assistant = classes.GLFileAssistant(config)
+    tmpfile = assistant.tmpfilename(destpath)
+    shutil.copy(lookedup, tmpfile)
+    already_present = True
+    assistant.setOriginal(srcpath)
+    assistant.setRewritten(destpath)
+    if isfile(joinpath(destdir, destpath)):
+      # The file already exists.
+      assistant.update(lookedup, flag, tmpfile, already_present)
+    else: # if not isfile(joinpath(destdir, destpath))
+      # Install the file.
+      # Don't protest if the file should be there but isn't: it happens
+      # frequently that developers don't put autogenerated files under version
+      # control.
+      assistant.add(lookedup, flag, tmpfile)
+    if isfile(tmpfile):
+      os.remove(tmpfile)
+    
+  else:
+    message = '%s: *** ' % constants.APP['name']
+    message += 'no mode specified'
+    message += '\n%s: *** Exit.\n' % constants.APP['name']
+    sys.stderr.write(message)
+    sys.exit(1)
+
+if __name__ == '__main__':
+  try: # Try to execute
+    main()
+  except BaseException as error:
+    errmode = 0 # gnulib-style errors
+    errno = error.errno
+    errinfo = error.errinfo
+    if errmode == 0:
+      message = '%s: *** ' % constants.APP['name']
+      if errinfo == None:
+        errinfo = string()
+      if errno == 1:
+        message += 'file %s not found' % errinfo
+      elif errno == 2:
+        message += 'patch file %s didn\'t apply cleanly' % errinfo
+      elif errno == 3:
+        message += 'cannot find %s - make sure ' % errinfo
+        message += 'you run gnulib-tool from within your package\'s directory'
+      elif errno == 4:
+        message += 'minimum supported autoconf version is 2.59. Try adding'
+        message += 'AC_PREREQ([%s])' % constants.DEFAULT_AUTOCONF_MINVERSION
+        message += ' to your configure.ac.'
+      elif errno == 5:
+        "%s is expected to contain gl_M4_BASE([%s])" % \
+          (repr(os.path.join(errinfo, 'gnulib-comp.m4')), repr(errinfo))
+      elif errno == 6:
+        message += 'missing --source-base option'
+      elif errno == 7:
+        message += 'missing --doc-base option. --doc-base has been introduced '
+        message += 'on 2006-07-11; if your last invocation of \'gnulib-tool '
+        message += '--import\' is before that date, you need to run'
+        message += '\'gnulib-tool --import\' once, with a --doc-base option.'
+      elif errno == 8:
+        message += 'missing --tests-base option'
+      elif errno == 9:
+        message += 'missing --lib option'
+      elif errno == 10:
+        message = 'gnulib-tool: option --conditional-dependencies is not '
+        message += 'supported with --with-tests\n'
+      elif errno == 11:
+        incompatibilities = string()
+        message += 'incompatible license on modules:%s' % constants.NL
+        for pair in errinfo:
+          incompatibilities += pair[0]
+          incompatibilities += ' %s' % pair[1]
+          incompatibilities += constants.NL
+        tempname = tempfile.mktemp()
+        with codecs.open(tempname, 'wb', 'UTF-8') as file:
+          file.write(incompatibilities)
+        sed_table = 's,^\\([^ ]*\\) ,\\1' +' ' *51 +',\n'
+        sed_table += 's,^\\(' +'.'*49 +'[^ ]*\) *,' +' '*17 +'\\1 ,'
+        args = ['sed', '-e', sed_table, tempname]
+        incompatibilities = sp.check_output(args).decode(ENCS['default'])
+        message += incompatibilities
+        os.remove(tempname)
+      elif errno == 12:
+        message += 'refusing to do nothing'
+      elif errno in [13, 14, 15, 16, 17]:
+        message += 'failed'
+      elif errno == 19:
+        message += 'could not create destination directory: %s' % errinfo
+      if errno != 10:
+        message += '\n%s: *** Exit.\n' % constants.APP['name']
+      sys.stderr.write(message)
+      sys.exit(1)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pygnulib/GLConfig.py	Sun Aug 20 11:17:58 2017 +0300
@@ -0,0 +1,1186 @@
+#!/usr/bin/python
+# encoding: UTF-8
+
+#===============================================================================
+# Define global imports
+#===============================================================================
+import os
+import re
+import sys
+import copy
+import codecs
+import tempfile
+import subprocess as sp
+from . import constants
+from .GLError import GLError
+
+
+#===============================================================================
+# Define module information
+#===============================================================================
+__author__ = constants.__author__
+__license__ = constants.__license__
+__copyright__ = constants.__copyright__
+
+
+#===============================================================================
+# Define global constants
+#===============================================================================
+PYTHON3 = constants.PYTHON3
+NoneType = type(None)
+APP = constants.APP
+DIRS = constants.DIRS
+ENCS = constants.ENCS
+UTILS = constants.UTILS
+FILES = constants.FILES
+MODES = constants.MODES
+TESTS = constants.TESTS
+compiler = constants.compiler
+joinpath = constants.joinpath
+cleaner = constants.cleaner
+relpath = constants.relativize
+string = constants.string
+isabs = os.path.isabs
+isdir = os.path.isdir
+isfile = os.path.isfile
+normpath = os.path.normpath
+
+
+#===============================================================================
+# Define GLConfig class
+#===============================================================================
+class GLConfig(object):
+  '''This class is used to store intermediate settings for all pygnulib
+  classes. It contains all necessary attributes to setup any other class.
+  By default all attributes are set to empty string, empty list or zero.
+  The most common value, however, is a None value.'''
+  
+  def __init__(self, destdir=None, localdir=None, auxdir=None,
+    sourcebase=None, m4base=None, pobase=None, docbase=None, testsbase=None,
+    modules=None, avoids=None, files=None, testflags=None, libname=None,
+    lgpl=None, makefile=None, libtool=None, conddeps=None, macro_prefix=None,
+    podomain=None, witness_c_macro=None, vc_files=None, symbolic=None,
+    lsymbolic=None, modcache=None, configure_ac=None, ac_version=None,
+    libtests=None, single_configure=None, verbose=None, dryrun=None,
+    errors=None):
+    '''GLConfig.__init__(arguments) -> GLConfig
+    
+    Create new GLConfig instance.'''
+    self.table = dict()
+    self.table['tempdir'] = tempfile.mkdtemp()
+    # destdir
+    self.resetDestDir()
+    if destdir != None:
+      self.setDestDir(destdir)
+    # localdir
+    self.resetLocalDir()
+    if localdir != None:
+      self.setLocalDir(localdir)
+    # auxdir
+    self.resetAuxDir()
+    if auxdir != None:
+      self.setAuxDir(auxdir)
+    # sourcebase
+    self.resetSourceBase()
+    if sourcebase != None:
+      self.setSourceBase(sourcebase)
+    # m4base
+    self.resetM4Base()
+    if m4base != None:
+      self.setM4Base(m4base)
+    # pobase
+    self.resetPoBase()
+    if pobase != None:
+      self.setPoBase(pobase)
+    # docbase
+    self.resetDocBase()
+    if docbase != None:
+      self.setDocBase(docbase)
+    # testsbase
+    self.resetTestsBase()
+    if testsbase != None:
+      self.setTestsBase(testsbase)
+    # modules
+    self.resetModules()
+    if modules != None:
+      self.setModules(modules)
+    # avoids
+    self.resetAvoids()
+    if avoids != None:
+      self.setAvoids(avoids)
+    # files
+    self.resetFiles()
+    if files != None:
+      self.setFiles(files)
+    # testflags
+    self.resetTestFlags()
+    if testflags != None:
+      self.setTestFlags(testflags)
+    # libname
+    self.resetLibName()
+    if libname != None:
+      self.setLibName(libname)
+    # lgpl
+    self.resetLGPL()
+    if lgpl != None:
+      self.setLGPL(lgpl)
+    # makefile
+    self.resetMakefile()
+    if makefile != None:
+      self.setMakefile(makefile)
+    # libtool
+    self.resetLibtool()
+    if libtool != None:
+      if type(libtool) is bool:
+        if not libtool:
+          self.disableLibtool()
+        else: # if libtool
+          self.enableLibtool()
+      else: # if type(libtool) is not bool
+        raise(TypeError('libtool must be a bool, not %s' % \
+          type(libtool).__name__))
+    # conddeps
+    self.resetCondDeps()
+    if conddeps != None:
+      if type(conddeps) is bool:
+        if not conddeps:
+          self.disableCondDeps()
+        else: # if conddeps
+          self.enableCondDeps()
+      else: # if type(conddeps) is not bool
+        raise(TypeError('conddeps must be a bool, not %s' % \
+          type(conddeps).__name__))
+    # macro_prefix
+    self.resetMacroPrefix()
+    if macro_prefix != None:
+      self.setMacroPrefix(macro_prefix)
+    # podomain
+    self.resetPoDomain()
+    if podomain != None:
+      self.setPoDomain(podomain)
+    # witness_c_macro
+    self.resetWitnessCMacro()
+    if witness_c_macro != None:
+      if type(witness_c_macro) is bool:
+        if not witness_c_macro:
+          self.setWitnessCMacro()
+        else: # if witness_c_macro
+          self.resetWitnessCMacro()
+      else: # if type(witness_c_macro) is not bool
+        raise(TypeError('witness_c_macro must be a bool, not %s' % \
+          type(witness_c_macro).__name__))
+    # vc_files
+    self.resetVCFiles()
+    if vc_files != None:
+      if type(vc_files) is bool:
+        if not vc_files:
+          self.disableVCFiles()
+        else: # if vc_files
+          self.enableVCFiles()
+      else: # if type(vc_files) is not bool
+        raise(TypeError('vc_files must be a bool, not %s' % \
+          type(vc_files).__name__))
+    # symbolic
+    self.resetSymbolic()
+    if symbolic != None:
+      if type(symbolic) is bool:
+        if not symbolic:
+          self.disableSymbolic()
+        else: # if symbolic
+          self.enableSymbolic()
+      else: # if type(symbolic) is not bool
+        raise(TypeError('symbolic must be a bool, not %s' % \
+          type(symbolic).__name__))
+    # lsymbolic
+    self.resetLSymbolic()
+    if lsymbolic != None:
+      if type(lsymbolic) is bool:
+        if not lsymbolic:
+          self.disableLSymbolic()
+        else: # if lsymbolic
+          self.enableLSymbolic()
+      else: # if type(lsymbolic) is not bool
+        raise(TypeError('lsymbolic must be a bool, not %s' % \
+          type(lsymbolic).__name__))
+    # modcache
+    self.resetModuleCaching()
+    if modcache != None:
+      if type(modcache) is bool:
+        if not modcache:
+          self.disableModuleCaching()
+        else: # if modcache
+          self.enableModuleCaching()
+      else: # if type(modcache) is not bool
+        raise(TypeError('modcache must be a bool, not %s' % \
+          type(modcache).__name__))
+    # configure_ac
+    self.resetAutoconfFile()
+    if configure_ac != None:
+      self.setAutoconfFile(configure_ac)
+    # ac_version
+    self.resetAutoconfVersion()
+    if ac_version != None:
+      self.setAutoconfVersion(ac_version)
+    # libtests
+    self.resetLibtests()
+    if libtests != None:
+      if type(libtests) is bool:
+        if not libtests:
+          self.disableLibtests()
+        else: # if libtests
+          self.enableLibtests()
+      else: # if type(libtests) is not bool
+        raise(TypeError('libtests must be a bool, not %s' % \
+          type(libtests).__name__))
+    # single_configure
+    self.resetSingleConfigure()
+    if single_configure != None:
+      if type(single_configure) is bool:
+        if not single_configure:
+          self.disableSingleConfigure()
+        else: # if single_configure
+          self.enableSingleConfigure()
+      else: # if type(single_configure) is not bool
+        raise(TypeError('single_configure must be a bool, not %s' % \
+          type(single_configure).__name__))
+    # verbose
+    self.resetVerbosity()
+    if verbose != None:
+      self.setVerbosity(verbose)
+    # dryrun
+    self.resetDryRun()
+    if dryrun != None:
+      if type(dryrun) is bool:
+        if not dryrun:
+          self.disableDryRun()
+        else: # if dryrun
+          self.enableDryRun()
+      else: # if type(dryrun) is not bool
+        raise(TypeError('dryrun must be a bool, not %s' % \
+          type(dryrun).__name__))
+    # errors
+    self.resetErrors()
+    if errors != None:
+      if type(errors) is bool:
+        if not errors:
+          self.disableErrors()
+        else: # if errors
+          self.enableErrors()
+      else: # if type(errors) is not bool
+        raise(TypeError('errors must be a bool, not %s' % \
+          type(errors).__name__))
+    
+  # Define special methods.
+  def __repr__(self):
+    '''x.__repr__() <==> repr(x)'''
+    return('<pygnulib.GLConfig>')
+    
+  def __getitem__(self, y):
+    '''x.__getitem__(y) <==> x[y]'''
+    if y in self.table:
+      result = self.table[y]
+      if type(y) is list:
+        result = list(self.table[y])
+      if y == "auxdir":
+        if self.table['auxdir']:
+          return self.table['auxdir']
+        return "build-aux"
+      return(self.table[y])
+    else: # if y not in self.table
+      raise(KeyError('GLConfig does not contain key: %s' % repr(y)))
+    
+  def dictionary(self):
+    '''Return the configuration as a dict object.'''
+    return(dict(self.table))
+    
+  def copy(self):
+    '''Return the copy of the configuration.'''
+    table = copy.deepcopy(self)
+    return(table)
+    
+  def update(self, dictionary):
+    '''Specify the dictionary whose keys will be used to update config.'''
+    if type(dictionary) is not GLConfig:
+      raise(TypeError('dictionary must be a GLConfig, not %s' % \
+        type(dictionary).__name__))
+    dictionary = dict(dictionary.table)
+    result = dict()
+    for key in dictionary:
+      src = self.table[key]
+      dest = dictionary[key]
+      result[key] = src
+      if src != dest:
+        if self.isdefault(key, src):
+          result[key] = dest
+        else: # if not self.isdefault(key, src)
+          result[key] == src
+          if not self.isdefault(key, dest):
+            if key in ['modules', 'avoids', 'tests']:
+              dest = sorted(set(src +dest))
+            result[key] = dest
+    self.table = dict(result)
+    
+  def update_key(self, dictionary, key):
+    '''Update the given key using value from the given dictionary.'''
+    if key in self.table:
+      if type(dictionary) is not GLConfig:
+        raise(TypeError('dictionary must be a GLConfig, not %s' % \
+          type(dictionary).__name__))
+      dictionary = dict(dictionary.table)
+      self.table[key] = dictionary[key]
+    else: # if key not in self.table
+      raise(KeyError('GLConfig does not contain key: %s' % repr(key)))
+    
+  def default(self, key):
+    '''Return default value for the given key.'''
+    if key in self.table:
+      if key == 'libname':
+        return(string('libgnu'))
+      elif key == 'macro_prefix':
+        return(string('gl'))
+      elif key == 'include_guard_prefix':
+        return(string('GL'))
+      elif key == 'ac_version':
+        return(2.59)
+      elif key == 'verbosity':
+        return(0)
+      elif key == 'copyrights':
+        return(True)
+      elif key in ['modules', 'avoids', 'tests', 'testflags']:
+        return(list())
+      elif key in ['libtool', 'lgpl', 'conddeps', 'modcache', 'symbolic',
+      'lsymbolic', 'libtests', 'dryrun']:
+        return(False)
+      if key == 'vc_files':
+        return(None)
+      elif key == 'errors':
+        return(True)
+      else: # otherwise
+        return(string())
+    else: # if key not in self.table
+      raise(KeyError('GLConfig does not contain key: %s' % repr(key)))
+    
+  def isdefault(self, key, value):
+    '''Check whether the value for the given key is a default value.'''
+    if key in self.table:
+      default = self.default(key)
+      return(value == default)
+    else: # if key not in self.table
+      raise(KeyError('GLConfig does not contain key: %s' % repr(key)))
+    
+  def keys(self):
+    '''Return list of keys.'''
+    return(list(self.table.keys()))
+    
+  def values(self):
+    '''Return list of values.'''
+    return(list(self.table.values()))
+    
+    
+  # Define destdir methods.
+  def getDestDir(self):
+    '''Return the target directory. For --import, this specifies where your
+    configure.ac can be found. Defaults to current directory.'''
+    return(self.table['destdir'])
+    
+  def setDestDir(self, destdir):
+    '''Specify the target directory. For --import, this specifies where your
+    configure.ac can be found. Defaults to current directory.'''
+    if type(destdir) is bytes or type(destdir) is string:
+      if type(destdir) is bytes:
+        destdir = string(destdir, ENCS['system'])
+      if destdir:
+        self.table['destdir'] = os.path.normpath(destdir)
+    else: # if destdir has not bytes/string type
+      raise(TypeError('destdir must be a string, not %s' % \
+        type(destdir).__name__))
+    
+  def resetDestDir(self):
+    '''Reset the target directory. For --import, this specifies where your
+    configure.ac can be found. Defaults to current directory.'''
+    self.table['destdir'] = string()
+    
+    
+  # Define localdir methods.
+  def getLocalDir(self):
+    '''Return a local override directory where to look up files before looking
+    in gnulib's directory.'''
+    return(self.table['localdir'])
+    
+  def setLocalDir(self, localdir):
+    '''Specify a local override directory where to look up files before looking
+    in gnulib's directory.'''
+    if type(localdir) is bytes or type(localdir) is string:
+      if type(localdir) is bytes:
+        localdir = string(localdir, ENCS['system'])
+      if localdir:
+        self.table['localdir'] = localdir
+    else: # if localdir has not bytes/string type
+      raise(TypeError('localdir must be a string, not %s' % \
+        type(localdir).__name__))
+    
+  def resetLocalDir(self):
+    '''Reset a local override directory where to look up files before looking
+    in gnulib's directory.'''
+    self.table['localdir'] = string()
+    
+    
+  # Define auxdir methods.
+  def getAuxDir(self):
+    '''Return directory relative to --dir where auxiliary build tools are
+    placed. Default comes from configure.ac or configure.in.'''
+    if self.table['auxdir']:
+      return self.table['auxdir']
+    return "build-aux"
+    
+  def setAuxDir(self, auxdir):
+    '''Specify directory relative to --dir where auxiliary build tools are
+    placed. Default comes from configure.ac or configure.in.'''
+    if type(auxdir) is bytes or type(auxdir) is string:
+      if type(auxdir) is bytes:
+        auxdir = string(auxdir, ENCS['system'])
+      if auxdir:
+        self.table['auxdir'] = auxdir
+    else: # if type of auxdir is not bytes or string
+      raise(TypeError('auxdir must be a string, not %s' % \
+        type(auxdir).__name__))
+    
+  def resetAuxDir(self):
+    '''Reset directory relative to --dir where auxiliary build tools are
+    placed. Default comes from configure.ac or configure.in.'''
+    self.table['auxdir'] = string()
+    
+    
+  # Define sourcebase methods.
+  def getSourceBase(self):
+    '''Return directory relative to destdir where source code is placed.'''
+    return(self.table['sourcebase'])
+    
+  def setSourceBase(self, sourcebase):
+    '''Specify directory relative to destdir where source code is placed.'''
+    if type(sourcebase) is bytes or type(sourcebase) is string:
+      if type(sourcebase) is bytes:
+        sourcebase = string(sourcebase, ENCS['system'])
+      if sourcebase:
+        self.table['sourcebase'] = sourcebase
+    else: # if type of sourcebase is not bytes or string
+      raise(TypeError('sourcebase must be a string, not %s' % \
+        type(sourcebase).__name__))
+    
+  def resetSourceBase(self):
+    '''Return directory relative to destdir where source code is placed.'''
+    self.table['sourcebase'] = string()
+    
+    
+  # Define m4base methods.
+  def getM4Base(self):
+    '''Return directory relative to destdir where *.m4 macros are placed.'''
+    return(self.table['m4base'])
+    
+  def setM4Base(self, m4base):
+    '''Specify directory relative to destdir where *.m4 macros are placed.'''
+    if type(m4base) is bytes or type(m4base) is string:
+      if type(m4base) is bytes:
+        m4base = string(m4base, ENCS['system'])
+      if m4base:
+        self.table['m4base'] = m4base
+    else: # if type of m4base is not bytes or string
+      raise(TypeError('m4base must be a string, not %s' % \
+        type(m4base).__name__))
+    
+  def resetM4Base(self):
+    '''Reset directory relative to destdir where *.m4 macros are placed.'''
+    self.table['m4base'] = string()
+    
+    
+  # Define pobase methods.
+  def getPoBase(self):
+    '''Return directory relative to destdir where *.po files are placed.'''
+    return(self.table['pobase'])
+    
+  def setPoBase(self, pobase):
+    '''Specify directory relative to destdir where *.po files are placed.'''
+    if type(pobase) is bytes or type(pobase) is string:
+      if type(pobase) is bytes:
+        pobase = string(pobase, ENCS['system'])
+      if pobase:
+        self.table['pobase'] = pobase
+    else: # if type of pobase is not bytes or string
+      raise(TypeError('pobase must be a string, not %s' % \
+        type(pobase).__name__))
+    
+  def resetPoBase(self):
+    '''Reset directory relative to destdir where *.po files are placed.'''
+    self.table['pobase'] = string()
+    
+    
+  # Define docbase methods.
+  def getDocBase(self):
+    '''Return directory relative to destdir where doc files are placed.
+    Default value for this variable is 'doc').'''
+    return(self.table['docbase'])
+    
+  def setDocBase(self, docbase):
+    '''Specify directory relative to destdir where doc files are placed.
+    Default value for this variable is 'doc').'''
+    if type(docbase) is bytes or type(docbase) is string:
+      if type(docbase) is bytes:
+        docbase = string(docbase, ENCS['system'])
+      if docbase:
+        self.table['docbase'] = docbase
+    else: # if type of docbase is not bytes or string
+      raise(TypeError('docbase must be a string, not %s' % \
+        type(docbase).__name__))
+    
+  def resetDocBase(self):
+    '''Reset directory relative to destdir where doc files are placed.
+    Default value for this variable is 'doc').'''
+    self.table['docbase'] = string()
+    
+    
+  # Define testsbase methods.
+  def getTestsBase(self):
+    '''Return directory relative to destdir where unit tests are placed.
+    Default value for this variable is 'tests').'''
+    return(self.table['testsbase'])
+    
+  def setTestsBase(self, testsbase):
+    '''Specify directory relative to destdir where unit tests are placed.
+    Default value for this variable is 'tests').'''
+    if type(testsbase) is bytes or type(testsbase) is string:
+      if type(testsbase) is bytes:
+        testsbase = string(testsbase, ENCS['system'])
+      if testsbase:
+        self.table['testsbase'] = testsbase
+    else: # if type of testsbase is not bytes or string
+      raise(TypeError('testsbase must be a string, not %s' % \
+        type(testsbase).__name__))
+    
+  def resetTestsBase(self):
+    '''Reset directory relative to destdir where unit tests are placed.
+    Default value for this variable is 'tests').'''
+    self.table['testsbase'] = string()
+    
+    
+  # Define modules methods.
+  def addModule(self, module):
+    '''Add the module to the modules list.'''
+    if type(module) is bytes or type(module) is string:
+      if type(module) is bytes:
+        module = module.decode(ENCS['default'])
+      if module not in self.table['modules']:
+        self.table['modules'] += [module]
+    else: # if module has not bytes or string type
+      raise(TypeError('module must be a string, not %s' % \
+        type(module).__name__))
+    
+  def removeModule(self, module):
+    '''Remove the module from the modules list.'''
+    if type(module) is bytes or type(module) is string:
+      if type(module) is bytes:
+        module = module.decode(ENCS['default'])
+      if module in self.table['modules']:
+        self.table['modules'].remove(module)
+    else: # if module has not bytes or string type
+      raise(TypeError('module must be a string, not %s' % \
+        type(module).__name__))
+    
+  def getModules(self):
+    '''Return the modules list.'''
+    return(list(self.table['modules']))
+    
+  def setModules(self, modules):
+    '''Set the modules list.'''
+    if type(modules) is list or type(modules) is tuple:
+      old_modules = self.table['modules']
+      self.table['modules'] = list()
+      for module in modules:
+        try: # Try to add each module
+          self.addModule(module)
+        except TypeError as error:
+          self.table['modules'] = old_modules
+          raise(TypeError('each module must be a string'))
+        except GLError as error:
+          self.table['modules'] = old_modules
+          raise(GLError(error.errno, error.errinfo))
+    else: # if type of modules is not list or tuple
+      raise(TypeError('modules must be a list or a tuple, not %s' % \
+        type(modules).__name__))
+    
+  def resetModules(self):
+    '''Reset the list of the modules.'''
+    self.table['modules'] = list()
+    
+    
+  # Define avoids methods.
+  def addAvoid(self, module):
+    '''Avoid including the given module. Useful if you have code that provides
+    equivalent functionality.'''
+    if type(module) is bytes or type(module) is string:
+      if type(module) is bytes:
+        module = module.decode(ENCS['default'])
+      if module not in self.table['avoids']:
+        self.table['avoids'].append(module)
+    else: # if module has not bytes or string type
+      raise(TypeError('avoid must be a string, not %s' % \
+        type(module).__name__))
+    
+  def removeAvoid(self, module):
+    '''Remove the given module from the list of avoided modules.'''
+    if type(module) is bytes or type(module) is string:
+      if type(module) is bytes:
+        module = module.decode(ENCS['default'])
+      if module in self.table['avoids']:
+        self.table['avoids'].remove(module)
+    else: # if module has not bytes or string type
+      raise(TypeError('avoid must be a string, not %s' % \
+        type(module).__name__))
+    
+  def getAvoids(self):
+    '''Return the list of the avoided modules.'''
+    return(list(self.table['avoids']))
+    
+  def setAvoids(self, modules):
+    '''Specify the modules which will be avoided.'''
+    if type(modules) is list or type(modules) is tuple:
+      old_avoids = self.table['avoids']
+      self.table['avoids'] = list()
+      for module in modules:
+        try: # Try to add each module
+          self.addAvoid(module)
+        except TypeError as error:
+          self.table['avoids'] = old_avoids
+          raise(TypeError('each module must be a string'))
+        except GLError as error:
+          self.table['avoids'] = old_avoids
+          raise(GLError(error.errno, error.errinfo))
+    else: # if type of modules is not list or tuple
+      raise(TypeError('modules must be a list or a tuple, not %s' % \
+          type(modules).__name__))
+    
+  def resetAvoids(self):
+    '''Reset the list of the avoided modules.'''
+    self.table['avoids'] = list()
+    
+    
+  # Define files methods.
+  def addFile(self, file):
+    '''Add file to the list of files.'''
+    if type(file) is bytes or type(file) is string:
+      if type(file) is bytes:
+        file = file.decode(ENCS['default'])
+      if file not in self.table['files']:
+        self.table['files'].append(file)
+    else: # if file has not bytes or string type
+      raise(TypeError('file must be a string, not %s' % \
+        type(file).__name__))
+    
+  def removeFile(self, file):
+    '''Remove the given file from the list of files.'''
+    if type(file) is bytes or type(file) is string:
+      if type(file) is bytes:
+        file = file.decode(ENCS['default'])
+      if file in self.table['files']:
+        self.table['files'].remove(file)
+    else: # if file has not bytes or string type
+      raise(TypeError('file must be a string, not %s' % \
+        type(file).__name__))
+    
+  def getFiles(self):
+    '''Return the list of the fileed files.'''
+    return(list(self.table['files']))
+    
+  def setFiles(self, files):
+    '''Specify the list of files.'''
+    if type(files) is list or type(files) is tuple:
+      old_files = self.table['files']
+      self.table['files'] = list()
+      for file in files:
+        try: # Try to add each file
+          self.addFile(file)
+        except TypeError as error:
+          self.table['files'] = old_files
+          raise(TypeError('each file must be a string'))
+        except GLError as error:
+          self.table['files'] = old_files
+          raise(GLError(error.errno, error.errinfo))
+    else: # if type of files is not list or tuple
+      raise(TypeError('files must be a list or a tuple, not %s' % \
+          type(files).__name__))
+    
+  def resetFiles(self):
+    '''Reset the list of files.'''
+    self.table['files'] = list()
+    
+    
+  # Define tests/testflags methods
+  def checkTestFlag(self, flag):
+    '''Return the status of the test flag.'''
+    if flag in TESTS.values():
+      return(flag in self.table['testflags'])
+    else: # if flag is not in TESTS
+      raise(TypeError('unknown flag: %s' % repr(flag)))
+    
+  def enableTestFlag(self, flag):
+    '''Enable test flag. You can get flags from TESTS variable.'''
+    if flag in TESTS.values():
+      if flag not in self.table['testflags']:
+        self.table['testflags'].append(flag)
+    else: # if flag is not in TESTS
+      raise(TypeError('unknown flag: %s' % repr(flag)))
+    
+  def disableTestFlag(self, flag):
+    '''Disable test flag. You can get flags from TESTS variable.'''
+    if flag in TESTS.values():
+      if flag in self.table['testflags']:
+        self.table['testflags'].remove(flag)
+    else: # if flag is not in TESTS
+      raise(TypeError('unknown flag: %s' % repr(flag)))
+    
+  def getTestFlags(self):
+    '''Return test flags. You can get flags from TESTS variable.'''
+    return(list(self.table['testflags']))
+    
+  def setTestFlags(self, testflags):
+    '''Specify test flags. You can get flags from TESTS variable.'''
+    if type(testflags) is list or type(testflags) is tuple:
+      old_testflags = self.table['testflags']
+      self.table['testflags'] = list()
+      for flag in testflags:
+        try: # Try to enable each flag
+          self.enableTestFlag(flag)
+        except TypeError as error:
+          raise(TypeError('each flag must be one of TESTS integers'))
+      self.table['testflags'] = testflags
+    else: # if type of testflags is not list or tuple
+      raise(TypeError('testflags must be a list or a tuple, not %s' % \
+        type(testflags).__name__))
+    
+  def resetTestFlags(self):
+    '''Reset test flags (only default flag will be enabled).'''
+    self.table['testflags'] = list()
+    self.table['tests'] = self.table['testflags']
+    
+    
+  # Define libname methods.
+  def getLibName(self):
+    '''Return the library name.'''
+    return(self.table['libname'])
+    
+  def setLibName(self, libname):
+    '''Specify the library name.'''
+    if type(libname) is bytes or type(libname) is string:
+      if type(libname) is bytes:
+        libname = string(libname, ENCS['system'])
+      if libname:
+        self.table['libname'] = libname
+    else: # if type of libname is not bytes or string
+      raise(TypeError('libname must be a string, not %s' % \
+        type(module).__name__))
+    
+  def resetLibName(self):
+    '''Reset the library name to 'libgnu'.'''
+    self.table['libname'] = string('libgnu')
+    
+    
+  # Define libtool methods.
+  def checkLibtool(self):
+    '''Check if user enabled libtool rules.'''
+    return(self.table['libtool'])
+    
+  def enableLibtool(self):
+    '''Enable libtool rules.'''
+    self.table['libtool'] = True
+    
+  def disableLibtool(self):
+    '''Disable libtool rules.'''
+    self.table['libtool'] = False
+    
+  def resetLibtool(self):
+    '''Reset libtool rules.'''
+    self.table['libtool'] = False
+    
+    
+  # Define conddeps methods.
+  def checkCondDeps(self):
+    '''Check if user enabled cond. dependencies.'''
+    return(self.table['conddeps'])
+    
+  def enableCondDeps(self):
+    '''Enable cond. dependencies (may save configure time and object code).'''
+    self.table['conddeps'] = True
+    
+  def disableCondDeps(self):
+    '''Disable cond. dependencies (may save configure time and object code).'''
+    self.table['conddeps'] = False
+    
+  def resetCondDeps(self):
+    '''Reset cond. dependencies (may save configure time and object code).'''
+    self.table['conddeps'] = False
+    
+    
+  # Define lgpl methods.
+  def getLGPL(self):
+    '''Check for abort if modules aren't available under the LGPL.
+    Default value is False, which means that lgpl is disabled.'''
+    return(self.table['lgpl'])
+    
+  def setLGPL(self, lgpl):
+    '''Abort if modules aren't available under the LGPL.
+    Default value is False, which means that lgpl is disabled.'''
+    if (type(lgpl) is int and 2 <= lgpl <= 3) or type(lgpl) is bool:
+      self.table['lgpl'] = lgpl
+    else: # if lgpl is not False, 2 or 3
+      raise(TypeError('invalid LGPL version: %s' % repr(lgpl)))
+    
+  def resetLGPL(self):
+    '''Disable abort if modules aren't available under the LGPL.
+    Default value is False, which means that lgpl is disabled.'''
+    self.table['lgpl'] = False
+    
+    
+  # Define macro_prefix methods.
+  def getIncludeGuardPrefix(self):
+    '''Return include_guard_prefix to use inside GLEmiter class.'''
+    return(self.table['include_guard_prefix'])
+    
+  def getMacroPrefix(self):
+    '''Return the prefix of the macros 'gl_EARLY' and 'gl_INIT'.
+    Default macro_prefix is 'gl'.'''
+    return(self.table['macro_prefix'])
+    
+  def setMacroPrefix(self, macro_prefix):
+    '''Specify the prefix of the macros 'gl_EARLY' and 'gl_INIT'.
+    Default macro_prefix is 'gl'.'''
+    if type(macro_prefix) is bytes or type(macro_prefix) is string:
+      if type(macro_prefix) is bytes:
+        macro_prefix = string(macro_prefix, ENCS['system'])
+      if macro_prefix:
+        self.table['macro_prefix'] = macro_prefix
+    else: # if type of macro_prefix is not bytes or string
+      raise(TypeError('macro_prefix must be a string, not %s' % \
+          type(macro_prefix).__name__))
+    if macro_prefix == 'gl':
+      include_guard_prefix = 'GL'
+    else: # macro_prefix != 'gl'
+      include_guard_prefix = 'GL_%s' % macro_prefix.upper()
+    if type(include_guard_prefix) is bytes:
+      include_guard_prefix = include_guard_prefix.decode(ENCS['default'])
+    self.table['include_guard_prefix'] = include_guard_prefix
+    
+  def resetMacroPrefix(self):
+    '''Reset the prefix of the macros 'gl_EARLY' and 'gl_INIT'.
+    Default macro_prefix is 'gl'.'''
+    self.table['macro_prefix'] = string('gl')
+    include_guard_prefix = string('GL')
+    if type(include_guard_prefix) is bytes:
+      include_guard_prefix = include_guard_prefix.decode(ENCS['default'])
+    self.table['include_guard_prefix'] = include_guard_prefix
+    
+    
+  # Define makefile methods.
+  def getMakefile(self):
+    '''Return the name of makefile in automake syntax in the source-base and
+    tests-base directories. Default is 'Makefile.am'.'''
+    return(self.table['makefile'])
+    
+  def setMakefile(self, makefile):
+    '''Specify the name of makefile in automake syntax in the source-base and
+    tests-base directories. Default is 'Makefile.am'.'''
+    if type(makefile) is bytes or type(makefile) is string:
+      if type(makefile) is bytes:
+        makefile = string(makefile, ENCS['system'])
+      if makefile:
+        self.table['makefile'] = makefile
+    else: # if type of makefile is not bytes or string
+      raise(TypeError('makefile must be a string, not %s' %
+        type(makefile).__name__))
+    
+  def resetMakefile(self):
+    '''Reset the name of makefile in automake syntax in the source-base and
+    tests-base directories. Default is 'Makefile.am'.'''
+    self.table['makefile'] = string()
+    
+    
+  # Define podomain methods.
+  def getPoDomain(self):
+    '''Return the prefix of the i18n domain. Usually use the package name.
+    A suffix '-gnulib' is appended.'''
+    return(self.table['podomain'])
+    
+  def setPoDomain(self, podomain):
+    '''Specify the prefix of the i18n domain. Usually use the package name.
+    A suffix '-gnulib' is appended.'''
+    if type(podomain) is bytes or type(podomain) is string:
+      if type(podomain) is bytes:
+        podomain = string(podomain, ENCS['system'])
+      if podomain:
+        self.table['podomain'] = podomain
+    else: # if type of podomain is not bytes or string
+      raise(TypeError('podomain must be a string, not %s' % \
+        type(podomain).__name__))
+    
+  def resetPoDomain(self):
+    '''Reset the prefix of the i18n domain. Usually use the package name.
+    A suffix '-gnulib' is appended.'''
+    self.table['podomain'] = string()
+    
+    
+  # Define witness_c_macro methods.
+  def getWitnessCMacro(self):
+    '''Return the C macro that is defined when the sources in this directory
+    are compiled or used.'''
+    return(self.table['witness_c_macro'])
+    
+  def setWitnessCMacro(self, witness_c_macro):
+    '''Specify the C macro that is defined when the sources in this directory
+    are compiled or used.'''
+    if type(witness_c_macro) is bytes or type(witness_c_macro) is string:
+      if type(witness_c_macro) is bytes:
+        witness_c_macro = string(witness_c_macro, ENCS['system'])
+      if witness_c_macro:
+        self.table['witness_c_macro'] = witness_c_macro
+    else: # if type of witness_c_macro is not bytes or string
+      raise(TypeError('witness_c_macro must be a string, not %s' %
+        type(witness_c_macro).__name__))
+    
+  def resetWitnessCMacro(self):
+    '''Return the C macro that is defined when the sources in this directory
+    are compiled or used.'''
+    self.table['witness_c_macro'] = string()
+    
+    
+  # Define vc_files methods.
+  def checkVCFiles(self):
+    '''Check if update of the version control files is enabled or disabled.'''
+    return(self.table['vc_files'])
+    
+  def enableVCFiles(self):
+    '''Enable update of the version control files.'''
+    self.table['vc_files'] = True
+    
+  def disableVCFiles(self):
+    '''Disable update of the version control files.'''
+    self.table['vc_files'] = False
+    
+  def resetVCFiles(self):
+    '''Reset update of the version control files and set it to None.'''
+    self.table['vc_files'] = None
+    
+    
+  # Define modcache methods.
+  def checkModuleCaching(self):
+    '''Get status of module caching optimization.'''
+    return(self.table['modcache'])
+    
+  def enableModuleCaching(self):
+    '''Enable module caching optimization.'''
+    self.table['modcache'] = True
+    
+  def disableModuleCaching(self):
+    '''Disable module caching optimization.'''
+    self.table['modcache'] = False
+    
+  def resetModuleCaching(self):
+    '''Reset module caching optimization.'''
+    self.table['modcache'] = False
+    
+    
+  # Define configure_ac methods.
+  def getAutoconfFile(self):
+    '''Return path of autoconf file relative to destdir.'''
+    return(self.table['configure_ac'])
+    
+  def setAutoconfFile(self, configure_ac):
+    '''Specify path of autoconf file relative to destdir.'''
+    if type(configure_ac) is bytes or type(configure_ac) is string:
+      if type(configure_ac) is bytes:
+        configure_ac = string(configure_ac, ENCS['system'])
+      if configure_ac:
+        self.table['configure_ac'] = \
+          relpath(self.table['destdir'],configure_ac)
+    else: # if type of configure_ac is not bytes or string
+      raise(TypeError('configure_ac must be a string, not %s' % \
+        type(configure_ac).__name__))
+    
+  def resetAutoconfFile(self):
+    '''Reset path of autoconf file relative to destdir.'''
+    configure_ac = string()
+    if isfile(joinpath(self.table['destdir'], 'configure.ac')):
+      configure_ac = joinpath(self.table['destdir'], 'configure.ac')
+    elif isfile(joinpath(self.table['destdir'], 'configure.in')):
+      configure_ac = joinpath(self.table['destdir'], 'configure.in')
+    self.table['configure_ac'] = configure_ac
+    
+    
+  # Define ac_version methods.
+  def getAutoconfVersion(self):
+    '''Return preferred autoconf version. Default value is 2.59.'''
+    return(self.table['ac_version'])
+    
+  def setAutoconfVersion(self, ac_version):
+    '''Specify preferred autoconf version. Default value is 2.59.'''
+    if type(ac_version) is float or type(ac_version) is int:
+      self.table['ac_version'] = float(ac_version)
+    else: # if ac_version has not int or float type
+      raise(TypeError('ac_version must be an int or a float, not %s' % \
+        type(ac_version).__name__))
+    
+  def resetAutoconfVersion(self):
+    '''Specify preferred autoconf version. Default value is 2.59.'''
+    self.table['ac_version'] = 2.59
+    
+    
+  # Define symbolic methods.
+  def checkCopyrights(self):
+    '''Check if copyright notices in files should be replaced.'''
+    return(self.table['copyrights'])
+  
+  def checkSymbolic(self):
+    '''Check if pygnulib will make symbolic links instead of copying files.'''
+    return(self.table['symbolic'])
+    
+  def enableSymbolic(self):
+    '''Enable creation of the symbolic links instead of copying files.'''
+    self.table['symbolic'] = True
+    self.table['copyrights'] = False
+    
+  def disableSymbolic(self):
+    '''Enable creation of the symbolic links instead of copying files.'''
+    self.table['symbolic'] = False
+    self.table['copyrights'] = True
+    
+  def resetSymbolic(self):
+    '''Reset creation of the symbolic links instead of copying files.'''
+    self.table['symbolic'] = False
+    self.table['copyrights'] = True
+    
+    
+  # Define lsymbolic methods.
+  def checkLSymbolic(self):
+    '''Check if pygnulib will make symbolic links instead of copying files, only
+    for files from the local override directory.'''
+    return(self.table['lsymbolic'])
+    
+  def enableLSymbolic(self):
+    '''Enable creation of symbolic links instead of copying files, only for
+    files from the local override directory.'''
+    self.table['lsymbolic'] = True
+    
+  def disableLSymbolic(self):
+    '''Disable creation of symbolic links instead of copying files, only for
+    files from the local override directory.'''
+    self.table['lsymbolic'] = False
+    
+  def resetLSymbolic(self):
+    '''Reset creation of symbolic links instead of copying files, only for
+    files from the local override directory.'''
+    self.table['lsymbolic'] = False
+    
+    
+  # Define verbosity methods.
+  def getVerbosity(self):
+    '''Get verbosity level.'''
+    return(self.table['verbosity'])
+    
+  def decreaseVerbosity(self):
+    '''Decrease verbosity level.'''
+    if self.table['verbosity'] > MODES['verbose-min']:
+      self.table['verbosity'] -= 1
+    
+  def increaseVerbosity(self):
+    '''Increase verbosity level.'''
+    if self.table['verbosity'] < MODES['verbose-max']:
+      self.table['verbosity'] += 1
+    
+  def setVerbosity(self, verbose):
+    '''Set verbosity level to verbose, where -2 <= verbose <= 2.
+    If verbosity level is less than -2, verbosity level will be set to -2.
+    If verbosity level is greater than 2, verbosity level will be set to 2.'''
+    if type(verbose) is int:
+      if MODES['verbose-min'] <= verbose <= MODES['verbose-max']:
+        self.table['verbosity'] = verbose
+      elif verbose < MODES['verbose-min']:
+        self.table['verbosity'] = MODES['verbose-min']
+      elif verbose > MODES['verbose-max']:
+        self.table['verbosity'] = MODES['verbose-max']
+    else: # if type(verbose) is not int
+      raise(TypeError('verbosity must be an int, not %s' % \
+        type(verbose).__name__))
+    
+  def resetVerbosity(self):
+    '''Reset verbosity level.'''
+    self.table['verbosity'] = 0
+    
+    
+  # Define libtests methods.
+  def checkLibtests(self):
+    '''Return True if a testsbase/libtests.a is needed.'''
+    return(self.table['libtests'])
+    
+  def enableLibtests(self):
+    '''If libtests is enabled, then testsbase/libtests.a is needed.'''
+    self.table['libtests'] = True
+    
+  def disableLibtests(self):
+    '''If libtests is disabled, then testsbase/libtests.a is not needed.'''
+    self.table['libtests'] = False
+    
+  def resetLibtests(self):
+    '''Reset status of testsbase/libtests.a.'''
+    self.table['libtests'] = False
+    
+    
+  # Define single_configure methods.
+  def checkSingleConfigure(self):
+    '''Check whether single configure file should be generated.'''
+    return(self.table['single_configure'])
+    
+  def enableSingleConfigure(self):
+    '''Enable generation of the single configure file.'''
+    self.table['single_configure'] = True
+    
+  def disableSingleConfigure(self):
+    '''Disable generation of the single configure file.'''
+    self.table['single_configure'] = False
+    
+  def resetSingleConfigure(self):
+    '''Reset status of the single configure file generation.'''
+    self.table['single_configure'] = False
+    
+    
+  # Define dryrun methods.
+  def checkDryRun(self):
+    '''Check whether dryrun is enabled.'''
+    return(self.table['dryrun'])
+    
+  def enableDryRun(self):
+    '''Enable dryrun mode.'''
+    self.table['dryrun'] = True
+    
+  def disableDryRun(self):
+    '''Disable dryrun mode.'''
+    self.table['dryrun'] = False
+    
+  def resetDryRun(self):
+    '''Reset status of dryrun mode.'''
+    self.table['dryrun'] = False
+    
+    
+  # Define errors methods.
+  def checkErrors(self):
+    '''Check if GLError will be raised in non-critical situations.'''
+    return(self.table['errors'])
+  
+  def enableErrors(self):
+    '''Raise GLError in non-critical situations.'''
+    self.table['errors'] = True
+    
+  def disableErrors(self):
+    '''Do not raise GLError in non-critical situations.'''
+    self.table['errors'] = False
+    
+  def resetErrors(self):
+    '''Reset status of raising GLError in non-critical situations.'''
+    self.table['errors'] = False
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pygnulib/GLEmiter.py	Sun Aug 20 11:17:58 2017 +0300
@@ -0,0 +1,1138 @@
+#!/usr/bin/python
+# encoding: UTF-8
+
+#===============================================================================
+# Define global imports
+#===============================================================================
+import os
+import re
+import sys
+import codecs
+import shutil
+import subprocess as sp
+from . import constants
+from .GLInfo import GLInfo
+from .GLError import GLError
+from .GLConfig import GLConfig
+from .GLModuleSystem import GLModule
+from .GLModuleSystem import GLModuleTable
+from .GLMakefileTable import GLMakefileTable
+from .GLFileSystem import GLFileAssistant
+from pprint import pprint
+
+
+#===============================================================================
+# Define module information
+#===============================================================================
+__author__ = constants.__author__
+__license__ = constants.__license__
+__copyright__ = constants.__copyright__
+
+
+#===============================================================================
+# Define global constants
+#===============================================================================
+PYTHON3 = constants.PYTHON3
+NoneType = type(None)
+APP = constants.APP
+DIRS = constants.DIRS
+ENCS = constants.ENCS
+UTILS = constants.UTILS
+FILES = constants.FILES
+MODES = constants.MODES
+TESTS = constants.TESTS
+compiler = constants.compiler
+joinpath = constants.joinpath
+cleaner = constants.cleaner
+string = constants.string
+isabs = os.path.isabs
+isdir = os.path.isdir
+isfile = os.path.isfile
+normpath = os.path.normpath
+relpath = os.path.relpath
+
+
+#===============================================================================
+# 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() -> string
+    
+    Emit a header for a generated file.'''
+    emit = string()
+    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 <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.\n"""
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    return(constants.nlconvert(emit))
+    
+  def autoconfSnippet(self, module, fileassistant, toplevel,
+    disable_libtool, disable_gettext, replace_auxdir, indentation):
+    '''GLEmiter.autoconfSnippet(module, toplevel,
+      disable_libtool, disable_gettext, replace_auxdir,
+      indentation) -> string
+    
+    Emit the autoconf snippet of a module.
+    GLConfig: include_guard_prefix.
+    
+    module is a GLModule instance, which is processed.
+    fileassistant is a GLFileAssistant instance, which is used to get temporary
+      directories and sed transformer.
+    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.'''
+    emit = string()
+    if type(module) is not GLModule:
+      raise(TypeError('module must be a GLModule, not %s' % \
+        type(module).__name__))
+    if type(fileassistant) is not GLFileAssistant:
+      raise(TypeError('fileassistant must be a GLFileAssistant, not %s' % \
+        type(fileassistant).__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 bytes or type(indentation) is string:
+      if type(indentation) is bytes:
+        indentation = indentation.decode(ENCS['default'])
+    else: # if indentation has not bytes or string type
+      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']
+    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)
+      transformer = fileassistant.transformers.get('aux', '')
+      pattern = compiler('(^.*?$)', re.S | re.M)
+      snippet = pattern.sub('%s\\1' % indentation, snippet)
+      if transformer:
+        args = ['sed', '-e', transformer]
+        path = fileassistant.tmpfilename('snippet')
+        with codecs.open(path, 'wb', 'UTF-8') as file:
+          file.write(snippet)
+        stdin = codecs.open(path, 'rb', 'UTF-8')
+        snippet = sp.check_output(args, stdin=stdin, shell=False)
+        snippet = snippet.decode(ENCS['shell'])
+        os.remove(path)
+      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.')
+      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 = compiler(regex, re.S | re.M)
+      emit = pattern.sub(repl, emit)
+    lines = [line for line in emit.split('\n') if line.strip()]
+    emit = '%s\n' % '\n'.join(lines)
+    emit = constants.nlconvert(emit)
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    return(emit)
+    
+  def autoconfSnippets(self, modules, moduletable, fileassistant,
+    verifier, toplevel, disable_libtool, disable_gettext, replace_auxdir):
+    '''GLEmiter.autoconfSnippets(modules, fileassistant,
+      verifier, toplevel, disable_libtool, disable_gettext,
+      replace_auxdir) -> string
+    
+    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.
+    fileassistant is a GLFileAssistant instance, which is used to get temporary
+      directories and sed transformers.
+    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.'''
+    emit = string()
+    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(fileassistant) is not GLFileAssistant:
+      raise(TypeError('fileassistant must be a GLFileAssistant, not %s' % \
+        type(fileassistant).__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']
+    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, fileassistant, 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, fileassistant, 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, fileassistant, toplevel,
+              disable_libtool, disable_gettext, replace_auxdir, '      ')
+            emit += '      %s=true\n' % shellvar
+            dependencies = module.getDependencies()
+            depmodules = [pair[0] for pair in dependencies]
+            # Intersect dependencies with the modules list.
+            depmodules = [dep for dep in depmodules if dep in 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
+              else: # if not moduletable.isConditional(depmodule)
+                # 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:
+          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)
+    emit = constants.nlconvert(emit)
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    return(emit)
+    
+  def po_Makevars(self):
+    '''GLEmiter.po_Makevars() -> string
+    
+    Emit the contents of po/ makefile parameterization.
+    GLConfig: pobase, podomain.'''
+    emit = string()
+    pobase = self.config['pobase']
+    podomain = self.config['podomain']
+    top_subdir = string()
+    source = '%s/' % os.path.normpath(pobase)
+    if os.path.sep in source:
+      for directory in source.split(os.path.sep):
+        if directory != '':
+          top_subdir += '../'
+    top_subdir = os.path.normpath(top_subdir)
+    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_subdir = %s\n" % top_subdir
+    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"""
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    return(constants.nlconvert(emit))
+    
+  def po_POTFILES_in(self, files):
+    '''GLEmiter.po_POTFILES_in(files) -> string
+    
+    Emit the file list to be passed to xgettext.
+    GLConfig: sourcebase.'''
+    emit = string()
+    sourcebase = self.config['sourcebase']
+    sourcebase = '%s%s' % (self.sourcebase, os.path.sep)
+    if type(sourcebase) is bytes:
+      sourcebase = sourcebase.decode(ENCS['default'])
+    files = [substart('lib/', sourcebase, file) for file in files]
+    files = [file for file in files if file.startswith(sourcebase)]
+    emit += "## DO NOT EDIT! GENERATED AUTOMATICALLY!\n"
+    emit += "%s\n" % self.copyright_notice()
+    emit += "# List of files which contain translatable strings.\n"
+    emit += '\n'.join(files)
+    emit += '\n'
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    return(constants.nlconvert(emit))
+    
+  def initmacro_start(self, macro_prefix_arg):
+    '''GLEmiter.initmacro_start(macro_prefix_arg) -> string
+    
+    Emit the first few statements of the gl_INIT macro.'''
+    emit = string()
+    if type(macro_prefix_arg) is bytes or type(macro_prefix_arg) is string:
+      if type(macro_prefix_arg) is bytes:
+        macro_prefix_arg = macro_prefix_arg.decode(ENCS['default'])
+    else: # if macro_prefix_arg has not bytes or string type
+      raise(TypeError('macro_prefix_arg must be a string, not %s' % \
+        type(macro_prefix_arg).__name__))
+    # 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],"
+    emit += " m4_defn([%V1%_LIBOBJ]))\n"
+    emit += "  m4_pushdef([AC_REPLACE_FUNCS],"
+    emit += " m4_defn([%V1%_REPLACE_FUNCS]))\n"
+    # 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],"
+    emit += " m4_defn([%V1%_LIBSOURCES]))\n"
+    # 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([%V1%_LIBSOURCES_LIST], [])\n"
+    emit += "  m4_pushdef([%V1%_LIBSOURCES_DIR], [])\n"
+    emit += "  gl_COMMON\n"
+    emit = emit.replace('%V1%', macro_prefix_arg)
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    return(constants.nlconvert(emit))
+    
+  def initmacro_end(self, macro_prefix_arg):
+    '''GLEmiter.initmacro_end(macro_prefix_arg) -> string
+    
+    Emit the last few statements of the gl_INIT macro.'''
+    emit = string()
+    if type(macro_prefix_arg) is bytes or type(macro_prefix_arg) is string:
+      if type(macro_prefix_arg) is bytes:
+        macro_prefix_arg = macro_prefix_arg.decode(ENCS['default'])
+    else: # if macro_prefix_arg has not bytes or string type
+      raise(TypeError('macro_prefix_arg must be a string, not %s' % \
+        type(macro_prefix_arg).__name__))
+    # 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 += """\
+  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([%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)
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    return(constants.nlconvert(emit))
+    
+  def initmacro_done(self, macro_prefix_arg, sourcebase_arg):
+    '''GLEmiter.initmacro_done(macro_prefix_arg, sourcebase_arg) -> string
+    
+    Emit a few statements after the gl_INIT macro.
+    GLConfig: sourcebase.'''
+    emit = string()
+    if type(macro_prefix_arg) is bytes or type(macro_prefix_arg) is string:
+      if type(macro_prefix_arg) is bytes:
+        macro_prefix_arg = macro_prefix_arg.decode(ENCS['default'])
+    else: # if macro_prefix_arg has not bytes or string type
+      raise(TypeError('macro_prefix_arg must be a string, not %s' % \
+        type(macro_prefix_arg).__name__))
+    if type(sourcebase_arg) is bytes or type(sourcebase_arg) is string:
+      if type(sourcebase_arg) is bytes:
+        sourcebase_arg = sourcebase_arg.decode(ENCS['default'])
+    else: # if sourcebase_arg has not bytes or string type
+      raise(TypeError('sourcebase_arg must be a string, not %s' % \
+        type(sourcebase_arg).__name__))
+    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)
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    return(constants.nlconvert(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 string and bool
+    
+    Emit the contents of the library Makefile. Returns string and a bool
+    variable which shows if subdirectories are used.
+    GLConfig: localdir, sourcebase, libname, pobase, auxdir, makefile, 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 bytes or type(destfile) is string:
+      if type(destfile) is bytes:
+        destfile = destfile.decode(ENCS['default'])
+    else: # if destfile has not bytes or string type
+      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 bytes or type(actioncmd) is string:
+      if type(actioncmd) is bytes:
+        actioncmd = actioncmd.decode(ENCS['default'])
+    else: # if actioncmd has not bytes or string type
+      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__))
+    emit = string()
+    localdir = self.config['localdir']
+    sourcebase = self.config['sourcebase']
+    modcache = self.config['modcache']
+    libname = self.config['libname']
+    pobase = self.config['pobase']
+    auxdir = self.config['auxdir']
+    makefile = self.config['makefile']
+    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']
+    ac_version = self.config['ac_version']
+    destfile = os.path.normpath(destfile)
+    
+    # When creating an includable Makefile.am snippet, augment variables with
+    # += instead of assigning them.
+    if makefile:
+      assign = '+='
+    else: # if not makefile
+      assign = '='
+    if libtool:
+      libext = 'la'
+      perhapsLT = 'LT'
+      LD_flags = False
+    else: # if not libtool
+      libext = 'a'
+      perhapsLT = ''
+      LD_flags = 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.
+      check_PROGRAMS = True
+    else: # if not for_test
+      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:
+      if len(actioncmd) <= 3000:
+        emit += "# Reproduce by: %s\n" % actioncmd
+    emit += '\n'
+    uses_subdirs = False
+    
+    # Modify allsnippets variable.
+    allsnippets = string()
+    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 LD_flags:
+          pattern = compiler('lib_LDFLAGS[\t ]*\\+=(.*?)$', re.S | re.M)
+          amsnippet1 = pattern.sub('', amsnippet1)
+        pattern = compiler('lib_([A-Z][A-Z](?:.*?))', re.S | re.M)
+        amsnippet1 = pattern.sub('%s_%s_\\1' % (libname, libext), amsnippet1)
+        amsnippet1 = amsnippet1.replace('lib%_LIBRARIES', 'lib_LIBRARIES')
+        amsnippet1 = amsnippet1.replace('lib%_LTLIBRARIES', 'lib_LTLIBRARIES')
+        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)
+        if check_PROGRAMS:
+          amsnippet1 = amsnippet1.replace('check_PROGRAMS', 'noinst_PROGRAMS')
+        
+        # Get unconditional snippet, edit it and save to amsnippet1.
+        amsnippet2 = module.getAutomakeSnippet_Unconditional()
+        pattern = compiler('lib_([A-Z][A-Z](?:.*?))', re.S | re.M)
+        amsnippet2 = pattern.sub('%s_%s_\\1' % (libname, libext), amsnippet2)
+        if type(amsnippet1) is bytes:
+          amsnippet1 = amsnippet1.decode(ENCS['default'])
+        if type(amsnippet2) is bytes:
+          amsnippet2 = amsnippet1.decode(ENCS['default'])
+        if not (amsnippet1 +amsnippet2).isspace():
+          allsnippets += '## begin gnulib module %s\n' % str(module)
+          if conddeps:
+            if moduletable.isConditional(module):
+              name = module.getConditionalName()
+              allsnippets += 'if %s\n' % name
+          allsnippets += amsnippet1
+          if conddeps:
+            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:
+      subdir_options = string()
+      # 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 = string(' subdir-objects')
+      emit += 'AUTOMAKE_OPTIONS = 1.5 gnits%s\n' % subdir_options
+    emit += '\n'
+    if not makefile:
+      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:
+      #  * http://debbugs.gnu.org/10997
+      #  * http://debbugs.gnu.org/11030
+      # So we need this workaround.
+      pattern = compiler('^pkgdata_DATA *\\+=', re.S | 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:
+      emit += 'MOSTLYCLEANDIRS =\n'
+      emit += 'CLEANFILES =\n'
+      emit += 'DISTCLEANFILES =\n'
+      emit += 'MAINTAINERCLEANFILES =\n'
+    
+    # Execute edits that apply to the Makefile.am being generated.
+    current_edit = int()
+    makefile_am_edits = makefiletable.count()
+    while current_edit != makefile_am_edits:
+      dictionary = makefiletable[current_edit]
+      if dictionary['var']:
+        paths = list()
+        paths += [joinpath(dictionary['dir'], 'Makefile.am')]
+        paths += [os.path.normpath('./%s/Makefile.am' % dictionary['dir'])]
+        paths = sorted(set(paths))
+        if destfile in paths:
+          emit += '%s += %s\n' % (dictionary['var'], dictionary['val'])
+      current_edit += 1
+    
+    # Define two parts of cppflags variable.
+    emit += '\n'
+    cppflags_part1 = string()
+    cppflags_part2 = string()
+    if witness_c_macro:
+      cppflags_part1 = ' -D%s=1' % witness_c_macro
+    if for_test:
+      cppflags_part2 = ' -DGNULIB_STRICT_CHECKING=1'
+    cppflags = '%s%s' % (cppflags_part1, cppflags_part2)
+    if not makefile:
+      emit += 'AM_CPPFLAGS =%s\n' % cppflags
+      emit += 'AM_CFLAGS =\n'
+    else: # if makefile
+      if cppflags:
+        emit += 'AM_CPPFLAGS +=%s\n' % cppflags
+    emit += '\n'
+    
+    # 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.
+    insnippets = False
+    inmakefile = False
+    regex = '^[a-zA-Z0-9_]*_%sLIBRARIES *\\+{0,1}= *%s.%s' % \
+      (perhapsLT, libname, libext)
+    pattern = compiler(regex, re.S | re.M)
+    insnippets = bool(pattern.findall(allsnippets))
+    # Then test if $sourcebase/Makefile.am (if it exists) specifies it.
+    path = joinpath(sourcebase, 'Makefile.am')
+    if makefile and isfile(path):
+      with codecs.open(path, 'rb', 'UTF-8') as file:
+        data = file.read()
+      inmakefile = bool(pattern.findall(data))
+    if not any([insnippets, inmakefile]):
+      # 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.
+      listing = list()
+      links = [module.getLink() for module in modules if not module.isTests()]
+      for link in links:
+        link = constants.nlremove(link)
+        position = link.find(' when linking with libtool')
+        if position != -1:
+          link = link[:position]
+        listing += [link]
+      listing = sorted(set([link for link in listing if link != '']))
+      for link in listing:
+        emit += '%s_%s_LDFLAGS += %s\n' % (libname, libext, link)
+    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'
+    emit = constants.nlconvert(emit)
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    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 string and a bool variable
+    which shows if subdirectories are used.
+    GLConfig: localdir, modules, libname, auxdir, makefile, 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 bytes or type(destfile) is string:
+      if type(destfile) is bytes:
+        destfile = destfile.decode(ENCS['default'])
+    else: # if destfile has not bytes or string type
+      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 bytes or type(witness_macro) is string:
+      if type(witness_macro) is bytes:
+        witness_macro = witness_macro.decode(ENCS['default'])
+    else: # if witness_macro has not bytes or string type
+      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__))
+    emit = string()
+    localdir = self.config['localdir']
+    auxdir = self.config['auxdir']
+    sourcebase = self.config['sourcebase']
+    modcache = self.config['modcache']
+    libname = self.config['libname']
+    m4base = self.config['m4base']
+    pobase = self.config['pobase']
+    testsbase = self.config['testsbase']
+    makefile = self.config['makefile']
+    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']
+    ac_version = self.config['ac_version']
+    libtests = self.config['libtests']
+    single_configure = self.config['single_configure']
+    
+    if libtool:
+      libext = 'la'
+      perhapsLT = 'LT'
+      LD_flags = False
+    else: # if not libtool
+      libext = 'a'
+      perhapsLT = ''
+      LD_flags = 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.
+      check_PROGRAMS = True
+    else: # if not for_test
+      check_PROGRAMS = False
+    
+    # Calculate testsbase_inverse
+    counter = int()
+    testsbase_inverse = string()
+    while counter < len(testsbase.split('/')):
+      testsbase_inverse += '../'
+      counter += 1
+    testsbase_inverse = os.path.normpath(testsbase_inverse)
+    
+    # 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 = string()
+    longrun_snippets = string()
+    for module in modules:
+      if for_test and not single_configure:
+        flag = module.isTests()
+      else: # if for_test and not single_configure
+        flag = True
+      if flag:
+        snippet = module.getAutomakeSnippet()
+        snippet = snippet.replace('lib_LIBRARIES', 'lib%_LIBRARIES')
+        snippet = snippet.replace('lib_LTLIBRARIES', 'lib%_LTLIBRARIES')
+        if LD_flags:
+          pattern = compiler('lib_LDFLAGS[\t ]*\\+=(.*?)$', re.S | re.M)
+          snippet = pattern.sub('', snippet)
+        pattern = compiler('lib_([A-Z][A-Z](?:.*?))', re.S | re.M)
+        snippet = pattern.sub('libtests_a_\\1', snippet)
+        snippet = snippet.replace('lib%_LIBRARIES', 'lib_LIBRARIES')
+        snippet = snippet.replace('lib%_LTLIBRARIES', 'lib_LTLIBRARIES')
+        snippet = snippet.replace('${gl_include_guard_prefix}',
+          include_guard_prefix)
+        if check_PROGRAMS:
+          snippet = snippet.replace('check_PROGRAMS', 'noinst_PROGRAMS')
+        # 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 snippet.strip():
+          # Check status of the module.
+          status = module.getStatus()
+          islongrun = False
+          for word in status:
+            if word == 'longrunning-test':
+              islongrun = True
+              break
+          if not islongrun:
+            snippet = snippet.replace('\n\nEXTRA_DIST', '\nEXTRA_DIST')
+            main_snippets += '## begin gnulib module %s\n' % str(module)
+            main_snippets += snippet
+            main_snippets += '## end   gnulib module %s\n\n' % str(module)
+          else: # if islongrunning
+            snippet = snippet.replace('\n\nEXTRA_DIST', '\nEXTRA_DIST')
+            longrun_snippets += '## begin gnulib module %s\n' % str(module)
+            longrun_snippets += snippet
+            longrun_snippets += '## end gnulib module %s\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
+    
+    # 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 = string()
+    if uses_subdirs:
+      subdir_options = string(' subdir-objects')
+    emit += 'AUTOMAKE_OPTIONS = 1.5 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:
+    #  * http://debbugs.gnu.org/10997
+    #  * http://debbugs.gnu.org/11030
+    # So we need this workaround.
+    pattern = compiler('^pkgdata_DATA *\\+=', re.S | re.M)
+    if bool(pattern.findall(main_snippets)) or \
+    bool(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.
+    # Execute edits that apply to the Makefile.am being generated.
+    current_edit = int()
+    makefile_am_edits = makefiletable.count()
+    while current_edit != makefile_am_edits:
+      dictionary = makefiletable[current_edit]
+      if dictionary['var']:
+        paths = list()
+        paths += [joinpath(dictionary['dir'], 'Makefile.am')]
+        paths += [os.path.normpath('./%s/Makefile.am' % dictionary['dir'])]
+        paths = sorted(set(paths))
+        if destfile in paths:
+          emit += '%s += %s\n' % (dictionary['var'], dictionary['val'])
+      current_edit += 1
+    
+    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'
+    
+    local_ldadd_before = string()
+    local_ldadd_after = string()
+    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
+      # 'error' module whose dependency to 'progname' is voluntarily omitted).
+      # The LIBTESTS_LIBDEPS can be passed to the linker once or twice, it does
+      # not matter.
+      local_ldadd_before = ' libtests.a'
+      local_ldadd_after = ' libtests.a $(LIBTESTS_LIBDEPS)'
+    emit += 'LDADD =%s %s/%s/%s.%s%s\n\n' % \
+      (local_ldadd_before, testsbase_inverse, sourcebase, libname, libext,
+        local_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"
+    main_snippets = main_snippets.replace('$(top_srcdir)/build-aux/',
+      '$(top_srcdir)/%s/' % auxdir)
+    longrun_snippets = longrun_snippets.replace('$(top_srcdir)/build-aux/',
+      '$(top_srcdir)/%s/' % auxdir)
+    emit += main_snippets +longrun_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'
+    emit = constants.nlconvert(emit)
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    result = tuple([emit, uses_subdirs])
+    return(result)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pygnulib/GLError.py	Sun Aug 20 11:17:58 2017 +0300
@@ -0,0 +1,115 @@
+#!/usr/bin/python
+# encoding: UTF-8
+
+#===============================================================================
+# Define global imports
+#===============================================================================
+import os
+import re
+import sys
+import locale
+import codecs
+from . import constants
+
+
+#===============================================================================
+# Define module information
+#===============================================================================
+__author__ = constants.__author__
+__license__ = constants.__license__
+__copyright__ = constants.__copyright__
+
+
+#===============================================================================
+# Define global constants
+#===============================================================================
+PYTHON3 = constants.PYTHON3
+NoneType = type(None)
+APP = constants.APP
+DIRS = constants.DIRS
+ENCS = constants.ENCS
+UTILS = constants.UTILS
+FILES = constants.FILES
+MODES = constants.MODES
+TESTS = constants.TESTS
+compiler = constants.compiler
+joinpath = constants.joinpath
+cleaner = constants.cleaner
+string = constants.string
+isabs = os.path.isabs
+isdir = os.path.isdir
+isfile = os.path.isfile
+normpath = os.path.normpath
+relpath = os.path.relpath
+
+
+#===============================================================================
+# Define GLError class
+#===============================================================================
+class GLError(Exception):
+  '''Exception handler for pygnulib classes.'''
+
+  def __init__(self, errno, errinfo=None):
+    '''Each error has following parameters:
+    errno: code of error; used to catch error type
+      1: file does not exist in GLFileSystem: <file>
+      2: cannot patch file inside GLFileSystem: <file>
+      3: configure file does not exist: <configure.ac>
+      4: minimum supported autoconf version is 2.59, not <version>
+      5: <gnulib-comp.m4> is expected to contain gl_M4_BASE([<m4base>])
+      6: missing sourcebase argument
+      7: missing docbase argument
+      8: missing testsbase argument
+      9: missing libname argument
+     10: conddeps are not supported with inctests
+     11: incompatible licenses on modules: <modules>
+     12: cannot process empy filelist
+     13: cannot create the given directory: <directory>
+     14: cannot delete the given file: <file>
+     15: cannot create the given file: <file>
+     16: cannot transform the given file: <file>
+     17: cannot update the given file: <file>
+     18: module lacks a license: <module>
+     19: could not create destination directory: <directory>
+    errinfo: additional information;
+    style: 0 or 1, wheter old-style'''
+    self.errno = errno; self.errinfo = errinfo
+    self.args = (self.errno, self.errinfo)
+
+  def __repr__(self):
+    errinfo = self.errinfo
+    errors = \
+    [ # Begin list of errors
+      "file does not exist in GLFileSystem: %s" % repr(errinfo),
+      "cannot patch file inside GLFileSystem: %s" % repr(errinfo),
+      "configure file does not exist: %s" % repr(errinfo),
+      "minimum supported autoconf version is 2.59, not %s" % repr(errinfo),
+      "%s is expected to contain gl_M4_BASE([%s])" % \
+        (repr(os.path.join(errinfo, 'gnulib-comp.m4')), repr(errinfo)),
+      "missing sourcebase argument; cache file doesn't contain it,"
+        +" so you might have to set this argument",
+      "missing docbase argument; you might have to create GLImport" \
+        +" instance with mode 0 and docbase argument",
+      "missing testsbase argument; cache file doesn't contain it,"
+        +" so you might have to set this argument"
+      "missing libname argument; cache file doesn't contain it,"
+        +" so you might have to set this argument",
+      "conddeps are not supported with inctests",
+      "incompatible licenses on modules: %s" % repr(errinfo),
+      "cannot process empy filelist",
+      "cannot create the given directory: %s" % repr(errinfo),
+      "cannot remove the given file: %s" % repr(errinfo),
+      "cannot create the given file: %s" % repr(errinfo),
+      "cannot transform the given file: %s" % repr(errinfo),
+      "cannot update/replace the given file: %s" % repr(errinfo),
+      "module lacks a license: %s" % repr(errinfo),
+      "error when running subprocess: %s" % repr(errinfo),
+    ] # Complete list of errors
+    if not PYTHON3:
+      self.message = (b'[Errno %d] %s' % \
+        (self.errno, errors[self.errno -1].encode(ENCS['default'])))
+    else: # if PYTHON3
+      self.message = ('[Errno %d] %s' % \
+        (self.errno, errors[self.errno -1]))
+    return(self.message)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pygnulib/GLFileSystem.py	Sun Aug 20 11:17:58 2017 +0300
@@ -0,0 +1,401 @@
+#!/usr/bin/python
+# encoding: UTF-8
+
+#===============================================================================
+# Define global imports
+#===============================================================================
+import os
+import re
+import sys
+import codecs
+import shutil
+import filecmp
+import subprocess as sp
+from . import constants
+from .GLError import GLError
+from .GLConfig import GLConfig
+
+
+#===============================================================================
+# Define module information
+#===============================================================================
+__author__ = constants.__author__
+__license__ = constants.__license__
+__copyright__ = constants.__copyright__
+
+
+#===============================================================================
+# Define global constants
+#===============================================================================
+PYTHON3 = constants.PYTHON3
+NoneType = type(None)
+APP = constants.APP
+DIRS = constants.DIRS
+ENCS = constants.ENCS
+UTILS = constants.UTILS
+FILES = constants.FILES
+MODES = constants.MODES
+TESTS = constants.TESTS
+compiler = constants.compiler
+joinpath = constants.joinpath
+cleaner = constants.cleaner
+string = constants.string
+isabs = os.path.isabs
+isdir = os.path.isdir
+isfile = os.path.isfile
+normpath = os.path.normpath
+relpath = os.path.relpath
+
+
+#===============================================================================
+# Define GLFileSystem class
+#===============================================================================
+class GLFileSystem(object):
+  '''GLFileSystem class is used to create virtual filesystem, which is based on
+  the gnulib directory and directory specified by localdir argument. Its main
+  method lookup(file) is used to find file in these directories or combine it
+  using Linux 'patch' utility.'''
+  
+  def __init__(self, config):
+    '''Create new GLFileSystem instance. The only argument is localdir,
+    which can be an empty string too.'''
+    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.GLFileSystem %s>' % hex(id(self))
+    return(result)
+    
+  def lookup(self, name):
+    '''GLFileSystem.lookup(name) -> tuple
+    
+    Lookup a file in gnulib and localdir directories or combine it using Linux
+    'patch' utility. If file was found, method returns string, else it raises
+    GLError telling that file was not found. Function also returns flag which
+    indicates whether file is a temporary file.
+    GLConfig: localdir.'''
+    if type(name) is bytes or type(name) is string:
+      if type(name) is bytes:
+        name = name.decode(ENCS['default'])
+    else: # if name has not bytes or string type
+      raise(TypeError(
+        'name must be a string, not %s' % type(module).__name__))
+    # If name exists in localdir, then we use it
+    path_gnulib = joinpath(DIRS['root'], name)
+    path_local = joinpath(self.config['localdir'], name)
+    path_diff = joinpath(self.config['localdir'], '%s.diff' % name)
+    path_temp = joinpath(self.config['tempdir'], name)
+    try: # Try to create directories
+      os.makedirs(os.path.dirname(path_temp))
+    except OSError as error:
+      pass # Skip errors if directory exists
+    if isfile(path_temp):
+      os.remove(path_temp)
+    if self.config['localdir'] and isfile(path_local):
+      result = (path_local, False)
+    else: # if path_local does not exist
+      if isfile(path_gnulib):
+        if self.config['localdir'] and isfile(path_diff):
+          shutil.copy(path_gnulib, path_temp)
+          command = 'patch -s "%s" < "%s"' % (path_temp, path_diff)
+          try: # Try to apply patch
+            sp.check_call(command, shell=True)
+          except sp.CalledProcessError as error:
+            raise(GLError(2, name))
+          result = (path_temp, True)
+        else: # if path_diff does not exist
+          result = (path_gnulib, False)
+      else: # if path_gnulib does not exist
+        raise(GLError(1, name))
+    return(result)
+
+
+#===============================================================================
+# Define GLFileAssistant class
+#===============================================================================
+class GLFileAssistant(object):
+  '''GLFileAssistant is used to help with file processing.'''
+  
+  def __init__(self, config, transformers=dict()):
+    '''Create GLFileAssistant instance.'''
+    if type(config) is not GLConfig:
+      raise(TypeError('config must be a GLConfig, not %s' % \
+        type(config).__name__))
+    if type(transformers) is not dict:
+      raise(TypeError('transformers must be a dict, not %s' % \
+        type(transformers).__name__))
+    for key in ['lib', 'aux', 'main', 'tests']:
+      if key not in transformers:
+        transformers[key] = 's,x,x,'
+      else: # if key in transformers
+        value = transformers[key]
+        if type(value) is bytes or type(value) is string:
+          if type(value) is bytes:
+            transformers[key] = value.decode(ENCS['default'])
+        else: # if value has not bytes or string type
+          raise(TypeError('transformers[%s] must be a string, not %s' % \
+            (key, type(value).__name__)))
+    self.original = None
+    self.rewritten = None
+    self.added = list()
+    self.makefile = list()
+    self.config = config
+    self.transformers = transformers
+    self.filesystem = GLFileSystem(self.config)
+    
+  def __repr__(self):
+    '''x.__repr__() <==> repr(x)'''
+    result = '<pygnulib.GLFileAssistant %s>' % hex(id(self))
+    return(result)
+    
+  def tmpfilename(self, path):
+    '''GLFileAssistant.tmpfilename() -> string
+    
+    Return the name of a temporary file (file is relative to destdir).'''
+    if type(path) is bytes or type(path) is string:
+      if type(path) is bytes:
+        path = path.decode(ENCS['default'])
+    else: # if path has not bytes or string type
+      raise(TypeError(
+        'path must be a string, not %s' % (type(path).__name__)))
+    if not self.config['dryrun']:
+      # Put the new contents of $file in a file in the same directory (needed
+      # to guarantee that an 'mv' to "$destdir/$file" works).
+      result = joinpath(self.config['destdir'], '%s.tmp' % path)
+      dirname = os.path.dirname(result)
+      if dirname and not isdir(dirname):
+        os.makedirs(dirname)
+    else: # if self.config['dryrun']
+      # Put the new contents of $file in a file in a temporary directory
+      # (because the directory of "$file" might not exist).
+      tempdir = self.config['tempdir']
+      result = joinpath(tempdir, '%s.tmp' % os.path.basename(path))
+      dirname = os.path.dirname(result)
+      if not isdir(dirname):
+        os.makedirs(dirname)
+    if type(result) is bytes:
+      result = bytes.decode(ENCS['default'])
+    return(result)
+    
+  def setOriginal(self, original):
+    '''GLFileAssistant.setOriginal(original)
+    
+    Set the name of the original file which will be used.'''
+    if type(original) is bytes or type(original) is string:
+      if type(original) is bytes:
+        original = original.decode(ENCS['default'])
+    else: # if original has not bytes or string type
+      raise(TypeError(
+        'original must be a string, not %s' % (type(original).__name__)))
+    self.original = original
+    
+  def setRewritten(self, rewritten):
+    '''GLFileAssistant.setRewritten(rewritten)
+    
+    Set the name of the rewritten file which will be used.'''
+    if type(rewritten) is bytes or type(rewritten) is string:
+      if type(rewritten) is bytes:
+        rewritten = rewritten.decode(ENCS['default'])
+    else: # if rewritten has not bytes or string type
+      raise(TypeError(
+        'rewritten must be a string, not %s' % type(rewritten).__name__))
+    self.rewritten = rewritten
+    
+  def addFile(self, file):
+    '''GLFileAssistant.addFile(file)
+    
+    Add file to the list of added files.'''
+    if file not in self.added:
+      self.added += [file]
+    
+  def removeFile(self, file):
+    '''GLFileAssistant.removeFile(file)
+    
+    Remove file from the list of added files.'''
+    if file in self.added:
+      self.added.pop(file)
+    
+  def getFiles(self):
+    '''Return list of the added files.'''
+    return(list(self.added))
+    
+  def add(self, lookedup, tmpflag, tmpfile):
+    '''GLFileAssistant.add(lookedup, tmpflag, tmpfile)
+    
+    This method copies a file from gnulib into the destination directory.
+    The destination is known to exist. If tmpflag is True, then lookedup file
+    is a temporary one.'''
+    original = self.original
+    rewritten = self.rewritten
+    destdir = self.config['destdir']
+    symbolic = self.config['symbolic']
+    lsymbolic = self.config['lsymbolic']
+    if original == None:
+      raise(TypeError('original must be set before applying the method'))
+    elif rewritten == None:
+      raise(TypeError('rewritten must be set before applying the method'))
+    if not self.config['dryrun']:
+      print('Copying file %s' % rewritten)
+      loriginal = joinpath(self.config['localdir'], original)
+      if (symbolic or (lsymbolic and lookedup == loriginal)) \
+      and not tmpflag and filecmp.cmp(lookedup, tmpfile):
+        constants.link_if_changed(lookedup, joinpath(destdir, rewritten))
+      else: # if any of these conditions is not met
+        try: # Try to move file
+          shutil.move(tmpfile, joinpath(destdir, rewritten))
+        except Exception as error:
+          raise(GLError(17, original))
+    else: # if self.config['dryrun']
+      print('Copy file %s' % rewritten)
+    
+  def update(self, lookedup, tmpflag, tmpfile, already_present):
+    '''GLFileAssistant.update(lookedup, tmpflag, tmpfile, already_present)
+    
+    This method copies a file from gnulib into the destination directory.
+    The destination is known to exist. If tmpflag is True, then lookedup file
+    is a temporary one.'''
+    original = self.original
+    rewritten = self.rewritten
+    destdir = self.config['destdir']
+    symbolic = self.config['symbolic']
+    lsymbolic = self.config['lsymbolic']
+    if original == None:
+      raise(TypeError('original must be set before applying the method'))
+    elif rewritten == None:
+      raise(TypeError('rewritten must be set before applying the method'))
+    if type(lookedup) is bytes or type(lookedup) is string:
+      if type(lookedup) is bytes:
+        lookedup = lookedup.decode(ENCS['default'])
+    else: # if lookedup has not bytes or string type
+      raise(TypeError('lookedup must be a string, not %s' % \
+        type(lookedup).__name__))
+    if type(already_present) is not bool:
+      raise(TypeError('already_present must be a bool, not %s' % \
+        type(already_present).__name__))
+    basename = rewritten
+    backupname = string('%s~' % basename)
+    basepath = joinpath(destdir, basename)
+    backuppath = joinpath(destdir, backupname)
+    if not filecmp.cmp(basepath, tmpfile):
+      if not self.config['dryrun']:
+        if already_present:
+          print('Updating file %s (backup in %s)' % (basename, backupname))
+        else: # if not already_present
+          message = 'Replacing file '
+          message += '%s (non-gnulib code backed up in ' % basename
+          message += '%s) !!' % backupname
+          print(message)
+        if isfile(backuppath):
+          os.remove(backuppath)
+        try: # Try to replace the given file
+          shutil.move(basepath, backuppath)
+        except Exception as error:
+          raise(GLError(17, original))
+        loriginal = joinpath(self.config['localdir'], original)
+        if (symbolic or (lsymbolic and lookedup == loriginal)) \
+        and not tmpflag and filecmp.cmp(lookedup, tmpfile):
+          constants.link_if_changed(lookedup, basepath)
+        else: # if any of these conditions is not met
+          try: # Try to move file
+            if os.path.exists(basepath):
+              os.remove(basepath)
+            shutil.move(tmpfile, rewritten)
+          except Exception as error:
+            raise(GLError(17, original))
+      else: # if self.config['dryrun']
+        if already_present:
+          print('Update file %s (backup in %s)' % (rewritten, backup))
+        else: # if not already_present
+          print('Replace file %s (backup in %s)' % (rewritten, backup))
+    
+  def add_or_update(self, already_present):
+    '''GLFileAssistant.add_or_update(already_present)
+    
+    This method handles a file that ought to be present afterwards.'''
+    original = self.original
+    rewritten = self.rewritten
+    if original == None:
+      raise(TypeError('original must be set before applying the method'))
+    elif rewritten == None:
+      raise(TypeError('rewritten must be set before applying the method'))
+    if type(already_present) is not bool:
+      raise(TypeError('already_present must be a bool, not %s' % \
+          type(already_present).__name__))
+    xoriginal = original
+    if original.startswith('tests=lib/'):
+      xoriginal = constants.substart('tests=lib/', 'lib/', original)
+    lookedup, tmpflag = self.filesystem.lookup(xoriginal)
+    tmpfile = self.tmpfilename(rewritten)
+    sed_transform_lib_file = self.transformers.get('lib', '')
+    sed_transform_build_aux_file = self.transformers.get('aux', '')
+    sed_transform_main_lib_file = self.transformers.get('main', '')
+    sed_transform_testsrelated_lib_file = self.transformers.get('tests', '')
+    try: # Try to copy lookedup file to tmpfile
+      shutil.copy(lookedup, tmpfile)
+    except Exception as error:
+      raise(GLError(15, lookedup))
+    transformer = string()
+    if original.startswith('lib/'):
+      if sed_transform_main_lib_file:
+        transformer = sed_transform_main_lib_file
+    elif original.startswith('build-aux/'):
+      if sed_transform_build_aux_file:
+        transformer = sed_transform_build_aux_file
+    elif original.startswith('tests=lib/'):
+      if sed_transform_testsrelated_lib_file:
+        transformer = sed_transform_testsrelated_lib_file
+    if transformer:
+      args = ['sed', '-e', transformer]
+      stdin = codecs.open(lookedup, 'rb', 'UTF-8')
+      try: # Try to transform file
+        data = sp.check_output(args, stdin=stdin, shell=False)
+        data = data.decode(ENCS['shell'])
+      except Exception as error:
+        raise(GLError(16, lookedup))
+      with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
+        file.write(data)
+    path = joinpath(self.config['destdir'], rewritten)
+    if isfile(path):
+      self.update(lookedup, tmpflag, tmpfile, already_present)
+      os.remove(tmpfile)
+    else: # if not isfile(path)
+      self.add(lookedup, tmpflag, tmpfile)
+      self.addFile(rewritten)
+    
+  def super_update(self, basename, tmpfile):
+    '''GLFileAssistant.super_update(basename, tmpfile) -> tuple
+    
+    Move tmpfile to destdir/basename path, making a backup of it.
+    Returns tuple, which contains basename, backupname and status.
+      0: tmpfile is the same as destfile;
+      1: tmpfile was used to update destfile;
+      2: destfile was created, because it didn't exist.'''
+    backupname = '%s~' % basename
+    basepath = joinpath(self.config['destdir'], basename)
+    backuppath = joinpath(self.config['destdir'], backupname)
+    if isfile(basepath):
+      if filecmp.cmp(basepath, tmpfile):
+        result_flag = 0
+      else: # if not filecmp.cmp(basepath, tmpfile)
+        result_flag = 1
+        if not self.config['dryrun']:
+          if isfile(backuppath):
+            os.remove(backuppath)
+          shutil.move(basepath, backuppath)
+          shutil.move(tmpfile, basepath)
+        else: # if self.config['dryrun']
+          os.remove(tmpfile)
+    else: # if not isfile(basepath)
+      result_flag = 2
+      if not self.config['dryrun']:
+        if isfile(basepath):
+          os.remove(basepath)
+        shutil.move(tmpfile, basepath)
+      else: # if self.config['dryrun']
+        os.remove(tmpfile)
+    result = tuple([basename, backupname, result_flag])
+    return(result)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pygnulib/GLImport.py	Sun Aug 20 11:17:58 2017 +0300
@@ -0,0 +1,1425 @@
+#!/usr/bin/python
+# encoding: UTF-8
+
+#===============================================================================
+# Define global imports
+#===============================================================================
+import os
+import re
+import sys
+import locale
+import codecs
+import shutil
+import filecmp
+import subprocess as sp
+from . import constants
+from .GLError import GLError
+from .GLConfig import GLConfig
+from .GLModuleSystem import GLModule
+from .GLModuleSystem import GLModuleTable
+from .GLModuleSystem import GLModuleSystem
+from .GLFileSystem import GLFileSystem
+from .GLFileSystem import GLFileAssistant
+from .GLMakefileTable import GLMakefileTable
+from .GLEmiter import GLEmiter
+
+
+#===============================================================================
+# Define module information
+#===============================================================================
+__author__ = constants.__author__
+__license__ = constants.__license__
+__copyright__ = constants.__copyright__
+
+
+#===============================================================================
+# Define global constants
+#===============================================================================
+PYTHON3 = constants.PYTHON3
+NoneType = type(None)
+APP = constants.APP
+DIRS = constants.DIRS
+ENCS = constants.ENCS
+UTILS = constants.UTILS
+FILES = constants.FILES
+MODES = constants.MODES
+TESTS = constants.TESTS
+compiler = constants.compiler
+joinpath = constants.joinpath
+cleaner = constants.cleaner
+relpath = constants.relativize
+string = constants.string
+isabs = os.path.isabs
+isdir = os.path.isdir
+isfile = os.path.isfile
+normpath = os.path.normpath
+
+
+#===============================================================================
+# Define GLImport class
+#===============================================================================
+class GLImport(object):
+  '''GLImport class is used to provide methods for --import, --add-import,
+  --remove-import and --update actions. This is a high-level class, so
+  developers may  have to use lower-level classes to create their own
+  scripts. However, if user needs just to use power of gnulib-tool, this class
+  is a very good choice.'''
+  
+  def __init__(self, config, mode):
+    '''Create GLImport instance.
+    The first variable, mode, must be one of the values of the MODES dict
+    object, which is accessible from constants module. The second one, config,
+    must be a GLConfig object.'''
+    if type(config) is not GLConfig:
+      raise(TypeError('config must have GLConfig type, not %s' % \
+        repr(config)))
+    if type(mode) is int and \
+      MODES['import'] <= mode <= MODES['update']:
+        self.mode = mode
+    else: # if mode is not int or is not 0-3
+      raise(TypeError('mode must be 0 <= mode <= 3, not %s' % \
+        repr(mode)))
+    
+    # Initialize some values.
+    self.cache = GLConfig()
+    self.config = config.copy()
+    os.rmdir(self.cache['tempdir'])
+    
+    # Get cached auxdir and libtool from configure.ac/in.
+    self.cache.setAuxDir('.')
+    path = joinpath(self.config['destdir'], 'configure.ac')
+    if not isfile(path):
+      path = joinpath(self.config['destdir'], 'configure.in')
+      if not isfile(path):
+        raise(GLError(3, path))
+    self.config.setAutoconfFile(path)
+    with codecs.open(path, 'rb', 'UTF-8') as file:
+      data = file.read()
+    pattern = compiler(r'^AC_CONFIG_AUX_DIR\((.*?)\)$', re.S | re.M)
+    match = pattern.findall(data)
+    if match:
+      result = cleaner(match)[0]
+      self.cache.setAuxDir(joinpath(result, self.config['destdir']))
+    pattern = compiler(r'A[CM]_PROG_LIBTOOL', re.S | re.M)
+    guessed_libtool = bool(pattern.findall(data))
+    if self.config['auxdir'] == None:
+      self.config.setAuxDir(self.cache['auxdir'])
+    
+    # Guess autoconf version.
+    pattern = compiler('.*AC_PREREQ\((.*?)\)', re.S | re.M)
+    versions = cleaner(pattern.findall(data))
+    if versions:
+      version = sorted(set([float(version) for version in versions]))[-1]
+      self.config.setAutoconfVersion(version)
+      if version < 2.59:
+        raise(GLError(4, version))
+    
+    # Get other cached variables.
+    path = joinpath(self.config['m4base'], 'gnulib-cache.m4')
+    if isfile(joinpath(self.config['m4base'], 'gnulib-cache.m4')):
+      with codecs.open(path, 'rb', 'UTF-8') as file:
+        data = file.read()
+      
+      # Create regex object and keys.
+      pattern = compiler('^(gl_.*?)\\((.*?)\\)$', re.S | re.M)
+      keys = \
+      [
+        'gl_LOCAL_DIR', 'gl_MODULES', 'gl_AVOID', 'gl_SOURCE_BASE',
+        'gl_M4_BASE', 'gl_PO_BASE', 'gl_DOC_BASE', 'gl_TESTS_BASE',
+        'gl_MAKEFILE_NAME', 'gl_MACRO_PREFIX', 'gl_PO_DOMAIN',
+        'gl_WITNESS_C_MACRO', 'gl_VC_FILES', 'gl_LIB',
+      ]
+      
+      # Find bool values.
+      if 'gl_LGPL(' in data:
+        keys.append('gl_LGPL')
+        self.cache.setLGPL(True)
+      if 'gl_LIBTOOL' in data:
+        self.cache.enableLibtool()
+        data = data.replace('gl_LIBTOOL', '')
+      if 'gl_CONDITIONAL_DEPENDENCIES' in data:
+        self.cache.enableCondDeps()
+        data = data.replace('gl_CONDITIONAL_DEPENDENCIES', '')
+      if 'gl_VC_FILES' in data:
+        self.cache.enableVCFiles()
+        data = data.replace('gl_VC_FILES', '')
+      if 'gl_WITH_TESTS' in data:
+        self.cache.enableTestFlag(TESTS['tests'])
+        data = data.replace('gl_WITH_TESTS', '')
+      if 'gl_WITH_OBSOLETE' in data:
+        self.cache.enableTestFlag(TESTS['obsolete'])
+        data = data.replace('gl_WITH_OBSOLETE', '')
+      if 'gl_WITH_CXX_TESTS' in data:
+        self.cache.enableTestFlag(TESTS['c++-test'])
+        data = data.replace('gl_WITH_CXX_TESTS', '')
+      if 'gl_WITH_LONGRUNNING_TESTS' in data:
+        self.cache.enableTestFlag(TESTS['longrunning-test'])
+        data = data.replace('gl_WITH_LONGRUNNING_TESTS', '')
+      if 'gl_WITH_PRIVILEGED_TESTS' in data:
+        self.cache.enableTestFlag(TESTS['privileged-test'])
+        data = data.replace('gl_WITH_PRIVILEGED_TESTS', '')
+      if 'gl_WITH_UNPORTABLE_TESTS' in data:
+        self.cache.enableTestFlag(TESTS['unportable-test'])
+        data = data.replace('gl_WITH_UNPORTABLE_TESTS', '')
+      if 'gl_WITH_ALL_TESTS' in data:
+        self.cache.enableTestFlag(TESTS['all-test'])
+        data = data.replace('gl_WITH_ALL_TESTS', '')
+      # Find string values
+      result = dict(pattern.findall(data))
+      values = cleaner([result.get(key, '') for key in keys])
+      tempdict = dict(zip(keys, values))
+      if 'gl_LGPL' in tempdict:
+        lgpl = cleaner(tempdict['gl_LGPL'])
+        if lgpl.isdecimal():
+          self.cache.setLGPL(int(self.cache['lgpl']))
+      else: # if 'gl_LGPL' not in tempdict
+        self.cache.setLGPL(False)
+      if tempdict['gl_LIB']:
+        self.cache.setLibName(cleaner(tempdict['gl_LIB']))
+      if tempdict['gl_LOCAL_DIR']:
+        self.cache.setLocalDir(cleaner(tempdict['gl_LOCAL_DIR']))
+      if tempdict['gl_MODULES']:
+        self.cache.setModules(cleaner(tempdict['gl_MODULES'].split()))
+      if tempdict['gl_AVOID']:
+        self.cache.setAvoids(cleaner(tempdict['gl_AVOID'].split()))
+      if tempdict['gl_SOURCE_BASE']:
+        self.cache.setSourceBase(cleaner(tempdict['gl_SOURCE_BASE']))
+      if tempdict['gl_M4_BASE']:
+        self.cache.setM4Base(cleaner(tempdict['gl_M4_BASE']))
+      if tempdict['gl_PO_BASE']:
+        self.cache.setPoBase(cleaner(tempdict['gl_PO_BASE']))
+      if tempdict['gl_DOC_BASE']:
+        self.cache.setDocBase(cleaner(tempdict['gl_DOC_BASE']))
+      if tempdict['gl_TESTS_BASE']:
+        self.cache.setTestsBase(cleaner(tempdict['gl_TESTS_BASE']))
+      if tempdict['gl_MAKEFILE_NAME']:
+        self.cache.setMakefile(cleaner(tempdict['gl_MAKEFILE_NAME']))
+      if tempdict['gl_MACRO_PREFIX']:
+        self.cache.setMacroPrefix(cleaner(tempdict['gl_MACRO_PREFIX']))
+      if tempdict['gl_PO_DOMAIN']:
+        self.cache.setPoDomain(cleaner(tempdict['gl_PO_DOMAIN']))
+      if tempdict['gl_WITNESS_C_MACRO']:
+        self.cache.setWitnessCMacro(cleaner(tempdict['gl_WITNESS_C_MACRO']))
+      
+      # Get cached filelist from gnulib-comp.m4.
+      destdir, m4base = self.config.getDestDir(), self.config.getM4Base()
+      path = joinpath(destdir, m4base, 'gnulib-comp.m4')
+      if isfile(path):
+        with codecs.open(path, 'rb', 'UTF-8') as file:
+          data = file.read()
+        regex = 'AC_DEFUN\\(\\[%s_FILE_LIST\\], \\[(.*?)\\]\\)' % \
+          self.cache['macro_prefix']
+        pattern = compiler(regex, re.S | re.M)
+        self.cache.setFiles(pattern.findall(data)[-1].strip().split())
+    
+    # The self.config['localdir'] defaults to the cached one. Recall that the 
+    # cached one is relative to $destdir, whereas the one we use is relative
+    # to . or absolute.
+    if not self.config['localdir']:
+      if self.cache['localdir']:
+        if isabs(self.config['destdir']):
+          localdir = joinpath(self.config['destdir'], self.cache['localdir'])
+        else: # if not isabs(self.config['destdir'])
+          if isabs(self.cache['localdir']):
+            localdir = joinpath(self.config['destdir'], self.cache['localdir'])
+          else: # if not isabs(self.cache['localdir'])
+            # NOTE: I NEED TO IMPLEMENT RELATIVE_CONCAT
+            localdir = os.path.relpath(joinpath(self.config['destdir'],
+              self.cache['localdir']))
+        self.config.setLocalDir(localdir)
+      
+    if self.mode != MODES['import']:
+      if self.cache['m4base'] and \
+      (self.config['m4base'] != self.cache['m4base']):
+        raise(GLError(5, m4base))
+      
+      # Perform actions with modules. In --add-import, append each given module
+      # to the list of cached modules; in --remove-import, remove each given
+      # module from the list of cached modules; in --update, simply set
+      # self.config['modules'] to its cached version.
+      new, old = self.config.getModules(), self.cache.getModules()
+      if self.mode == MODES['add-import']:
+        modules = sorted(set(new +old))
+      elif self.mode == MODES['remove-import']:
+        modules = [module for module in old if module in new]
+      elif self.mode == MODES['update']:
+        modules = self.cache.getModules()
+      
+      # If user tries to apply conddeps and testflag['tests'] together.
+      if self.config['tests'] and self.config['conddeps']:
+        raise(GLError(10, None))
+      
+      # Update configuration dictionary.
+      self.config.update(self.cache)
+      for key in config.keys():
+        value = config[key]
+        if not config.isdefault(key, value):
+          self.config.update_key(config, key)
+      self.config.setModules(modules)
+    
+    # Check if conddeps is enabled together with inctests.
+    inctests = self.config.checkTestFlag(TESTS['tests'])
+    if self.config['conddeps'] and inctests:
+      raise(GLError(10, None))
+    
+    # Define GLImport attributes.
+    self.emiter = GLEmiter(self.config)
+    self.filesystem = GLFileSystem(self.config)
+    self.modulesystem = GLModuleSystem(self.config)
+    self.moduletable = GLModuleTable(self.config, list())
+    self.makefiletable = GLMakefileTable(self.config)
+    
+  def __repr__(self):
+    '''x.__repr__ <==> repr(x)'''
+    result = '<pygnulib.GLImport %s>' % hex(id(self))
+    return(result)
+    
+  def rewrite_old_files(self, files):
+    '''GLImport.rewrite_old_files(files) -> list
+    
+    Replace auxdir, docbase, sourcebase, m4base and testsbase from default
+    to their version from cached config.'''
+    if type(files) is not list:
+      raise(TypeError(
+        'files argument must has list type, not %s' % type(files).__name__))
+    files = \
+    [ # Begin to convert bytes to string
+      file.decode(ENCS['default']) \
+      if type(file) is bytes else file \
+      for file in files
+    ] # Finish to convert bytes to string
+    for file in files:
+      if type(file) is not string:
+        raise(TypeError('each file must be a string instance'))
+    files = sorted(set(files))
+    files = ['%s%s' % (file, os.path.sep) for file in files]
+    auxdir = self.cache['auxdir']
+    docbase = self.cache['docbase']
+    sourcebase = self.cache['sourcebase']
+    m4base = self.cache['m4base']
+    testsbase = self.cache['testsbase']
+    result = list()
+    for file in files:
+      if file.startswith('build-aux/'):
+        path = constants.substart('build-aux/', '%s/' % auxdir, file)
+      elif file.startswith('doc/'):
+        path = constants.substart('doc/', '%s/' % docbase, file)
+      elif file.startswith('lib/'):
+        path = constants.substart('lib/', '%s/' % sourcebase, file)
+      elif file.startswith('m4/'):
+        path = constants.substart('m4/', '%s/' % m4base, file)
+      elif file.startswith('tests/'):
+        path = constants.substart('tests/', '%s/' % testsbase, file)
+      elif file.startswith('tests=lib/'):
+        path = constants.substart('tests=lib/', '%s/' % testsbase, file)
+      elif file.startswith('top/'):
+        path = constants.substart('top/', '', file)
+      else: # file is not a special file
+        path = file
+      result += [os.path.normpath(path)]
+    result = sorted(set(result))
+    return(list(result))
+    
+  def rewrite_new_files(self, files):
+    '''GLImport.rewrite_new_files(files)
+    
+    Replace auxdir, docbase, sourcebase, m4base and testsbase from default
+    to their version from config.'''
+    if type(files) is not list:
+      raise(TypeError(
+        'files argument must has list type, not %s' % type(files).__name__))
+    files = \
+    [ # Begin to convert bytes to string
+      file.decode(ENCS['default']) \
+      if type(file) is bytes else file \
+      for file in files
+    ] # Finish to convert bytes to string
+    for file in files:
+      if type(file) is not string:
+        raise(TypeError('each file must be a string instance'))
+    files = sorted(set(files))
+    auxdir = self.config['auxdir']
+    docbase = self.config['docbase']
+    sourcebase = self.config['sourcebase']
+    m4base = self.config['m4base']
+    testsbase = self.config['testsbase']
+    result = list()
+    for file in files:
+      if file.startswith('build-aux/'):
+        path = constants.substart('build-aux/', '%s/' % auxdir, file)
+      elif file.startswith('doc/'):
+        path = constants.substart('doc/', '%s/' % docbase, file)
+      elif file.startswith('lib/'):
+        path = constants.substart('lib/', '%s/' % sourcebase, file)
+      elif file.startswith('m4/'):
+        path = constants.substart('m4/', '%s/' % m4base, file)
+      elif file.startswith('tests/'):
+        path = constants.substart('tests/', '%s/' % testsbase, file)
+      elif file.startswith('tests=lib/'):
+        path = constants.substart('tests=lib/', '%s/' % testsbase, file)
+      elif file.startswith('top/'):
+        path = constants.substart('top/', '', file)
+      else: # file is not a special file
+        path = file
+      result += [os.path.normpath(path)]
+    result = sorted(set(result))
+    return(list(result))
+    
+  def actioncmd(self):
+    '''Return command-line invocation comment.'''
+    modules = self.config.getModules()
+    avoids = self.config.getAvoids()
+    destdir = self.config.getDestDir()
+    localdir = self.config.getLocalDir()
+    auxdir = self.config.getAuxDir()
+    sourcebase = self.config.getSourceBase()
+    m4base = self.config.getM4Base()
+    docbase = self.config.getDocBase()
+    pobase = self.config.getPoBase()
+    testsbase = self.config.getTestsBase()
+    testflags = self.config.getTestFlags()
+    conddeps = self.config.checkCondDeps()
+    libname = self.config.getLibName()
+    lgpl = self.config.getLGPL()
+    makefile = self.config.getMakefile()
+    libtool = self.config.checkLibtool()
+    macro_prefix = self.config.getMacroPrefix()
+    witness_c_macro = self.config.getWitnessCMacro()
+    podomain = self.config.getPoDomain()
+    vc_files = self.config.checkVCFiles()
+    verbose = self.config.getVerbosity()
+    
+    # Create command-line invocation comment.
+    actioncmd = 'gnulib-tool --import'
+    actioncmd += ' --dir=%s' % destdir
+    if localdir:
+      actioncmd += ' --local-dir=%s' % localdir
+    actioncmd += ' --lib=%s' % libname
+    actioncmd += ' --source-base=%s' % sourcebase
+    actioncmd += ' --m4-base=%s' % m4base
+    if pobase:
+      actioncmd += ' --po-base=%s' % pobase
+    actioncmd += ' --doc-base=%s' % docbase
+    actioncmd += ' --tests-base=%s' % testsbase
+    actioncmd += ' --aux-dir=%s' % auxdir
+    if self.config.checkTestFlag(TESTS['tests']):
+      actioncmd += ' --with-tests'
+    if self.config.checkTestFlag(TESTS['obsolete']):
+      actioncmd += ' --with-obsolete'
+    if self.config.checkTestFlag(TESTS['c++-test']):
+      actioncmd += ' --with-c++-tests'
+    if self.config.checkTestFlag(TESTS['longrunning-test']):
+      actioncmd += ' --with-longrunning-tests'
+    if self.config.checkTestFlag(TESTS['privileged-test']):
+      actioncmd += ' --with-privileged-test'
+    if self.config.checkTestFlag(TESTS['unportable-test']):
+      actioncmd += ' --with-unportable-tests'
+    if self.config.checkTestFlag(TESTS['all-test']):
+      actioncmd += ' --with-all-tests'
+    for module in avoids:
+      actioncmd += ' --avoid=%s' % module
+    if lgpl:
+      if lgpl == True:
+        actioncmd += ' --lgpl'
+      else: # if lgpl != True
+        actioncmd += ' --lgpl=%s' % lgpl
+    if makefile:
+      actioncmd += ' --makefile-name=%s' % makefile
+    if conddeps:
+      actioncmd += ' --conditional-dependencies'
+    else: # if not conddeps
+      actioncmd += ' --no-conditional-dependencies'
+    if libtool:
+      actioncmd += ' --libtool'
+    else: # if not libtool
+      actioncmd += ' --no-libtool'
+    actioncmd += ' --macro-prefix=%s' % macro_prefix
+    if podomain:
+      actioncmd = ' --podomain=%s' % podomain
+    if witness_c_macro:
+      actioncmd += ' --witness_c_macro=%s' % witness_c_macro
+    if vc_files == True:
+      actioncmd += ' --vc-files'
+    elif vc_files == False:
+      actioncmd += ' --no-vc-files'
+    actioncmd += ' ' # Add a space
+    actioncmd += ' '.join(modules)
+    return(actioncmd)
+    
+  def gnulib_cache(self):
+    '''GLImport.gnulib_cache() -> string
+    
+    Emit the contents of generated $m4base/gnulib-cache.m4 file.
+    GLConfig: destdir, localdir, tests, sourcebase, m4base, pobase, docbase,
+    testsbase, conddeps, libtool, macro_prefix, podomain, vc_files.'''
+    emit = string()
+    moduletable = self.moduletable
+    actioncmd = self.actioncmd()
+    destdir = self.config['destdir']
+    localdir = self.config['localdir']
+    testflags = list(self.config['testflags'])
+    sourcebase = self.config['sourcebase']
+    m4base = self.config['m4base']
+    pobase = self.config['pobase']
+    docbase = self.config['docbase']
+    testsbase = self.config['testsbase']
+    lgpl = self.config['lgpl']
+    libname = self.config['libname']
+    makefile = self.config['makefile']
+    conddeps = self.config['conddeps']
+    libtool = self.config['libtool']
+    macro_prefix = self.config['macro_prefix']
+    podomain = self.config['podomain']
+    witness_c_macro = self.config['witness_c_macro']
+    vc_files = self.config['vc_files']
+    modules = [str(module) for module in moduletable['base']]
+    avoids = [str(avoid) for avoid in moduletable['avoids']]
+    emit += self.emiter.copyright_notice()
+    emit += '''#
+# This file represents the specification of how gnulib-tool is used.
+# It acts as a cache: It is written and read by gnulib-tool.
+# In projects that use version control, this file is meant to be put under
+# version control, like the configure.ac and various Makefile.am files.
+
+
+# Specification in the form of a command-line invocation:
+#   %s
+
+# Specification in the form of a few \
+gnulib-tool.m4 macro invocations:\n''' % actioncmd
+    if not localdir or localdir.startswith('/'):
+      relative_localdir = localdir
+    else: # if localdir or not localdir.startswith('/')
+      relative_localdir = constants.relativize(destdir, localdir)
+    emit += 'gl_LOCAL_DIR([%s])\n' % relative_localdir
+    emit += 'gl_MODULES([\n'
+    emit += '  %s\n' % '\n  '.join(modules)
+    emit += '])\n'
+    if self.config.checkTestFlag(TESTS['obsolete']):
+      emit += 'gl_WITH_OBSOLETE\n'
+    if self.config.checkTestFlag(TESTS['cxx-tests']):
+      emit += 'gl_WITH_CXX_TESTS\n'
+    if self.config.checkTestFlag(TESTS['privileged-tests']):
+      emit += 'gl_WITH_PRIVILEGED_TESTS\n'
+    if self.config.checkTestFlag(TESTS['unportable-tests']):
+      emit += 'gl_WITH_UNPORTABLE_TESTS\n'
+    if self.config.checkTestFlag(TESTS['all-tests']):
+      emit += 'gl_WITH_ALL_TESTS\n'
+    emit += 'gl_AVOID([%s])\n' % ' '.join(avoids)
+    emit += 'gl_SOURCE_BASE([%s])\n' % sourcebase
+    emit += 'gl_M4_BASE([%s])\n' % m4base
+    emit += 'gl_PO_BASE([%s])\n' % pobase
+    emit += 'gl_DOC_BASE([%s])\n' % docbase
+    emit += 'gl_TESTS_BASE([%s])\n' % testsbase
+    if self.config.checkTestFlag(TESTS['tests']):
+      emit += 'gl_WITH_TESTS\n'
+    emit += 'gl_LIB([%s])\n' % libname
+    if lgpl != False:
+      if lgpl == True:
+        emit += 'gl_LGPL\n'
+      else: # if lgpl != True
+        emit += 'gl_LGPL([%d])\n' % lgpl
+    emit += 'gl_MAKEFILE_NAME([%s])\n' % makefile
+    if conddeps:
+      emit += 'gl_CONDITIONAL_DEPENDENCIES\n'
+    if libtool:
+      emit += 'gl_LIBTOOL\n'
+    emit += 'gl_MACRO_PREFIX([%s])\n' % macro_prefix
+    emit += 'gl_PO_DOMAIN([%s])\n' % podomain
+    emit += 'gl_WITNESS_C_DOMAIN([%s])\n' % witness_c_macro
+    if vc_files:
+      emit += 'gl_VC_FILES([%s])\n' % vc_files
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    return(constants.nlconvert(emit))
+    
+  def gnulib_comp(self, files):
+    '''GLImport.gnulib_comp(files) -> string
+    
+    Emit the contents of generated $m4base/gnulib-comp.m4 file.
+    GLConfig: destdir, localdir, tests, sourcebase, m4base, pobase, docbase,
+    testsbase, conddeps, libtool, macro_prefix, podomain, vc_files.'''
+    emit = string()
+    assistant = self.assistant
+    moduletable = self.moduletable
+    destdir = self.config['destdir']
+    localdir = self.config['localdir']
+    auxdir = self.config['auxdir']
+    testflags = list(self.config['testflags'])
+    sourcebase = self.config['sourcebase']
+    m4base = self.config['m4base']
+    pobase = self.config['pobase']
+    docbase = self.config['docbase']
+    testsbase = self.config['testsbase']
+    lgpl = self.config['lgpl']
+    libname = self.config['libname']
+    makefile = self.config['makefile']
+    conddeps = self.config['conddeps']
+    libtool = self.config['libtool']
+    macro_prefix = self.config['macro_prefix']
+    podomain = self.config['podomain']
+    witness_c_macro = self.config['witness_c_macro']
+    configure_ac = self.config['configure_ac']
+    vc_files = self.config['vc_files']
+    libtests = self.config['libtests']
+    modules = [str(module) for module in moduletable['base']]
+    avoids = [str(avoid) for avoid in moduletable['avoids']]
+    emit += '# DO NOT EDIT! GENERATED AUTOMATICALLY!\n'
+    emit += self.emiter.copyright_notice()
+    emit += '''#
+# This file represents the compiled summary of the specification in
+# gnulib-cache.m4. It lists the computed macro invocations that need
+# to be invoked from configure.ac.
+# In projects that use version control, this file can be treated like
+# other built files.
+
+
+# This macro should be invoked from %s, in the section
+# "Checks for programs", right after AC_PROG_CC, and certainly before
+# any checks for libraries, header files, types and library functions.
+AC_DEFUN([%s_EARLY],
+[
+  m4_pattern_forbid([^gl_[A-Z]])dnl the gnulib macro namespace
+  m4_pattern_allow([^gl_ES$])dnl a valid locale name
+  m4_pattern_allow([^gl_LIBOBJS$])dnl a variable
+  m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable
+  AC_REQUIRE([gl_PROG_AR_RANLIB])\n''' % (configure_ac, macro_prefix)
+    uses_subdirs = False
+    for module in moduletable['main']:
+      # 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 uses_subdirs:
+      emit += '  AC_REQUIRE([AM_PROG_CC_C_O])\n'
+    for module in moduletable['final']:
+      emit += '  # Code from module %s:\n' % str(module)
+      snippet = module.getAutoconfSnippet_Early()
+      lines = [line for line in snippet.split(constants.NL) if line != '']
+      if lines:
+        emit += '  %s\n' % '\n  '.join(lines)
+    emit += '])\n'
+    emit += '''
+# This macro should be invoked from %s, in the section
+# "Check for header files, types and library functions".
+AC_DEFUN([%s_INIT],
+[\n''' % (configure_ac, macro_prefix)
+    if libtool:
+      emit += '  AM_CONDITIONAL([GL_COND_LIBTOOL], [true])\n'
+      emit += '  gl_cond_libtool=true\n'
+    else: # if not libtool
+      emit += '  AM_CONDITIONAL([GL_COND_LIBTOOL], [false])\n'
+      emit += '  gl_cond_libtool=false\n'
+      emit += '  gl_libdeps=\n'
+      emit += '  gl_ltlibdeps=\n'
+    replace_auxdir = False
+    if auxdir != 'build-aux':
+      replace_auxdir = True
+    emit += '  gl_m4_base=\'%s\'\n' % m4base
+    emit += self.emiter.initmacro_start(macro_prefix)
+    emit += '  gl_source_base=\'%s\'\n' % sourcebase
+    if witness_c_macro:
+      emit += '  m4_pushdef([gl_MODULE_INDICATOR_CONDITION], [%s])\n' % \
+        witness_c_macro
+    # Emit main autoconf snippets.
+    emit += self.emiter.autoconfSnippets(moduletable['main'],
+      moduletable, assistant, 0, True, False, True, replace_auxdir)
+    if witness_c_macro:
+      emit += '  m4_popdef([gl_MODULE_INDICATOR_CONDITION])\n'
+    emit += '  # End of code from modules\n'
+    emit += self.emiter.initmacro_end(macro_prefix)
+    emit += '  gltests_libdeps=\n'
+    emit += '  gltests_ltlibdeps=\n'
+    emit += self.emiter.initmacro_start('%stests' % macro_prefix)
+    emit += '  gl_source_base=\'%s\'\n' % testsbase
+    # Define a tests witness macro that depends on the package.
+    # PACKAGE is defined by AM_INIT_AUTOMAKE, PACKAGE_TARNAME is defined by
+    # AC_INIT.
+    # See <http://lists.gnu.org/archive/html/automake/2009-05/msg00145.html>.
+    emit += 'changequote(,)dnl\n'
+    emit += '  %stests_WITNESS=' % macro_prefix
+    emit += 'IN_`echo "${PACKAGE-$PACKAGE_TARNAME}" | LC_ALL=C tr \
+abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | LC_ALL=C sed -e \
+\'s/[^A-Z0-9_]/_/g\'`_GNULIB_TESTS\n'
+    emit += 'changequote([, ])dnl\n'
+    emit += '  AC_SUBST([%stests_WITNESS])\n' % macro_prefix
+    emit += '  gl_module_indicator_condition=$%stests_WITNESS\n' % macro_prefix
+    emit += '  m4_pushdef([gl_MODULE_INDICATOR_CONDITION], '
+    emit += '[$gl_module_indicator_condition])\n'
+    # Emit tests autoconf snippets.
+    emit += self.emiter.autoconfSnippets(moduletable['tests'],
+      moduletable, assistant, 0, True, True, True, replace_auxdir)
+    emit += '  m4_popdef([gl_MODULE_INDICATOR_CONDITION])\n'
+    emit += self.emiter.initmacro_end('%stests' % macro_prefix)
+    # _LIBDEPS and _LTLIBDEPS variables are not needed if this library is
+    # created using libtool, because libtool already handles the dependencies.
+    if not libtool:
+      libname_upper = libname.upper().replace('-', '_')
+      emit += '  %s_LIBDEPS="$gl_libdeps"\n' % libname_upper
+      emit += '  AC_SUBST([%s_LIBDEPS])\n' % libname_upper
+      emit += '  %s_LTLIBDEPS="$gl_ltlibdeps"\n' % libname_upper
+      emit += '  AC_SUBST([%s_LTLIBDEPS])\n' % libname_upper
+    if libtests:
+      emit += '  LIBTESTS_LIBDEPS="$gltests_libdeps"\n'
+      emit += '  AC_SUBST([LIBTESTS_LIBDEPS])\n'
+    emit += '])\n'
+    emit += self.emiter.initmacro_done(macro_prefix, sourcebase)
+    emit += self.emiter.initmacro_done('%stests' % macro_prefix, testsbase)
+    emit += '''
+# This macro records the list of files which have been installed by
+# gnulib-tool and may be removed by future gnulib-tool invocations.
+AC_DEFUN([%s_FILE_LIST], [\n''' % macro_prefix
+    emit += '  %s\n' % '\n  '.join(files)
+    emit += '])\n'
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    return(emit)
+    
+  def _done_dir_(self, directory, dirs_added, dirs_removed):
+    '''GLImport._done_dir_(directory, dirs_added, dirs_removed)
+    
+    This method is used to determine ignore argument for _update_ignorelist_
+    method and then call it.'''
+    destdir = self.config['destdir']
+    if isdir(joinpath(destdir, 'CVS')) or \
+    isdir(joinpath(destdir, directory, 'CVS')) or \
+    isfile(joinpath(destdir, directory, '.cvsignore')):
+      self._update_ignorelist_(directory, '.cvsignore',
+        dirs_added, dirs_removed)
+    if isdir(joinpath(destdir, '.git')) or \
+    isfile(joinpath(destdir, directory, '.gitignore')):
+      self._update_ignorelist_(directory, '.gitignore',
+        dirs_added, dirs_removed)
+      
+    
+  def _update_ignorelist_(self, directory, ignore, dirs_added, dirs_removed):
+    '''GLImport._update_ignorelist_(directory, ignore, dirs_added, dirs_removed)
+    
+    Update .gitignore or .cvsignore files.'''
+    result = string()
+    destdir = self.config['destdir']
+    if ignore == '.gitignore':
+      anchor = '/'
+    else:
+      anchor = ''
+    srcpath = joinpath(destdir, directory, ignore)
+    backupname = '%s~' % srcpath
+    if isfile(srcpath):
+      if dirs_added or dirs_removed:
+        with codecs.open(srcpath, 'rb', 'UTF-8') as file:
+          srcdata = file.read()
+        dirs_ignore = sorted(set(srcdata.split('\n')))
+        dirs_ignore = [line for line in dirs_ignore if line.strip()]
+        srcdata = '\n'.join(sorted(set(dirs_ignore))).strip()
+        dirs_ignore += [d for d in dirs_added if d not in dirs_ignore]
+        dirs_ignore = [d for d in dirs_ignore if d in dirs_removed]
+        dirs_ignore = ['%s%s' % (anchor, d) for d in dirs_ignore]
+        dirs_ignore = sorted(set(dirs_ignore))
+        destdata = '\n'.join(sorted(set(dirs_ignore))).strip()
+        if srcdata != destdata:
+          if not self.config['dryrun']:
+            print('Updating %s (backup in %s)' % (srcpath, backupname))
+            shutil.move(srcpath, backupname)
+            result = string()
+            with codecs.open(srcpath, 'wb', 'UTF-8') as file:
+              file.write(destdata)
+          else: # if self.config['dryrun']
+            print('Updating %s (backup in %s)' % (srcpath, backupname))
+    else: # if not isfile(srcpath)
+      if dirs_added:
+        if not self.config['dryrun']:
+          print('Creating %s' % srcpath)
+          dirs_added = sorted(set(dirs_added))
+          dirs_added = ['%s%s' % (anchor, d) for d in dirs_added]
+          if ignore == '.cvsignore':
+            dirs_added = ['.deps', '.dirstamp'] +dirs_added
+          with codecs.open(srcpath, 'wb', 'UTF-8') as file:
+            file.write('\n'.join(dirs_added))
+            file.write('\n')
+        else: # if self.config['dryrun']
+          print('Create %s' % srcpath)
+    
+  def prepare(self):
+    '''Make all preparations before the execution of the code.
+    Returns filetable and sed transformers, which change the license.'''
+    destdir = self.config['destdir']
+    localdir = self.config['localdir']
+    auxdir = self.config['auxdir']
+    modules = list(self.config['modules'])
+    avoids = list(self.config['avoids'])
+    testflags = list(self.config['testflags'])
+    sourcebase = self.config['sourcebase']
+    m4base = self.config['m4base']
+    pobase = self.config['pobase']
+    docbase = self.config['docbase']
+    testsbase = self.config['testsbase']
+    lgpl = self.config['lgpl']
+    copyrights = self.config['copyrights']
+    libname = self.config['libname']
+    makefile = self.config['makefile']
+    conddeps = self.config['conddeps']
+    libtool = self.config['libtool']
+    macro_prefix = self.config['macro_prefix']
+    podomain = self.config['podomain']
+    witness_c_macro = self.config['witness_c_macro']
+    vc_files = self.config['vc_files']
+    configure_ac = self.config['configure_ac']
+    ac_version = self.config['ac_version']
+    verbose = self.config['verbosity']
+    base_modules = sorted(set([self.modulesystem.find(m) for m in modules]))
+    avoids = sorted(set([self.modulesystem.find(a) for a in avoids]))
+    
+    # Perform transitive closure.
+    self.moduletable.setAvoids(avoids)
+    final_modules = self.moduletable.transitive_closure(base_modules)
+    
+    # Show final module list.
+    if verbose >= 0:
+      bold_on = ''
+      bold_off = ''
+      term = os.getenv('TERM')
+      if term == 'xterm':
+        bold_on = '\x1b[1m'
+        bold_off = '\x1b[0m'
+      print('Module list with included dependencies (indented):')
+      for module in final_modules:
+        if str(module) in self.config.getModules():
+          print('  %s%s%s' % (bold_on, module, bold_off))
+        else: # if str(module) not in self.config.getModules()
+          print('    %s' % module)
+    
+    # Separate modules into main_modules and tests_modules.
+    modules = self.moduletable.transitive_closure_separately(
+      base_modules, final_modules)
+    main_modules, tests_modules = modules
+    
+    # Transmit base_modules, final_modules, main_modules and tests_modules.
+    self.moduletable.setBaseModules(base_modules)
+    self.moduletable.setFinalModules(final_modules)
+    self.moduletable.setMainModules(main_modules)
+    self.moduletable.setTestsModules(tests_modules)
+    
+    # Print main_modules and tests_modules.
+    if verbose >= 1:
+      print('Main module list:')
+      for module in main_modules:
+        print('  %s' % str(module))
+      print('Tests-related module list:')
+      for module in tests_modules:
+        print('  %s' % str(module))
+    
+    # Determine whether a $testsbase/libtests.a is needed.
+    libtests = False
+    for module in tests_modules:
+      files = module.getFiles()
+      for file in files:
+        if file.startswith('lib/'):
+          libtests = True
+          break
+    if libtests:
+      self.config.enableLibtests()
+    
+    # Add dummy package if it is needed.
+    main_modules = self.moduletable.add_dummy(main_modules)
+    if libtests: # if we need to use libtests.a
+      tests_modules = self.moduletable.add_dummy(tests_modules)
+    
+    # Check license incompatibilities.
+    listing = list()
+    compatibilities = dict()
+    incompatibilities = string()
+    compatibilities['all'] = ['GPLed build tool', 'public domain', 'unlimited',
+      'unmodifiable license text']
+    compatibilities[3] = ['LGPL', 'LGPLv2+', 'LGPLv3+']
+    compatibilities[2] = ['LGPLv2+']
+    if lgpl:
+      for module in main_modules:
+        license = module.getLicense()
+        if license not in compatibilities['all']:
+          if lgpl == 3 or lgpl == True:
+            if license not in compatibilities[3]:
+              listing.append(tuple([str(module), license]))
+          elif lgpl == 2:
+            if license not in compatibilities[2]:
+              listing.append(tuple([str(module), license]))
+      if listing:
+        raise(GLError(11, listing))
+    
+    # Print notices from modules.
+    for module in main_modules:
+      notice = module.getNotice()
+      notice = notice.strip()
+      if notice:
+        print('Notice from module %s:' % str(module))
+        pattern = compiler('^(.*?)$', re.S | re.M)
+        notice = pattern.sub('  \\1', notice)
+        print(notice)
+
+    # Determine script to apply to imported library files.
+    lgpl2gpl = '''
+      s/GNU Lesser General/GNU General/g
+      s/Lesser General Public License/General Public License/g
+      s/GNU Library General/GNU General/g
+      s/Library General Public License/General Public License/g
+      s/version 2\\(.1\\)\\{0,1\\}\\([ ,]\\)/version 3\\2/g'''
+    sed_transform_lib_file = string()
+    if 'config-h' in [str(module) for module in main_modules]:
+      sed_transform_lib_file += '''
+        s/^#ifdef[\t ]*HAVE_CONFIG_H[\t ]*$/#if 1/
+      '''
+    sed_transform_main_lib_file = sed_transform_lib_file
+    if copyrights:
+      if lgpl: # if lgpl is enabled
+        if lgpl == 3:
+          sed_transform_main_lib_file += '''
+            s/GNU General/GNU Lesser General/g
+            s/General Public License/Lesser General Public License/g
+            s/Lesser Lesser General Public License/Lesser General Public''' \
+              +' License/g'
+        elif lgpl == 2:
+          sed_transform_main_lib_file += '''
+            s/GNU General/GNU Lesser General/g
+            s/General Public License/Lesser General Public License/g
+            s/Lesser Lesser General Public License/Lesser General Public''' \
+              +'''License/g
+            s/version [23]\\([ ,]\\)/version 2.1\\1/g'''
+      else: # if lgpl is disabled
+        sed_transform_main_lib_file += lgpl2gpl
+
+    # Determine script to apply to auxiliary files that go into $auxdir/.
+    sed_transform_build_aux_file = string()
+    if copyrights:
+      sed_transform_build_aux_file += lgpl2gpl
+
+    # Determine script to apply to library files that go into $testsbase/.
+    sed_transform_testsrelated_lib_file = sed_transform_lib_file
+    if copyrights:
+      sed_transform_testsrelated_lib_file += lgpl2gpl
+    
+    # Determine the final file lists.
+    main_filelist, tests_filelist = \
+      self.moduletable.filelist_separately(main_modules, tests_modules)
+    filelist = sorted(set(main_filelist +tests_filelist), key=string.lower)
+    if not filelist:
+      raise(GLError(12, None))
+    
+    # Print list of files.
+    if verbose >= 0:
+      print('File list:')
+      for file in filelist:
+        if file.startswith('tests=lib/'):
+          rest = file[10:]
+          print('  lib/%s -> tests/%s' % (rest, rest))
+        else:
+          print('  %s' % file)
+    
+    # Prepare basic filelist and basic old_files/new_files variables.
+    filelist = sorted(set(filelist))
+    new_files = filelist +['m4/gnulib-tool.m4']
+    old_files = list(self.cache['files'])
+    path = joinpath(destdir, m4base, 'gnulib-tool.m4')
+    if isfile(path):
+      old_files += [joinpath('m4', 'gnulib-tool.m4')]
+    
+    # Construct tables and transformers.
+    transformers = dict()
+    transformers['lib'] = string(sed_transform_lib_file)
+    transformers['aux'] = string(sed_transform_build_aux_file)
+    transformers['main'] = string(sed_transform_main_lib_file)
+    transformers['tests'] = string(sed_transform_testsrelated_lib_file)
+    old_table = list()
+    new_table = list()
+    for src in old_files:
+      dest = self.rewrite_old_files([src])[-1]
+      old_table += [tuple([dest, src])]
+    for src in new_files:
+      dest = self.rewrite_new_files([src])[-1]
+      new_table += [tuple([dest, src])]
+    old_table = sorted(set(old_table))
+    new_table = sorted(set(new_table))
+    
+    # Prepare the filetable.
+    filetable = dict()
+    filetable['all'] = sorted(set(filelist))
+    filetable['old'] = \
+      sorted(set(old_table), key=lambda t: tuple(t[0].lower()))
+    filetable['new'] = \
+      sorted(set(new_table), key=lambda t: tuple(t[0].lower()))
+    filetable['added'] = list()
+    filetable['removed'] = list()
+    
+    # Return the result.
+    result = tuple([filetable, transformers])
+    return(result)
+    
+  def execute(self, filetable, transformers):
+    '''Perform operations on the lists of files, which are given in a special
+    format except filelist argument. Such lists of files can be created using
+    GLImport.prepare() function.'''
+    if type(filetable) is not dict:
+      raise(TypeError('filetable must be a dict, not %s' % \
+        type(filetable).__name__))
+    for key in ['all', 'old', 'new', 'added', 'removed']:
+      if key not in filetable:
+        raise(KeyError('filetable must contain key %s' % repr(key)))
+    destdir = self.config['destdir']
+    localdir = self.config['localdir']
+    auxdir = self.config['auxdir']
+    modules = list(self.config['modules'])
+    avoids = list(self.config['avoids'])
+    testflags = list(self.config['testflags'])
+    sourcebase = self.config['sourcebase']
+    m4base = self.config['m4base']
+    pobase = self.config['pobase']
+    docbase = self.config['docbase']
+    testsbase = self.config['testsbase']
+    lgpl = self.config['lgpl']
+    copyrights = self.config['copyrights']
+    libname = self.config['libname']
+    makefile = self.config['makefile']
+    conddeps = self.config['conddeps']
+    libtool = self.config['libtool']
+    macro_prefix = self.config['macro_prefix']
+    podomain = self.config['podomain']
+    witness_c_macro = self.config['witness_c_macro']
+    vc_files = self.config['vc_files']
+    configure_ac = self.config['configure_ac']
+    ac_version = self.config['ac_version']
+    verbose = self.config['verbosity']
+    actioncmd = self.actioncmd()
+    
+    # Create all necessary directories.
+    dirs = list()
+    if pobase:
+      dirs += [pobase]
+    if [file for file in filetable['all'] if file.startswith('doc/')]:
+      dirs += [docbase]
+    dirs += [sourcebase, m4base, auxdir]
+    dirs += [os.path.dirname(pair[0]) for pair in filetable['new']]
+    dirs = sorted(set([joinpath(destdir, d) for d in dirs]))
+    for directory in dirs:
+      if not isdir(directory):
+        print('Creating directory %s' % directory)
+        if not self.config['dryrun']:
+            try: # Try to create directory
+              os.makedirs(directory)
+            except Exception as error:
+              raise(GLError(13, directory))
+        else: # if self.config['dryrun']
+          print('Create directory %s' % directory)
+    
+    # Create GLFileAssistant instance to process files.
+    self.assistant = GLFileAssistant(self.config, transformers)
+    
+    # Files which are in filetable['old'] and not in filetable['new'].
+    # They will be removed and added to filetable['removed'] list.
+    pairs = [f for f in filetable['old'] if f not in filetable['old']]
+    pairs = sorted(set(pairs), key=lambda t: tuple(t[0].lower()))
+    files = sorted(set(pair[0] for pair in pairs))
+    for file in files:
+      path = joinpath(destdir, file)
+      if isfile(path) or os.path.islink(path):
+        if not self.config['dryrun']:
+          backup = string('%s~' % path)
+          print('Removing file %s (backup in )' % (path, backup))
+          try: # Try to move file
+            if os.path.exists(backup):
+              os.remove(backup)
+            shutil.move(path, '%s~' % path)
+          except Exception as error:
+            raise(GLError(14, file))
+        else: # if self.config['dryrun']
+          print('Remove file %s (backup in %s~)' % (path, path))
+        filetable['removed'] += [file]
+    
+    # Files which are in filetable['new'] and not in filetable['old'].
+    # They will be added/updated and added to filetable['added'] list.
+    already_present = False
+    pairs = [f for f in filetable['new'] if f not in filetable['old']]
+    pairs = sorted(set(pairs))
+    for pair in pairs:
+      original = pair[1]
+      rewritten = pair[0]
+      self.assistant.setOriginal(original)
+      self.assistant.setRewritten(rewritten)
+      self.assistant.add_or_update(already_present)
+    
+    # Files which are in filetable['new'] and in filetable['old'].
+    # They will be added/updated and added to filetable['added'] list.
+    already_present = True
+    pairs = [f for f in filetable['new'] if f in filetable['old']]
+    pairs = sorted(set(pairs))
+    for pair in pairs:
+      original = pair[1]
+      rewritten = pair[0]
+      self.assistant.setOriginal(original)
+      self.assistant.setRewritten(rewritten)
+      self.assistant.add_or_update(already_present)
+    
+    # Add files which were added to the list of filetable['added'].
+    filetable['added'] += self.assistant.getFiles()
+    filetable['added'] = sorted(set(filetable['added']))
+    
+    # Determine include_guard_prefix.
+    include_guard_prefix = self.config['include_guard_prefix']
+    
+    # Determine makefile name.
+    if not makefile:
+      makefile_am = string('Makefile.am')
+    else: # if makefile
+      makefile_am = makefile
+    
+    # Create normal Makefile.ams.
+    for_test = False
+    
+    # Setup list of Makefile.am edits that are to be performed afterwards.
+    # Some of these edits apply to files that we will generate; others are
+    # under the responsibility of the developer.
+    makefile_am_edits = dict()
+    if makefile_am == 'Makefile.am':
+      sourcebase_dir = os.path.dirname(sourcebase)
+      sourcebase_base = os.path.basename(sourcebase)
+      self.makefiletable.editor(sourcebase_dir, 'SUBDIRS', sourcebase_base)
+    if pobase:
+      pobase_dir = os.path.dirname(pobase)
+      pobase_base = os.path.basename(pobase)
+      self.makefiletable.editor(pobase_dir, 'SUBDIRS', pobase_base)
+    if self.config.checkTestFlag(TESTS['tests']):
+      if makefile_am == 'Makefile.am':
+        testsbase_dir = os.path.dirname(testsbase)
+        testsbase_base = os.path.basename(testsbase)
+        self.makefiletable.editor(testsbase_dir, 'SUBDIRS', testsbase_base)
+    self.makefiletable.editor('', 'ACLOCAL_AMFLAGS', '-I %s' % m4base)
+    self.makefiletable.parent()
+    
+    # Create library makefile.
+    basename = joinpath(sourcebase, makefile_am)
+    tmpfile = self.assistant.tmpfilename(basename)
+    emit, uses_subdirs = self.emiter.lib_Makefile_am(basename,
+      self.moduletable['main'], self.moduletable, self.makefiletable,
+      actioncmd, for_test)
+    with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
+      file.write(emit)
+    filename, backup, flag = self.assistant.super_update(basename, tmpfile)
+    if flag == 1:
+        if not self.config['dryrun']:
+          print('Updating %s (backup in %s)' % (filename, backup))
+        else: # if self.config['dryrun']
+          print('Update %s (backup in %s)' % (filename, backup))
+    elif flag == 2:
+      if not self.config['dryrun']:
+        print('Creating %s' % filename)
+      else: # if self.config['dryrun']:
+        print('Create %s' % filename)
+      filetable['added'] += [filename]
+    if isfile(tmpfile):
+      os.remove(tmpfile)
+    
+    # Create po/ directory.
+    filesystem = GLFileSystem(self.config)
+    if pobase:
+      # Create po makefile and auxiliary files.
+      for file in ['Makefile.in.in', 'remove-potcdate.sin']:
+        tmpfile = self.assistant.tmpfilename(joinpath(pobase, file))
+        path = joinpath('build-aux', 'po', file)
+        lookedup, flag = filesystem.lookup(path)
+        shutil.move(lookedup, tmpfile)
+        basename = joinpath(pobase, file)
+        filename, backup, flag = self.assistant.super_update(basename, tmpfile)
+        if flag == 1:
+          if not self.config['dryrun']:
+            print('Updating %s (backup in %s)' % (filename, backup))
+          else: # if self.config['dryrun']
+            print('Update %s (backup in %s)' % (filename, backup))
+        elif flag == 2:
+          if not self.config['dryrun']:
+            print('Creating %s' % filename)
+          else: # if self.config['dryrun']:
+            print('Create %s' % filename)
+          filetable['added'] += [filename]
+      if isfile(tmpfile):
+        os.remove(tmpfile)
+      
+      # Create po makefile parameterization, part 1.
+      basename = joinpath(pobase, 'Makevars')
+      tmpfile = self.assistant.tmpfilename(basename)
+      emit = self.emiter.po_Makevars()
+      with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
+        file.write(emit)
+      filename, backup, flag = self.assistant.super_update(basename, tmpfile)
+      if flag == 1:
+        if not self.config['dryrun']:
+          print('Updating %s (backup in %s)' % (filename, backup))
+        else: # if self.config['dryrun']
+          print('Update %s (backup in %s)' % (filename, backup))
+      elif flag == 2:
+        if not self.config['dryrun']:
+          print('Creating %s' % filename)
+        else: # if self.config['dryrun']:
+          print('Create %s' % filename)
+        filetable['added'] += [filename]
+      if isfile(tmpfile):
+        os.remove(tmpfile)
+      
+      # Create po makefile parameterization, part 2.
+      basename = joinpath(pobase, 'POTFILES.in')
+      tmpfile = self.assistant.tmpfilename(basename)
+      with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
+        file.write(self.emiter.po_POTFILES_in(filetable['all']))
+      basename = joinpath(pobase, 'POTFILES.in')
+      filename, backup, flag = self.assistant.super_update(basename, tmpfile)
+      if flag == 1:
+        if not self.config['dryrun']:
+          print('Updating %s (backup in %s)' % (filename, backup))
+        else: # if self.config['dryrun']
+          print('Update %s (backup in %s)' % (filename, backup))
+      elif flag == 2:
+        if not self.config['dryrun']:
+          print('Creating %s' % filename)
+        else: # if self.config['dryrun']:
+          print('Create %s' % filename)
+        filetable['added'] += [filename]
+      if isfile(tmpfile):
+        os.remove(tmpfile)
+      
+      # Fetch PO files.
+      TP_URL = 'http://translationproject.org/latest/'
+      TP_RSYNC_URI = 'translationproject.org::tp/latest/'
+      if not self.config['dryrun']:
+        print('Fetching gnulib PO files from %s' % TP_URL)
+        os.chdir(joinpath(destdir, pobase))
+        cmd = 'if type rsync 2>/dev/null | grep / > /dev/null; '
+        cmd += 'then echo 1; else echo 0; fi'
+        result = sp.check_output(cmd, shell=True)
+        result = bool(int(result))
+        if result: # use rsync
+          args = ['rsync', '-Lrtz', '%sgulib/' % TP_RSYNC_URI, '.']
+        else: # use wget
+          args = ['wget', '--quiet', '-r', '-l1', '-nd', '-np', 'A.po',
+            '%sgnulib' % TP_URL]
+        sp.call(args, shell=True)
+      else: # if self.config['dryrun']
+        print('Fetch gnulib PO files from %s' % TP_URL)
+      
+      # Create po/LINGUAS.
+      basename = joinpath(pobase, 'LINGUAS')
+      if not self.config['dryrun']:
+        tmpfile = self.assistant.tmpfilename(basename)
+        data = string('# Set of available languages.\n')
+        files = [constants.subend('.po', '', file) \
+          for file in os.listdir(joinpath(destdir, pobase))]
+        files = [file.decode(ENCS['default']) if type(file) is bytes \
+          else file for file in files]
+        data += '\n'.join(files)
+        with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
+          file.write(data)
+        filename, backup, flag = self.assistant.super_update(basename, tmpfile)
+        if flag == 1:
+          print('Updating %s (backup in %s)' % (filename, backup))
+        elif flag == 2:
+          print('Creating %s' % filename)
+          filetable['added'] += [filename]
+        if isfile(tmpfile):
+          os.remove(tmpfile)
+      else: # if not self.config['dryrun']
+        backupname = '%s~' % basename
+        if isfile(destdir, basename):
+          print('Update %s (backup in %s)' % (basename, backupname))
+        else: # if not isfile(destdir, basename)
+          print('Create %s' % basename)
+      
+    # Create m4/gnulib-cache.m4.
+    basename = joinpath(m4base, 'gnulib-cache.m4')
+    tmpfile = self.assistant.tmpfilename(basename)
+    emit = self.gnulib_cache()
+    with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
+      file.write(emit)
+    filename, backup, flag = self.assistant.super_update(basename, tmpfile)
+    if flag == 1:
+      if not self.config['dryrun']:
+        print('Updating %s (backup in %s)' % (filename, backup))
+      else: # if self.config['dryrun']
+        print('Update %s (backup in %s)' % (filename, backup))
+    elif flag == 2:
+      if not self.config['dryrun']:
+        print('Creating %s' % filename)
+      else: # if self.config['dryrun']:
+        print('Create %s' % filename)
+        if emit[-2:] == '\r\n':
+          emit = emit[:-2]
+        elif emit[-1:] == '\n':
+          emit = emit[:-1]
+        print(emit)
+    if isfile(tmpfile):
+      os.remove(tmpfile)
+    
+    # Create m4/gnulib-comp.m4.
+    basename = joinpath(m4base, 'gnulib-comp.m4')
+    tmpfile = self.assistant.tmpfilename(basename)
+    emit = self.gnulib_comp(filetable['all'])
+    with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
+      file.write(emit)
+    filename, backup, flag = self.assistant.super_update(basename, tmpfile)
+    if flag == 1:
+      if not self.config['dryrun']:
+        print('Updating %s (backup in %s)' % (filename, backup))
+      else: # if self.config['dryrun']
+        print('Update %s (backup in %s)' % (filename, backup))
+    elif flag == 2:
+      if not self.config['dryrun']:
+        print('Creating %s' % filename)
+      else: # if self.config['dryrun']:
+        print('Create %s' % filename)
+        if emit[-2:] == '\r\n':
+          emit = emit[:-2]
+        elif emit[-1:] == '\n':
+          emit = emit[:-1]
+        print(emit)
+    if isfile(tmpfile):
+      os.remove(tmpfile)
+    
+    # Create tests Makefile.
+    inctests = self.config.checkTestFlag(TESTS['tests'])
+    if inctests:
+      basename = joinpath(testsbase, makefile_am)
+      tmpfile = self.assistant.tmpfilename(basename)
+      emit, uses_subdirs = self.emiter.lib_Makefile_am(basename,
+        self.moduletable['tests'], self.moduletable, self.makefiletable,
+        actioncmd, for_test)
+      with codecs.open(tmpfile, 'wb', 'UTF-8') as file:
+        file.write(emit)
+      filename, backup, flag = self.assistant.super_update(basename, tmpfile)
+      if flag == 1:
+        if not self.config['dryrun']:
+          print('Updating %s (backup in %s)' % (filename, backup))
+        else: # if self.config['dryrun']
+          print('Update %s (backup in %s)' % (filename, backup))
+      elif flag == 2:
+        if not self.config['dryrun']:
+          print('Creating %s' % filename)
+        else: # if self.config['dryrun']:
+          print('Create %s' % filename)
+        filetable['added'] += [filename]
+      if isfile(tmpfile):
+        os.remove(tmpfile)
+    
+    # Update the .cvsignore and .gitignore files.
+    ignorelist = list()
+    filetable['added'] = sorted(set(filetable['added']))
+    filetable['removed'] = sorted(set(filetable['added']))
+    for file in filetable['added']:
+      directory, basename = os.path.split(file)
+      ignorelist += [tuple([directory, '|A|', basename])]
+    for file in filetable['removed']:
+      directory, basename = os.path.split(file)
+      ignorelist += [tuple([directory, '|R|', basename])]
+    last_dir = string()
+    last_dirs_added = list()
+    last_dirs_removed = list()
+    for row in ignorelist:
+      next_dir = row[0]
+      operand = row[1]
+      filename = row[2]
+      if next_dir != last_dir:
+        self._done_dir_(last_dir, last_dirs_added, last_dirs_removed)
+        last_dir = next_dir
+        last_dirs_added = list()
+        last_dirs_removed = list()
+      if operand == '|A|':
+        last_dirs_added += [filename]
+      elif operand == '|R|':
+        last_dirs_removed += [filename]
+    self._done_dir_(last_dir, last_dirs_added, last_dirs_removed)
+    exit()
+    
+    # Finish the work.
+    print('Finished.\n')
+    print('You may need to add #include directives \
+for the following .h files.')
+    modules = sorted(set([module for module in self.moduletable['base'] \
+      if module in self.moduletable['main']]))
+    # First the #include <...> directives without #ifs, sorted for convenience,
+    # then the #include "..." directives without #ifs, sorted for convenience,
+    # then the #include directives that are surrounded by #ifs. Not sorted.
+    includes_angles = list()
+    includes_quotes = list()
+    includes_if = list()
+    for module in modules:
+      include = module.getInclude()
+      for include in include.split('\n'):
+        if '%s#if' % constants.NL in '%s%s' % (constants.NL, include):
+          includes_if += [include]
+        else: # if '%s#if' % constants.NL in '%s%s' % (constants.NL, include)
+          if 'include "' in include:
+            includes_quotes += [include]
+          else: # if 'include "' not in include
+            includes_angles += [include]
+    includes_angles = sorted(set(includes_angles))
+    includes_quotes = sorted(set(includes_quotes))
+    includes = includes_angles +includes_quotes +includes_if
+    includes = [include for include in includes if include.split()]
+    for include in includes:
+      print('  %s' % include)
+    
+    # Get link directives.
+    links = [module.getLink() for module in self.moduletable['main']]
+    links = sorted(set([link for link in links if link.strip()]))
+    if links:
+      print('''
+You may need to use the following Makefile variables when linking.
+Use them in <program>_LDADD when linking a program, or
+in <library>_a_LDFLAGS or <library>_la_LDFLAGS when linking a library.''')
+      for link in links:
+        print('  %s' % link)
+    
+    # Print reminders.
+    print('')
+    print('Don\'t forget to')
+    if makefile_am == 'Makefile.am':
+      print('  - add "%s/Makefile" to AC_CONFIG_FILES in %s,' % \
+        (sourcebase, configure_ac))
+    else: # if makefile_am != 'Makefile.am'
+      print('  - "include %s" from within "%s/Makefile.am",' % \
+        (makefile, sourcebase))
+    if pobase:
+      print('  - add "%s/Makefile.in to AC_CONFIG_FILES in %s,' % \
+        (pobase, configure_ac))
+    if inctests:
+      if makefile_am == 'Makefile.am':
+        print('  - add "%s/Makefile" to AC_CONFIG_FILES in %s,' % \
+          (testsbase, configure_ac))
+      else: # if makefile_am != 'Makefile.am'
+        print('  - "include %s" from within "%s/Makefile.am",' % \
+          (makefile, testsbase))
+    # Print makefile edits.
+    current_edit = int()
+    makefile_am_edits = self.makefiletable.count()
+    while current_edit != makefile_am_edits:
+      dictionary = self.makefiletable[current_edit]
+      if dictionary['var']:
+        print('  - mention "%s" in %s in %s,' % \
+          (dictionary['val'], dictionary['var'],
+            joinpath(dictionary['dir'], 'Makefile.am')))
+      current_edit += 1
+    
+    # Detect position_early_after.
+    with codecs.open(configure_ac, 'rb', 'UTF-8') as file:
+      data = file.read()
+    match_result1 = \
+      bool(compiler('^ *AC_PROG_CC_STDC', re.S | re.M).findall(data))
+    match_result2 = \
+      bool(compiler('^ *AC_PROG_CC_C99', re.S | re.M).findall(data))
+    if match_result1:
+      position_early_after = 'AC_PROG_CC_STDC'
+    elif match_result2:
+      position_early_after = 'AC_PROG_CC_C99'
+    else: # if not any([match_result1, match_result2])
+      position_early_after = 'AC_PROG_CC'
+    print('  - invoke %s_EARLY in %s, right after %s,' % \
+      (macro_prefix, configure_ac, position_early_after))
+    print('  - invoke %s_INIT in %s.' % \
+      (macro_prefix, configure_ac))
+    sp.call(['rm', '-rf', self.config['tempdir']], shell=False)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pygnulib/GLInfo.py	Sun Aug 20 11:17:58 2017 +0300
@@ -0,0 +1,302 @@
+#!/usr/bin/python
+# encoding: UTF-8
+
+#===============================================================================
+# Define global imports
+#===============================================================================
+import os
+import re
+import sys
+import locale
+import codecs
+import subprocess as sp
+from . import constants
+
+
+#===============================================================================
+# Define module information
+#===============================================================================
+__author__ = constants.__author__
+__license__ = constants.__license__
+__copyright__ = constants.__copyright__
+
+
+#===============================================================================
+# Define global constants
+#===============================================================================
+PYTHON3 = constants.PYTHON3
+NoneType = type(None)
+APP = constants.APP
+DIRS = constants.DIRS
+ENCS = constants.ENCS
+UTILS = constants.UTILS
+FILES = constants.FILES
+MODES = constants.MODES
+TESTS = constants.TESTS
+compiler = constants.compiler
+joinpath = constants.joinpath
+cleaner = constants.cleaner
+string = constants.string
+isabs = os.path.isabs
+isdir = os.path.isdir
+isfile = os.path.isfile
+normpath = os.path.normpath
+relpath = os.path.relpath
+
+
+#===============================================================================
+# Define GLInfo class
+#===============================================================================
+class GLInfo(object):
+  '''This class is used to get fromatted information about gnulib-tool.
+  This information is mainly used in stdout messages, but can be used
+  anywhere else. The return values are not the same as for the module,
+  but still depends on them.'''
+  
+  def __repr__(self):
+    '''x.__repr__ <==> repr(x)'''
+    result = '<pygnulib.GLInfo %s>' % hex(id(self))
+    return(result)
+  
+  def package(self):
+    '''Return formatted string which contains name of the package.'''
+    result = 'GNU gnulib'
+    return(result)
+    
+  def authors(self):
+    '''Return formatted string which contains authors.
+    The special __author__ variable is used (type is list).'''
+    result = string()
+    for item in __author__:
+      if item == __author__[-2]:
+        result += '%s ' % item
+      elif item == __author__[-1]:
+        result += 'and %s' % item
+      else:
+        result += '%s, ' % item
+    return(result)
+    
+  def license(self):
+    '''Return formatted string which contains license and its description.'''
+    result = 'License GPLv3+: GNU GPL version 3 or later'
+    result += ' <http://gnu.org/licenses/gpl.html>\n'
+    result += 'This is free software: you are free'
+    result += ' to change and redistribute it.\n'
+    result += 'There is NO WARRANTY, to the extent permitted by law.'
+    return(result)
+    
+  def copyright(self):
+    '''Return formatted string which contains copyright.
+    The special __copyright__ variable is used (type is str).'''
+    result = 'Copyright (C) %s' % __copyright__
+    return(result)
+    
+  def date(self):
+    '''Return formatted string which contains date and time in GMT format.'''
+    if isdir(DIRS['git']):
+      counter = int() # Create counter
+      result = string() # Create string
+      args = ['git', 'log']
+      result = sp.check_output(args).decode(ENCS['shell'])
+      # Get date as "Fri Mar 21 07:16:51 2008 -0600" from string
+      pattern = re.compile('Date:[\t ]*(.*?)$', re.S | re.M)
+      result = pattern.findall(result)[0]
+      # Turn "Fri Mar 21 07:16:51 2008 -0600" into "Mar 21 2008 07:16:51 -0600"
+      pattern = re.compile('^[^ ]* ([^ ]*) ([0-9]*) ([0-9:]*) ([0-9]*) ')
+      result = pattern.sub('\\1 \\2 \\4 \\3 ', result)
+      # Use GNU date to compute the time in GMT
+      args = ['date', '-d', result, '-u', '+%Y-%m-%d %H:%M:%S']
+      proc = sp.check_output(args)
+      result = string(proc, ENCS['shell'])
+      result = result.rstrip(os.linesep)
+      return(result)
+    
+  def usage(self):
+    '''Show help message.'''
+    result = '''\
+Usage: gnulib-tool --list
+       gnulib-tool --find filename
+       gnulib-tool --import [module1 ... moduleN]
+       gnulib-tool --add-import [module1 ... moduleN]
+       gnulib-tool --remove-import [module1 ... moduleN]
+       gnulib-tool --update
+       gnulib-tool --create-testdir --dir=directory [module1 ... moduleN]
+       gnulib-tool --create-megatestdir --dir=directory [module1 ... moduleN]
+       gnulib-tool --test --dir=directory module1 ... moduleN
+       gnulib-tool --megatest --dir=directory [module1 ... moduleN]
+       gnulib-tool --extract-description module
+       gnulib-tool --extract-comment module
+       gnulib-tool --extract-status module
+       gnulib-tool --extract-notice module
+       gnulib-tool --extract-applicability module
+       gnulib-tool --extract-filelist module
+       gnulib-tool --extract-dependencies module
+       gnulib-tool --extract-autoconf-snippet module
+       gnulib-tool --extract-automake-snippet module
+       gnulib-tool --extract-include-directive module
+       gnulib-tool --extract-link-directive module
+       gnulib-tool --extract-license module
+       gnulib-tool --extract-maintainer module
+       gnulib-tool --extract-tests-module module
+       gnulib-tool --copy-file file [destination]
+
+Operation modes:
+
+      --list                print the available module names
+      --find                find the modules which contain the specified file
+      --import              import the given modules into the current package
+      --add-import          augment the list of imports from gnulib into the
+                            current package, by adding the given modules;
+                            if no modules are specified, update the current
+                            package from the current gnulib
+      --remove-import       reduce the list of imports from gnulib into the
+                            current package, by removing the given modules
+      --update              update the current package, restore files omitted
+                            from version control
+      --create-testdir      create a scratch package with the given modules
+                            (pass --with-tests to include the unit tests)
+      --create-megatestdir  create a mega scratch package with the given modules
+                            one by one and all together
+                            (pass --with-tests to include the unit tests)
+      --test                test the combination of the given modules
+                            (pass --with-tests to include the unit tests)
+                            (recommended to use CC=\"gcc -Wall\" here)
+      --megatest            test the given modules one by one and all together
+                            (pass --with-tests to include the unit tests)
+                            (recommended to use CC=\"gcc -Wall\" here)
+      --extract-description        extract the description
+      --extract-comment            extract the comment
+      --extract-status             extract the status (obsolete etc.)
+      --extract-notice             extract the notice or banner
+      --extract-applicability      extract the applicability
+      --extract-filelist           extract the list of files
+      --extract-dependencies       extract the dependencies
+      --extract-autoconf-snippet   extract the snippet for configure.ac
+      --extract-automake-snippet   extract the snippet for library makefile
+      --extract-include-directive  extract the #include directive
+      --extract-link-directive     extract the linker directive
+      --extract-license            report the license terms of the source files
+                                   under lib/
+      --extract-maintainer         report the maintainer(s) inside gnulib
+      --extract-tests-module       report the unit test module, if it exists
+      --copy-file                  copy a file that is not part of any module
+      --help                Show this help text.
+      --version             Show version and authorship information.
+
+General options:
+
+      --dir=DIRECTORY       Specify the target directory.
+                            For --import, this specifies where your
+                            configure.ac can be found.  Defaults to current
+                            directory.
+      --local-dir=DIRECTORY  Specify a local override directory where to look
+                            up files before looking in gnulib's directory.
+      --cache-modules       Enable module caching optimization.
+      --no-cache-modules    Disable module caching optimization.
+      --verbose             Increase verbosity. May be repeated.
+      --quiet               Decrease verbosity. May be repeated.
+
+Options for --import, --add/remove-import, --update:
+
+      --dry-run             Only print what would have been done.
+
+Options for --import, --add/remove-import,
+            --create-[mega]testdir, --[mega]test:
+
+      --with-tests          Include unit tests for the included modules.
+      --with-obsolete       Include obsolete modules when they occur among the
+                            dependencies. By default, dependencies to obsolete
+                            modules are ignored.
+      --with-c++-tests      Include even unit tests for C++ interoperability.
+      --with-longrunning-tests
+                            Include even unit tests that are long-runners.
+      --with-privileged-tests
+                            Include even unit tests that require root
+                            privileges.
+      --with-unportable-tests
+                            Include even unit tests that fail on some platforms.
+      --with-all-tests      Include all kinds of problematic unit tests.
+      --avoid=MODULE        Avoid including the given MODULE. Useful if you
+                            have code that provides equivalent functionality.
+                            This option can be repeated.
+      --conditional-dependencies
+                            Support conditional dependencies (may save configure
+                            time and object code).
+      --no-conditional-dependencies
+                            Don't use conditional dependencies.
+      --libtool             Use libtool rules.
+      --no-libtool          Don't use libtool rules.
+
+Options for --import, --add/remove-import:
+
+      --lib=LIBRARY         Specify the library name.  Defaults to 'libgnu'.
+      --source-base=DIRECTORY
+                            Directory relative to --dir where source code is
+                            placed (default \"lib\").
+      --m4-base=DIRECTORY   Directory relative to --dir where *.m4 macros are
+                            placed (default \"m4\").
+      --po-base=DIRECTORY   Directory relative to --dir where *.po files are
+                            placed (default \"po\").
+      --doc-base=DIRECTORY  Directory relative to --dir where doc files are
+                            placed (default \"doc\").
+      --tests-base=DIRECTORY
+                            Directory relative to --dir where unit tests are
+                            placed (default \"tests\").
+      --aux-dir=DIRECTORY   Directory relative to --dir where auxiliary build
+                            tools are placed (default comes from configure.ac).
+      --lgpl[=2|=3]         Abort if modules aren't available under the LGPL.
+                            Also modify license template from GPL to LGPL.
+                            The version number of the LGPL can be specified;
+                            the default is currently LGPLv3.
+      --makefile-name=NAME  Name of makefile in automake syntax in the
+                            source-base and tests-base directories
+                            (default \"Makefile.am\").
+      --macro-prefix=PREFIX  Specify the prefix of the macros 'gl_EARLY' and
+                            'gl_INIT'. Default is 'gl'.
+      --po-domain=NAME      Specify the prefix of the i18n domain. Usually use
+                            the package name. A suffix '-gnulib' is appended.
+      --witness-c-macro=NAME  Specify the C macro that is defined when the
+                            sources in this directory are compiled or used.
+      --vc-files            Update version control related files.
+      --no-vc-files         Don't update version control related files
+                            (.gitignore and/or .cvsignore).
+      --no-changelog        Don't update or create ChangeLog files.
+
+Options for --create-[mega]testdir, --[mega]test:
+
+      --without-c++-tests   Exclude unit tests for C++ interoperability.
+      --without-longrunning-tests
+                            Exclude unit tests that are long-runners.
+      --without-privileged-tests
+                            Exclude unit tests that require root privileges.
+      --without-unportable-tests
+                            Exclude unit tests that fail on some platforms.
+      --single-configure    Generate a single configure file, not a separate
+                            configure file for the tests directory.
+
+Options for --import, --add/remove-import, --update,
+            --create-[mega]testdir, --[mega]test:
+
+  -s, --symbolic, --symlink Make symbolic links instead of copying files.
+      --local-symlink       Make symbolic links instead of copying files, only
+                            for files from the local override directory.
+
+Options for --import, --add/remove-import, --update:
+
+  -S, --more-symlinks       Make symbolic links instead of copying files, and
+                            don't replace copyright notices.
+
+Report bugs to <bug-gnulib@gnu.org>.'''
+    return(result)
+    
+  def version(self):
+    '''Return formatted string which contains git or CVS version.'''
+    if isdir(DIRS['git']):
+      version_gen = joinpath(DIRS['build-aux'], 'git-version-gen')
+      args = [version_gen, DIRS['root']]
+      result = sp.check_output(args).decode(ENCS['shell'])
+      result = result.strip()
+      if result == 'UNKNOWN':
+        result = string()
+      return(result)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pygnulib/GLMakefileTable.py	Sun Aug 20 11:17:58 2017 +0300
@@ -0,0 +1,133 @@
+#!/usr/bin/python
+# encoding: UTF-8
+
+#===============================================================================
+# Define global imports
+#===============================================================================
+import os
+import re
+import sys
+import codecs
+import hashlib
+import subprocess as sp
+from . import constants
+from .GLError import GLError
+from .GLConfig import GLConfig
+from .GLFileSystem import GLFileSystem
+
+
+#===============================================================================
+# Define module information
+#===============================================================================
+__author__ = constants.__author__
+__license__ = constants.__license__
+__copyright__ = constants.__copyright__
+
+
+#===============================================================================
+# Define global constants
+#===============================================================================
+PYTHON3 = constants.PYTHON3
+NoneType = type(None)
+APP = constants.APP
+DIRS = constants.DIRS
+ENCS = constants.ENCS
+UTILS = constants.UTILS
+FILES = constants.FILES
+MODES = constants.MODES
+TESTS = constants.TESTS
+compiler = constants.compiler
+joinpath = constants.joinpath
+cleaner = constants.cleaner
+string = constants.string
+isabs = os.path.isabs
+isdir = os.path.isdir
+isfile = os.path.isfile
+normpath = os.path.normpath
+relpath = os.path.relpath
+filter_filelist = constants.filter_filelist
+
+
+#===============================================================================
+# Define GLMakefileTable class
+#===============================================================================
+class GLMakefileTable(object):
+  '''This class is used to edit Makefile and store edits as table.
+  When user creates  Makefile, he may need to use this class.'''
+  
+  def __init__(self, config):
+    '''GLMakefileTable.__init__(config) -> GLMakefileTable
+    
+    Create GLMakefileTable instance.'''
+    if type(config) is not GLConfig:
+      raise(TypeError('config must be a GLConfig, not %s' % \
+        type(config).__name__))
+    self.config = config
+    self.table = list()
+    
+  def __getitem__(self, y):
+    '''x.__getitem__(y) = x[y]'''
+    if type(y) is not int:
+      raise(TypeError('indices must be integers, not %s' % \
+        type(y).__name__))
+    result = self.table[y]
+    return(dict(result))
+    
+  def editor(self, dir, var, val):
+    '''GLMakefileTable.editor(dir, var, val)
+    
+    This method is used to remember that ${dir}Makefile.am needs to be edited
+    to that ${var} mentions ${val}.'''
+    if type(dir) is bytes or type(dir) is string:
+      if type(dir) is bytes:
+        dir = dir.decode(ENCS['default'])
+    else: # if dir has not bytes or string type
+      raise(TypeError(
+        'dir must be a string, not %s' % (type(dir).__name__)))
+    if type(var) is bytes or type(var) is string:
+      if type(var) is bytes:
+        var = var.decode(ENCS['default'])
+    else: # if var has not bytes or string type
+      raise(TypeError(
+        'var must be a string, not %s' % (type(var).__name__)))
+    if type(val) is bytes or type(val) is string:
+      if type(val) is bytes:
+        val = val.decode(ENCS['default'])
+    else: # if val has not bytes or string type
+      raise(TypeError(
+        'val must be a string, not %s' % (type(val).__name__)))
+    dictionary = {'dir': dir, 'var': var, 'val': val}
+    self.table += [dictionary]
+    
+  def parent(self):
+    '''GLMakefileTable.parent()
+    
+    Add a special row to Makefile.am table with the first parent directory
+    which contains or will contain Makefile.am file.
+    GLConfig: sourcebase, m4base, testsbase, testflags, makefile.'''
+    m4base = self.config['m4base']
+    sourcebase = self.config['sourcebase']
+    testsbase = self.config['testsbase']
+    makefile = self.config['makefile']
+    inctests = self.config.checkTestFlag(TESTS['tests'])
+    dir1 = string('%s%s' % (m4base, os.path.sep))
+    mfd = string('Makefile.am')
+    if not makefile:
+      mfx = string('Makefile.am')
+    else: # if makefile
+      mfx = makefile
+    dir2 = string()
+    while dir1 and \
+    (joinpath(self.config['destdir'], dir1, mfd) or \
+    joinpath(dir1, mfd) == joinpath(sourcebase, mfx) or \
+    (inctests and joinpath(dir1, mfd) == joinpath(testsbase, mfx))):
+      dir2 = joinpath(os.path.basename(dir1), dir2)
+      dir1 = os.path.dirname(dir1)
+    self.editor(dir1, 'EXTRA_DIST', joinpath(dir2, 'gnulib-cache.m4'))
+    
+  def count(self):
+    '''GLMakefileTable.count() -> int
+    
+    Count number of edits which were applied.'''
+    return(len(self.table))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pygnulib/GLModuleSystem.py	Sun Aug 20 11:17:58 2017 +0300
@@ -0,0 +1,1267 @@
+#!/usr/bin/python
+# encoding: UTF-8
+
+#===============================================================================
+# Define global imports
+#===============================================================================
+import os
+import re
+import sys
+import codecs
+import hashlib
+import subprocess as sp
+from . import constants
+from .GLError import GLError
+from .GLConfig import GLConfig
+from .GLFileSystem import GLFileSystem
+
+
+#===============================================================================
+# Define module information
+#===============================================================================
+__author__ = constants.__author__
+__license__ = constants.__license__
+__copyright__ = constants.__copyright__
+
+
+#===============================================================================
+# Define global constants
+#===============================================================================
+PYTHON3 = constants.PYTHON3
+NoneType = type(None)
+APP = constants.APP
+DIRS = constants.DIRS
+ENCS = constants.ENCS
+UTILS = constants.UTILS
+FILES = constants.FILES
+MODES = constants.MODES
+TESTS = constants.TESTS
+compiler = constants.compiler
+joinpath = constants.joinpath
+cleaner = constants.cleaner
+string = constants.string
+isabs = os.path.isabs
+isdir = os.path.isdir
+isfile = os.path.isfile
+normpath = os.path.normpath
+relpath = os.path.relpath
+filter_filelist = constants.filter_filelist
+
+
+#===============================================================================
+# Define GLModuleSystem class
+#===============================================================================
+class GLModuleSystem(object):
+  '''GLModuleSystem is used to operate with module system using dynamic
+  searching and patching.'''
+  
+  def __init__(self, config):
+    '''GLModuleSystem.__init__(config) -> GLModuleSystem
+    
+    Create new GLModuleSystem instance. Some functions use GLFileSystem class
+    to look up a file in localdir or gnulib directories, or combine it through
+    'patch' utility.'''
+    self.args = dict()
+    if type(config) is not GLConfig:
+      raise(TypeError('config must be a GLConfig, not %s' % \
+        type(config).__name__))
+    self.config = config
+    self.filesystem = GLFileSystem(self.config)
+    
+  def __repr__(self):
+    '''x.__repr__ <==> repr(x)'''
+    result = '<pygnulib.GLModuleSystem %s>' % hex(id(self))
+    return(result)
+    
+  def exists(self, module):
+    '''GLModuleSystem.exists(module) -> bool
+    
+    Check whether the given module exists.
+    GLConfig: localdir.'''
+    if type(module) is bytes or string:
+      if type(module) is bytes:
+        module = module.decode(ENCS['default'])
+    else: # if module has not bytes or string type
+      raise(TypeError(
+        'module must be a string, not %s' % type(module).__name__))
+    result = bool()
+    badnames = ['CVS', 'ChangeLog', 'COPYING', 'README', 'TEMPLATE',
+      'TEMPLATE-EXTENDED', 'TEMPLATE-TESTS']
+    if isfile(joinpath(DIRS['modules'], module)) or \
+    all([ # Begin all(iterable) function
+      self.config['localdir'],
+      isdir(joinpath(self.config['localdir'], 'modules')),
+      isfile(joinpath(self.config['localdir'], 'modules', module))
+    ]): # Close all(iterable) function
+      if module not in badnames:
+        result = True
+    return(result)
+    
+  def find(self, module):
+    '''GLModuleSystem.find(module) -> GLModule
+    
+    Find the given module.'''
+    if type(module) is bytes or string:
+      if type(module) is bytes:
+        module = module.decode(ENCS['default'])
+    else: # if module has not bytes or string type
+      raise(TypeError(
+        'module must be a string, not %s' % type(module).__name__))
+    if self.exists(module):
+      path, istemp = self.filesystem.lookup(joinpath('modules', module))
+      result = GLModule(self.config, path, istemp)
+      return(result)
+    else: # if not self.exists(module)
+      if self.config['errors']:
+        raise(GLError(3, module))
+      else: # if not self.config['errors']
+        sys.stderr.write('gnulib-tool: warning: ')
+        sys.stderr.write('file %s does not exist\n' % str(module))
+    
+  def list(self):
+    '''GLModuleSystem.list() -> list
+   
+    Return the available module names as tuple. We could use a combination
+    of os.walk() function and re module. However, it takes too much time to
+    complete, so this version uses subprocess to run shell commands.'''
+    result = string()
+    listing = list()
+    localdir = self.config['localdir']
+    find_args = ['find', 'modules', '-type', 'f', '-print']
+    sed_args = \
+    [
+      'sed',
+      '-e', r's,^modules/,,',
+      '-e', r'/^CVS\//d',
+      '-e', r'/\/CVS\//d',
+      '-e', r'/^ChangeLog$/d',
+      '-e', r'/\/ChangeLog$/d',
+      '-e', r'/^COPYING$/d',
+      '-e', r'/\/COPYING$/d',
+      '-e', r'/^README$/d',
+      '-e', r'/\/README$/d',
+      '-e', r'/^TEMPLATE$/d',
+      '-e', r'/^TEMPLATE-EXTENDED$/d',
+      '-e', r'/^TEMPLATE-TESTS$/d',
+      '-e', r'/^\..*/d',
+      '-e', r'/~$/d',
+      '-e', r'/-tests$/d',
+    ]
+    
+    # Read modules from gnulib root directory.
+    os.chdir(constants.DIRS['root'])
+    find = sp.Popen(find_args, stdout=sp.PIPE)
+    result += find.stdout.read().decode(ENCS['shell'])
+    
+    # Read modules from local directory.
+    if localdir and isdir(joinpath(localdir, 'modules')):
+      os.chdir(localdir)
+      find = sp.Popen(find_args, stdout=sp.PIPE)
+      result += find.stdout.read().decode(ENCS['shell'])
+      sed_args += ['-e', r's,\.diff$,,']
+    
+    # Save the list of the modules to file.
+    os.chdir(DIRS['cwd'])
+    path = joinpath(self.config['tempdir'], 'list')
+    with codecs.open(path, 'wb', 'UTF-8') as file:
+      file.write(result)
+    
+    # Filter the list of the modules.
+    stdin = codecs.open(path, 'rb', 'UTF-8')
+    sed = sp.Popen(sed_args, stdin=stdin, stdout=sp.PIPE)
+    result = sed.stdout.read().decode(ENCS['shell'])
+    stdin.close(); os.remove(path)
+    listing = [line for line in result.split('\n') if line.strip()]
+    listing = sorted(set(listing))
+    return(listing)
+
+
+#===============================================================================
+# Define GLModule class
+#===============================================================================
+class GLModule(object):
+  '''GLModule is used to create a module object from the file with the given
+  path. GLModule can get all information about module, get its dependencies,
+  files, etc.'''
+  
+  def __init__(self, config, module, patched=False):
+    '''GLModule.__init__(config, module[, patched]) -> GLModule
+    
+    Create new GLModule instance. Arguments are module and patched, where
+    module is a string representing the path to the module and patched is a
+    bool indicating that module was created after applying patch.'''
+    self.args = dict()
+    self.cache = dict()
+    self.content = string()
+    if type(config) is not GLConfig:
+      raise(TypeError('config must be a GLConfig, not %s' % \
+        type(config).__name__))
+    if type(module) is bytes or type(module) is string:
+      if type(module) is bytes:
+        module = module.decode(ENCS['default'])
+    else: # if module has not bytes or string type
+      raise(TypeError('module must be a string, not %s' % \
+        type(module).__name__))
+    if type(patched) is not bool:
+      raise(TypeError('patched must be a bool, not %s' % \
+        type(module).__name__))
+    self.module = module
+    self.patched = patched
+    self.config = config
+    self.filesystem = GLFileSystem(self.config)
+    self.modulesystem = GLModuleSystem(self.config)
+    with codecs.open(module, 'rb', 'UTF-8') as file:
+      self.content = file.read()
+    self.regex ='(?:Description:|Comment:|Status:|Notice:|Applicability:|\
+Files:|Depends-on:|configure\\.ac-early:|configure\\.ac:|Makefile\\.am:|\
+Include:|Link:|License:|Maintainer:)'
+    
+  def __eq__(self, module):
+    '''x.__eq__(y) <==> x==y'''
+    result = bool()
+    if type(module) is GLModule:
+      if self.module == module.module:
+        result = True
+    return(result)
+    
+  def __ne__(self, module):
+    '''x.__ne__(y) <==> x!=y'''
+    result = bool()
+    if type(module) is GLModule:
+      if self.module != module.module:
+        result = True
+    return(result)
+    
+  def __ge__(self, module):
+    '''x.__ge__(y) <==> x>=y'''
+    result = bool()
+    if type(module) is GLModule:
+      if self.module >= module.module:
+        result = True
+    return(result)
+    
+  def __gt__(self, module):
+    '''x.__gt__(y) <==> x>y'''
+    result = bool()
+    if type(module) is GLModule:
+      if self.module > module.module:
+        result = True
+    return(result)
+    
+  def __hash__(self):
+    '''x.__hash__() <==> hash(x)'''
+    module = hash(self.module)
+    patched = hash(self.patched)
+    result = module^patched
+    return(result)
+    
+  def __le__(self, module):
+    '''x.__le__(y) <==> x<=y'''
+    result = bool()
+    if type(module) is GLModule:
+      if self.module <= module.module:
+        result = True
+    return(result)
+    
+  def __lt__(self, module):
+    '''x.__lt__(y) <==> x<y'''
+    result = bool()
+    if type(module) is GLModule:
+      if self.module < module.module:
+        result = True
+    return(result)
+    
+  def __str__(self):
+    '''x.__str__() <==> str(x)'''
+    result = self.getName()
+    return(result)
+    
+  def __repr__(self):
+    '''x.__repr__ <==> repr(x)'''
+    result = '<pygnulib.GLModule %s %s>' % \
+      (repr(self.getName()), hex(id(self)))
+    return(result)
+    
+  def getName(self):
+    '''GLModule.getName() -> string
+    
+    Return the name of the module.'''
+    pattern = compiler(joinpath('modules', '(.*?)$'))
+    result = pattern.findall(self.module)[0]
+    return(result)
+    
+  def isPatched(self):
+    '''GLModule.isPatched() -> bool
+    
+    Check whether module was created after applying patch.'''
+    return(self.patched)
+    
+  def isTests(self):
+    '''GLModule.isTests() -> bool
+    
+    Check whether module is a -tests version of module.'''
+    result = self.getName().endswith('-tests')
+    return(result)
+    
+  def isNonTests(self):
+    '''GLModule.isTests() -> bool
+    
+    Check whether module is not a -tests version of module.'''
+    result = not(self.isTests())
+    return(result)
+    
+  def getTestsName(self):
+    '''Return -tests version of the module name.'''
+    result = self.getName()
+    if not result.endswith('-tests'):
+      result += '-tests'
+    return(result)
+    
+  def getTestsModule(self):
+    '''Return -tests version of the module as GLModule.'''
+    result = self.modulesystem.find(self.getTestsName())
+    return(result)
+    
+  def getShellFunc(self):
+    '''GLModule.getShellFunc() -> string
+    
+    Computes the shell function name that will contain the m4 macros for the
+    module.'''
+    isalnum = True
+    macro_prefix = self.config['macro_prefix']
+    for char in str(module):
+      if char not in constants.ALPHANUMERIC:
+        isalnum = False
+        break
+    if isalnum:
+      module = str(self)
+    else: # if not isalnum
+      module = '%s\n' % str(self)
+      if type(module) is string:
+        module = module.encode(ENCS['default'])
+      module = hashlib.md5(module).hexdigest()
+    result = 'func_%s_gnulib_m4code_%s' % (macro_prefix, module)
+    if type(result) is bytes:
+      result = result.decode(ENCS['default'])
+    return(result)
+    
+  def getShellVar(self):
+    '''GLModule.getShellVar() -> string
+    
+    Compute the shell variable name the will be set to true once the m4 macros
+    for the module have been executed.'''
+    isalnum = True
+    macro_prefix = self.config['macro_prefix']
+    for char in str(module):
+      if char not in constants.ALPHANUMERIC:
+        isalnum = False
+        break
+    if isalnum:
+      module = str(self)
+    else: # if not isalnum
+      module = '%s\n' % str(self)
+      if type(module) is string:
+        module = module.encode(ENCS['default'])
+      module = hashlib.md5(module).hexdigest()
+    result = '%s_gnulib_enabled_%s' % (macro_prefix, module)
+    if type(result) is bytes:
+      result = result.decode(ENCS['default'])
+    return(result)
+    
+  def getConditionalName(self):
+    '''GLModule.getConditionalName() -> string
+    
+    Return the automake conditional name.
+    GLConfig: macro_prefix.'''
+    macro_prefix = self.config['macro_prefix']
+    nonascii = \
+    [ # Begin to filter non-ascii chars
+      char for char in self.getName() if char not in \
+      'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
+    ] # Finish to filter non-ascii chars
+    if nonascii:
+      name = self.getName().encode(ENCS['default'])
+      name = hashlib.md5(name).hexdigest()
+      conditional = '%s_GNULIB_ENABLED_%s' % (macro_prefix, name)
+    else: # if not nonascii
+      result = '%s_GNULIB_ENABLED_%s' (macro_prefix, name)
+    if type(result) is bytes:
+      result = result.decode(ENCS['default'])
+    return(result)
+    
+  def getDescription(self):
+    '''GLModule.getDescription() -> string
+    
+    Return description of the module.'''
+    section = 'Description:'
+    if 'description' not in self.cache:
+      if section not in self.content:
+        result = string()
+      else: # if section in self.content
+        pattern = '^%s[\t ]*(.*?)%s' % (section, self.regex)
+        pattern = compiler(pattern, re.S | re.M)
+        result = pattern.findall(self.content)
+        if type(result) is list:
+          if not result:
+            result = string()
+          else: # if result
+            result = result[-1]
+      result = result.strip()
+      self.cache['description'] = result
+    return(self.cache['description'])
+    
+  def getComment(self):
+    '''GLModule.getComment() -> string
+    
+    Return comment to module.'''
+    section = 'Comment:'
+    if 'comment' not in self.cache:
+      if section not in self.content:
+        result = string()
+      else: # if section in self.content
+        pattern = '^%s[\t ]*(.*?)%s' % (section, self.regex)
+        pattern = compiler(pattern, re.S | re.M)
+        result = pattern.findall(self.content)
+        if type(result) is list:
+          if not result:
+            result = string()
+          else: # if result
+            result = result[-1]
+      result = result.strip()
+      self.cache['comment'] = result
+    return(self.cache['comment'])
+    
+  def getStatus(self):
+    '''GLModule.getStatus() -> string
+    
+    Return module status.'''
+    section = 'Status:'
+    if 'status' not in self.cache:
+      if section not in self.content:
+        result = string()
+      else: # if section in self.content
+        snippet = self.content.split(section)[-1]
+        snippet = snippet.replace('\r\n', '\n')
+        lines = ['%s\n' % line for line in snippet.split('\n')]
+        parts = list()
+        for line in lines:
+          regex = '^(Description|Comment|Status|Notice|Applicability|'
+          regex += 'Files|Depends-on|configure\\.ac-early|configure\\.ac|'
+          regex += 'Makefile\\.am|Include|Link|License|Maintainer):$'
+          pattern = compiler(regex)
+          findflag = pattern.findall(line)
+          if findflag:
+            break
+          parts += [line]
+        result = [part.strip() for part in parts if part.strip()]
+      self.cache['status'] = list(result)
+    return(list(self.cache['status']))
+    
+  def getNotice(self):
+    '''GLModule.getNotice() -> string
+    
+    Return notice to module.'''
+    section = 'Notice:'
+    if 'notice' not in self.cache:
+      if section not in self.content:
+        result = string()
+      else: # if section in self.content
+        snippet = self.content.split(section)[-1]
+        snippet = snippet.replace('\r\n', '\n')
+        lines = ['%s\n' % line for line in snippet.split('\n')]
+        parts = list()
+        for line in lines:
+          regex = '^(Description|Comment|Status|Notice|Applicability|'
+          regex += 'Files|Depends-on|configure\\.ac-early|configure\\.ac|'
+          regex += 'Makefile\\.am|Include|Link|License|Maintainer):$'
+          pattern = compiler(regex)
+          findflag = pattern.findall(line)
+          if findflag:
+            break
+          parts += [line]
+        result = ''.join(parts)
+      self.cache['notice'] = result
+    return(self.cache['notice'])
+    
+  def getApplicability(self):
+    '''GLModule.getApplicability() -> string
+    
+    Return applicability of module.'''
+    section = 'Applicability:'
+    if 'applicability' not in self.cache:
+      if section not in self.content:
+        result = string()
+      else: # if section in self.content
+        snippet = self.content.split(section)[-1]
+        snippet = snippet.replace('\r\n', '\n')
+        lines = ['%s\n' % line for line in snippet.split('\n')]
+        parts = list()
+        for line in lines:
+          regex = '^(Description|Comment|Status|Notice|Applicability|'
+          regex += 'Files|Depends-on|configure\\.ac-early|configure\\.ac|'
+          regex += 'Makefile\\.am|Include|Link|License|Maintainer):$'
+          pattern = compiler(regex)
+          findflag = pattern.findall(line)
+          if findflag:
+            break
+          parts += [line]
+        parts = [part.strip() for part in parts]
+        result = ''.join(parts)
+      if not result.strip():
+        if self.getName().endswith('-tests'):
+          result = 'tests'
+        else: # if not self.getName().endswith('-tests')
+          result = 'main'
+      if type(result) is bytes:
+        result = result.decode(ENCS['default'])
+      result = result.strip()
+      self.cache['applicability'] = result
+    return(self.cache['applicability'])
+    
+  def getFiles(self):
+    '''GLModule.getFiles() -> list
+    
+    Return list of files.
+    GLConfig: ac_version.'''
+    ac_version = self.config['ac_version']
+    section = 'Files:'
+    result = list()
+    if 'files' not in self.cache:
+      if section not in self.content:
+        result = list()
+      else: # if section in self.content
+        snippet = self.content.split(section)[-1]
+        snippet = snippet.replace('\r\n', '\n')
+        lines = ['%s\n' % line for line in snippet.split('\n')]
+        parts = list()
+        for line in lines:
+          regex = '^(Description|Comment|Status|Notice|Applicability|'
+          regex += 'Files|Depends-on|configure\\.ac-early|configure\\.ac|'
+          regex += 'Makefile\\.am|Include|Link|License|Maintainer):$'
+          pattern = compiler(regex)
+          findflag = pattern.findall(line)
+          if findflag:
+            break
+          parts += [line]
+        result = [part.strip() for part in parts if part.strip()]
+      result += [joinpath('m4', '00gnulib.m4')]
+      result += [joinpath('m4', 'gnulib-common.m4')]
+      if ac_version == 2.59:
+        result += [joinpath('m4', 'onceonly.m4')]
+      self.cache['files'] = list(result)
+    return(list(self.cache['files']))
+    
+  def getDependencies(self):
+    '''GLModule.getDependencies() -> list
+    
+    Return list of dependencies.
+    GLConfig: localdir.'''
+    localdir = self.config['localdir']
+    result = list()
+    section = 'Depends-on:'
+    if 'dependencies' not in self.cache:
+      if section not in self.content:
+        depmodules = list()
+      else: # if section in self.content
+        snippet = self.content.split(section)[-1]
+        snippet = snippet.replace('\r\n', '\n')
+        lines = ['%s\n' % line for line in snippet.split('\n')]
+        parts = list()
+        for line in lines:
+          regex = '^(Description|Comment|Status|Notice|Applicability|'
+          regex += 'Files|Depends-on|configure\\.ac-early|configure\\.ac|'
+          regex += 'Makefile\\.am|Include|Link|License|Maintainer):$'
+          pattern = compiler(regex)
+          findflag = pattern.findall(line)
+          if findflag:
+            break
+          parts += [line]
+        modules = ''.join(parts)
+        modules = [line for line in modules.split('\n') if line.strip()]
+        modules = [module for module in modules if not module.startswith('#')]
+        for line in modules:
+          split = [part for part in line.split(' ') if part.strip()]
+          if len(split) == 1:
+            module = line.strip()
+            condition = None
+          else: # if len(split) != 1
+            module = split[0]
+            condition = split[1]
+            if type(condition) is bytes:
+              condition = condition.decode(ENCS['default'])
+          result += [tuple([self.modulesystem.find(module), condition])]
+      self.cache['dependencies'] = result
+    return(list(self.cache['dependencies']))
+    
+  def getAutoconfSnippet_Early(self):
+    '''GLModule.getAutoconfSnippet_Early() -> string
+    
+    Return autoconf-early snippet.'''
+    section = 'configure.ac-early:'
+    if 'autoconf-early' not in self.cache:
+      if section not in self.content:
+        result = string()
+      else: # if section in self.content
+        snippet = self.content.split(section)[-1]
+        snippet = snippet.replace('\r\n', '\n')
+        lines = ['%s\n' % line for line in snippet.split('\n')]
+        parts = list()
+        for line in lines:
+          regex = '^(Description|Comment|Status|Notice|Applicability|'
+          regex += 'Files|Depends-on|configure\\.ac-early|configure\\.ac|'
+          regex += 'Makefile\\.am|Include|Link|License|Maintainer):$'
+          pattern = compiler(regex)
+          findflag = pattern.findall(line)
+          if findflag:
+            break
+          parts += [line]
+        result = ''.join(parts)
+      self.cache['autoconf-early'] = result
+    return(self.cache['autoconf-early'])
+    
+  def getAutoconfSnippet(self):
+    '''GLModule.getAutoconfSnippet() -> string
+    
+    Return autoconf snippet.'''
+    section = 'configure.ac:'
+    if 'autoconf' not in self.cache:
+      if section not in self.content:
+        result = string()
+      else: # if section in self.content
+        snippet = self.content.split(section)[-1]
+        snippet = snippet.replace('\r\n', '\n')
+        lines = ['%s\n' % line for line in snippet.split('\n')]
+        parts = list()
+        for line in lines:
+          regex = '^(Description|Comment|Status|Notice|Applicability|'
+          regex += 'Files|Depends-on|configure\\.ac-early|configure\\.ac|'
+          regex += 'Makefile\\.am|Include|Link|License|Maintainer):$'
+          pattern = compiler(regex)
+          findflag = pattern.findall(line)
+          if findflag:
+            break
+          parts += [line]
+        result = ''.join(parts)
+      self.cache['autoconf'] = result
+    return(self.cache['autoconf'])
+    
+  def getAutomakeSnippet(self):
+    '''getAutomakeSnippet() -> string
+    
+    Get automake snippet.
+    GLConfig: auxdir, ac_version.'''
+    result = string() # Define stack variable
+    conditional = self.getAutomakeSnippet_Conditional()
+    if conditional.strip():
+      result += self.getAutomakeSnippet_Conditional()
+    else: # if not conditional.strip()
+      result += '\n'
+    result += self.getAutomakeSnippet_Unconditional()
+    return(result)
+    
+  def getAutomakeSnippet_Conditional(self):
+    '''GLModule.getAutomakeSnippet_Conditional() -> string
+    
+    Return conditional automake snippet.'''
+    section = 'Makefile.am:'
+    if 'makefile-conditional' not in self.cache:
+      if section not in self.content:
+        result = string()
+      else: # if section in self.content
+        snippet = self.content.split(section)[-1]
+        snippet = snippet.replace('\r\n', '\n')
+        lines = ['%s\n' % line for line in snippet.split('\n')]
+        parts = list()
+        for line in lines:
+          regex = '^(Description|Comment|Status|Notice|Applicability|'
+          regex += 'Files|Depends-on|configure\\.ac-early|configure\\.ac|'
+          regex += 'Makefile\\.am|Include|Link|License|Maintainer):$'
+          pattern = compiler(regex)
+          findflag = pattern.findall(line)
+          if findflag:
+            break
+          parts += [line]
+        result = ''.join(parts)
+      self.cache['makefile-conditional'] = result
+    return(self.cache['makefile-conditional'])
+    
+  def getAutomakeSnippet_Unconditional(self):
+    '''GLModule.getAutomakeSnippet_Unconditional() -> string
+    
+    Return unconditional automake snippet.
+    GLConfig: auxdir, ac_version.'''
+    auxdir = self.config['auxdir']
+    ac_version = self.config['ac_version']
+    result = string()
+    if 'makefile-unconditional' not in self.cache:
+      if self.isTests():
+        files = self.getFiles()
+        extra_files = filter_filelist(constants.NL, files,
+          'tests/', '', 'tests/', '').split(constants.NL)
+        extra_files = sorted(set(extra_files))
+        if extra_files:
+          result += string('EXTRA_DIST += %s' % ' '.join(extra_files))
+          result += constants.NL *2
+      else: # if not tests module
+        # TODO: unconditional automake snippet for nontests modules
+        snippet = self.getAutomakeSnippet_Conditional()
+        snippet = snippet.replace('\\\n', ' ')
+        pattern = compiler('^lib_SOURCES[\t ]*\\+=[\t ]*(.*?)$', re.S | re.M)
+        mentioned_files = pattern.findall(snippet)
+        if mentioned_files != list():
+          mentioned_files = mentioned_files[-1].split(' ')
+          mentioned_files = [f.strip() for f in mentioned_files]
+          mentioned_files = [f for f in mentioned_files if f != '']
+          mentioned_files = sorted(set(mentioned_files))
+        all_files = self.getFiles()
+        lib_files = filter_filelist(constants.NL, all_files,
+          'lib/', '', 'lib/', '').split(constants.NL)
+        extra_files = [f for f in lib_files if f not in mentioned_files]
+        extra_files = sorted(set(extra_files))
+        if extra_files != [''] and extra_files:
+          result += string('EXTRA_DIST += %s' % ' '.join(extra_files))
+          result += '\n\n'
+        # Synthesize also an EXTRA_lib_SOURCES augmentation
+        if str(self) != 'relocatable-prog-wrapper' and str(self) != 'pt_chown':
+          extra_files = filter_filelist(constants.NL, extra_files,
+            '', '.c', '', '').split(constants.NL)
+          extra_files = sorted(set(extra_files))
+          if extra_files != ['']:
+            result += string('EXTRA_lib_SOURCES += %s' % ' '.join(extra_files))
+            result += '\n\n'
+        # Synthesize an EXTRA_DIST augmentation also for the files in build-aux
+        buildaux_files = filter_filelist(constants.NL, all_files,
+          'build-aux/', '', 'build-aux/', '').split(constants.NL)
+        buildaux_files = sorted(set(buildaux_files))
+        if buildaux_files != ['']:
+          buildaux_files = ''.join(buildaux_files)
+          buildaux_files = joinpath('$(top_srcdir)', auxdir, buildaux_files)
+          result += string('EXTRA_DIST += %s' % buildaux_files)
+          result += '\n\n'
+        # Synthesize an EXTRA_DIST augmentation also for the files from top/.
+        top_files = filter_filelist(constants.NL, all_files,
+          'top/', '', 'top/', '').split(constants.NL)
+        top_files = sorted(set(top_files))
+        if top_files != ['']:
+          top_files = ''.join(top_files)
+          top_files = joinpath('$(top_srcdir)', top_files)
+          result += string('EXTRA_DIST += %s' % top_files)
+          result += '\n\n'
+      result = constants.nlconvert(result)
+      self.cache['makefile-unconditional'] = result
+    return(self.cache['makefile-unconditional'])
+    
+  def getInclude(self):
+    '''GLModule.getInclude() -> string
+    
+    Return include directive.'''
+    section = 'Include:'
+    if 'include' not in self.cache:
+      if section not in self.content:
+        result = string()
+      else: # if section in self.content
+        snippet = self.content.split(section)[-1]
+        snippet = snippet.replace('\r\n', '\n')
+        lines = ['%s\n' % line for line in snippet.split('\n')]
+        parts = list()
+        for line in lines:
+          regex = '^(Description|Comment|Status|Notice|Applicability|'
+          regex += 'Files|Depends-on|configure\\.ac-early|configure\\.ac|'
+          regex += 'Makefile\\.am|Include|Link|License|Maintainer):$'
+          pattern = compiler(regex)
+          findflag = pattern.findall(line)
+          if findflag:
+            break
+          parts += [line]
+        result = ''.join(parts)
+      result = result.strip()
+      pattern = compiler('^(["<].*?[>"])', re.S | re.M)
+      result = pattern.sub('#include \\1', result)
+      self.cache['include'] = result
+    return(self.cache['include'])
+    
+  def getLink(self):
+    '''GLModule.getLink() -> string
+    
+    Return link directive.'''
+    section = 'Link:'
+    if 'link' not in self.cache:
+      if section not in self.content:
+        result = string()
+      else: # if section in self.content
+        snippet = self.content.split(section)[-1]
+        snippet = snippet.replace('\r\n', '\n')
+        lines = ['%s\n' % line for line in snippet.split('\n')]
+        parts = list()
+        for line in lines:
+          regex = '^(Description|Comment|Status|Notice|Applicability|'
+          regex += 'Files|Depends-on|configure\\.ac-early|configure\\.ac|'
+          regex += 'Makefile\\.am|Include|Link|License|Maintainer):$'
+          pattern = compiler(regex)
+          findflag = pattern.findall(line)
+          if findflag:
+            break
+          parts += [line]
+        parts = [part.strip() for part in parts if part.strip()]
+        result = ''.join(parts)
+      self.cache['link'] = result
+    return(self.cache['link'])
+    
+  def getLicense(self):
+    '''GLModule.getLicense(self) -> string
+    
+    Get license and warn user if module lacks a license.'''
+    license = self.getLicense_Raw()
+    if not self.isTests():
+      if not license:
+        if self.config['errors']:
+          raise(GLError(18, string(self)))
+        else: # if not self.config['errors']
+          sys.stderr.write('gnulib-tool: warning: ')
+          sys.stderr.write('module %s lacks a license\n' % str(self))
+    if not license:
+      license = 'GPL'
+    return(license)
+    
+  def getLicense_Raw(self):
+    '''GLModule.getLicense_Raw() -> string
+    
+    Return module license.'''
+    section = 'License:'
+    if 'license' not in self.cache:
+      if section not in self.content:
+        result = string()
+      else: # if section in self.content
+        pattern = '^%s[\t ]*(.*?)%s' % (section, self.regex)
+        pattern = compiler(pattern, re.S | re.M)
+        result = pattern.findall(self.content)
+        if type(result) is list:
+          if not result:
+            result = string()
+          else: # if result
+            result = result[-1]
+      result = result.strip()
+      self.cache['license'] = result
+    return(self.cache['license'])
+    
+  def getMaintainer(self):
+    '''GLModule.getMaintainer() -> string
+    
+    Return maintainer directive.'''
+    section = 'Maintainer:'
+    if 'maintainer' not in self.cache:
+      if section not in self.content:
+        result = string()
+      else: # if section in self.content
+        snippet = self.content.split(section)[-1]
+        snippet = snippet.replace('\r\n', '\n')
+        lines = ['%s\n' % line for line in snippet.split('\n')]
+        parts = list()
+        for line in lines:
+          regex = '^(Description|Comment|Status|Notice|Applicability|'
+          regex += 'Files|Depends-on|configure\\.ac-early|configure\\.ac|'
+          regex += 'Makefile\\.am|Include|Link|License|Maintainer):$'
+          pattern = compiler(regex)
+          findflag = pattern.findall(line)
+          if findflag:
+            break
+          parts += [line]
+        result = ''.join(parts)
+      result = result.strip()
+      self.cache['maintainer'] = result
+    return(self.cache['maintainer'])
+
+
+#===============================================================================
+# Define GLModuleTable class
+#===============================================================================
+class GLModuleTable(object):
+  '''GLModuleTable is used to work with the list of the modules.'''
+  
+  def __init__(self, config, avoids=list()):
+    '''GLModuleTable.__init__(config, avoids) -> GLModuleTable
+    
+    Create new GLModuleTable instance. If modules are specified, then add
+    every module from iterable as unconditional module. If avoids is specified,
+    then in transitive_closure every dependency which is in avoids won't be
+    included in the final modules list. If testflags iterable is enabled, then
+    don't add module which status is in the testflags. If conddeps are enabled,
+    then store condition for each dependency if it has a condition.
+    The only necessary argument is localdir, which is needed just to create
+    modulesystem instance to look for dependencies.'''
+    self.avoids = list() # Avoids
+    self.dependers = dict() # Dependencies
+    self.conditionals = dict() # Conditional modules
+    self.unconditionals = dict() # Unconditional modules
+    self.base_modules = list() # Base modules
+    self.main_modules = list() # Main modules
+    self.tests_modules = list() # Tests modules
+    self.final_modules = list() # Final modules
+    if type(config) is not GLConfig:
+      raise(TypeError('config must be a GLConfig, not %s' % \
+        type(config).__name__))
+    for avoid in avoids:
+      if type(avoid) is not GLModule:
+        raise(TypeError('each avoid must be a GLModule instance'))
+      self.avoids += [avoids]
+    self.config = config
+    self.filesystem = GLFileSystem(self.config)
+    self.modulesystem = GLModuleSystem(self.config)
+    
+  def __repr__(self):
+    '''x.__repr__() <==> repr(x)'''
+    result = '<pygnulib.GLModuleTable %s>' % hex(id(self))
+    return(result)
+    
+  def __getitem__(self, y):
+    '''x.__getitem__(y) <==> x[y]'''
+    if y in ['base', 'final', 'main', 'tests', 'avoids']:
+      if y == 'base':
+        return(self.getBaseModules())
+      elif y == 'final':
+        return(self.getFinalModules())
+      elif y == 'main':
+        return(self.getMainModules())
+      elif y == 'tests':
+        return(self.getTestsModules())
+      else: # if y == 'avoids'
+        return(self.getAvoids())
+    else: # if y is not in list
+      raise(KeyError('GLModuleTable does not contain key: %s' % repr(y)))
+    
+  def addConditional(self, parent, module, condition):
+    '''GLModuleTable.addConditional(module, condition)
+    
+    Add new conditional dependency from parent to module with condition.'''
+    if type(parent) is not GLModule:
+      raise(TypeError('parent must be a GLModule, not %s' % \
+        type(parent).__name__))
+    if type(module) is not GLModule:
+      raise(TypeError('module must be a GLModule, not %s' % \
+        type(module).__name__))
+    if type(condition) is bytes or type(condition) is string \
+    or condition == True:
+      if type(condition) is bytes:
+        condition = condition.decode(ENCS['default'])
+    else: # if condition has not bytes or string type or is not True
+      raise(TypeError('condition must be a string or True, not %s' % \
+        type(condition).__name__))
+    if not str(module) in self.unconditionals:
+      if str(module) not in self.dependers:
+        self.dependers[module] = list()
+      self.dependers[module] += [module]
+      key = '%s---%s' % (str(parent), str(module))
+      self.conditionals[key] = condition
+    
+  def addUnconditional(self, module):
+    '''GLModuleTable.addUnconditional(module)
+    
+    Add module as unconditional dependency.'''
+    if type(module) is not GLModule:
+      raise(TypeError('module must be a GLModule, not %s' % \
+        type(module).__name__))
+    if str(module) in self.dependers:
+      self.dependers.pop(str(module))
+    self.unconditionals[str(module)] = True
+    
+  def isConditional(self, module):
+    '''GLModuleTable.isConditional(module) -> bool
+    
+    Check whether module is unconditional.'''
+    if type(module) is not GLModule:
+      raise(TypeError('module must be a GLModule, not %s' % \
+        type(module).__name__))
+    result = str(module) in self.dependers
+    return(result)
+    
+  def getCondition(self, parent, module):
+    '''GLModuleTable.getCondition(module) -> string or True
+    
+    Return condition from parent to module. Condition can be string or True.
+    If module is not in the list of conddeps, method returns None.'''
+    if type(parent) is not GLModule:
+      raise(TypeError('parent must be a GLModule, not %s' % \
+        type(parent).__name__))
+    if type(module) is not GLModule:
+      raise(TypeError('module must be a GLModule, not %s' % \
+        type(module).__name__))
+    key = '%s---%s' % (str(parent), str(module))
+    result = None
+    if key in self.conditionals:
+      result = self.conditionals[key]
+    return(result)
+    
+  def transitive_closure(self, modules):
+    '''GLModuleTable.transitive_closure(modules) -> list
+    
+    Use transitive closure to add module and its dependencies. Add every
+    module and its dependencies from modules list, but do not add dependencies
+    which contain in avoids list. If any testflag is enabled, then do not add
+    dependencies which have the status as this flag. If conddeps are enabled,
+    then store condition for each dependency if it has a condition. This method
+    is used to update final list of modules. Method returns list of modules.
+    GLConfig: testflags.'''
+    for module in modules:
+      if type(module) is not GLModule:
+        raise(TypeError('each module must be a GLModule instance'))
+    handledmodules = list()
+    inmodules = modules
+    outmodules = list()
+    if self.config['conddeps']:
+      for module in modules:
+        self.addUnconditional(module)
+    while inmodules:
+      inmodules_this_round = inmodules
+      inmodules = list()
+      for module in inmodules_this_round:
+        outmodules += [module]
+        if self.config['conddeps']:
+          automake_snippet = \
+            module.getAutomakeSnippet_Conditional()
+          pattern = compiler('^if')
+          if not pattern.findall(automake_snippet):
+            self.addUnconditional(module)
+          conditional = self.isConditional(module)
+        dependencies = module.getDependencies()
+        depmodules = [pair[0] for pair in dependencies]
+        conditions = [pair[1] for pair in dependencies]
+        if TESTS['tests'] in self.config['testflags']:
+          testsname = module.getTestsName()
+          if self.modulesystem.exists(testsname):
+            testsmodule = self.modulesystem.find(testsname)
+            depmodules += [testsmodule]
+            conditions += [None]
+        for depmodule in depmodules:
+          include = True
+          includes = list()
+          status = depmodule.getStatus()
+          for word in status:
+            if word == 'obsolete':
+              if TESTS['obsolete'] in self.config['testflags'] or \
+              TESTS['all-test'] in self.config['testflags']:
+                includes += [False]
+            elif word == 'c++-test':
+              if TESTS['c++-test'] in self.config['testflags'] or \
+              TESTS['all-test'] in self.config['testflags']:
+                includes += [False]
+            elif word == 'longrunning-test':
+              if TESTS['longrunning-test'] in self.config['testflags'] or \
+              TESTS['all-test'] in self.config['testflags']:
+                includes += [False]
+            elif word == 'privileged-test':
+              if TESTS['privileged-test'] in self.config['testflags'] or \
+              TESTS['all-test'] in self.config['testflags']:
+                includes += [False]
+            elif word == 'all-test':
+              if TESTS['all-test'] in self.config['testflags'] or \
+              TESTS['all-test'] in self.config['testflags']:
+                includes += [False]
+            else: # if any other word
+              if word.endswith('-tests'):
+                if TESTS['all-test'] in self.config['testflags']:
+                  includes += [False]
+            include = any(includes)
+          if include and depmodule not in self.avoids:
+            inmodules += [depmodule]
+            if self.config['conddeps']:
+              index = depmodules.index(depmodule)
+              condition = conditions[index]
+              if condition:
+                self.addConditional(module, depmodule, condition)
+              else: # if condition
+                if conditional:
+                  self.addConditional(module, depmodule, True)
+                else: # if not conditional
+                  self.addUnconditional(module)
+      listing = list() # Create empty list
+      inmodules = sorted(set(inmodules))
+      handledmodules = sorted(set(handledmodules +inmodules_this_round))
+      inmodules = \
+      [ # Begin to filter inmodules
+        module for module in inmodules if module not in handledmodules
+      ] # Finish to filter inmodules
+      inmodules = sorted(set(inmodules))
+    modules = sorted(set(outmodules))
+    self.modules = modules
+    return(list(modules))
+    
+  def transitive_closure_separately(self, basemodules, finalmodules):
+    '''GLModuleTable.transitive_closure_separately(*args, **kwargs) -> tuple
+    
+    Determine main module list and tests-related module list separately.
+    The main module list is the transitive closure of the specified modules,
+    ignoring tests modules. Its lib/* sources go into $sourcebase/. If lgpl is
+    specified, it will consist only of LGPLed source.
+    The tests-related module list is the transitive closure of the specified
+    modules, including tests modules, minus the main module list excluding
+    modules of applicability 'all'. Its lib/* sources (brought in through
+    dependencies of *-tests modules) go into $testsbase/. It may contain GPLed
+    source, even if lgpl is specified.
+    Arguments are basemodules and finalmodules, where basemodules argument
+    represents modules specified by user and finalmodules represents modules
+    list after previous transitive_closure.
+    Method returns tuple which contains two lists: the list of main modules and
+    the list of tests-related modules. Both lists contain dependencies.
+    GLConfig: testflags.'''
+    inctests = False
+    main_modules = list()
+    tests_modules = list()
+    if TESTS['tests'] in self.config['testflags']:
+      self.config['testflags'].pop(TESTS['tests'])
+      inctests = True
+    for module in basemodules:
+      if type(module) is not GLModule:
+        raise(TypeError('each module must be a GLModule instance'))
+    for module in finalmodules:
+      if type(module) is not GLModule:
+        raise(TypeError('each module must be a GLModule instance'))
+    main_modules = self.transitive_closure(basemodules)
+    tests_modules = \
+      [m for m in finalmodules if m not in main_modules] + \
+      [m for m in main_modules if m.getApplicability() != 'main']
+    tests_modules = sorted(set(tests_modules))
+    if inctests:
+      testflags = sorted(set(self.config['testflags'] +[TESTS['tests']]))
+      self.config.setTestFlags(testflags)
+    result = tuple([main_modules, tests_modules])
+    return(result)
+    
+  def add_dummy(self, modules):
+    '''GLModuleTable.add_dummy(modules) -> list
+
+    Add dummy package to list of modules if dummy package is needed. If not,
+    return original list of modules.
+    GLConfig: auxdir, ac_version.'''
+    auxdir = self.config['auxdir']
+    ac_version = self.config['ac_version']
+    have_lib_sources = False
+    for module in modules:
+      if type(module) is not GLModule:
+        raise(TypeError('each module must be a GLModule instance'))
+      snippet = module.getAutomakeSnippet()
+      snippet = snippet.replace('\\\n', '')
+      pattern = compiler('^lib_SOURCES[\t ]*\\+=[\t ]*(.*?)$', re.S | re.M)
+      files = pattern.findall(snippet)
+      if files: # if source files were found
+        files = files[-1].split(' ')
+        for file in files:
+          if not file.endswith('.h'):
+            have_lib_sources = True
+            break
+    if not have_lib_sources:
+      dummy = self.modulesystem.find('dummy')
+      modules = sorted(set(modules +[dummy]))
+    return(list(modules))
+    
+  def filelist(self, modules):
+    '''GLModuleTable.filelist(modules) -> list
+
+    Determine the final file list for the given list of modules. The list of
+    modules must already include dependencies.
+    GLConfig: ac_version.'''
+    ac_version = self.config['ac_version']
+    filelist = list()
+    for module in modules:
+      if type(module) is not GLModule:
+        raise(TypeError('each module must be a GLModule instance'))
+    listings = [module.getFiles() for module in modules]
+    for listing in listings:
+      for file in listing:
+        if file not in filelist:
+          filelist += [file]
+    return(filelist)
+    
+  def filelist_separately(self, main_modules, tests_modules):
+    '''GLModuleTable.filelist_separately(**kwargs) -> list
+
+    Determine the final file lists. They must be computed separately, because
+    files in lib/* go into $sourcebase/ if they are in the main file list but
+    into $testsbase/ if they are in the tests-related file list. Furthermore
+    lib/dummy.c can be in both.'''
+    ac_version = self.config['ac_version']
+    main_filelist = self.filelist(main_modules)
+    tests_filelist = self.filelist(tests_modules)
+    tests_filelist = \
+    [ # Begin to sort filelist
+      file.replace('lib/', 'tests=lib/', 1) \
+      if file.startswith('lib/') else file
+      for file in tests_filelist
+    ] # Finish to sort filelist
+    result = tuple([main_filelist, tests_filelist])
+    return(result)
+    
+  def getAvoids(self):
+    '''GLModuleTable.getAvoids() -> list
+    
+    Return list of avoids.'''
+    return(list(self.avoids))
+    
+  def setAvoids(self, modules):
+    '''GLModuleTable.setAvoids(modules)
+    
+    Specify list of avoids.'''
+    for module in modules:
+      if type(module) is not GLModule:
+        raise(TypeError('each module must be a GLModule instance'))
+    self.avoids = sorted(set(modules))
+    
+  def getBaseModules(self):
+    '''GLModuleTable.getBaseModules() -> list
+    
+    Return list of base modules.'''
+    return(list(self.base_modules))
+    
+  def setBaseModules(self, modules):
+    '''GLModuleTable.setBaseModules(modules)
+    
+    Specify list of base modules.'''
+    for module in modules:
+      if type(module) is not GLModule:
+        raise(TypeError('each module must be a GLModule instance'))
+    self.base_modules = sorted(set(modules))
+    
+  def getFinalModules(self):
+    '''GLModuleTable.getFinalModules() -> list
+    
+    Return list of final modules.'''
+    return(list(self.final_modules))
+    
+  def setFinalModules(self, modules):
+    '''GLModuleTable.setFinalModules(modules)
+    
+    Specify list of final modules.'''
+    for module in modules:
+      if type(module) is not GLModule:
+        raise(TypeError('each module must be a GLModule instance'))
+    self.final_modules = sorted(set(modules))
+    
+  def getMainModules(self):
+    '''GLModuleTable.getMainModules() -> list
+    
+    Return list of main modules.'''
+    return(list(self.main_modules))
+    
+  def setMainModules(self, modules):
+    '''GLModuleTable.setMainModules(modules)
+    
+    Specify list of main modules.'''
+    for module in modules:
+      if type(module) is not GLModule:
+        raise(TypeError('each module must be a GLModule instance'))
+    self.main_modules = sorted(set(modules))
+    
+  def getTestsModules(self):
+    '''GLModuleTable.getTestsModules() -> list
+    
+    Return list of tests modules.'''
+    return(list(self.tests_modules))
+    
+  def setTestsModules(self, modules):
+    '''GLModuleTable.setTestsModules(modules)
+    
+    Specify list of tests modules.'''
+    for module in modules:
+      if type(module) is not GLModule:
+        raise(TypeError('each module must be a GLModule instance'))
+    self.tests_modules = sorted(set(modules))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pygnulib/GLTestDir.py	Sun Aug 20 11:17:58 2017 +0300
@@ -0,0 +1,987 @@
+#!/usr/bin/python
+# encoding: UTF-8
+
+#===============================================================================
+# Define global imports
+#===============================================================================
+import os
+import re
+import sys
+import locale
+import codecs
+import shutil
+import filecmp
+import subprocess as sp
+from . import constants
+from .GLError import GLError
+from .GLConfig import GLConfig
+from .GLModuleSystem import GLModule
+from .GLModuleSystem import GLModuleTable
+from .GLModuleSystem import GLModuleSystem
+from .GLFileSystem import GLFileSystem
+from .GLFileSystem import GLFileAssistant
+from .GLMakefileTable import GLMakefileTable
+from .GLEmiter import GLEmiter
+
+
+#===============================================================================
+# Define module information
+#===============================================================================
+__author__ = constants.__author__
+__license__ = constants.__license__
+__copyright__ = constants.__copyright__
+
+
+#===============================================================================
+# Define global constants
+#===============================================================================
+PYTHON3 = constants.PYTHON3
+NoneType = type(None)
+APP = constants.APP
+DIRS = constants.DIRS
+ENCS = constants.ENCS
+UTILS = constants.UTILS
+FILES = constants.FILES
+MODES = constants.MODES
+TESTS = constants.TESTS
+compiler = constants.compiler
+joinpath = constants.joinpath
+cleaner = constants.cleaner
+relpath = constants.relativize
+string = constants.string
+isabs = os.path.isabs
+isdir = os.path.isdir
+isfile = os.path.isfile
+normpath = os.path.normpath
+
+
+#===============================================================================
+# Define GLTestDir class
+#===============================================================================
+class GLTestDir(object):
+  '''GLTestDir class is used to create a scratch package with the given
+  list of the modules.'''
+  
+  def __init__(self, config, testdir):
+    '''GLTestDir.__init__(config, testdir) -> GLTestDir
+    
+    Create new GLTestDir instance.'''
+    if type(config) is not GLConfig:
+      raise(TypeError('config must be a GLConfig, not %s' % \
+        type(config).__name__))
+    if type(testdir) is bytes or type(testdir) is string:
+      if type(testdir) is bytes:
+        testdir = testdir.decode(ENCS['default'])
+    self.config = config
+    self.testdir = os.path.normpath(testdir)
+    if not os.path.exists(self.testdir):
+      try: # Try to create directory
+        os.mkdir(self.testdir)
+      except Exception as error:
+        raise(GLError(19, self.testdir))
+    self.emiter = GLEmiter(self.config)
+    self.filesystem = GLFileSystem(self.config)
+    self.modulesystem = GLModuleSystem(self.config)
+    self.moduletable = GLModuleTable(self.config)
+    self.assistant = GLFileAssistant(self.config)
+    self.makefiletable = GLMakefileTable(self.config)
+    
+    # Subdirectory names.
+    self.config.setSourceBase('gllib')
+    self.config.setM4Base('glm4')
+    self.config.setDocBase('gldoc')
+    self.config.setTestsBase('gltests')
+    self.config.setMacroPrefix('gl')
+    self.config.resetPoBase()
+    self.config.resetPoDomain()
+    self.config.resetWitnessCMacro()
+    self.config.resetVCFiles()
+    
+  def rewrite_files(self, files):
+    '''GLTestDir.rewrite_files(files)
+    
+    Replace auxdir, docbase, sourcebase, m4base and testsbase from default
+    to their version from config.'''
+    if type(files) is not list:
+      raise(TypeError(
+        'files argument must has list type, not %s' % type(files).__name__))
+    files = \
+    [ # Begin to convert bytes to string
+      file.decode(ENCS['default']) \
+      if type(file) is bytes else file \
+      for file in files
+    ] # Finish to convert bytes to string
+    for file in files:
+      if type(file) is not string:
+        raise(TypeError('each file must be a string instance'))
+    files = sorted(set(files))
+    auxdir = self.config['auxdir']
+    docbase = self.config['docbase']
+    sourcebase = self.config['sourcebase']
+    m4base = self.config['m4base']
+    testsbase = self.config['testsbase']
+    result = list()
+    for file in files:
+      if file.startswith('build-aux/'):
+        path = constants.substart('build-aux/', '%s/' % auxdir, file)
+      elif file.startswith('doc/'):
+        path = constants.substart('doc/', '%s/' % docbase, file)
+      elif file.startswith('lib/'):
+        path = constants.substart('lib/', '%s/' % sourcebase, file)
+      elif file.startswith('m4/'):
+        path = constants.substart('m4/', '%s/' % m4base, file)
+      elif file.startswith('tests/'):
+        path = constants.substart('tests/', '%s/' % testsbase, file)
+      elif file.startswith('tests=lib/'):
+        path = constants.substart('tests=lib/', '%s/' % testsbase, file)
+      elif file.startswith('top/'):
+        path = constants.substart('top/', '', file)
+      else: # file is not a special file
+        path = file
+      result += [os.path.normpath(path)]
+    result = sorted(set(result))
+    return(list(result))
+    
+  def execute(self):
+    '''GLTestDir.execute()
+    
+    Create a scratch package with the given modules.'''
+    localdir = self.config['localdir']
+    auxdir = self.config['auxdir']
+    testflags = list(self.config['testflags'])
+    sourcebase = self.config['sourcebase']
+    m4base = self.config['m4base']
+    pobase = self.config['pobase']
+    docbase = self.config['docbase']
+    testsbase = self.config['testsbase']
+    libname = self.config['libname']
+    libtool = self.config['libtool']
+    witness_c_macro = self.config['witness_c_macro']
+    symbolic = self.config['symbolic']
+    lsymbolic = self.config['lsymbolic']
+    single_configure = self.config['single_configure']
+    include_guard_prefix = self.config['include_guard_prefix']
+    macro_prefix = self.config['macro_prefix']
+    verbose = self.config['verbosity']
+    
+    base_modules = [self.modulesystem.find(m) for m in self.config['modules']]
+    if not base_modules:
+      base_modules = self.modulesystem.list()
+      base_modules = [self.modulesystem.find(m) for m in base_modules]
+    # All modules together.
+    # Except config-h, which breaks all modules which use HAVE_CONFIG_H.
+    # Except ftruncate, mountlist, which abort the configuration on mingw.
+    # Except lib-ignore, which leads to link errors when Sun C++ is used.
+    base_modules = sorted(set(base_modules))
+    base_modules = [module for module in base_modules if str(module) not in \
+      ['config-h', 'ftruncate', 'mountlist', 'lib-ignore']]
+    
+    # When computing transitive closures, don't consider $module to depend on
+    # $module-tests. Need this because tests are implicitly GPL and may depend
+    # on GPL modules - therefore we don't want a warning in this case.
+    saved_testflags = list(self.config['testflags'])
+    self.config.disableTestFlag(TESTS['tests'])
+    for requested_module in base_modules:
+      requested_licence = requested_module.getLicense()
+      # Here we use self.moduletable.transitive_closure([module]), not just
+      # module.getDependencies, so that we also detect weird situations like
+      # an LGPL module which depends on a GPLed build tool module which depends
+      # on a GPL module.
+      if requested_licence != 'GPL':
+        modules = self.moduletable.transitive_closure([requested_module])
+        for module in modules:
+          license = module.getLicense()
+          errormsg = 'module %s depends on a module ' % requested_module
+          errormsg += 'with an incompatible license: %s\n' % module
+          if requested_licence == 'GPLv2+':
+            if license not in ['GPLv2+', 'LGPLv2+']:
+              sys.stderr.write(errormsg)
+          elif requested_licence in ['LGPL']:
+            if license not in ['LGPL', 'LGPLv2+']:
+              sys.stderr.write(errormsg)
+          elif requested_licence in ['LGPLv2+']:
+            if license not in ['LGPLv2+']:
+              sys.stderr.write(errormsg)
+    self.config.setTestFlags(saved_testflags)
+    
+    # Determine final module list.
+    modules = self.moduletable.transitive_closure(base_modules)
+    final_modules = list(modules)
+    
+    # Show final module list.
+    if verbose >= 0:
+      bold_on = ''
+      bold_off = ''
+      term = os.getenv('TERM')
+      if term == 'xterm':
+        bold_on = '\x1b[1m'
+        bold_off = '\x1b[0m'
+      print('Module list with included dependencies (indented):')
+      for module in final_modules:
+        if str(module) in self.config.getModules():
+          print('  %s%s%s' % (bold_on, module, bold_off))
+        else: # if str(module) not in self.config.getModules()
+          print('    %s' % module)
+    
+    # Generate lists of the modules.
+    if single_configure:
+      # Determine main module list and tests-related module list separately.
+      main_modules, tests_modules = \
+        self.moduletable.transitive_closure_separately(
+          base_modules, final_modules)
+      # Print main_modules and tests_modules.
+      if verbose >= 1:
+        print('Main module list:')
+        for module in main_modules:
+          print('  %s' % str(module))
+        print('Tests-related module list:')
+        for module in tests_modules:
+          print('  %s' % str(module))
+      # Determine whether a $testsbase/libtests.a is needed.
+      libtests = False
+      for module in tests_modules:
+        files = module.getFiles()
+        for file in files:
+          if file.startswith('lib/'):
+            libtests = True
+            break
+      if libtests:
+        self.config.enableLibtests()
+    
+    if single_configure:
+      # Add dummy package if it is needed.
+      main_modules = self.moduletable.add_dummy(main_modules)
+      if 'dummy' in [str(module) for module in main_modules]:
+        main_modules = [m for m in main_modules if str(m) != 'dummy']
+        dummy = self.modulesystem.find('dummy')
+        main_modules = sorted(set(main_modules)) +[dummy]
+      if libtests: # if we need to use libtests.a
+        tests_modules = self.moduletable.add_dummy(tests_modules)
+        if 'dummy' in [str(module) for module in tests_modules]:
+          tests_modules = [m for m in tests_modules if str(m) != 'dummy']
+          dummy = self.modulesystem.find('dummy')
+          tests_modules = sorted(set(tests_modules)) +[dummy]
+    else: # if not single_configure
+      modules = self.moduletable.add_dummy(modules)
+      if 'dummy' in [str(module) for module in modules]:
+        modules = [m for m in modules if str(m) != 'dummy']
+        dummy = self.modulesystem.find('dummy')
+        modules = sorted(set(modules)) +[dummy]
+    
+    # Show banner notice of every module.
+    if single_configure:
+      for module in main_modules:
+        notice = module.getNotice()
+        if notice:
+          print('Notice from module %s:' % str(module))
+          pattern = compiler('^(.*?)$', re.S | re.M)
+          notice = pattern.sub('  \\1', notice)
+          print(notice)
+    else: # if not single_configure
+      for module in modules:
+        notice = module.getNotice()
+        if notice:
+          print('Notice from module %s:' % str(module))
+          pattern = compiler('^(.*?)$', re.S | re.M)
+          notice = pattern.sub('  \\1', notice)
+          print(notice)
+    
+    # Determine final file list.
+    if single_configure:
+      main_filelist, tests_filelist = \
+        self.moduletable.filelist_separately(main_modules, tests_modules)
+      filelist = sorted(set(main_filelist +tests_filelist))
+    else: # if not single_configure
+      filelist = self.moduletable.filelist(modules)
+    
+    filelist = sorted(set(filelist))
+    
+    # Print list of files.
+    if verbose >= 0:
+      print('File list:')
+      for file in filelist:
+        if file.startswith('tests=lib/'):
+          rest = file[10:]
+          print('  lib/%s -> tests/%s' % (rest, rest))
+        else:
+          print('  %s' % file)
+    
+    # Add files for which the copy in gnulib is newer than the one that
+    # "automake --add-missing --copy" would provide.
+    filelist += ['build-aux/config.guess', 'build-aux/config.sub']
+    filelist = sorted(set(filelist))
+    
+    # Create directories.
+    directories = [os.path.dirname(file) \
+      for file in self.rewrite_files(filelist)]
+    directories = sorted(set(directories))
+    
+    # Copy files or make symbolic links.
+    filetable = list()
+    for src in filelist:
+      dest = self.rewrite_files([src])[-1]
+      filetable += [tuple([dest, src])]
+    for row in filetable:
+      src = row[1]
+      dest = row[0]
+      destpath = joinpath(self.testdir, dest)
+      dirname = os.path.dirname(destpath)
+      if not isdir(dirname):
+        os.makedirs(dirname)
+      if src.startswith('tests=lib/'):
+        src = constants.substart('tests=lib/', 'lib/', src)
+      lookedup, flag = self.filesystem.lookup(src)
+      if isfile(destpath):
+        os.remove(destpath)
+      if flag:
+        shutil.copy(lookedup, destpath)
+      else: # if not flag
+        if symbolic or (lsymbolic and lookedup == joinpath(localdir, src)):
+          constants.link_relative(lookedup, destpath)
+        else:
+          shutil.copy(lookedup, destpath)
+    
+    # Create $sourcebase/Makefile.am.
+    for_test = True
+    directory = joinpath(self.testdir, sourcebase)
+    if not isdir(directory):
+      os.mkdir(directory)
+    destfile = joinpath(directory, 'Makefile.am')
+    if single_configure:
+      emit, uses_subdirs = self.emiter.lib_Makefile_am(destfile, main_modules,
+        self.moduletable, self.makefiletable, '', for_test)
+    else: # if not single_configure
+      emit, uses_subdirs = self.emiter.lib_Makefile_am(destfile, modules,
+        self.moduletable, self.makefiletable, '', for_test)
+    with codecs.open(destfile, 'wb', 'UTF-8') as file:
+      file.write(emit)
+    any_uses_subdirs = uses_subdirs
+    
+    # Create $m4base/Makefile.am.
+    directory = joinpath(self.testdir, m4base)
+    if not isdir(directory):
+      os.mkdir(directory)
+    destfile = joinpath(directory, 'Makefile.am')
+    emit = string()
+    emit += '## Process this file with automake to produce Makefile.in.\n\n'
+    emit += 'EXTRA_DIST =\n'
+    for file in filelist:
+      if file.startswith('m4/'):
+        file = constants.substart('m4/', '', file)
+        emit += 'EXTRA_DIST += %s\n' % file
+    emit = constants.nlconvert(emit)
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    with codecs.open(destfile, 'wb', 'UTF-8') as file:
+      file.write(emit)
+    
+    subdirs = [sourcebase, m4base]
+    subdirs_with_configure_ac = list()
+    
+    testsbase_appened = False
+    inctests = self.config.checkTestFlag(TESTS['tests'])
+    if inctests:
+      directory = joinpath(self.testdir, testsbase)
+      if not isdir(directory):
+        os.mkdir(directory)
+      if single_configure:
+        # Create $testsbase/Makefile.am.
+        destfile = joinpath(directory, 'Makefile.am')
+        print(repr(destfile))
+        witness_macro = '%stests_WITNESS' % macro_prefix
+        emit, uses_subdirs = self.emiter.tests_Makefile_am(destfile,
+          tests_modules, self.makefiletable, witness_macro, for_test)
+        with codecs.open(destfile, 'wb', 'UTF-8') as file:
+          file.write(emit)
+      else: # if not single_configure
+        # Create $testsbase/Makefile.am.
+        destfile = joinpath(directory, 'Makefile.am')
+        libtests = False
+        self.config.disableLibtests()
+        emit, uses_subdirs = self.emiter.tests_Makefile_am(destfile,
+          modules, self.makefiletable, '', for_test)
+        with codecs.open(destfile, 'wb', 'UTF-8') as file:
+          file.write(emit)
+        # Viewed from the $testsbase subdirectory, $auxdir is different.
+        emit = string()
+        saved_auxdir = self.config['auxdir']
+        testsbase = '%s/' % os.path.normpath(testsbase)
+        counter = int()
+        auxdir = string()
+        finish = (len(testsbase.split('/')) -1)
+        while counter < finish:
+          auxdir += '../'
+          counter += 1
+        auxdir = os.path.normpath(joinpath(auxdir, saved_auxdir))
+        testsbase = os.path.normpath(testsbase)
+        self.config.setAuxDir(auxdir)
+        # Create $testsbase/configure.ac.
+        emit += '# Process this file with autoconf '
+        emit += 'to produce a configure script.\n'
+        emit += 'AC_INIT([dummy], [0])\n'
+        emit += 'AC_CONFIG_AUX_DIR([%s])\n' % auxdir
+        emit += 'AM_INIT_AUTOMAKE\n\n'
+        emit += 'AC_CONFIG_HEADERS([config.h])\n\n'
+        emit += 'AC_PROG_CC\n'
+        emit += 'AC_PROG_INSTALL\n'
+        emit += 'AC_PROG_MAKE_SET\n'
+        emit += 'gl_PROG_AR_RANLIB\n\n'
+        if uses_subdirs:
+          emit += 'AM_PROG_CC_C_O\n\n'
+        snippets = list()
+        for module in modules:
+          if str(module) in ['gnumakefile', 'maintainer-makefile']:
+            # These are meant to be used only in the top-level directory.
+            pass
+          else: # if str(module) not in ['gnumakefile', 'maintainer-makefile']
+            snippet = module.getAutoconfSnippet_Early()
+            lines = [line for line in snippet.split('\n') if line.strip()]
+            snippet = '\n'.join(lines)
+            pattern = compiler('AC_REQUIRE\\(\\[([^()].*?)\\]\\)', re.S | re.M)
+            snippet = pattern.sub('\\1', snippet)
+            snippet = snippet.strip()
+            snippets += [snippet]
+        snippets = [snippet for snippet in snippets if snippet.strip()]
+        emit += '%s\n' % '\n'.join(snippets)
+        if libtool:
+          emit += 'LT_INIT([win32-dll])\n'
+          emit += 'LT_LANG([C++])\n'
+          emit += 'AM_CONDITIONAL([GL_COND_LIBTOOL], [true])\n'
+          emit += 'gl_cond_libtool=true\n'
+        else: # if not libtool
+          emit += 'AM_CONDITIONAL([GL_COND_LIBTOOL], [false])\n'
+          emit += 'gl_cond_libtool=false\n'
+          emit += 'gl_libdeps=\n'
+          emit += 'gl_ltlibdeps=\n'
+        # Wrap the set of autoconf snippets into an autoconf macro that is then
+        # invoked. This is needed because autoconf does not support AC_REQUIRE
+        # at the top level:
+        #   error: AC_REQUIRE(gt_CSHARPCOMP): cannot be used outside of an
+        #     AC_DEFUN'd macro
+        # but we want the AC_REQUIRE to have its normal meaning (provide one
+        # expansion of the required macro before the current point, and only
+        # one expansion total).
+        emit += 'AC_DEFUN([gl_INIT], [\n'
+        replace_auxdir = True
+        emit += "gl_m4_base='../%s'\n" % m4base
+        emit += self.emiter.initmacro_start(macro_prefix)
+        # We don't have explicit ordering constraints between the various
+        # autoconf snippets. It's cleanest to put those of the library before
+        # those of the tests.
+        emit += "gl_source_base='../%s'\n" % sourcebase
+        emit += self.emiter.autoconfSnippets(modules,
+          self.moduletable, self.assistant, 1, False, False, False,
+          replace_auxdir)
+        emit += "gl_source_base='.'"
+        emit += self.emiter.autoconfSnippets(modules,
+          self.moduletable, self.assistant, 2, False, False, False,
+          replace_auxdir)
+        emit += self.emiter.initmacro_end(macro_prefix)
+        # _LIBDEPS and _LTLIBDEPS variables are not needed if this library is
+        # created using libtool, because libtool already handles the
+        # dependencies.
+        if not libtool:
+          libname_upper = libname.upper().replace('-', '_')
+          emit += '  %s_LIBDEPS="$gl_libdeps"\n' % libname_upper
+          emit += '  AC_SUBST([%s_LIBDEPS])\n' % libname_upper
+          emit += '  %s_LTLIBDEPS="$gl_ltlibdeps"\n' % libname_upper
+          emit += '  AC_SUBST([%s_LTLIBDEPS])\n' % libname_upper
+        emit += '])\n'
+        # FIXME use $sourcebase or $testsbase?
+        emit += self.emiter.initmacro_done(macro_prefix, sourcebase)
+        emit += '\ngl_INIT\n\n'
+        # Usually $testsbase/config.h will be a superset of config.h. Verify
+        # this by "merging" config.h into $testsbase/config.h; look out for gcc
+        # warnings.
+        emit += 'AH_TOP([#include \"../config.h\"])\n\n'
+        emit += 'AC_CONFIG_FILES([Makefile])\n'
+        emit += 'AC_OUTPUT\n'
+        emit = constants.nlconvert(emit)
+        if type(emit) is bytes:
+          emit = emit.decode(ENCS['default'])
+        path = joinpath(self.testdir, testsbase, 'configure.ac')
+        with codecs.open(path, 'wb', 'UTF-8') as file:
+          file.write(emit)
+        
+        # Restore changed variables.
+        self.config.setAuxDir(saved_auxdir)
+        auxdir = self.config['auxdir']
+        subdirs_with_configure_ac += [testsbase]
+      
+      subdirs += [testsbase]
+      testsbase_appened = True
+    
+    # Create Makefile.am.
+    emit = string()
+    emit += '## Process this file with automake to produce Makefile.in.\n\n'
+    emit += 'AUTOMAKE_OPTIONS = 1.5 foreign\n\n'
+    emit += 'SUBDIRS = %s\n\n' % ' '.join(subdirs)
+    emit += 'ACLOCAL_AMFLAGS = -I %s\n' % m4base
+    emit = constants.nlconvert(emit)
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    path = joinpath(self.testdir, 'Makefile.am')
+    with codecs.open(path, 'wb', 'UTF-8') as file:
+      file.write(emit)
+    
+    # Create configure.ac
+    emit = string()
+    emit += '# Process this file with autoconf '
+    emit += 'to produce a configure script.\n'
+    emit += 'AC_INIT([dummy], [0])\n'
+    if auxdir != '.':
+      emit += 'AC_CONFIG_AUX_DIR([%s])\n' % auxdir
+    emit += 'AM_INIT_AUTOMAKE\n\n'
+    emit += 'AC_CONFIG_HEADERS([config.h])\n\n'
+    emit += 'AC_PROG_CC\n'
+    emit += 'AC_PROG_INSTALL\n'
+    emit += 'AC_PROG_MAKE_SET\n\n'
+    emit += '# For autobuild.\n'
+    emit += 'AC_CANONICAL_BUILD\n'
+    emit += 'AC_CANONICAL_HOST\n\n'
+    emit += 'm4_pattern_forbid([^gl_[A-Z]])dnl the gnulib macro namespace\n'
+    emit += 'm4_pattern_allow([^gl_ES$])dnl a valid locale name\n'
+    emit += 'm4_pattern_allow([^gl_LIBOBJS$])dnl a variable\n'
+    emit += 'm4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable\n\n'
+    emit += 'gl_PROG_AR_RANLIB\n\n'
+    if any_uses_subdirs:
+      emit += 'AM_PROG_CC_C_O\n'
+    snippets = list()
+    for module in final_modules:
+      if single_configure:
+        solution = True
+      else: # if not single_configure
+        solution = module.isNonTests()
+      if solution:
+        snippet = module.getAutoconfSnippet_Early()
+        lines = [line for line in snippet.split('\n') if line.strip()]
+        snippet = '\n'.join(lines)
+        pattern = compiler('AC_REQUIRE\\(\\[([^()].*?)\\]\\)', re.S | re.M)
+        snippet = pattern.sub('\\1', snippet)
+        snippet = snippet.strip()
+        snippets += [snippet]
+    snippets = [snippet for snippet in snippets if snippet.strip()]
+    emit += '%s\n' % '\n'.join(snippets)
+    if libtool:
+      emit += 'LT_INIT([win32-dll])\n'
+      emit += 'LT_LANG([C++])\n'
+      emit += 'AM_CONDITIONAL([GL_COND_LIBTOOL], [true])\n'
+      emit += 'gl_cond_libtool=true\n'
+    else: # if not libtool
+      emit += 'AM_CONDITIONAL([GL_COND_LIBTOOL], [false])\n'
+      emit += 'gl_cond_libtool=false\n'
+      emit += 'gl_libdeps=\n'
+      emit += 'gl_ltlibdeps=\n'
+    # Wrap the set of autoconf snippets into an autoconf macro that is then
+    # invoked. This is needed because autoconf does not support AC_REQUIRE
+    # at the top level:
+    #   error: AC_REQUIRE(gt_CSHARPCOMP): cannot be used outside of an
+    #     AC_DEFUN'd macro
+    # but we want the AC_REQUIRE to have its normal meaning (provide one
+    # expansion of the required macro before the current point, and only one
+    # expansion total).
+    emit += 'AC_DEFUN([gl_INIT], [\n'
+    if auxdir != 'build-aux':
+      replace_auxdir = True
+    else: # auxdir == 'build-aux'
+      replace_auxdir = False
+    emit += 'gl_m4_base=\'%s\'\n' % m4base
+    emit += self.emiter.initmacro_start(macro_prefix)
+    emit += 'gl_source_base=\'%s\'\n' % sourcebase
+    if single_configure:
+      emit += self.emiter.autoconfSnippets(main_modules, self.moduletable,
+        self.assistant, 0, False, False, False, replace_auxdir)
+    else: # if not single_configure
+      emit += self.emiter.autoconfSnippets(modules, self.moduletable,
+        self.assistant, 1, False, False, False, replace_auxdir)
+    emit += self.emiter.initmacro_end(macro_prefix)
+    if single_configure:
+      emit += '  gltests_libdeps=\n'
+      emit += '  gltests_ltlibdeps=\n'
+      emit += self.emiter.initmacro_start('%stests' % macro_prefix)
+      emit += '  gl_source_base=\'%s\'\n' % testsbase
+      # Define a tests witness macro.
+      emit += '  %stests_WITNESS=IN_GNULIB_TESTS\n' % macro_prefix
+      emit += '  AC_SUBST([%stests_WITNESS])\n' % macro_prefix
+      emit += '  gl_module_indicator_condition=$%stests_WITNESS\n' % \
+        macro_prefix
+      emit += '  m4_pushdef([gl_MODULE_INDICATOR_CONDITION], '
+      emit += '[$gl_module_indicator_condition])\n'
+      snippets = self.emiter.autoconfSnippets(tests_modules, self.moduletable,
+        self.assistant, 1, True, False, False, replace_auxdir)
+      emit += snippets.strip()
+      emit += '  m4_popdef([gl_MODULE_INDICATOR_CONDITION])\n'
+      emit += self.emiter.initmacro_end('%stests' % macro_prefix)
+    # _LIBDEPS and _LTLIBDEPS variables are not needed if this library is
+    # created using libtool, because libtool already handles the dependencies.
+    if not libtool:
+      libname_upper = libname.upper().replace('-', '_')
+      emit += '  %s_LIBDEPS="$gl_libdeps"\n' % libname_upper
+      emit += '  AC_SUBST([%s_LIBDEPS])\n' % libname_upper
+      emit += '  %s_LTLIBDEPS="$gl_ltlibdeps"\n' % libname_upper
+      emit += '  AC_SUBST([%s_LTLIBDEPS])\n' % libname_upper
+    if single_configure and libtests:
+      emit += '  LIBTESTS_LIBDEPS="$gltests_libdeps"\n'
+      emit += '  AC_SUBST([LIBTESTS_LIBDEPS])\n'
+    emit += '])\n'
+    emit += self.emiter.initmacro_done(macro_prefix, sourcebase)
+    if single_configure:
+      emit += self.emiter.initmacro_done('%stests' % macro_prefix, testsbase)
+    emit += '\ngl_INIT\n\n'
+    if subdirs_with_configure_ac:
+      if single_configure:
+        emit += 'AC_CONFIG_SUBDIRS([%s])\n' % \
+          ' '.join(subdirs_with_configure_ac[:-1])
+      else: # if not single_configure
+        emit += 'AC_CONFIG_SUBDIRS([%s])\n' % \
+          ' '.join(subdirs_with_configure_ac)
+    makefiles = ['Makefile']
+    for directory in subdirs:
+      # For subdirs that have a configure.ac by their own, it's the subdir's
+      # configure.ac which creates the subdir's Makefile.am, not this one.
+      makefiles += [joinpath(directory, 'Makefile')]
+    if not single_configure:
+      makefiles = makefiles[:-1]
+    emit += 'AC_CONFIG_FILES([%s])\n' % ' '.join(makefiles)
+    emit += 'AC_OUTPUT\n'
+    path = joinpath(self.testdir, 'configure.ac')
+    with codecs.open(path, 'wb', 'UTF-8') as file:
+      file.write(emit)
+    
+    # Create autogenerated files.
+    # Do not use "${AUTORECONF} --force --install", because it may invoke
+    # autopoint, which brings in older versions of some of our .m4 files.
+    os.chdir(self.testdir)
+    # gettext
+    if isfile(joinpath(m4base, 'gettext.m4')):
+      args = [UTILS['autopoint'], '--force']
+      constants.execute(args, verbose)
+      for src in os.listdir(m4base):
+        src = joinpath(m4base, src)
+        if src.endswith('.m4~'):
+          dest = src[:-1]
+          if isfile(dest):
+            os.remove(dest)
+          shutil.move(src, dest)
+    # libtoolize
+    if libtool:
+      args = [UTILS['libtoolize'], '--copy']
+      constants.execute(args, verbose)
+    # aclocal
+    args = [UTILS['aclocal'], '-I', m4base]
+    constants.execute(args, verbose)
+    if not isdir('build-aux'):
+      os.mkdir('build-aux')
+    # autoconf
+    args = [UTILS['autoconf']]
+    constants.execute(args, verbose)
+    # autoheader
+    args = [UTILS['autoheader']]
+    constants.execute(args, verbose)
+    # automake
+    args = [UTILS['automake'], '--add-missing', '--copy']
+    constants.execute(args, verbose)
+    os.chdir(DIRS['cwd'])
+    if inctests and not single_configure:
+      # Do not use "${AUTORECONF} --force --install", because it may invoke
+      # autopoint, which brings in older versions of some of our .m4 files.
+      os.chdir(joinpath(self.testdir, testsbase))
+      # gettext
+      if isfile(joinpath(m4base, 'gettext.m4')):
+        args = [UTILS['autopoint'], '--force']
+        constants.execute(args, verbose)
+        for src in os.listdir(m4base):
+          src = joinpath(m4base, src)
+          if src.endswith('.m4~'):
+            dest = src[:-1]
+            if isfile(dest):
+              os.remove(dest)
+            shutil.move(src, dest)
+      # aclocal
+      args = [UTILS['aclocal'], '-I', joinpath('..', m4base)]
+      constants.execute(args, verbose)
+      if not isdir(joinpath('../build-aux')):
+        os.mkdir('../build-aux')
+      # autoconf
+      args = [UTILS['autoconf']]
+      constants.execute(args, verbose)
+      # autoheader
+      args = [UTILS['autoheader']]
+      constants.execute(args, verbose)
+      # automake
+      args = [UTILS['automake'], '--add-missing', '--copy']
+      constants.execute(args, verbose)
+      os.chdir(DIRS['cwd'])
+    
+    # Need to run configure and make once, to create built files that are to be
+    # distributed (such as parse-datetime.c).
+    path = joinpath(self.testdir, sourcebase, 'Makefile.am')
+    with codecs.open(path, 'rb', 'UTF-8') as file:
+      snippet = file.read()
+    cleaned_files = list()
+    tests_cleaned_files = list()
+    built_sources = list()
+    tests_built_sources = list()
+    distributed_built_sources = list()
+    tests_distributed_built_sources = list()
+    
+    # Extract the value of "CLEANFILES += ..." and "MOSTLYCLEANFILES += ...".
+    regex_find = list()
+    snippet = snippet.replace('\\\n', '')
+    pattern = compiler('^CLEANFILES[\t ]*\\+=(.*?)$', re.S | re.M)
+    regex_find += pattern.findall(snippet)
+    pattern = compiler('^MOSTLYCLEANFILES[\t ]*\\+=(.*?)$', re.S | re.M)
+    regex_find += pattern.findall(snippet)
+    regex_find = [line.strip() for line in regex_find if line.strip()]
+    for part in regex_find:
+      cleaned_files += \
+        [line.strip() for line in part.split(' ') if line.strip()]
+    
+    # Extract the value of "BUILT_SOURCES += ...". Remove variable references
+    # such $(FOO_H) because they don't refer to distributed files.
+    regex_find = list()
+    pattern = compiler('^BUILT_SOURCES[\t ]*\\+=(.*?)$', re.S | re.M)
+    regex_find += pattern.findall(snippet)
+    regex_find = [line.strip() for line in regex_find if line.strip()]
+    for part in regex_find:
+      built_sources += \
+        [line.strip() for line in part.split(' ') if line.strip()]
+    built_sources = [line for line in built_sources \
+      if not bool(compiler('[$]\\([A-Za-z0-9_]*\\)$').findall(line))]
+    distributed_built_sources = [file for file in built_sources \
+      if file not in cleaned_files]
+    
+    if inctests:
+      # Likewise for built files in the $testsbase directory.
+      path = joinpath(self.testdir, testsbase, 'Makefile.am')
+      with codecs.open(path, 'rb', 'UTF-8') as file:
+        snippet = file.read()
+      
+      # Extract the value of "CLEANFILES += ..." and "MOSTLYCLEANFILES += ...".
+      regex_find = list()
+      snippet = snippet.replace('\\\n', '')
+      pattern = compiler('^CLEANFILES[\t ]*\\+=(.*?)$', re.S | re.M)
+      regex_find += pattern.findall(snippet)
+      pattern = compiler('^MOSTLYCLEANFILES[\t ]*\\+=(.*?)$', re.S | re.M)
+      regex_find += pattern.findall(snippet)
+      regex_find = [line.strip() for line in regex_find if line.strip()]
+      for part in regex_find:
+        tests_cleaned_files += \
+          [line.strip() for line in part.split(' ') if line.strip()]
+      
+      # Extract the value of "BUILT_SOURCES += ...". Remove variable references
+      # such $(FOO_H) because they don't refer to distributed files.
+      regex_find = list()
+      tests_built_sources = list()
+      pattern = compiler('^BUILT_SOURCES[\t ]*\\+=(.*?)$', re.S | re.M)
+      regex_find += pattern.findall(snippet)
+      regex_find = [line.strip() for line in regex_find if line.strip()]
+      for part in regex_find:
+        tests_built_sources += \
+          [line.strip() for line in part.split(' ') if line.strip()]
+      tests_built_sources = [line for line in tests_built_sources \
+        if not bool(compiler('[$]\\([A-Za-z0-9_]*\\)$').findall(line))]
+      tests_distributed_built_sources = [file for file in tests_built_sources \
+        if file not in cleaned_files]
+    
+    if distributed_built_sources or tests_distributed_built_sources:
+      os.chdir(self.testdir)
+      sp.call('./configure')
+      if distributed_built_sources:
+        os.chdir(sourcebase)
+        with codecs.open('Makefile', 'ab', 'UTF-8') as file:
+          file.write('built_sources: $(BUILT_SOURCES)\n')
+        args = [UTILS['make'],
+          'AUTOCONF=%s'   % UTILS['autoconf'],
+          'AUTOHEADER=%s' % UTILS['autoheader'],
+          'ACLOCAL=%s'    % UTILS['aclocal'],
+          'AUTOMAKE=%s'   % UTILS['automake'],
+          'AUTORECONF=%s' % UTILS['autoreconf'],
+          'built_sources']
+        sp.call(args)
+        os.chdir('..')
+      if tests_distributed_built_sources:
+        os.chdir(testsbase)
+        with codecs.open('Makefile', 'ab', 'UTF-8') as file:
+          file.write('built_sources: $(BUILT_SOURCES)\n')
+        args = [UTILS['make'],
+          'AUTOCONF=%s'   % UTILS['autoconf'],
+          'AUTOHEADER=%s' % UTILS['autoheader'],
+          'ACLOCAL=%s'    % UTILS['aclocal'],
+          'AUTOMAKE=%s'   % UTILS['automake'],
+          'AUTORECONF=%s' % UTILS['autoreconf'],
+          'built_sources']
+        sp.call(args)
+        os.chdir('..')
+      args = [UTILS['make'],
+        'AUTOCONF=%s'   % UTILS['autoconf'],
+        'AUTOHEADER=%s' % UTILS['autoheader'],
+        'ACLOCAL=%s'    % UTILS['aclocal'],
+        'AUTOMAKE=%s'   % UTILS['automake'],
+        'AUTORECONF=%s' % UTILS['autoreconf'],
+        'AUTOPOINT=%s'  % UTILS['autopoint'],
+        'LIBTOOLIZE=%s' % UTILS['libtoolize'],
+        'distclean']
+      sp.call(args)
+    sp.call(['rm', '-rf', self.config['tempdir']], shell=False)
+
+
+#===============================================================================
+# Define GLMegaTestDir class
+#===============================================================================
+class GLMegaTestDir(object):
+  '''GLMegaTestDir class is used to create a mega scratch package with the
+  given modules one by one and all together.'''
+  
+  def __init__(self, config, megatestdir):
+    '''GLMegaTestDir.__init__(config, megatestdir) -> GLMegaTestDir
+    
+    Create new GLTestDir instance.'''
+    if type(config) is not GLConfig:
+      raise(TypeError('config must be a GLConfig, not %s' % \
+        type(config).__name__))
+    if type(megatestdir) is bytes or type(megatestdir) is string:
+      if type(megatestdir) is bytes:
+        megatestdir = megatestdir.decode(ENCS['default'])
+    self.config = config
+    self.megatestdir = os.path.normpath(megatestdir)
+    if not os.path.exists(self.megatestdir):
+      try: # Try to create directory
+        os.mkdir(self.megatestdir)
+      except Exception as error:
+        raise(GLError(19, self.megatestdir))
+    self.emiter = GLEmiter(self.config)
+    self.filesystem = GLFileSystem(self.config)
+    self.modulesystem = GLModuleSystem(self.config)
+    self.moduletable = GLModuleTable(self.config)
+    self.assistant = GLFileAssistant(self.config)
+    self.makefiletable = GLMakefileTable(self.config)
+    
+  def execute(self):
+    '''GLMegaTestDir.execute()
+    
+    Create a mega scratch package with the given modules one by one and all
+    together.'''
+    megasubdirs = list()
+    modules = [self.modulesystem.find(m) for m in self.config['modules']]
+    if not modules:
+      modules = self.modulesystem.list()
+      modules = [self.modulesystem.find(m) for m in modules]
+    modules = sorted(set(modules))
+    
+    # First, all modules one by one.
+    for module in modules:
+      self.config.setModules([str(module)])
+      #GLTestDir(self.config, self.megatestdir).execute()
+      megasubdirs += [str(module)]
+    
+    # Then, all modules all together.
+    # Except config-h, which breaks all modules which use HAVE_CONFIG_H.
+    modules = [module for module in modules if str(module) != 'config-h']
+    self.config.setModules([str(module) for module in modules])
+    #GLTestDir(self.config, self.megatestdir).execute()
+    megasubdirs += ['ALL']
+    
+    # Create autobuild.
+    emit = string()
+    repdict = dict()
+    repdict['Jan'] = repdict['January']   = '01'
+    repdict['Feb'] = repdict['February']  = '02'
+    repdict['Mar'] = repdict['March']     = '03'
+    repdict['Apr'] = repdict['April']     = '04'
+    repdict['May'] = repdict['May']       = '05'
+    repdict['Jun'] = repdict['June']      = '06'
+    repdict['Jul'] = repdict['July']      = '07'
+    repdict['Aug'] = repdict['August']    = '08'
+    repdict['Sep'] = repdict['September'] = '09'
+    repdict['Oct'] = repdict['October']   = '10'
+    repdict['Nov'] = repdict['November']  = '11'
+    repdict['Dec'] = repdict['December']  = '12'
+    if isfile(joinpath(DIRS['root'], 'CVS', 'Entries')):
+      vc_witness = joinpath(DIRS['root'], 'CVS', 'Entries')
+    else: # if not isfile(joinpath(DIRS['root'], 'CVS', 'Entries'))
+      vc_witness = joinpath(DIRS['root'], '.git', 'refs', 'heads', 'master')
+    mdate_sh = joinpath(DIRS['root'], 'build-aux', 'mdate-sh')
+    args = ['sh', mdate_sh, vc_witness]
+    cvsdate = sp.check_output(args).decode(ENCS['shell']).strip()
+    for key in repdict:
+      if len(key) > 3:
+        cvsdate = cvsdate.replace(key, repdict[key])
+    for key in repdict:
+      cvsdate = cvsdate.replace(key, repdict[key])
+    cvsdate = ''.join([date for date in cvsdate.split(' ') if date.strip()])
+    cvsdate = '%s%s%s' % (cvsdate[4:], cvsdate[2:4], cvsdate[:2])
+    emit += '#!/bin/sh\n'
+    emit += 'CVSDATE=%s\n' % cvsdate
+    emit += ': ${MAKE=make}\n'
+    emit += 'test -d logs || mkdir logs\n'
+    emit += 'for module in %s; do\n' % ' '.join(megasubdirs)
+    emit += '  echo "Working on module $module..."\n'
+    emit += '  safemodule=`echo $module | sed -e \'s|/|-|g\'`\n'
+    emit += '  (echo "To: gnulib@autobuild.josefsson.org"\\\n'
+    emit += '   echo\n'
+    emit += '   set -x\n'
+    emit += '   : autobuild project... $module\n'
+    emit += '   : autobuild revision... cvs-$CVSDATE-000000\n'
+    emit += '   : autobuild timestamp... `date "+%Y%m%d-%H%M%S"`\n'
+    emit += '   : autobuild hostname... `hostname`\n'
+    emit += '   cd $module && ./configure $CONFIGURE_OPTIONS && $MAKE'
+    emit += ' && $MAKE check && $MAKE distclean\n'
+    emit += '   echo rc=$?\n'
+    emit += '  ) 2>&1 | { if test -n "$AUTOBUILD_SUBST"; then '
+    emit += 'sed -e "$AUTOBUILD_SUBST"; else cat; fi; } > logs/$safemodule\n'
+    emit += 'done\n'
+    emit = constants.nlconvert(emit)
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    path = joinpath(self.megatestdir, 'do-autobuild')
+    with codecs.open(path, 'wb', 'UTF-8') as file:
+      file.write(emit)
+    
+    # Create Makefile.am.
+    emit = string()
+    emit += '## Process this file with automake to produce Makefile.in.\n\n'
+    emit += 'AUTOMAKE_OPTIONS = 1.5 foreign\n\n'
+    emit += 'SUBDIRS = %s\n\n' % ' '.join(megasubdirs)
+    emit += 'EXTRA_DIST = do-autobuild\n'
+    emit = constants.nlconvert(emit)
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    path = joinpath(self.megatestdir, 'Makefile.am')
+    with codecs.open(path, 'wb', 'UTF-8') as file:
+      file.write(emit)
+    
+    
+    emit = string()
+    emit += '# Process this file with autoconf '
+    emit += 'to produce a configure script.\n'
+    emit += 'AC_INIT([dummy], [0])\n\n'
+    if auxdir != '.':
+      emit += 'AC_CONFIG_AUX_DIR([%s])\n' % auxdir
+    emit += 'AM_INIT_AUTOMAKE\n\n'
+    emit += 'AC_PROG_MAKE_SET\n\n'
+    emit += 'AC_CONFIG_SUBDIRS([%s])\n' % ' '.megasubdirs
+    emit += 'AC_CONFIG_FILES([Makefile])\n'
+    emit += 'AC_OUTPUT\n'
+    emit = constants.nlconvert(emit)
+    if type(emit) is bytes:
+      emit = emit.decode(ENCS['default'])
+    path = joinpath(self.megatestdir, 'Makefile.am')
+    with codecs.open(path, 'wb', 'UTF-8') as file:
+      file.write(emit)
+    
+    # Create autogenerated files.
+    os.chdir(DIRS['cwd'])
+    args = [UTILS['aclocal']]
+    constants.execute(args, verbose)
+    try: # Try to make a directory
+      if not isdir('build-aux'):
+        os,mkdir('build-aux')
+    except Exception as error:
+      pass
+    args = [UTILS['autoconf']]
+    constants.execute(args, verbose)
+    args = [UTILS['automake'], '--add-missing', '--copy']
+    constants.execute(args, verbose)
+    sp.call(['rm', '-rf', self.config['tempdir']], shell=False)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pygnulib/__init__.py	Sun Aug 20 11:17:58 2017 +0300
@@ -0,0 +1,21 @@
+'''Gnulib - The GNU Portability Library
+GNU software has a well-deserved reputation for running on many different types
+of systems. While our primary goal is to write software for the GNU system, many
+users and developers have been introduced to us through the systems that they
+were already using.
+Gnulib is a central location for common GNU code, intended to be shared among
+GNU packages. GCC has libiberty, but this is hard to disentangle from the GCC
+build tree.
+Gnulib takes a different approach. Its components are intended to be shared at
+the source level, rather than being a library that gets built, installed, and
+linked against. Thus, there is no distribution tarball; the idea is to copy
+files from Gnulib into your own source tree.
+Gnulib also includes copies of a few files purely for convenience: the GNU
+coding standards, the GNU maintainer information, the GPL and other licenses (in
+Texinfo), assorted configuration scripts, and more. The goal is to provide all
+the common infrastructure needed by GNU packages.'''
+
+__copyright__ = '2012 Free Software Foundation, Inc.'
+__author__ = 'Dmitriy Selyutin'
+__license__ = 'GNU GPLv3+'
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pygnulib/classes.py	Sun Aug 20 11:17:58 2017 +0300
@@ -0,0 +1,77 @@
+#!/usr/bin/python
+# encoding: UTF-8
+
+'''An easy access to pygnulib classes.'''
+
+#===============================================================================
+# Define global imports
+#===============================================================================
+__all__ = list()
+
+try:
+  # Constants
+  from . import constants
+  
+  # Main classes
+  from .GLConfig import GLConfig
+  from .GLError import GLError
+  from .GLInfo import GLInfo
+  
+  # File system
+  from .GLFileSystem import GLFileSystem
+  from .GLFileSystem import GLFileAssistant
+  
+  # Module system
+  from .GLModuleSystem import GLModule
+  from .GLModuleSystem import GLModuleSystem
+  from .GLModuleSystem import GLModuleTable
+  
+  # Different modes
+  from .GLImport import GLImport
+  from .GLEmiter import GLEmiter
+  from .GLTestDir import GLTestDir
+  from .GLTestDir import GLMegaTestDir
+  
+  # Other modules
+  from .GLMakefileTable import GLMakefileTable
+except ValueError as error:
+  # Constants
+  import constants
+  
+  # Main classes
+  from GLConfig import GLConfig
+  from GLError import GLError
+  from GLInfo import GLInfo
+  
+  # File system
+  from GLFileSystem import GLFileSystem
+  from GLFileSystem import GLFileAssistant
+  
+  # Module system
+  from GLModuleSystem import GLModule
+  from GLModuleSystem import GLModuleSystem
+  from GLModuleSystem import GLModuleTable
+  
+  # Different modes
+  from GLImport import GLImport
+  from GLEmiter import GLEmiter
+  from GLTestDir import GLTestDir
+  from GLTestDir import GLMegaTestDir
+  
+  # Other modules
+  from GLMakefileTable import GLMakefileTable
+
+# Append modules to namespace.
+__all__ += ['GLConfig', 'GLError', 'GLInfo']
+__all__ += ['GLFileSystem', 'GLFileAssistant']
+__all__ += ['GLModule', 'GLModuleSystem', 'GLModuleTable']
+__all__ += ['GLImport', 'GLEmiter', 'GLTestDir']
+__all__ += ['GLMakefileTable']
+
+#===============================================================================
+# Define module information
+#===============================================================================
+__author__ = constants.__author__
+__license__ = constants.__license__
+__copyright__ = constants.__copyright__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pygnulib/constants.py	Sun Aug 20 11:17:58 2017 +0300
@@ -0,0 +1,436 @@
+#!/usr/bin/python
+# encoding: UTF-8
+
+'''An easy access to pygnulib constants.'''
+
+from __future__ import unicode_literals
+#===============================================================================
+# Define global imports
+#===============================================================================
+import re
+import os
+import sys
+import platform
+import tempfile
+import subprocess as sp
+
+
+#===============================================================================
+# Define module information
+#===============================================================================
+__all__ = list()
+__author__ = \
+[
+  'Bruno Haible',
+  'Paul Eggert',
+  'Simon Josefsson',
+  'Dmitriy Selyutin',
+]
+__license__ = 'GNU GPLv3+'
+__copyright__ = '2012 Free Software Foundation, Inc.'
+
+
+#===============================================================================
+# Backward compatibility
+#===============================================================================
+# Check for Python version
+if sys.version_info.major == 2:
+  PYTHON3 = False
+else:
+  PYTHON3 = True
+
+# Create string compatibility
+if not PYTHON3:
+  string = unicode
+else: # if PYTHON3
+  string = str
+
+# Current working directory
+if not PYTHON3:
+  os.getcwdb = os.getcwd
+  os.getcwd = os.getcwdu
+
+
+#===============================================================================
+# Define global constants
+#===============================================================================
+# Declare neccessary variables
+APP = dict() # Application
+DIRS = dict() # Directories
+UTILS = dict() # Utilities
+ENCS = dict() # Encodings
+FILES = dict() # Files
+MODES = dict() # Modes
+TESTS = dict() # Tests
+NL = '''
+''' # Newline character
+ALPHANUMERIC = 'abcdefghijklmnopqrstuvwxyz\
+ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+0123456789' # Alphanumeric characters
+
+# Set ENCS dictionary
+import __main__ as interpreter
+if not hasattr(interpreter, '__file__'):
+  if sys.stdout.encoding != None:
+    ENCS['default'] = sys.stdout.encoding
+  else: # sys.stdout.encoding == None
+    ENCS['default'] = 'UTF-8'
+else: # if hasattr(interpreter, '__file__'):
+  ENCS['default'] = 'UTF-8'
+ENCS['system'] = sys.getfilesystemencoding()
+ENCS['shell'] = sys.stdout.encoding
+if ENCS['shell'] == None:
+  ENCS['shell'] = 'UTF-8'
+
+# Set APP dictionary
+APP['name'] = sys.argv[0]
+if not APP['name']:
+  APP['name'] = 'gnulib-tool.py'
+APP['path'] = os.path.realpath(sys.argv[0])
+if type(APP['name']) is bytes:
+  APP['name'] = string(APP['name'], ENCS['system'])
+if type(APP['path']) is bytes:
+  APP['path'] = string(APP['path'], ENCS['system'])
+
+# Set DIRS dictionary
+DIRS['root'] = os.path.dirname(APP['path'])
+DIRS['cwd'] = os.getcwd()
+DIRS['build-aux'] = os.path.join(DIRS['root'], 'build-aux')
+DIRS['config'] = os.path.join(DIRS['root'], 'config')
+DIRS['doc'] = os.path.join(DIRS['root'], 'doc')
+DIRS['lib'] = os.path.join(DIRS['root'], 'lib')
+DIRS['m4'] = os.path.join(DIRS['root'], 'm4')
+DIRS['modules'] = os.path.join(DIRS['root'], 'modules')
+DIRS['tests'] = os.path.join(DIRS['root'], 'tests')
+DIRS['git'] = os.path.join(DIRS['root'], '.git')
+DIRS['cvs'] = os.path.join(DIRS['root'], 'CVS')
+
+# Set FILES dictionary
+FILES['changelog'] = os.path.join(DIRS['root'], 'ChangeLog')
+
+# Set MODES dictionary
+MODES = \
+{
+  'import': 0,
+  'add-import': 1,
+  'remove-import': 2,
+  'update': 3,
+}
+MODES['verbose-min'] = -2
+MODES['verbose-default'] = 0
+MODES['verbose-max'] = 2
+
+# Set TESTS dictionary
+TESTS = \
+{
+  'tests':             0,
+  'obsolete':          1,
+  'c++-test':          2,
+  'cxx-test':          2,
+  'c++-tests':         2,
+  'cxx-tests':         2,
+  'longrunning-test':  3,
+  'longrunning-tests': 3,
+  'privileged-test':   4,
+  'privileged-tests':  4,
+  'unportable-test':   5,
+  'unportable-tests':  5,
+  'all-test':          6,
+  'all-tests':         6,
+}
+
+# Define AUTOCONF minimum version
+DEFAULT_AUTOCONF_MINVERSION = 2.59
+# You can set AUTOCONFPATH to empty if autoconf 2.57 is already in your PATH
+AUTOCONFPATH = ''
+# You can set AUTOMAKEPATH to empty if automake 1.9.x is already in your PATH
+AUTOMAKEPATH = ''
+# You can set GETTEXTPATH to empty if autopoint 0.15 is already in your PATH
+GETTEXTPATH = ''
+# You can set LIBTOOLPATH to empty if libtoolize 2.x is already in your PATH
+LIBTOOLPATH = ''
+
+# You can also set the variable AUTOCONF individually
+if AUTOCONFPATH:
+  UTILS['autoconf'] = AUTOCONFPATH + 'autoconf'
+else:
+  if os.getenv('AUTOCONF'):
+    UTILS['autoconf'] = os.getenv('AUTOCONF')
+  else:
+    UTILS['autoconf'] = 'autoconf'
+
+# You can also set the variable AUTORECONF individually
+if AUTOCONFPATH:
+  UTILS['autoreconf'] = AUTOCONFPATH + 'autoreconf'
+else:
+  if os.getenv('AUTORECONF'):
+    UTILS['autoreconf'] = os.getenv('AUTORECONF')
+  else:
+    UTILS['autoreconf'] = 'autoreconf'
+
+# You can also set the variable AUTOHEADER individually
+if AUTOCONFPATH:
+  UTILS['autoheader'] = AUTOCONFPATH + 'autoheader'
+else:
+  if os.getenv('AUTOHEADER'):
+    UTILS['autoheader'] = os.getenv('AUTOHEADER')
+  else:
+    UTILS['autoheader'] = 'autoheader'
+
+# You can also set the variable AUTOMAKE individually
+if AUTOMAKEPATH:
+  UTILS['automake'] = AUTOMAKEPATH + 'automake'
+else:
+  if os.getenv('AUTOMAKE'):
+    UTILS['automake'] = os.getenv('AUTOMAKE')
+  else:
+    UTILS['automake'] = 'automake'
+
+# You can also set the variable ACLOCAL individually
+if AUTOMAKEPATH:
+  UTILS['aclocal'] = AUTOMAKEPATH + 'aclocal'
+else:
+  if os.getenv('ACLOCAL'):
+    UTILS['aclocal'] = os.getenv('ACLOCAL')
+  else:
+    UTILS['aclocal'] = 'aclocal'
+
+# You can also set the variable AUTOPOINT individually
+if GETTEXTPATH:
+  UTILS['autopoint'] = GETTEXTPATH + 'autopoint'
+else:
+  if os.getenv('AUTOPOINT'):
+    UTILS['autopoint'] = os.getenv('AUTOPOINT')
+  else:
+    UTILS['autopoint'] = 'autopoint'
+
+# You can also set the variable LIBTOOLIZE individually
+if LIBTOOLPATH:
+  UTILS['libtoolize'] = LIBTOOLPATH + 'libtoolize'
+else:
+  if os.getenv('LIBTOOLIZE'):
+    UTILS['libtoolize'] = os.getenv('LIBTOOLIZE')
+  else:
+    UTILS['libtoolize'] = 'libtoolize'
+
+# You can also set the variable MAKE
+if os.getenv('MAKE'):
+  UTILS['make'] = os.getenv('MAKE')
+else:
+  UTILS['make'] = 'make'
+
+
+#===============================================================================
+# Define global functions
+#===============================================================================
+def execute(args, verbose):
+  '''Execute the given shell command.'''
+  if verbose >= 0:
+    print("executing %s" % ' '.join(args))
+    try: # Try to run
+      retcode = sp.call(args)
+    except Exception as error:
+      print(error)
+      sys.exit(1)
+  else:
+    # Commands like automake produce output to stderr even when they succeed.
+    # Turn this output off if the command succeeds.
+    temp = tempfile.mktemp()
+    if type(temp) is bytes:
+      temp = temp.decode(ENCS['system'])
+    xargs = '%s > %s 2>&1' % (' '.join(args), temp)
+    try: # Try to run
+      retcode = sp.call(xargs, shell=True)
+    except Exception as error:
+      print(error)
+      sys.exit(1)
+    if retcode == 0:
+      os.remove(temp)
+    else:
+      print("executing %s" % ' '.join(args))
+      with codecs.open(temp, 'rb') as file:
+        cmdout = file.read()
+      print(cmdout)
+      os.remove(temp)
+      sys.exit(retcode)
+
+def compiler(pattern, flags=0):
+  '''Compile regex pattern depending on version of Python.'''
+  if not PYTHON3:
+    pattern = re.compile(pattern, re.UNICODE | flags)
+  else: # if PYTHON3
+    pattern = re.compile(pattern, flags)
+  return(pattern)
+
+def cleaner(sequence):
+  '''Clean string or list of strings after using regex.'''
+  if type(sequence) is string:
+    sequence = sequence.replace('[', '')
+    sequence = sequence.replace(']', '')
+  elif type(sequence) is list:
+    sequence = [value.replace('[', '').replace(']', '') for value in sequence]
+    sequence = [value.replace('(', '').replace(')', '') for value in sequence]
+    sequence = [False if value == 'false' else value for value in sequence]
+    sequence = [True if value == 'true' else value for value in sequence]
+    sequence = [value.strip() for value in sequence]
+  return(sequence)
+
+def joinpath(head, *tail):
+  '''joinpath(head, *tail) -> string
+  
+  Join two or more pathname components, inserting '/' as needed. If any
+  component is an absolute path, all previous path components will be
+  discarded. The second argument may be string or list of strings.'''
+  newtail = list()
+  if type(head) is bytes:
+    head = head.decode(ENCS['default'])
+  for item in tail:
+    if type(item) is bytes:
+      item = item.decode(ENCS['default'])
+    newtail += [item]
+  result = os.path.normpath(os.path.join(head, *tail))
+  if type(result) is bytes:
+    result = result.decode(ENCS['default'])
+  return(result)
+
+def relativize(dir1, dir2):
+  '''Compute a relative pathname reldir such that dir1/reldir = dir2.'''
+  dir0 = os.getcwd()
+  if type(dir1) is bytes:
+    dir1 = dir1.decode(ENCS['default'])
+  if type(dir2) is bytes:
+    dir2 = dir2.decode(ENCS['default'])
+  while dir1:
+    dir1 = '%s%s' % (os.path.normpath(dir1), os.path.sep)
+    dir2 = '%s%s' % (os.path.normpath(dir2), os.path.sep)
+    if dir1.startswith(os.path.sep):
+      first = dir1[:dir1.find(os.path.sep, 1)]
+    else: # if not dir1.startswith('/')
+      first = dir1[:dir1.find(os.path.sep)]
+    if first != '.':
+      if first == '..':
+        dir2 = os.path.basename(joinpath(dir0, dir2))
+        dir0 = os.path.dirname(dir0)
+      else: # if first != '..'
+        # Get first component of dir2
+        if dir2.startswith(os.path.sep):
+          first2 = dir2[:dir2.find(os.path.sep, 1)]
+        else: # if not dir1.startswith('/')
+          first2 = dir2[:dir2.find(os.path.sep)]
+        if first == first2:
+          dir2 = dir2[dir2.find(os.path.sep)+1:]
+        else: # if first != first2
+          dir2 = joinpath('..', dir2)
+        dir0 = joinpath(dir0, first)
+    dir1 = dir1[dir1.find(os.path.sep)+1:]
+  result = os.path.normpath(dir2)
+  return(result)
+
+def link_relative(src, dest):
+    '''Like ln -s, except that src is given relative to the current directory
+    (or absolute), not given relative to the directory of dest.'''
+    if type(src) is bytes or type(src) is string:
+      if type(src) is bytes:
+        src = src.decode(ENCS['default'])
+    else: # if src has not bytes or string type
+      raise(TypeError(
+        'src must be a string, not %s' % (type(src).__name__)))
+    if type(dest) is bytes or type(dest) is string:
+      if type(dest) is bytes:
+        dest = dest.decode(ENCS['default'])
+    else: # if dest has not bytes or string type
+      raise(TypeError(
+        'dest must be a string, not %s' % (type(dest).__name__)))
+    if src.startswith('/'):
+      os.symlink(src, dest)
+    else: # if not src.startswith('/')
+      if dest.startswith('/'):
+        if not constants.PYTHON3:
+          cwd = os.getcwdu()
+        else: # if constants.PYTHON3
+          cwd = os.getcwd()
+        os.symlink(joinpath(cwd, src), dest)
+      else: # if not dest.startswith('/')
+        destdir = os.path.dirname(dest)
+        if not destdir:
+          destdir = '.'
+        if type(destdir) is bytes:
+          destdir = destdir.decode(ENCS['default'])
+        src = relativize(destdir, src)
+        os.symlink(src, dest)
+
+def link_if_changed(src, dest):
+  '''Create a symlink, but avoids munging timestamps if the link is correct.'''
+  if type(src) is bytes:
+    src = src.decode(ENCS['default'])
+  if type(dest) is bytes:
+    dest = dest.decode(ENCS['default'])
+  ln_target = os.path.realpath(src)
+  if not (os.path.islink(dest) and src == ln_target):
+    os.remove(dest)
+    link_relative(src, dest)
+
+def filter_filelist(separator, filelist,
+  prefix, suffix, removed_prefix, removed_suffix,
+  added_prefix=string(), added_suffix=string()):
+  '''filter_filelist(*args) -> list
+  
+  Filter the given list of files. Filtering: Only the elements starting with
+  prefix and ending with suffix are considered. Processing: removed_prefix
+  and removed_suffix are removed from each element, added_prefix and
+  added_suffix are added to each element.'''
+  listing = list()
+  for filename in filelist:
+    if filename.startswith(prefix) and filename.endswith(suffix):
+      pattern = compiler('^%s(.*?)%s$' % (removed_prefix, removed_suffix))
+      result = pattern.sub('%s\\1%s' % (added_prefix, added_suffix), filename)
+      listing += [result]
+  result = separator.join(listing)
+  return(result)
+
+def substart(orig, repl, data):
+  result = data
+  if data.startswith(orig):
+    result = repl + data[len(orig):]
+  return(result)
+
+def subend(orig, repl, data):
+  result = data
+  if data.endswith(orig):
+    result = repl + data[:len(repl)]
+  return(result)
+
+def nlconvert(text):
+  '''Convert line-endings to specific for this platform.'''
+  system = platform.system().lower()
+  text = text.replace('\r\n', '\n')
+  if system == 'windows':
+    text = text.replace('\n', '\r\n')
+  return(text)
+
+def nlremove(text):
+  '''Remove empty lines from the source text.'''
+  text = nlconvert(text)
+  text = text.replace('\r\n', '\n')
+  lines = [line for line in text.split('\n') if line != '']
+  text = '\n'.join(lines)
+  text = nlconvert(text)
+  return(text)
+
+def nlcount(text):
+  '''Return count of newlines before and after text.'''
+  counter = int()
+  before = int()
+  after = int()
+  text = text.replace('\r\n', '\n')
+  while text[counter] == '\n':
+    before += 1
+    counter += 1
+  counter = len(text) -1
+  while text[counter] == '\n':
+    after += 1
+    counter -= 1
+  print(before, after)
+
+__all__ += ['APP', 'DIRS', 'FILES', 'MODES', 'UTILS']
+