pthread-cond: Fix compilation error on native Windows.
[gnulib.git] / pygnulib / GLMakefileTable.py
blobefd276d20cf4ed0438fb11f53b66e6578a6390be
1 # Copyright (C) 2002-2024 Free Software Foundation, Inc.
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation, either version 3 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <https://www.gnu.org/licenses/>.
16 from __future__ import annotations
18 #===============================================================================
19 # Define global imports
20 #===============================================================================
21 import os
22 from .constants import joinpath
23 from .GLConfig import GLConfig
25 #===============================================================================
26 # Define GLMakefileTable class
27 #===============================================================================
28 class GLMakefileTable:
29 '''This class is used to edit Makefile and store edits as table.
30 When user creates Makefile.am, he may need to use this class.
31 The internal representation consists of a list of edits.
32 Each edit is a dictionary with keys 'dir', 'var', 'val', 'dotfirst'.
33 An edit may be removed; this is done by removing its 'var' key but
34 keeping it in the list. Removed edits must be ignored.'''
36 config: GLConfig
37 table: list[dict[str, str | bool]]
39 def __init__(self, config: GLConfig) -> None:
40 '''Create GLMakefileTable instance.'''
41 if type(config) is not GLConfig:
42 raise TypeError('config must be a GLConfig, not %s'
43 % type(config).__name__)
44 self.config = config
45 self.table = []
47 def __getitem__(self, y: int) -> dict[str, str | bool]:
48 '''x.__getitem__(y) = x[y]'''
49 if type(y) is not int:
50 raise TypeError('indices must be integers, not %s'
51 % type(y).__name__)
52 result = self.table[y]
53 # Do *not* clone the result here. We want GLEmiter to be able to make
54 # side effects on the result.
55 return result
57 def editor(self, dir: str, var: str, val: str, dotfirst: bool = False) -> None:
58 '''This method is used to remember that ${dir}Makefile.am needs to be edited
59 to that ${var} mentions ${val}.
60 If ${dotfirst} is non-empty, this mention needs to be present after '.'.
61 This is a special hack for the SUBDIRS variable, cf.
62 <https://www.gnu.org/software/automake/manual/html_node/Subdirectories.html>.'''
63 if type(dir) is not str:
64 raise TypeError('dir must be a string, not %s' % (type(dir).__name__))
65 if type(var) is not str:
66 raise TypeError('var must be a string, not %s' % (type(var).__name__))
67 if type(val) is not str:
68 raise TypeError('val must be a string, not %s' % (type(val).__name__))
69 if type(dotfirst) is not bool:
70 raise TypeError('dotfirst must be a bool, not %s' % (type(dotfirst).__name__))
71 dictionary = {'dir': dir, 'var': var, 'val': val, 'dotfirst': dotfirst}
72 self.table.append(dictionary)
74 def parent(self, gentests: bool, source_makefile_am: str, tests_makefile_am: str) -> None:
75 '''Add a special row to Makefile.am table with the first parent directory
76 which contains or will contain Makefile.am file.
77 GLConfig: sourcebase, m4base, testsbase, incl_test_categories,
78 excl_test_categories, makefile_name.
79 gentests is a bool that is True if any files are to be placed in $testsbase.
80 source_makefile_am is the name of the source Makefile.am.
81 tests_makefile_am is the name of the tests Makefile.am.'''
82 if type(gentests) is not bool:
83 raise TypeError('gentests must be a bool, not %s' % (type(gentests).__name__))
84 if type(source_makefile_am) is not str:
85 raise TypeError('source_makefile_am must be a str, not %s' % (type(source_makefile_am).__name__))
86 if type(tests_makefile_am) is not str:
87 raise TypeError('tests_makefile_am must be a str, not %s' % (type(tests_makefile_am).__name__))
88 m4base = self.config['m4base']
89 sourcebase = self.config['sourcebase']
90 testsbase = self.config['testsbase']
91 dir1 = '%s%s' % (m4base, os.path.sep)
92 dir2 = ''
93 while (dir1
94 and not (os.path.isfile(joinpath(self.config['destdir'], dir1, 'Makefile.am'))
95 or joinpath(dir1, 'Makefile.am') == joinpath(sourcebase, source_makefile_am)
96 or (gentests and joinpath(dir1, 'Makefile.am') == joinpath(testsbase, tests_makefile_am)))):
97 dir2 = joinpath(os.path.basename(dir1), dir2)
98 dir1 = os.path.dirname(dir1)
99 self.editor(dir1, 'EXTRA_DIST', joinpath(dir2, 'gnulib-cache.m4'))
101 def count(self) -> int:
102 '''Count number of edits which are stored, including the removed ones.'''
103 return len(self.table)