1#!/usr/bin/env python3
2#
3# Copyright (c) 2022 Meta
4#
5# SPDX-License-Identifier: Apache-2.0
6
7import argparse
8import os
9import re
10
11
12def front_matter(sys_nerr):
13    return f'''
14/*
15 * This file generated by {__file__}
16 */
17
18#include <errno.h>
19#include <stdint.h>
20#include <string.h>
21
22#include <zephyr/sys/util.h>
23
24#define sys_nerr {sys_nerr}'''
25
26
27def gen_strerror_table(input, output):
28    with open(input, 'r') as inf:
29
30        highest_errno = 0
31        symbols = []
32        msgs = {}
33
34        for line in inf.readlines():
35            # Select items of the form below (note: ERRNO is numeric)
36            # #define SYMBOL ERRNO /**< MSG */
37            pat = r'^#define[\s]+(E[A-Z_]*)[\s]+([1-9][0-9]*)[\s]+/\*\*<[\s]+(.*)[\s]+\*/[\s]*$'
38            match = re.match(pat, line)
39
40            if not match:
41                continue
42
43            symbol = match[1]
44            errno = int(match[2])
45            msg = match[3]
46
47            symbols.append(symbol)
48            msgs[symbol] = msg
49
50            highest_errno = max(int(errno), highest_errno)
51
52        try:
53            os.makedirs(os.path.dirname(output))
54        except BaseException:
55            # directory already present
56            pass
57
58        with open(output, 'w') as outf:
59
60            print(front_matter(highest_errno + 1), file=outf)
61
62            # Generate string table
63            print(
64                f'static const char *const sys_errlist[sys_nerr] = {{', file=outf)
65            print('[0] = "Success",', file=outf)
66            for symbol in symbols:
67                print(f'[{symbol}] = "{msgs[symbol]}",', file=outf)
68
69            print('};', file=outf)
70
71            # Generate string lengths (includes trailing '\0')
72            print(
73                f'static const uint8_t sys_errlen[sys_nerr] = {{', file=outf)
74            print('[0] = 8,', file=outf)
75            for symbol in symbols:
76                print(f'[{symbol}] = {len(msgs[symbol]) + 1},', file=outf)
77
78            print('};', file=outf)
79
80
81def parse_args():
82    parser = argparse.ArgumentParser(allow_abbrev=False)
83    parser.add_argument(
84        '-i',
85        '--input',
86        dest='input',
87        required=True,
88        help='input file (e.g. lib/libc/minimal/include/errno.h)')
89    parser.add_argument(
90        '-o',
91        '--output',
92        dest='output',
93        required=True,
94        help='output file (e.g. build/zephyr/misc/generated/libc/minimal/strerror_table.h)')
95
96    args = parser.parse_args()
97
98    return args
99
100
101def main():
102    args = parse_args()
103    gen_strerror_table(args.input, args.output)
104
105
106if __name__ == '__main__':
107    main()
108