1#!/usr/bin/python3
2# Check is all errno definitions at errlist.h documented in the manual.
3# Copyright (C) 2020-2022 Free Software Foundation, Inc.
4# This file is part of the GNU C Library.
5#
6# The GNU C Library is free software; you can redistribute it and/or
7# modify it under the terms of the GNU Lesser General Public
8# License as published by the Free Software Foundation; either
9# version 2.1 of the License, or (at your option) any later version.
10#
11# The GNU C Library is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14# Lesser General Public License for more details.
15#
16# You should have received a copy of the GNU Lesser General Public
17# License along with the GNU C Library; if not, see
18# <https://www.gnu.org/licenses/>.
19
20import argparse
21import sys
22import re
23
24RE_MANUAL = re.compile(
25    r'(?:^@errno){(\w+)')
26
27RE_ERRLIST = re.compile(
28    r'\(E[a-zA-Z0-9]+\)')
29
30PASS=0
31FAIL=1
32
33# Each manual entry is in the form:
34#
35#  errno{EAGAIN, 35, Resource temporarily unavailable}
36def parse_manual(f):
37    errlist = [RE_MANUAL.findall(s) for s in f]
38    return map(lambda x : x[0], filter(None, errlist))
39
40# Each errlist entry is in the form:
41#
42#  _S(ERR_MAP(EAGAIN), N_("Resource temporarily unavailable"))
43def parse_errlist(f):
44    errlist = [RE_ERRLIST.findall(s) for s in f]
45    # Each element is '[]' or '['(EAGAIN)']'
46    return map(lambda s : s[0][s[0].find('(')+1:s[0].find(')')],
47               filter(None, errlist))
48
49def check_errno_definitions(manual_fname, errlist_fname):
50    with open(manual_fname, 'r') as mfile, open(errlist_fname, 'r') as efile:
51        merr = parse_manual(mfile)
52        eerr = parse_errlist(efile)
53        diff = set(eerr).difference(merr)
54        if not diff:
55            sys.exit(PASS)
56        else:
57            print("Failure: the following value(s) are not in manual:",
58                  ", ".join(str(e) for e in diff))
59            sys.exit(FAIL)
60
61def main():
62    parser = argparse.ArgumentParser(description='Generate errlist.h')
63    parser.add_argument('-m', dest='manual', metavar='FILE',
64                        help='manual errno texi file')
65    parser.add_argument('-e', dest='errlist', metavar='FILE',
66                        help='errlist with errno definitions')
67    args = parser.parse_args()
68
69    check_errno_definitions(args.manual, args.errlist)
70
71
72if __name__ == '__main__':
73    main()
74