1#!/usr/bin/python
2# encoding: UTF-8
3
4#===============================================================================
5# Define global imports
6#===============================================================================
7import os
8import re
9import sys
10import copy
11import codecs
12import tempfile
13import subprocess as sp
14from . import constants
15from .GLError import GLError
16
17
18#===============================================================================
19# Define module information
20#===============================================================================
21__author__ = constants.__author__
22__license__ = constants.__license__
23__copyright__ = constants.__copyright__
24
25
26#===============================================================================
27# Define global constants
28#===============================================================================
29PYTHON3 = constants.PYTHON3
30NoneType = type(None)
31APP = constants.APP
32DIRS = constants.DIRS
33ENCS = constants.ENCS
34UTILS = constants.UTILS
35MODES = constants.MODES
36TESTS = constants.TESTS
37compiler = constants.compiler
38joinpath = constants.joinpath
39cleaner = constants.cleaner
40relpath = constants.relativize
41string = constants.string
42isabs = os.path.isabs
43isdir = os.path.isdir
44isfile = os.path.isfile
45normpath = os.path.normpath
46
47
48#===============================================================================
49# Define GLConfig class
50#===============================================================================
51class GLConfig(object):
52    '''This class is used to store intermediate settings for all pygnulib
53    classes. It contains all necessary attributes to setup any other class.
54    By default all attributes are set to empty string, empty list or zero.
55    The most common value, however, is a None value.'''
56
57    def __init__(self, destdir=None, localdir=None, auxdir=None,
58                 sourcebase=None, m4base=None, pobase=None, docbase=None, testsbase=None,
59                 modules=None, avoids=None, files=None, testflags=None, libname=None,
60                 lgpl=None, makefile=None, libtool=None, conddeps=None, macro_prefix=None,
61                 podomain=None, witness_c_macro=None, vc_files=None, symbolic=None,
62                 lsymbolic=None, modcache=None, configure_ac=None, ac_version=None,
63                 libtests=None, single_configure=None, verbose=None, dryrun=None,
64                 errors=None):
65        '''GLConfig.__init__(arguments) -> GLConfig
66
67        Create new GLConfig instance.'''
68        self.table = dict()
69        self.table['tempdir'] = tempfile.mkdtemp()
70        # destdir
71        self.resetDestDir()
72        if destdir != None:
73            self.setDestDir(destdir)
74        # localdir
75        self.resetLocalDir()
76        if localdir != None:
77            self.setLocalDir(localdir)
78        # auxdir
79        self.resetAuxDir()
80        if auxdir != None:
81            self.setAuxDir(auxdir)
82        # sourcebase
83        self.resetSourceBase()
84        if sourcebase != None:
85            self.setSourceBase(sourcebase)
86        # m4base
87        self.resetM4Base()
88        if m4base != None:
89            self.setM4Base(m4base)
90        # pobase
91        self.resetPoBase()
92        if pobase != None:
93            self.setPoBase(pobase)
94        # docbase
95        self.resetDocBase()
96        if docbase != None:
97            self.setDocBase(docbase)
98        # testsbase
99        self.resetTestsBase()
100        if testsbase != None:
101            self.setTestsBase(testsbase)
102        # modules
103        self.resetModules()
104        if modules != None:
105            self.setModules(modules)
106        # avoids
107        self.resetAvoids()
108        if avoids != None:
109            self.setAvoids(avoids)
110        # files
111        self.resetFiles()
112        if files != None:
113            self.setFiles(files)
114        # testflags
115        self.resetTestFlags()
116        if testflags != None:
117            self.setTestFlags(testflags)
118        # libname
119        self.resetLibName()
120        if libname != None:
121            self.setLibName(libname)
122        # lgpl
123        self.resetLGPL()
124        if lgpl != None:
125            self.setLGPL(lgpl)
126        # makefile
127        self.resetMakefile()
128        if makefile != None:
129            self.setMakefile(makefile)
130        # libtool
131        self.resetLibtool()
132        if libtool != None:
133            if type(libtool) is bool:
134                if not libtool:
135                    self.disableLibtool()
136                else:  # if libtool
137                    self.enableLibtool()
138            else:  # if type(libtool) is not bool
139                raise(TypeError('libtool must be a bool, not %s' %
140                                type(libtool).__name__))
141        # conddeps
142        self.resetCondDeps()
143        if conddeps != None:
144            if type(conddeps) is bool:
145                if not conddeps:
146                    self.disableCondDeps()
147                else:  # if conddeps
148                    self.enableCondDeps()
149            else:  # if type(conddeps) is not bool
150                raise(TypeError('conddeps must be a bool, not %s' %
151                                type(conddeps).__name__))
152        # macro_prefix
153        self.resetMacroPrefix()
154        if macro_prefix != None:
155            self.setMacroPrefix(macro_prefix)
156        # podomain
157        self.resetPoDomain()
158        if podomain != None:
159            self.setPoDomain(podomain)
160        # witness_c_macro
161        self.resetWitnessCMacro()
162        if witness_c_macro != None:
163            if type(witness_c_macro) is bool:
164                if not witness_c_macro:
165                    self.setWitnessCMacro()
166                else:  # if witness_c_macro
167                    self.resetWitnessCMacro()
168            else:  # if type(witness_c_macro) is not bool
169                raise(TypeError('witness_c_macro must be a bool, not %s' %
170                                type(witness_c_macro).__name__))
171        # vc_files
172        self.resetVCFiles()
173        if vc_files != None:
174            if type(vc_files) is bool:
175                if not vc_files:
176                    self.disableVCFiles()
177                else:  # if vc_files
178                    self.enableVCFiles()
179            else:  # if type(vc_files) is not bool
180                raise(TypeError('vc_files must be a bool, not %s' %
181                                type(vc_files).__name__))
182        # symbolic
183        self.resetSymbolic()
184        if symbolic != None:
185            if type(symbolic) is bool:
186                if not symbolic:
187                    self.disableSymbolic()
188                else:  # if symbolic
189                    self.enableSymbolic()
190            else:  # if type(symbolic) is not bool
191                raise(TypeError('symbolic must be a bool, not %s' %
192                                type(symbolic).__name__))
193        # lsymbolic
194        self.resetLSymbolic()
195        if lsymbolic != None:
196            if type(lsymbolic) is bool:
197                if not lsymbolic:
198                    self.disableLSymbolic()
199                else:  # if lsymbolic
200                    self.enableLSymbolic()
201            else:  # if type(lsymbolic) is not bool
202                raise(TypeError('lsymbolic must be a bool, not %s' %
203                                type(lsymbolic).__name__))
204        # modcache
205        self.resetModuleCaching()
206        if modcache != None:
207            if type(modcache) is bool:
208                if not modcache:
209                    self.disableModuleCaching()
210                else:  # if modcache
211                    self.enableModuleCaching()
212            else:  # if type(modcache) is not bool
213                raise(TypeError('modcache must be a bool, not %s' %
214                                type(modcache).__name__))
215        # configure_ac
216        self.resetAutoconfFile()
217        if configure_ac != None:
218            self.setAutoconfFile(configure_ac)
219        # ac_version
220        self.resetAutoconfVersion()
221        if ac_version != None:
222            self.setAutoconfVersion(ac_version)
223        # libtests
224        self.resetLibtests()
225        if libtests != None:
226            if type(libtests) is bool:
227                if not libtests:
228                    self.disableLibtests()
229                else:  # if libtests
230                    self.enableLibtests()
231            else:  # if type(libtests) is not bool
232                raise(TypeError('libtests must be a bool, not %s' %
233                                type(libtests).__name__))
234        # single_configure
235        self.resetSingleConfigure()
236        if single_configure != None:
237            if type(single_configure) is bool:
238                if not single_configure:
239                    self.disableSingleConfigure()
240                else:  # if single_configure
241                    self.enableSingleConfigure()
242            else:  # if type(single_configure) is not bool
243                raise(TypeError('single_configure must be a bool, not %s' %
244                                type(single_configure).__name__))
245        # verbose
246        self.resetVerbosity()
247        if verbose != None:
248            self.setVerbosity(verbose)
249        # dryrun
250        self.resetDryRun()
251        if dryrun != None:
252            if type(dryrun) is bool:
253                if not dryrun:
254                    self.disableDryRun()
255                else:  # if dryrun
256                    self.enableDryRun()
257            else:  # if type(dryrun) is not bool
258                raise(TypeError('dryrun must be a bool, not %s' %
259                                type(dryrun).__name__))
260        # errors
261        self.resetErrors()
262        if errors != None:
263            if type(errors) is bool:
264                if not errors:
265                    self.disableErrors()
266                else:  # if errors
267                    self.enableErrors()
268            else:  # if type(errors) is not bool
269                raise(TypeError('errors must be a bool, not %s' %
270                                type(errors).__name__))
271
272    # Define special methods.
273    def __repr__(self):
274        '''x.__repr__() <==> repr(x)'''
275        return('<pygnulib.GLConfig>')
276
277    def __getitem__(self, y):
278        '''x.__getitem__(y) <==> x[y]'''
279        if y in self.table:
280            result = self.table[y]
281            if type(y) is list:
282                result = list(self.table[y])
283            if y == "auxdir":
284                if self.table['auxdir']:
285                    return self.table['auxdir']
286                return "build-aux"
287            return(self.table[y])
288        else:  # if y not in self.table
289            raise(KeyError('GLConfig does not contain key: %s' % repr(y)))
290
291    def dictionary(self):
292        '''Return the configuration as a dict object.'''
293        return(dict(self.table))
294
295    def copy(self):
296        '''Return the copy of the configuration.'''
297        table = copy.deepcopy(self)
298        return(table)
299
300    def update(self, dictionary):
301        '''Specify the dictionary whose keys will be used to update config.'''
302        if type(dictionary) is not GLConfig:
303            raise(TypeError('dictionary must be a GLConfig, not %s' %
304                            type(dictionary).__name__))
305        dictionary = dict(dictionary.table)
306        result = dict()
307        for key in dictionary:
308            src = self.table[key]
309            dest = dictionary[key]
310            result[key] = src
311            if src != dest:
312                if self.isdefault(key, src):
313                    result[key] = dest
314                else:  # if not self.isdefault(key, src)
315                    result[key] == src
316                    if not self.isdefault(key, dest):
317                        if key in ['modules', 'avoids', 'tests']:
318                            dest = sorted(set(src + dest))
319                        result[key] = dest
320        self.table = dict(result)
321
322    def update_key(self, dictionary, key):
323        '''Update the given key using value from the given dictionary.'''
324        if key in self.table:
325            if type(dictionary) is not GLConfig:
326                raise(TypeError('dictionary must be a GLConfig, not %s' %
327                                type(dictionary).__name__))
328            dictionary = dict(dictionary.table)
329            self.table[key] = dictionary[key]
330        else:  # if key not in self.table
331            raise(KeyError('GLConfig does not contain key: %s' % repr(key)))
332
333    def default(self, key):
334        '''Return default value for the given key.'''
335        if key in self.table:
336            if key == 'libname':
337                return(string('libgnu'))
338            elif key == 'macro_prefix':
339                return(string('gl'))
340            elif key == 'include_guard_prefix':
341                return(string('GL'))
342            elif key == 'ac_version':
343                return(2.59)
344            elif key == 'verbosity':
345                return(0)
346            elif key == 'copyrights':
347                return(True)
348            elif key in ['modules', 'avoids', 'tests', 'testflags']:
349                return(list())
350            elif key in ['libtool', 'lgpl', 'conddeps', 'modcache', 'symbolic',
351                         'lsymbolic', 'libtests', 'dryrun']:
352                return(False)
353            if key == 'vc_files':
354                return(None)
355            elif key == 'errors':
356                return(True)
357            else:  # otherwise
358                return(string())
359        else:  # if key not in self.table
360            raise(KeyError('GLConfig does not contain key: %s' % repr(key)))
361
362    def isdefault(self, key, value):
363        '''Check whether the value for the given key is a default value.'''
364        if key in self.table:
365            default = self.default(key)
366            return(value == default)
367        else:  # if key not in self.table
368            raise(KeyError('GLConfig does not contain key: %s' % repr(key)))
369
370    def keys(self):
371        '''Return list of keys.'''
372        return(list(self.table.keys()))
373
374    def values(self):
375        '''Return list of values.'''
376        return(list(self.table.values()))
377
378    # Define destdir methods.
379    def getDestDir(self):
380        '''Return the target directory. For --import, this specifies where your
381        configure.ac can be found. Defaults to current directory.'''
382        return(self.table['destdir'])
383
384    def setDestDir(self, destdir):
385        '''Specify the target directory. For --import, this specifies where your
386        configure.ac can be found. Defaults to current directory.'''
387        if type(destdir) is bytes or type(destdir) is string:
388            if type(destdir) is bytes:
389                destdir = string(destdir, ENCS['system'])
390            if destdir:
391                self.table['destdir'] = os.path.normpath(destdir)
392        else:  # if destdir has not bytes/string type
393            raise(TypeError('destdir must be a string, not %s' %
394                            type(destdir).__name__))
395
396    def resetDestDir(self):
397        '''Reset the target directory. For --import, this specifies where your
398        configure.ac can be found. Defaults to current directory.'''
399        self.table['destdir'] = string()
400
401    # Define localdir methods.
402    def getLocalDir(self):
403        '''Return a local override directory where to look up files before looking
404        in gnulib's directory.'''
405        return(self.table['localdir'])
406
407    def setLocalDir(self, localdir):
408        '''Specify a local override directory where to look up files before looking
409        in gnulib's directory.'''
410        if type(localdir) is bytes or type(localdir) is string:
411            if type(localdir) is bytes:
412                localdir = string(localdir, ENCS['system'])
413            if localdir:
414                self.table['localdir'] = localdir
415        else:  # if localdir has not bytes/string type
416            raise(TypeError('localdir must be a string, not %s' %
417                            type(localdir).__name__))
418
419    def resetLocalDir(self):
420        '''Reset a local override directory where to look up files before looking
421        in gnulib's directory.'''
422        self.table['localdir'] = string()
423
424    # Define auxdir methods.
425    def getAuxDir(self):
426        '''Return directory relative to --dir where auxiliary build tools are
427        placed. Default comes from configure.ac or configure.in.'''
428        if self.table['auxdir']:
429            return self.table['auxdir']
430        return "build-aux"
431
432    def setAuxDir(self, auxdir):
433        '''Specify directory relative to --dir where auxiliary build tools are
434        placed. Default comes from configure.ac or configure.in.'''
435        if type(auxdir) is bytes or type(auxdir) is string:
436            if type(auxdir) is bytes:
437                auxdir = string(auxdir, ENCS['system'])
438            if auxdir:
439                self.table['auxdir'] = auxdir
440        else:  # if type of auxdir is not bytes or string
441            raise(TypeError('auxdir must be a string, not %s' %
442                            type(auxdir).__name__))
443
444    def resetAuxDir(self):
445        '''Reset directory relative to --dir where auxiliary build tools are
446        placed. Default comes from configure.ac or configure.in.'''
447        self.table['auxdir'] = string()
448
449    # Define sourcebase methods.
450    def getSourceBase(self):
451        '''Return directory relative to destdir where source code is placed.'''
452        return(self.table['sourcebase'])
453
454    def setSourceBase(self, sourcebase):
455        '''Specify directory relative to destdir where source code is placed.'''
456        if type(sourcebase) is bytes or type(sourcebase) is string:
457            if type(sourcebase) is bytes:
458                sourcebase = string(sourcebase, ENCS['system'])
459            if sourcebase:
460                self.table['sourcebase'] = sourcebase
461        else:  # if type of sourcebase is not bytes or string
462            raise(TypeError('sourcebase must be a string, not %s' %
463                            type(sourcebase).__name__))
464
465    def resetSourceBase(self):
466        '''Return directory relative to destdir where source code is placed.'''
467        self.table['sourcebase'] = string()
468
469    # Define m4base methods.
470    def getM4Base(self):
471        '''Return directory relative to destdir where *.m4 macros are placed.'''
472        return(self.table['m4base'])
473
474    def setM4Base(self, m4base):
475        '''Specify directory relative to destdir where *.m4 macros are placed.'''
476        if type(m4base) is bytes or type(m4base) is string:
477            if type(m4base) is bytes:
478                m4base = string(m4base, ENCS['system'])
479            if m4base:
480                self.table['m4base'] = m4base
481        else:  # if type of m4base is not bytes or string
482            raise(TypeError('m4base must be a string, not %s' %
483                            type(m4base).__name__))
484
485    def resetM4Base(self):
486        '''Reset directory relative to destdir where *.m4 macros are placed.'''
487        self.table['m4base'] = string()
488
489    # Define pobase methods.
490    def getPoBase(self):
491        '''Return directory relative to destdir where *.po files are placed.'''
492        return(self.table['pobase'])
493
494    def setPoBase(self, pobase):
495        '''Specify directory relative to destdir where *.po files are placed.'''
496        if type(pobase) is bytes or type(pobase) is string:
497            if type(pobase) is bytes:
498                pobase = string(pobase, ENCS['system'])
499            if pobase:
500                self.table['pobase'] = pobase
501        else:  # if type of pobase is not bytes or string
502            raise(TypeError('pobase must be a string, not %s' %
503                            type(pobase).__name__))
504
505    def resetPoBase(self):
506        '''Reset directory relative to destdir where *.po files are placed.'''
507        self.table['pobase'] = string()
508
509    # Define docbase methods.
510    def getDocBase(self):
511        '''Return directory relative to destdir where doc files are placed.
512        Default value for this variable is 'doc').'''
513        return(self.table['docbase'])
514
515    def setDocBase(self, docbase):
516        '''Specify directory relative to destdir where doc files are placed.
517        Default value for this variable is 'doc').'''
518        if type(docbase) is bytes or type(docbase) is string:
519            if type(docbase) is bytes:
520                docbase = string(docbase, ENCS['system'])
521            if docbase:
522                self.table['docbase'] = docbase
523        else:  # if type of docbase is not bytes or string
524            raise(TypeError('docbase must be a string, not %s' %
525                            type(docbase).__name__))
526
527    def resetDocBase(self):
528        '''Reset directory relative to destdir where doc files are placed.
529        Default value for this variable is 'doc').'''
530        self.table['docbase'] = string()
531
532    # Define testsbase methods.
533    def getTestsBase(self):
534        '''Return directory relative to destdir where unit tests are placed.
535        Default value for this variable is 'tests').'''
536        return(self.table['testsbase'])
537
538    def setTestsBase(self, testsbase):
539        '''Specify directory relative to destdir where unit tests are placed.
540        Default value for this variable is 'tests').'''
541        if type(testsbase) is bytes or type(testsbase) is string:
542            if type(testsbase) is bytes:
543                testsbase = string(testsbase, ENCS['system'])
544            if testsbase:
545                self.table['testsbase'] = testsbase
546        else:  # if type of testsbase is not bytes or string
547            raise(TypeError('testsbase must be a string, not %s' %
548                            type(testsbase).__name__))
549
550    def resetTestsBase(self):
551        '''Reset directory relative to destdir where unit tests are placed.
552        Default value for this variable is 'tests').'''
553        self.table['testsbase'] = string()
554
555    # Define modules methods.
556    def addModule(self, module):
557        '''Add the module to the modules list.'''
558        if type(module) is bytes or type(module) is string:
559            if type(module) is bytes:
560                module = module.decode(ENCS['default'])
561            if module not in self.table['modules']:
562                self.table['modules'] += [module]
563        else:  # if module has not bytes or string type
564            raise(TypeError('module must be a string, not %s' %
565                            type(module).__name__))
566
567    def removeModule(self, module):
568        '''Remove the module from the modules list.'''
569        if type(module) is bytes or type(module) is string:
570            if type(module) is bytes:
571                module = module.decode(ENCS['default'])
572            if module in self.table['modules']:
573                self.table['modules'].remove(module)
574        else:  # if module has not bytes or string type
575            raise(TypeError('module must be a string, not %s' %
576                            type(module).__name__))
577
578    def getModules(self):
579        '''Return the modules list.'''
580        return(list(self.table['modules']))
581
582    def setModules(self, modules):
583        '''Set the modules list.'''
584        if type(modules) is list or type(modules) is tuple:
585            old_modules = self.table['modules']
586            self.table['modules'] = list()
587            for module in modules:
588                try:  # Try to add each module
589                    self.addModule(module)
590                except TypeError as error:
591                    self.table['modules'] = old_modules
592                    raise(TypeError('each module must be a string'))
593                except GLError as error:
594                    self.table['modules'] = old_modules
595                    raise(GLError(error.errno, error.errinfo))
596        else:  # if type of modules is not list or tuple
597            raise(TypeError('modules must be a list or a tuple, not %s' %
598                            type(modules).__name__))
599
600    def resetModules(self):
601        '''Reset the list of the modules.'''
602        self.table['modules'] = list()
603
604    # Define avoids methods.
605    def addAvoid(self, module):
606        '''Avoid including the given module. Useful if you have code that provides
607        equivalent functionality.'''
608        if type(module) is bytes or type(module) is string:
609            if type(module) is bytes:
610                module = module.decode(ENCS['default'])
611            if module not in self.table['avoids']:
612                self.table['avoids'].append(module)
613        else:  # if module has not bytes or string type
614            raise(TypeError('avoid must be a string, not %s' %
615                            type(module).__name__))
616
617    def removeAvoid(self, module):
618        '''Remove the given module from the list of avoided modules.'''
619        if type(module) is bytes or type(module) is string:
620            if type(module) is bytes:
621                module = module.decode(ENCS['default'])
622            if module in self.table['avoids']:
623                self.table['avoids'].remove(module)
624        else:  # if module has not bytes or string type
625            raise(TypeError('avoid must be a string, not %s' %
626                            type(module).__name__))
627
628    def getAvoids(self):
629        '''Return the list of the avoided modules.'''
630        return(list(self.table['avoids']))
631
632    def setAvoids(self, modules):
633        '''Specify the modules which will be avoided.'''
634        if type(modules) is list or type(modules) is tuple:
635            old_avoids = self.table['avoids']
636            self.table['avoids'] = list()
637            for module in modules:
638                try:  # Try to add each module
639                    self.addAvoid(module)
640                except TypeError as error:
641                    self.table['avoids'] = old_avoids
642                    raise(TypeError('each module must be a string'))
643                except GLError as error:
644                    self.table['avoids'] = old_avoids
645                    raise(GLError(error.errno, error.errinfo))
646        else:  # if type of modules is not list or tuple
647            raise(TypeError('modules must be a list or a tuple, not %s' %
648                            type(modules).__name__))
649
650    def resetAvoids(self):
651        '''Reset the list of the avoided modules.'''
652        self.table['avoids'] = list()
653
654    # Define files methods.
655    def addFile(self, file):
656        '''Add file to the list of files.'''
657        if type(file) is bytes or type(file) is string:
658            if type(file) is bytes:
659                file = file.decode(ENCS['default'])
660            if file not in self.table['files']:
661                self.table['files'].append(file)
662        else:  # if file has not bytes or string type
663            raise(TypeError('file must be a string, not %s' %
664                            type(file).__name__))
665
666    def removeFile(self, file):
667        '''Remove the given file from the list of files.'''
668        if type(file) is bytes or type(file) is string:
669            if type(file) is bytes:
670                file = file.decode(ENCS['default'])
671            if file in self.table['files']:
672                self.table['files'].remove(file)
673        else:  # if file has not bytes or string type
674            raise(TypeError('file must be a string, not %s' %
675                            type(file).__name__))
676
677    def getFiles(self):
678        '''Return the list of the fileed files.'''
679        return(list(self.table['files']))
680
681    def setFiles(self, files):
682        '''Specify the list of files.'''
683        if type(files) is list or type(files) is tuple:
684            old_files = self.table['files']
685            self.table['files'] = list()
686            for file in files:
687                try:  # Try to add each file
688                    self.addFile(file)
689                except TypeError as error:
690                    self.table['files'] = old_files
691                    raise(TypeError('each file must be a string'))
692                except GLError as error:
693                    self.table['files'] = old_files
694                    raise(GLError(error.errno, error.errinfo))
695        else:  # if type of files is not list or tuple
696            raise(TypeError('files must be a list or a tuple, not %s' %
697                            type(files).__name__))
698
699    def resetFiles(self):
700        '''Reset the list of files.'''
701        self.table['files'] = list()
702
703    # Define tests/testflags methods
704    def checkTestFlag(self, flag):
705        '''Return the status of the test flag.'''
706        if flag in TESTS.values():
707            return(flag in self.table['testflags'])
708        else:  # if flag is not in TESTS
709            raise(TypeError('unknown flag: %s' % repr(flag)))
710
711    def enableTestFlag(self, flag):
712        '''Enable test flag. You can get flags from TESTS variable.'''
713        if flag in TESTS.values():
714            if flag not in self.table['testflags']:
715                self.table['testflags'].append(flag)
716        else:  # if flag is not in TESTS
717            raise(TypeError('unknown flag: %s' % repr(flag)))
718
719    def disableTestFlag(self, flag):
720        '''Disable test flag. You can get flags from TESTS variable.'''
721        if flag in TESTS.values():
722            if flag in self.table['testflags']:
723                self.table['testflags'].remove(flag)
724        else:  # if flag is not in TESTS
725            raise(TypeError('unknown flag: %s' % repr(flag)))
726
727    def getTestFlags(self):
728        '''Return test flags. You can get flags from TESTS variable.'''
729        return(list(self.table['testflags']))
730
731    def setTestFlags(self, testflags):
732        '''Specify test flags. You can get flags from TESTS variable.'''
733        if type(testflags) is list or type(testflags) is tuple:
734            old_testflags = self.table['testflags']
735            self.table['testflags'] = list()
736            for flag in testflags:
737                try:  # Try to enable each flag
738                    self.enableTestFlag(flag)
739                except TypeError as error:
740                    raise(TypeError('each flag must be one of TESTS integers'))
741            self.table['testflags'] = testflags
742        else:  # if type of testflags is not list or tuple
743            raise(TypeError('testflags must be a list or a tuple, not %s' %
744                            type(testflags).__name__))
745
746    def resetTestFlags(self):
747        '''Reset test flags (only default flag will be enabled).'''
748        self.table['testflags'] = list()
749        self.table['tests'] = self.table['testflags']
750
751    # Define libname methods.
752    def getLibName(self):
753        '''Return the library name.'''
754        return(self.table['libname'])
755
756    def setLibName(self, libname):
757        '''Specify the library name.'''
758        if type(libname) is bytes or type(libname) is string:
759            if type(libname) is bytes:
760                libname = string(libname, ENCS['system'])
761            if libname:
762                self.table['libname'] = libname
763        else:  # if type of libname is not bytes or string
764            raise(TypeError('libname must be a string, not %s' %
765                            type(module).__name__))
766
767    def resetLibName(self):
768        '''Reset the library name to 'libgnu'.'''
769        self.table['libname'] = string('libgnu')
770
771    # Define libtool methods.
772    def checkLibtool(self):
773        '''Check if user enabled libtool rules.'''
774        return(self.table['libtool'])
775
776    def enableLibtool(self):
777        '''Enable libtool rules.'''
778        self.table['libtool'] = True
779
780    def disableLibtool(self):
781        '''Disable libtool rules.'''
782        self.table['libtool'] = False
783
784    def resetLibtool(self):
785        '''Reset libtool rules.'''
786        self.table['libtool'] = False
787
788    # Define conddeps methods.
789    def checkCondDeps(self):
790        '''Check if user enabled cond. dependencies.'''
791        return(self.table['conddeps'])
792
793    def enableCondDeps(self):
794        '''Enable cond. dependencies (may save configure time and object code).'''
795        self.table['conddeps'] = True
796
797    def disableCondDeps(self):
798        '''Disable cond. dependencies (may save configure time and object code).'''
799        self.table['conddeps'] = False
800
801    def resetCondDeps(self):
802        '''Reset cond. dependencies (may save configure time and object code).'''
803        self.table['conddeps'] = False
804
805    # Define lgpl methods.
806    def getLGPL(self):
807        '''Check for abort if modules aren't available under the LGPL.
808        Default value is False, which means that lgpl is disabled.'''
809        return(self.table['lgpl'])
810
811    def setLGPL(self, lgpl):
812        '''Abort if modules aren't available under the LGPL.
813        Default value is False, which means that lgpl is disabled.'''
814        if (type(lgpl) is int and 2 <= lgpl <= 3) or type(lgpl) is bool:
815            self.table['lgpl'] = lgpl
816        else:  # if lgpl is not False, 2 or 3
817            raise(TypeError('invalid LGPL version: %s' % repr(lgpl)))
818
819    def resetLGPL(self):
820        '''Disable abort if modules aren't available under the LGPL.
821        Default value is False, which means that lgpl is disabled.'''
822        self.table['lgpl'] = False
823
824    def getIncludeGuardPrefix(self):
825        '''Return include_guard_prefix to use inside GLEmiter class.'''
826        return(self.table['include_guard_prefix'])
827
828    def getModuleIndicatorPrefix(self):
829        '''Return module_indicator_prefix to use inside GLEmiter class.'''
830        return(getIncludeGuardPrefix(self))
831
832    # Define macro_prefix methods.
833    def getMacroPrefix(self):
834        '''Return the prefix of the macros 'gl_EARLY' and 'gl_INIT'.
835        Default macro_prefix is 'gl'.'''
836        return(self.table['macro_prefix'])
837
838    def setMacroPrefix(self, macro_prefix):
839        '''Specify the prefix of the macros 'gl_EARLY' and 'gl_INIT'.
840        Default macro_prefix is 'gl'.'''
841        if type(macro_prefix) is bytes or type(macro_prefix) is string:
842            if type(macro_prefix) is bytes:
843                macro_prefix = string(macro_prefix, ENCS['system'])
844            if macro_prefix:
845                self.table['macro_prefix'] = macro_prefix
846        else:  # if type of macro_prefix is not bytes or string
847            raise(TypeError('macro_prefix must be a string, not %s' %
848                            type(macro_prefix).__name__))
849        if macro_prefix == 'gl':
850            include_guard_prefix = 'GL'
851        else:  # macro_prefix != 'gl'
852            include_guard_prefix = 'GL_%s' % macro_prefix.upper()
853        if type(include_guard_prefix) is bytes:
854            include_guard_prefix = include_guard_prefix.decode(ENCS['default'])
855        self.table['include_guard_prefix'] = include_guard_prefix
856
857    def resetMacroPrefix(self):
858        '''Reset the prefix of the macros 'gl_EARLY' and 'gl_INIT'.
859        Default macro_prefix is 'gl'.'''
860        self.table['macro_prefix'] = string('gl')
861        include_guard_prefix = string('GL')
862        if type(include_guard_prefix) is bytes:
863            include_guard_prefix = include_guard_prefix.decode(ENCS['default'])
864        self.table['include_guard_prefix'] = include_guard_prefix
865
866    # Define makefile methods.
867    def getMakefile(self):
868        '''Return the name of makefile in automake syntax in the source-base and
869        tests-base directories. Default is 'Makefile.am'.'''
870        return(self.table['makefile'])
871
872    def setMakefile(self, makefile):
873        '''Specify the name of makefile in automake syntax in the source-base and
874        tests-base directories. Default is 'Makefile.am'.'''
875        if type(makefile) is bytes or type(makefile) is string:
876            if type(makefile) is bytes:
877                makefile = string(makefile, ENCS['system'])
878            if makefile:
879                self.table['makefile'] = makefile
880        else:  # if type of makefile is not bytes or string
881            raise(TypeError('makefile must be a string, not %s' %
882                            type(makefile).__name__))
883
884    def resetMakefile(self):
885        '''Reset the name of makefile in automake syntax in the source-base and
886        tests-base directories. Default is 'Makefile.am'.'''
887        self.table['makefile'] = string()
888
889    # Define podomain methods.
890    def getPoDomain(self):
891        '''Return the prefix of the i18n domain. Usually use the package name.
892        A suffix '-gnulib' is appended.'''
893        return(self.table['podomain'])
894
895    def setPoDomain(self, podomain):
896        '''Specify the prefix of the i18n domain. Usually use the package name.
897        A suffix '-gnulib' is appended.'''
898        if type(podomain) is bytes or type(podomain) is string:
899            if type(podomain) is bytes:
900                podomain = string(podomain, ENCS['system'])
901            if podomain:
902                self.table['podomain'] = podomain
903        else:  # if type of podomain is not bytes or string
904            raise(TypeError('podomain must be a string, not %s' %
905                            type(podomain).__name__))
906
907    def resetPoDomain(self):
908        '''Reset the prefix of the i18n domain. Usually use the package name.
909        A suffix '-gnulib' is appended.'''
910        self.table['podomain'] = string()
911
912    # Define witness_c_macro methods.
913    def getWitnessCMacro(self):
914        '''Return the C macro that is defined when the sources in this directory
915        are compiled or used.'''
916        return(self.table['witness_c_macro'])
917
918    def setWitnessCMacro(self, witness_c_macro):
919        '''Specify the C macro that is defined when the sources in this directory
920        are compiled or used.'''
921        if type(witness_c_macro) is bytes or type(witness_c_macro) is string:
922            if type(witness_c_macro) is bytes:
923                witness_c_macro = string(witness_c_macro, ENCS['system'])
924            if witness_c_macro:
925                self.table['witness_c_macro'] = witness_c_macro
926        else:  # if type of witness_c_macro is not bytes or string
927            raise(TypeError('witness_c_macro must be a string, not %s' %
928                            type(witness_c_macro).__name__))
929
930    def resetWitnessCMacro(self):
931        '''Return the C macro that is defined when the sources in this directory
932        are compiled or used.'''
933        self.table['witness_c_macro'] = string()
934
935    # Define vc_files methods.
936    def checkVCFiles(self):
937        '''Check if update of the version control files is enabled or disabled.'''
938        return(self.table['vc_files'])
939
940    def enableVCFiles(self):
941        '''Enable update of the version control files.'''
942        self.table['vc_files'] = True
943
944    def disableVCFiles(self):
945        '''Disable update of the version control files.'''
946        self.table['vc_files'] = False
947
948    def resetVCFiles(self):
949        '''Reset update of the version control files and set it to None.'''
950        self.table['vc_files'] = None
951
952    # Define modcache methods.
953    def checkModuleCaching(self):
954        '''Get status of module caching optimization.'''
955        return(self.table['modcache'])
956
957    def enableModuleCaching(self):
958        '''Enable module caching optimization.'''
959        self.table['modcache'] = True
960
961    def disableModuleCaching(self):
962        '''Disable module caching optimization.'''
963        self.table['modcache'] = False
964
965    def resetModuleCaching(self):
966        '''Reset module caching optimization.'''
967        self.table['modcache'] = False
968
969    # Define configure_ac methods.
970    def getAutoconfFile(self):
971        '''Return path of autoconf file relative to destdir.'''
972        return(self.table['configure_ac'])
973
974    def setAutoconfFile(self, configure_ac):
975        '''Specify path of autoconf file relative to destdir.'''
976        if type(configure_ac) is bytes or type(configure_ac) is string:
977            if type(configure_ac) is bytes:
978                configure_ac = string(configure_ac, ENCS['system'])
979            if configure_ac:
980                self.table['configure_ac'] = \
981                    relpath(self.table['destdir'], configure_ac)
982        else:  # if type of configure_ac is not bytes or string
983            raise(TypeError('configure_ac must be a string, not %s' %
984                            type(configure_ac).__name__))
985
986    def resetAutoconfFile(self):
987        '''Reset path of autoconf file relative to destdir.'''
988        configure_ac = string()
989        if isfile(joinpath(self.table['destdir'], 'configure.ac')):
990            configure_ac = joinpath(self.table['destdir'], 'configure.ac')
991        elif isfile(joinpath(self.table['destdir'], 'configure.in')):
992            configure_ac = joinpath(self.table['destdir'], 'configure.in')
993        self.table['configure_ac'] = configure_ac
994
995    # Define ac_version methods.
996    def getAutoconfVersion(self):
997        '''Return preferred autoconf version. Default value is 2.59.'''
998        return(self.table['ac_version'])
999
1000    def setAutoconfVersion(self, ac_version):
1001        '''Specify preferred autoconf version. Default value is 2.59.'''
1002        if type(ac_version) is float or type(ac_version) is int:
1003            self.table['ac_version'] = float(ac_version)
1004        else:  # if ac_version has not int or float type
1005            raise(TypeError('ac_version must be an int or a float, not %s' %
1006                            type(ac_version).__name__))
1007
1008    def resetAutoconfVersion(self):
1009        '''Specify preferred autoconf version. Default value is 2.59.'''
1010        self.table['ac_version'] = 2.59
1011
1012    # Define symbolic methods.
1013    def checkCopyrights(self):
1014        '''Check if copyright notices in files should be replaced.'''
1015        return(self.table['copyrights'])
1016
1017    def checkSymbolic(self):
1018        '''Check if pygnulib will make symbolic links instead of copying files.'''
1019        return(self.table['symbolic'])
1020
1021    def enableSymbolic(self):
1022        '''Enable creation of the symbolic links instead of copying files.'''
1023        self.table['symbolic'] = True
1024        self.table['copyrights'] = False
1025
1026    def disableSymbolic(self):
1027        '''Enable creation of the symbolic links instead of copying files.'''
1028        self.table['symbolic'] = False
1029        self.table['copyrights'] = True
1030
1031    def resetSymbolic(self):
1032        '''Reset creation of the symbolic links instead of copying files.'''
1033        self.table['symbolic'] = False
1034        self.table['copyrights'] = True
1035
1036    # Define lsymbolic methods.
1037    def checkLSymbolic(self):
1038        '''Check if pygnulib will make symbolic links instead of copying files, only
1039        for files from the local override directory.'''
1040        return(self.table['lsymbolic'])
1041
1042    def enableLSymbolic(self):
1043        '''Enable creation of symbolic links instead of copying files, only for
1044        files from the local override directory.'''
1045        self.table['lsymbolic'] = True
1046
1047    def disableLSymbolic(self):
1048        '''Disable creation of symbolic links instead of copying files, only for
1049        files from the local override directory.'''
1050        self.table['lsymbolic'] = False
1051
1052    def resetLSymbolic(self):
1053        '''Reset creation of symbolic links instead of copying files, only for
1054        files from the local override directory.'''
1055        self.table['lsymbolic'] = False
1056
1057    # Define verbosity methods.
1058    def getVerbosity(self):
1059        '''Get verbosity level.'''
1060        return(self.table['verbosity'])
1061
1062    def decreaseVerbosity(self):
1063        '''Decrease verbosity level.'''
1064        if self.table['verbosity'] > MODES['verbose-min']:
1065            self.table['verbosity'] -= 1
1066
1067    def increaseVerbosity(self):
1068        '''Increase verbosity level.'''
1069        if self.table['verbosity'] < MODES['verbose-max']:
1070            self.table['verbosity'] += 1
1071
1072    def setVerbosity(self, verbose):
1073        '''Set verbosity level to verbose, where -2 <= verbose <= 2.
1074        If verbosity level is less than -2, verbosity level will be set to -2.
1075        If verbosity level is greater than 2, verbosity level will be set to 2.'''
1076        if type(verbose) is int:
1077            if MODES['verbose-min'] <= verbose <= MODES['verbose-max']:
1078                self.table['verbosity'] = verbose
1079            elif verbose < MODES['verbose-min']:
1080                self.table['verbosity'] = MODES['verbose-min']
1081            elif verbose > MODES['verbose-max']:
1082                self.table['verbosity'] = MODES['verbose-max']
1083        else:  # if type(verbose) is not int
1084            raise(TypeError('verbosity must be an int, not %s' %
1085                            type(verbose).__name__))
1086
1087    def resetVerbosity(self):
1088        '''Reset verbosity level.'''
1089        self.table['verbosity'] = 0
1090
1091    # Define libtests methods.
1092    def checkLibtests(self):
1093        '''Return True if a testsbase/libtests.a is needed.'''
1094        return(self.table['libtests'])
1095
1096    def enableLibtests(self):
1097        '''If libtests is enabled, then testsbase/libtests.a is needed.'''
1098        self.table['libtests'] = True
1099
1100    def disableLibtests(self):
1101        '''If libtests is disabled, then testsbase/libtests.a is not needed.'''
1102        self.table['libtests'] = False
1103
1104    def resetLibtests(self):
1105        '''Reset status of testsbase/libtests.a.'''
1106        self.table['libtests'] = False
1107
1108    # Define single_configure methods.
1109    def checkSingleConfigure(self):
1110        '''Check whether single configure file should be generated.'''
1111        return(self.table['single_configure'])
1112
1113    def enableSingleConfigure(self):
1114        '''Enable generation of the single configure file.'''
1115        self.table['single_configure'] = True
1116
1117    def disableSingleConfigure(self):
1118        '''Disable generation of the single configure file.'''
1119        self.table['single_configure'] = False
1120
1121    def resetSingleConfigure(self):
1122        '''Reset status of the single configure file generation.'''
1123        self.table['single_configure'] = False
1124
1125    # Define dryrun methods.
1126    def checkDryRun(self):
1127        '''Check whether dryrun is enabled.'''
1128        return(self.table['dryrun'])
1129
1130    def enableDryRun(self):
1131        '''Enable dryrun mode.'''
1132        self.table['dryrun'] = True
1133
1134    def disableDryRun(self):
1135        '''Disable dryrun mode.'''
1136        self.table['dryrun'] = False
1137
1138    def resetDryRun(self):
1139        '''Reset status of dryrun mode.'''
1140        self.table['dryrun'] = False
1141
1142    # Define errors methods.
1143    def checkErrors(self):
1144        '''Check if GLError will be raised in non-critical situations.'''
1145        return(self.table['errors'])
1146
1147    def enableErrors(self):
1148        '''Raise GLError in non-critical situations.'''
1149        self.table['errors'] = True
1150
1151    def disableErrors(self):
1152        '''Do not raise GLError in non-critical situations.'''
1153        self.table['errors'] = False
1154
1155    def resetErrors(self):
1156        '''Reset status of raising GLError in non-critical situations.'''
1157        self.table['errors'] = False
1158