1#!/usr/bin/env python3
2# coding=utf-8
3# Transfer kconfig configuration file to buildef/config file.
4# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved.
5
6import os
7import sys
8import time
9import getopt
10import re
11import logging
12import codecs
13
14
15logging.basicConfig(level=logging.NOTSET)
16
17HEADER_TYPE_BUILD = 0
18HEADER_TYPE_CONFIG = 1
19HEADER_TYPE_INVALID = 2
20
21def cmd_help():
22    logging.info("Interpret the configuration file which was generated by Kconfig tool, and")
23    logging.info("Transfer it to header file which will be used in C code")
24    logging.info("Command format:")
25    logging.info("   Kconfig2macro.py [-e][-f configFileName] [-o headerFileName]")
26    logging.info("The default configFileName is .config")
27    logging.info("The default headerFileName is config.h")
28
29def headerType(in_file):
30    with open(in_file, 'r') as fd_in:
31        lines = fd_in.readlines()
32        for line in lines:
33
34            if line.find("CONFIG_OS_HARDWARE_PLATFORM=") >= 0:
35                return HEADER_TYPE_BUILD
36    return HEADER_TYPE_CONFIG
37
38
39def write_header(out_file):
40    with codecs.open(out_file,
41                     'w',
42                     encoding='gbk',
43                     errors='ignore') as fd_out:
44        file_path, file_name = os.path.split(out_file)
45        name = ((str(file_name)).split('.'))[0]
46        header_macro = '%s_H' % (str.upper(name))
47        text = r'''/*
48 * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
49 *
50 * UniProton is licensed under Mulan PSL v2.
51 * You can use this software according to the terms and conditions of the Mulan PSL v2.
52 * You may obtain a copy of Mulan PSL v2 at:
53 *          http://license.coscl.org.cn/MulanPSL2
54 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
55 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
56 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
57 * See the Mulan PSL v2 for more details.
58 * Create: 2009-12-22
59 * Description: the common part buildef.h
60 */
61'''
62
63        text = '%s#ifndef %s\n' % (text, header_macro)
64        text = '%s#define %s\n' % (text, header_macro)
65        text = '%s\n' % (text)
66        text = '%s#ifdef __cplusplus\n#if __cplusplus\nextern "C" {\n#endif\n#endif\n' % (text)
67
68        fd_out.write(text)
69    return 0
70
71
72def get_macro_fix(macro):
73    prefix = ""
74    suffix = "\n"
75    if macro == "OS_HARDWARE_PLATFORM" or macro == "OS_CPU_TYPE" or macro == "OS_BYTE_ORDER":
76        prefix = '#ifndef %s\n' % (macro)
77        suffix = "#endif\n\n"
78
79    return prefix, suffix
80
81def write_macro(fd_out, line, flag):
82    export_flag = False
83    match_s = re.search(r'\w+', line)
84    if match_s is None:
85        return
86
87    macro = match_s.group()
88    if not macro.startswith("CONFIG_"):
89        return
90
91    macro = macro[len("CONFIG_"):]
92    if macro.startswith("INTERNAL_"):
93        return
94
95    if macro.startswith("EXPORT_"):
96        macro = macro[len("EXPORT_"):]
97        export_flag = flag
98
99    if line.find("is not set") >= 0:
100        value = "NO"
101    else:
102        expression = line.split("=", 1)
103        if len(expression) < 2:
104            return
105        value = expression[1].strip()
106        if value == 'y':
107            value = ""
108    prefix, suffix = get_macro_fix(macro)
109    text = '%s#define %s %s\n%s' %(prefix ,macro, value.strip('"'), suffix)
110    if export_flag == True or flag == False:
111        fd_out.write(text.rstrip() + "\n\n")
112def write_config(in_file, out_file, flag):
113    with codecs.open(out_file, 'a+') as fd_out, open(in_file) as fd_in:
114        fd_out.write("\n")
115        lines = fd_in.readlines()
116        for line in lines:
117            if line.startswith('##'):
118                fd_out(line.replace("##", "/*") + "*/")
119            elif line.startswith("CONFIG_"):
120                write_macro(fd_out, line, flag)
121
122    return 0
123
124def write_def_config(filename, string):
125    with open(filename, 'r', errors='ignore') as fp:
126        for line in fp:
127            if string in line:
128                return line
129
130    with codecs.open(file, 'a+') as fd_in:
131        text = '#define %-35s NO \n\n' %(str)
132
133        fd_in.write(text)
134
135    return 0
136
137def write_external_macro(out_file):
138    with codecs.open(out_file, 'a+') as fd_out:
139
140        text = '#define OS_LITTLE_ENDIAN 0x1234\n\n#define OS_BIG_ENDIAN 0x4321\n\n#define OS_CORTEX_M4 0x1\n\n#define OS_STM32F407 0x1\n\n'
141
142        fd_out.write(text)
143
144    return 0
145
146def write_c_external_tail(out_file):
147    with codecs.open(out_file, 'a+') as fd_out:
148
149
150        text = '#ifdef __cplusplus\n#if __cplusplus\n}\n#endif\n#endif\n'
151
152        fd_out.write(text)
153
154    return 0
155
156def write_tail(out_file):
157    with codecs.open(out_file, 'a+') as fd_out:
158
159        text = '\n#endif\n'
160
161        fd_out.write(text)
162
163    return 0
164
165def kconfig2macro(in_file, out_file, flag):
166    header_type = headerType(in_file)
167    if header_type == HEADER_TYPE_INVALID:
168        return -10
169
170    ret = write_header(out_file)
171    if ret != 0:
172        return ret
173
174    ret = write_config(in_file, out_file, flag)
175    if ret != 0:
176        return ret
177
178    ret = write_external_macro(out_file)
179    if ret != 0:
180        return ret
181
182    ret = write_c_external_tail(out_file)
183    if ret != 0:
184        return ret
185
186    ret = write_tail(out_file)
187    if ret != 0:
188        return ret
189
190    return 0
191def do_cmd(argv, flag):
192    in_file = ".config"
193    out_file = "config.h"
194
195    try:
196        opts, args = getopt.getopt(argv,"ehf:o:",["help", "inFile=", "outFile="])
197    except getopt.GetoptError:
198        cmd_help()
199        return -1
200
201    if len(args) > 0:
202        cmd_help()
203        return -2
204
205    for opt, arg in opts:
206        if opt in ('-h', '--help'):
207            cmd_help()
208            return 0
209        elif opt in ('-e'):
210            flag = True
211        elif opt in ('-f', '--inFile'):
212            in_file = arg
213        elif opt in ('-o', '--outFile'):
214            out_file = arg
215        else:
216            logging.error("ERROR: Invalid Input %s", opt)
217            cmd_help()
218            return -3
219
220    if os.path.exists(in_file) == False:
221        logging.info("config input file <%s> doesn't exist", in_file)
222        return -4
223
224    return kconfig2macro(in_file, out_file, flag)
225
226
227if __name__ == "__main__":
228    res = do_cmd(sys.argv[1:], False)
229    sys.exit(res)
230