1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# Copyright (c) 2023 Huawei Device Co., Ltd.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16'''
17注意:
181. 扩展syscap头文件的枚举定义,须在开始位置标记最小值,且必须大于等于500。
19'''
20import argparse
21import os
22
23LICENCE = '''/*
24 * Copyright (c) 2023 Huawei Device Co., Ltd.
25 * Licensed under the Apache License, Version 2.0 (the "License");
26 * you may not use this file except in compliance with the License.
27 * You may obtain a copy of the License at
28 *
29 *     http://www.apache.org/licenses/LICENSE-2.0
30 *
31 * Unless required by applicable law or agreed to in writing, software
32 * distributed under the License is distributed on an "AS IS" BASIS,
33 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34 * See the License for the specific language governing permissions and
35 * limitations under the License.
36 */
37
38'''
39
40BEFORE_ENUM = '''#ifndef SYSCAP_DEFINE_H
41#define SYSCAP_DEFINE_H
42
43#include <stdint.h>
44
45#define SINGLE_SYSCAP_LEN (256 + 17)
46#ifdef __cplusplus
47#if __cplusplus
48extern "C" {
49#endif /* __cplusplus */
50#endif /* __cplusplus */
51
52typedef struct SystemCapabilityWithNum {
53    char str[SINGLE_SYSCAP_LEN];
54    uint16_t num;
55} SyscapWithNum;
56
57/*
58 * New SyscapNum must be added last and
59 * don't delete anyone, just comment after it.
60 */
61'''
62
63AFTER_STRUCT = '''
64#ifdef __cplusplus
65#if __cplusplus
66}
67#endif /* __cplusplus */
68#endif /* __cplusplus */
69#endif  // SYSCAP_DEFINE_H
70'''
71
72
73def gen_define_enum(enum:list):
74    header = 'typedef enum SystemCapabilityNum {\n'
75    tail = '} SyscapNum;\n\n'
76    trunk = ''.join(enum)
77    return header + trunk + tail
78
79
80def gen_define_array(stru:list):
81    header = 'const static SyscapWithNum g_arraySyscap[] = {\n'
82    tail = '};\n\n'
83    trunk = ''.join(stru)
84    return header + trunk + tail
85
86
87def read_syscap(path):
88    syscap_enum = []
89    op_flag = False
90    with open(path, 'r') as fb:
91        f = fb.readlines()
92    for line in f:
93        if line.startswith('typedef enum '):
94            op_flag = True
95            continue
96        elif op_flag and line.startswith('}'):
97            break
98        if op_flag:
99            syscap_enum.append(line)
100
101    syscap_stru = []
102    op_flag = False
103    for line in f:
104        if line.startswith('const static SyscapWithNum '):
105            op_flag = True
106            continue
107        elif op_flag and line.startswith('}'):
108            op_flag = False
109            break
110        if op_flag:
111            syscap_stru.append(line)
112
113    return syscap_enum, syscap_stru
114
115
116def merge_define(base, extern):
117    base_enmu, base_stru = read_syscap(base)
118    ext_enmu, ext_stru = read_syscap(extern)
119
120    if '500' in base_enmu[-1] and '500,' in ext_enmu[0]:
121        res_enmu = base_enmu[:-1] + ext_enmu
122    else:
123        res_enmu = base_enmu + ext_enmu
124
125    res_stru = base_stru + ext_stru
126    return res_enmu, res_stru
127
128
129def assemble_header_file(fenum, fstru):
130    enum, stru = merge_define(fenum, fstru)
131    enum_def = gen_define_enum(enum)
132    stru_def = gen_define_array(stru)
133    return LICENCE + BEFORE_ENUM + enum_def + stru_def + AFTER_STRUCT
134
135
136def parse_args():
137    parser = argparse.ArgumentParser()
138    parser.add_argument('--base',
139                        help='base syscap config header.')
140    parser.add_argument('--extern',
141                        help='extern syscap config header.')
142    parser.add_argument('--output',
143                        help='output app file')
144    arguments = parser.parse_args()
145    return arguments
146
147
148if __name__ == '__main__':
149    args = parse_args()
150    base_file = args.base
151    extern_file = args.extern
152    output_file = args.output
153
154    full = assemble_header_file(base_file, extern_file)
155    with os.fdopen(os.open(output_file, os.O_WRONLY | os.O_CREAT, mode=0o640), 'w') as out:
156        out.writelines(full)
157
158