1a8e1175bSopenharmony_ci#!/usr/bin/env python3 2a8e1175bSopenharmony_ci 3a8e1175bSopenharmony_ci"""Generate library/ssl_debug_helpers_generated.c 4a8e1175bSopenharmony_ci 5a8e1175bSopenharmony_ciThe code generated by this module includes debug helper functions that can not be 6a8e1175bSopenharmony_ciimplemented by fixed codes. 7a8e1175bSopenharmony_ci 8a8e1175bSopenharmony_ci""" 9a8e1175bSopenharmony_ci 10a8e1175bSopenharmony_ci# Copyright The Mbed TLS Contributors 11a8e1175bSopenharmony_ci# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 12a8e1175bSopenharmony_ciimport sys 13a8e1175bSopenharmony_ciimport re 14a8e1175bSopenharmony_ciimport os 15a8e1175bSopenharmony_ciimport textwrap 16a8e1175bSopenharmony_ciimport argparse 17a8e1175bSopenharmony_cifrom mbedtls_dev import build_tree 18a8e1175bSopenharmony_ci 19a8e1175bSopenharmony_ci 20a8e1175bSopenharmony_cidef remove_c_comments(string): 21a8e1175bSopenharmony_ci """ 22a8e1175bSopenharmony_ci Remove C style comments from input string 23a8e1175bSopenharmony_ci """ 24a8e1175bSopenharmony_ci string_pattern = r"(?P<string>\".*?\"|\'.*?\')" 25a8e1175bSopenharmony_ci comment_pattern = r"(?P<comment>/\*.*?\*/|//[^\r\n]*$)" 26a8e1175bSopenharmony_ci pattern = re.compile(string_pattern + r'|' + comment_pattern, 27a8e1175bSopenharmony_ci re.MULTILINE | re.DOTALL) 28a8e1175bSopenharmony_ci 29a8e1175bSopenharmony_ci def replacer(match): 30a8e1175bSopenharmony_ci if match.lastgroup == 'comment': 31a8e1175bSopenharmony_ci return "" 32a8e1175bSopenharmony_ci return match.group() 33a8e1175bSopenharmony_ci return pattern.sub(replacer, string) 34a8e1175bSopenharmony_ci 35a8e1175bSopenharmony_ci 36a8e1175bSopenharmony_ciclass CondDirectiveNotMatch(Exception): 37a8e1175bSopenharmony_ci pass 38a8e1175bSopenharmony_ci 39a8e1175bSopenharmony_ci 40a8e1175bSopenharmony_cidef preprocess_c_source_code(source, *classes): 41a8e1175bSopenharmony_ci """ 42a8e1175bSopenharmony_ci Simple preprocessor for C source code. 43a8e1175bSopenharmony_ci 44a8e1175bSopenharmony_ci Only processes condition directives without expanding them. 45a8e1175bSopenharmony_ci Yield object according to the classes input. Most match firstly 46a8e1175bSopenharmony_ci 47a8e1175bSopenharmony_ci If the directive pair does not match , raise CondDirectiveNotMatch. 48a8e1175bSopenharmony_ci 49a8e1175bSopenharmony_ci Assume source code does not include comments and compile pass. 50a8e1175bSopenharmony_ci 51a8e1175bSopenharmony_ci """ 52a8e1175bSopenharmony_ci 53a8e1175bSopenharmony_ci pattern = re.compile(r"^[ \t]*#[ \t]*" + 54a8e1175bSopenharmony_ci r"(?P<directive>(if[ \t]|ifndef[ \t]|ifdef[ \t]|else|endif))" + 55a8e1175bSopenharmony_ci r"[ \t]*(?P<param>(.*\\\n)*.*$)", 56a8e1175bSopenharmony_ci re.MULTILINE) 57a8e1175bSopenharmony_ci stack = [] 58a8e1175bSopenharmony_ci 59a8e1175bSopenharmony_ci def _yield_objects(s, d, p, st, end): 60a8e1175bSopenharmony_ci """ 61a8e1175bSopenharmony_ci Output matched source piece 62a8e1175bSopenharmony_ci """ 63a8e1175bSopenharmony_ci nonlocal stack 64a8e1175bSopenharmony_ci start_line, end_line = '', '' 65a8e1175bSopenharmony_ci if stack: 66a8e1175bSopenharmony_ci start_line = '#{} {}'.format(d, p) 67a8e1175bSopenharmony_ci if d == 'if': 68a8e1175bSopenharmony_ci end_line = '#endif /* {} */'.format(p) 69a8e1175bSopenharmony_ci elif d == 'ifdef': 70a8e1175bSopenharmony_ci end_line = '#endif /* defined({}) */'.format(p) 71a8e1175bSopenharmony_ci else: 72a8e1175bSopenharmony_ci end_line = '#endif /* !defined({}) */'.format(p) 73a8e1175bSopenharmony_ci has_instance = False 74a8e1175bSopenharmony_ci for cls in classes: 75a8e1175bSopenharmony_ci for instance in cls.extract(s, st, end): 76a8e1175bSopenharmony_ci if has_instance is False: 77a8e1175bSopenharmony_ci has_instance = True 78a8e1175bSopenharmony_ci yield pair_start, start_line 79a8e1175bSopenharmony_ci yield instance.span()[0], instance 80a8e1175bSopenharmony_ci if has_instance: 81a8e1175bSopenharmony_ci yield start, end_line 82a8e1175bSopenharmony_ci 83a8e1175bSopenharmony_ci for match in pattern.finditer(source): 84a8e1175bSopenharmony_ci 85a8e1175bSopenharmony_ci directive = match.groupdict()['directive'].strip() 86a8e1175bSopenharmony_ci param = match.groupdict()['param'] 87a8e1175bSopenharmony_ci start, end = match.span() 88a8e1175bSopenharmony_ci 89a8e1175bSopenharmony_ci if directive in ('if', 'ifndef', 'ifdef'): 90a8e1175bSopenharmony_ci stack.append((directive, param, start, end)) 91a8e1175bSopenharmony_ci continue 92a8e1175bSopenharmony_ci 93a8e1175bSopenharmony_ci if not stack: 94a8e1175bSopenharmony_ci raise CondDirectiveNotMatch() 95a8e1175bSopenharmony_ci 96a8e1175bSopenharmony_ci pair_directive, pair_param, pair_start, pair_end = stack.pop() 97a8e1175bSopenharmony_ci yield from _yield_objects(source, 98a8e1175bSopenharmony_ci pair_directive, 99a8e1175bSopenharmony_ci pair_param, 100a8e1175bSopenharmony_ci pair_end, 101a8e1175bSopenharmony_ci start) 102a8e1175bSopenharmony_ci 103a8e1175bSopenharmony_ci if directive == 'endif': 104a8e1175bSopenharmony_ci continue 105a8e1175bSopenharmony_ci 106a8e1175bSopenharmony_ci if pair_directive == 'if': 107a8e1175bSopenharmony_ci directive = 'if' 108a8e1175bSopenharmony_ci param = "!( {} )".format(pair_param) 109a8e1175bSopenharmony_ci elif pair_directive == 'ifdef': 110a8e1175bSopenharmony_ci directive = 'ifndef' 111a8e1175bSopenharmony_ci param = pair_param 112a8e1175bSopenharmony_ci else: 113a8e1175bSopenharmony_ci directive = 'ifdef' 114a8e1175bSopenharmony_ci param = pair_param 115a8e1175bSopenharmony_ci 116a8e1175bSopenharmony_ci stack.append((directive, param, start, end)) 117a8e1175bSopenharmony_ci assert not stack, len(stack) 118a8e1175bSopenharmony_ci 119a8e1175bSopenharmony_ci 120a8e1175bSopenharmony_ciclass EnumDefinition: 121a8e1175bSopenharmony_ci """ 122a8e1175bSopenharmony_ci Generate helper functions around enumeration. 123a8e1175bSopenharmony_ci 124a8e1175bSopenharmony_ci Currently, it generate translation function from enum value to string. 125a8e1175bSopenharmony_ci Enum definition looks like: 126a8e1175bSopenharmony_ci [typedef] enum [prefix name] { [body] } [suffix name]; 127a8e1175bSopenharmony_ci 128a8e1175bSopenharmony_ci Known limitation: 129a8e1175bSopenharmony_ci - the '}' and ';' SHOULD NOT exist in different macro blocks. Like 130a8e1175bSopenharmony_ci ``` 131a8e1175bSopenharmony_ci enum test { 132a8e1175bSopenharmony_ci .... 133a8e1175bSopenharmony_ci #if defined(A) 134a8e1175bSopenharmony_ci .... 135a8e1175bSopenharmony_ci }; 136a8e1175bSopenharmony_ci #else 137a8e1175bSopenharmony_ci .... 138a8e1175bSopenharmony_ci }; 139a8e1175bSopenharmony_ci #endif 140a8e1175bSopenharmony_ci ``` 141a8e1175bSopenharmony_ci """ 142a8e1175bSopenharmony_ci 143a8e1175bSopenharmony_ci @classmethod 144a8e1175bSopenharmony_ci def extract(cls, source_code, start=0, end=-1): 145a8e1175bSopenharmony_ci enum_pattern = re.compile(r'enum\s*(?P<prefix_name>\w*)\s*' + 146a8e1175bSopenharmony_ci r'{\s*(?P<body>[^}]*)}' + 147a8e1175bSopenharmony_ci r'\s*(?P<suffix_name>\w*)\s*;', 148a8e1175bSopenharmony_ci re.MULTILINE | re.DOTALL) 149a8e1175bSopenharmony_ci 150a8e1175bSopenharmony_ci for match in enum_pattern.finditer(source_code, start, end): 151a8e1175bSopenharmony_ci yield EnumDefinition(source_code, 152a8e1175bSopenharmony_ci span=match.span(), 153a8e1175bSopenharmony_ci group=match.groupdict()) 154a8e1175bSopenharmony_ci 155a8e1175bSopenharmony_ci def __init__(self, source_code, span=None, group=None): 156a8e1175bSopenharmony_ci assert isinstance(group, dict) 157a8e1175bSopenharmony_ci prefix_name = group.get('prefix_name', None) 158a8e1175bSopenharmony_ci suffix_name = group.get('suffix_name', None) 159a8e1175bSopenharmony_ci body = group.get('body', None) 160a8e1175bSopenharmony_ci assert prefix_name or suffix_name 161a8e1175bSopenharmony_ci assert body 162a8e1175bSopenharmony_ci assert span 163a8e1175bSopenharmony_ci # If suffix_name exists, it is a typedef 164a8e1175bSopenharmony_ci self._prototype = suffix_name if suffix_name else 'enum ' + prefix_name 165a8e1175bSopenharmony_ci self._name = suffix_name if suffix_name else prefix_name 166a8e1175bSopenharmony_ci self._body = body 167a8e1175bSopenharmony_ci self._source = source_code 168a8e1175bSopenharmony_ci self._span = span 169a8e1175bSopenharmony_ci 170a8e1175bSopenharmony_ci def __repr__(self): 171a8e1175bSopenharmony_ci return 'Enum({},{})'.format(self._name, self._span) 172a8e1175bSopenharmony_ci 173a8e1175bSopenharmony_ci def __str__(self): 174a8e1175bSopenharmony_ci return repr(self) 175a8e1175bSopenharmony_ci 176a8e1175bSopenharmony_ci def span(self): 177a8e1175bSopenharmony_ci return self._span 178a8e1175bSopenharmony_ci 179a8e1175bSopenharmony_ci def generate_translation_function(self): 180a8e1175bSopenharmony_ci """ 181a8e1175bSopenharmony_ci Generate function for translating value to string 182a8e1175bSopenharmony_ci """ 183a8e1175bSopenharmony_ci translation_table = [] 184a8e1175bSopenharmony_ci 185a8e1175bSopenharmony_ci for line in self._body.splitlines(): 186a8e1175bSopenharmony_ci 187a8e1175bSopenharmony_ci if line.strip().startswith('#'): 188a8e1175bSopenharmony_ci # Preprocess directive, keep it in table 189a8e1175bSopenharmony_ci translation_table.append(line.strip()) 190a8e1175bSopenharmony_ci continue 191a8e1175bSopenharmony_ci 192a8e1175bSopenharmony_ci if not line.strip(): 193a8e1175bSopenharmony_ci continue 194a8e1175bSopenharmony_ci 195a8e1175bSopenharmony_ci for field in line.strip().split(','): 196a8e1175bSopenharmony_ci if not field.strip(): 197a8e1175bSopenharmony_ci continue 198a8e1175bSopenharmony_ci member = field.strip().split()[0] 199a8e1175bSopenharmony_ci translation_table.append( 200a8e1175bSopenharmony_ci '{space}case {member}:\n{space} return "{member}";' 201a8e1175bSopenharmony_ci .format(member=member, space=' '*8) 202a8e1175bSopenharmony_ci ) 203a8e1175bSopenharmony_ci 204a8e1175bSopenharmony_ci body = textwrap.dedent('''\ 205a8e1175bSopenharmony_ci const char *{name}_str( {prototype} in ) 206a8e1175bSopenharmony_ci {{ 207a8e1175bSopenharmony_ci switch (in) {{ 208a8e1175bSopenharmony_ci {translation_table} 209a8e1175bSopenharmony_ci default: 210a8e1175bSopenharmony_ci return "UNKNOWN_VALUE"; 211a8e1175bSopenharmony_ci }} 212a8e1175bSopenharmony_ci }} 213a8e1175bSopenharmony_ci ''') 214a8e1175bSopenharmony_ci body = body.format(translation_table='\n'.join(translation_table), 215a8e1175bSopenharmony_ci name=self._name, 216a8e1175bSopenharmony_ci prototype=self._prototype) 217a8e1175bSopenharmony_ci return body 218a8e1175bSopenharmony_ci 219a8e1175bSopenharmony_ci 220a8e1175bSopenharmony_ciclass SignatureAlgorithmDefinition: 221a8e1175bSopenharmony_ci """ 222a8e1175bSopenharmony_ci Generate helper functions for signature algorithms. 223a8e1175bSopenharmony_ci 224a8e1175bSopenharmony_ci It generates translation function from signature algorithm define to string. 225a8e1175bSopenharmony_ci Signature algorithm definition looks like: 226a8e1175bSopenharmony_ci #define MBEDTLS_TLS1_3_SIG_[ upper case signature algorithm ] [ value(hex) ] 227a8e1175bSopenharmony_ci 228a8e1175bSopenharmony_ci Known limitation: 229a8e1175bSopenharmony_ci - the definitions SHOULD exist in same macro blocks. 230a8e1175bSopenharmony_ci """ 231a8e1175bSopenharmony_ci 232a8e1175bSopenharmony_ci @classmethod 233a8e1175bSopenharmony_ci def extract(cls, source_code, start=0, end=-1): 234a8e1175bSopenharmony_ci sig_alg_pattern = re.compile(r'#define\s+(?P<name>MBEDTLS_TLS1_3_SIG_\w+)\s+' + 235a8e1175bSopenharmony_ci r'(?P<value>0[xX][0-9a-fA-F]+)$', 236a8e1175bSopenharmony_ci re.MULTILINE | re.DOTALL) 237a8e1175bSopenharmony_ci matches = list(sig_alg_pattern.finditer(source_code, start, end)) 238a8e1175bSopenharmony_ci if matches: 239a8e1175bSopenharmony_ci yield SignatureAlgorithmDefinition(source_code, definitions=matches) 240a8e1175bSopenharmony_ci 241a8e1175bSopenharmony_ci def __init__(self, source_code, definitions=None): 242a8e1175bSopenharmony_ci if definitions is None: 243a8e1175bSopenharmony_ci definitions = [] 244a8e1175bSopenharmony_ci assert isinstance(definitions, list) and definitions 245a8e1175bSopenharmony_ci self._definitions = definitions 246a8e1175bSopenharmony_ci self._source = source_code 247a8e1175bSopenharmony_ci 248a8e1175bSopenharmony_ci def __repr__(self): 249a8e1175bSopenharmony_ci return 'SigAlgs({})'.format(self._definitions[0].span()) 250a8e1175bSopenharmony_ci 251a8e1175bSopenharmony_ci def span(self): 252a8e1175bSopenharmony_ci return self._definitions[0].span() 253a8e1175bSopenharmony_ci 254a8e1175bSopenharmony_ci def __str__(self): 255a8e1175bSopenharmony_ci """ 256a8e1175bSopenharmony_ci Generate function for translating value to string 257a8e1175bSopenharmony_ci """ 258a8e1175bSopenharmony_ci translation_table = [] 259a8e1175bSopenharmony_ci for m in self._definitions: 260a8e1175bSopenharmony_ci name = m.groupdict()['name'] 261a8e1175bSopenharmony_ci return_val = name[len('MBEDTLS_TLS1_3_SIG_'):].lower() 262a8e1175bSopenharmony_ci translation_table.append( 263a8e1175bSopenharmony_ci ' case {}:\n return "{}";'.format(name, return_val)) 264a8e1175bSopenharmony_ci 265a8e1175bSopenharmony_ci body = textwrap.dedent('''\ 266a8e1175bSopenharmony_ci const char *mbedtls_ssl_sig_alg_to_str( uint16_t in ) 267a8e1175bSopenharmony_ci {{ 268a8e1175bSopenharmony_ci switch( in ) 269a8e1175bSopenharmony_ci {{ 270a8e1175bSopenharmony_ci {translation_table} 271a8e1175bSopenharmony_ci }}; 272a8e1175bSopenharmony_ci 273a8e1175bSopenharmony_ci return "UNKNOWN"; 274a8e1175bSopenharmony_ci }}''') 275a8e1175bSopenharmony_ci body = body.format(translation_table='\n'.join(translation_table)) 276a8e1175bSopenharmony_ci return body 277a8e1175bSopenharmony_ci 278a8e1175bSopenharmony_ci 279a8e1175bSopenharmony_ciclass NamedGroupDefinition: 280a8e1175bSopenharmony_ci """ 281a8e1175bSopenharmony_ci Generate helper functions for named group 282a8e1175bSopenharmony_ci 283a8e1175bSopenharmony_ci It generates translation function from named group define to string. 284a8e1175bSopenharmony_ci Named group definition looks like: 285a8e1175bSopenharmony_ci #define MBEDTLS_SSL_IANA_TLS_GROUP_[ upper case named group ] [ value(hex) ] 286a8e1175bSopenharmony_ci 287a8e1175bSopenharmony_ci Known limitation: 288a8e1175bSopenharmony_ci - the definitions SHOULD exist in same macro blocks. 289a8e1175bSopenharmony_ci """ 290a8e1175bSopenharmony_ci 291a8e1175bSopenharmony_ci @classmethod 292a8e1175bSopenharmony_ci def extract(cls, source_code, start=0, end=-1): 293a8e1175bSopenharmony_ci named_group_pattern = re.compile(r'#define\s+(?P<name>MBEDTLS_SSL_IANA_TLS_GROUP_\w+)\s+' + 294a8e1175bSopenharmony_ci r'(?P<value>0[xX][0-9a-fA-F]+)$', 295a8e1175bSopenharmony_ci re.MULTILINE | re.DOTALL) 296a8e1175bSopenharmony_ci matches = list(named_group_pattern.finditer(source_code, start, end)) 297a8e1175bSopenharmony_ci if matches: 298a8e1175bSopenharmony_ci yield NamedGroupDefinition(source_code, definitions=matches) 299a8e1175bSopenharmony_ci 300a8e1175bSopenharmony_ci def __init__(self, source_code, definitions=None): 301a8e1175bSopenharmony_ci if definitions is None: 302a8e1175bSopenharmony_ci definitions = [] 303a8e1175bSopenharmony_ci assert isinstance(definitions, list) and definitions 304a8e1175bSopenharmony_ci self._definitions = definitions 305a8e1175bSopenharmony_ci self._source = source_code 306a8e1175bSopenharmony_ci 307a8e1175bSopenharmony_ci def __repr__(self): 308a8e1175bSopenharmony_ci return 'NamedGroup({})'.format(self._definitions[0].span()) 309a8e1175bSopenharmony_ci 310a8e1175bSopenharmony_ci def span(self): 311a8e1175bSopenharmony_ci return self._definitions[0].span() 312a8e1175bSopenharmony_ci 313a8e1175bSopenharmony_ci def __str__(self): 314a8e1175bSopenharmony_ci """ 315a8e1175bSopenharmony_ci Generate function for translating value to string 316a8e1175bSopenharmony_ci """ 317a8e1175bSopenharmony_ci translation_table = [] 318a8e1175bSopenharmony_ci for m in self._definitions: 319a8e1175bSopenharmony_ci name = m.groupdict()['name'] 320a8e1175bSopenharmony_ci iana_name = name[len('MBEDTLS_SSL_IANA_TLS_GROUP_'):].lower() 321a8e1175bSopenharmony_ci translation_table.append(' case {}:\n return "{}";'.format(name, iana_name)) 322a8e1175bSopenharmony_ci 323a8e1175bSopenharmony_ci body = textwrap.dedent('''\ 324a8e1175bSopenharmony_ci const char *mbedtls_ssl_named_group_to_str( uint16_t in ) 325a8e1175bSopenharmony_ci {{ 326a8e1175bSopenharmony_ci switch( in ) 327a8e1175bSopenharmony_ci {{ 328a8e1175bSopenharmony_ci {translation_table} 329a8e1175bSopenharmony_ci }}; 330a8e1175bSopenharmony_ci 331a8e1175bSopenharmony_ci return "UNKOWN"; 332a8e1175bSopenharmony_ci }}''') 333a8e1175bSopenharmony_ci body = body.format(translation_table='\n'.join(translation_table)) 334a8e1175bSopenharmony_ci return body 335a8e1175bSopenharmony_ci 336a8e1175bSopenharmony_ci 337a8e1175bSopenharmony_ciOUTPUT_C_TEMPLATE = '''\ 338a8e1175bSopenharmony_ci/* Automatically generated by generate_ssl_debug_helpers.py. DO NOT EDIT. */ 339a8e1175bSopenharmony_ci 340a8e1175bSopenharmony_ci/** 341a8e1175bSopenharmony_ci * \\file ssl_debug_helpers_generated.c 342a8e1175bSopenharmony_ci * 343a8e1175bSopenharmony_ci * \\brief Automatically generated helper functions for debugging 344a8e1175bSopenharmony_ci */ 345a8e1175bSopenharmony_ci/* 346a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 347a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 348a8e1175bSopenharmony_ci * 349a8e1175bSopenharmony_ci */ 350a8e1175bSopenharmony_ci 351a8e1175bSopenharmony_ci#include "common.h" 352a8e1175bSopenharmony_ci 353a8e1175bSopenharmony_ci#if defined(MBEDTLS_DEBUG_C) 354a8e1175bSopenharmony_ci 355a8e1175bSopenharmony_ci#include "ssl_debug_helpers.h" 356a8e1175bSopenharmony_ci 357a8e1175bSopenharmony_ci{functions} 358a8e1175bSopenharmony_ci 359a8e1175bSopenharmony_ci#endif /* MBEDTLS_DEBUG_C */ 360a8e1175bSopenharmony_ci/* End of automatically generated file. */ 361a8e1175bSopenharmony_ci 362a8e1175bSopenharmony_ci''' 363a8e1175bSopenharmony_ci 364a8e1175bSopenharmony_ci 365a8e1175bSopenharmony_cidef generate_ssl_debug_helpers(output_directory, mbedtls_root): 366a8e1175bSopenharmony_ci """ 367a8e1175bSopenharmony_ci Generate functions of debug helps 368a8e1175bSopenharmony_ci """ 369a8e1175bSopenharmony_ci mbedtls_root = os.path.abspath( 370a8e1175bSopenharmony_ci mbedtls_root or build_tree.guess_mbedtls_root()) 371a8e1175bSopenharmony_ci with open(os.path.join(mbedtls_root, 'include/mbedtls/ssl.h')) as f: 372a8e1175bSopenharmony_ci source_code = remove_c_comments(f.read()) 373a8e1175bSopenharmony_ci 374a8e1175bSopenharmony_ci definitions = dict() 375a8e1175bSopenharmony_ci for start, instance in preprocess_c_source_code(source_code, 376a8e1175bSopenharmony_ci EnumDefinition, 377a8e1175bSopenharmony_ci SignatureAlgorithmDefinition, 378a8e1175bSopenharmony_ci NamedGroupDefinition): 379a8e1175bSopenharmony_ci if start in definitions: 380a8e1175bSopenharmony_ci continue 381a8e1175bSopenharmony_ci if isinstance(instance, EnumDefinition): 382a8e1175bSopenharmony_ci definition = instance.generate_translation_function() 383a8e1175bSopenharmony_ci else: 384a8e1175bSopenharmony_ci definition = instance 385a8e1175bSopenharmony_ci definitions[start] = definition 386a8e1175bSopenharmony_ci 387a8e1175bSopenharmony_ci function_definitions = [str(v) for _, v in sorted(definitions.items())] 388a8e1175bSopenharmony_ci if output_directory == sys.stdout: 389a8e1175bSopenharmony_ci sys.stdout.write(OUTPUT_C_TEMPLATE.format( 390a8e1175bSopenharmony_ci functions='\n'.join(function_definitions))) 391a8e1175bSopenharmony_ci else: 392a8e1175bSopenharmony_ci with open(os.path.join(output_directory, 'ssl_debug_helpers_generated.c'), 'w') as f: 393a8e1175bSopenharmony_ci f.write(OUTPUT_C_TEMPLATE.format( 394a8e1175bSopenharmony_ci functions='\n'.join(function_definitions))) 395a8e1175bSopenharmony_ci 396a8e1175bSopenharmony_ci 397a8e1175bSopenharmony_cidef main(): 398a8e1175bSopenharmony_ci """ 399a8e1175bSopenharmony_ci Command line entry 400a8e1175bSopenharmony_ci """ 401a8e1175bSopenharmony_ci parser = argparse.ArgumentParser() 402a8e1175bSopenharmony_ci parser.add_argument('--mbedtls-root', nargs='?', default=None, 403a8e1175bSopenharmony_ci help='root directory of mbedtls source code') 404a8e1175bSopenharmony_ci parser.add_argument('output_directory', nargs='?', 405a8e1175bSopenharmony_ci default='library', help='source/header files location') 406a8e1175bSopenharmony_ci 407a8e1175bSopenharmony_ci args = parser.parse_args() 408a8e1175bSopenharmony_ci 409a8e1175bSopenharmony_ci generate_ssl_debug_helpers(args.output_directory, args.mbedtls_root) 410a8e1175bSopenharmony_ci return 0 411a8e1175bSopenharmony_ci 412a8e1175bSopenharmony_ci 413a8e1175bSopenharmony_ciif __name__ == '__main__': 414a8e1175bSopenharmony_ci sys.exit(main()) 415