summaryrefslogtreecommitdiff
path: root/scripts/mbedtls_dev/c_parsing_helper.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/mbedtls_dev/c_parsing_helper.py')
-rw-r--r--scripts/mbedtls_dev/c_parsing_helper.py131
1 files changed, 0 insertions, 131 deletions
diff --git a/scripts/mbedtls_dev/c_parsing_helper.py b/scripts/mbedtls_dev/c_parsing_helper.py
deleted file mode 100644
index 2657b7d230d..00000000000
--- a/scripts/mbedtls_dev/c_parsing_helper.py
+++ /dev/null
@@ -1,131 +0,0 @@
-"""Helper functions to parse C code in heavily constrained scenarios.
-
-Currently supported functionality:
-
-* read_function_declarations: read function declarations from a header file.
-"""
-
-# Copyright The Mbed TLS Contributors
-# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
-
-### WARNING: the code in this file has not been extensively reviewed yet.
-### We do not think it is harmful, but it may be below our normal standards
-### for robustness and maintainability.
-
-import re
-from typing import Dict, Iterable, Iterator, List, Optional, Tuple
-
-
-class ArgumentInfo:
- """Information about an argument to an API function."""
- #pylint: disable=too-few-public-methods
-
- _KEYWORDS = [
- 'const', 'register', 'restrict',
- 'int', 'long', 'short', 'signed', 'unsigned',
- ]
- _DECLARATION_RE = re.compile(
- r'(?P<type>\w[\w\s*]*?)\s*' +
- r'(?!(?:' + r'|'.join(_KEYWORDS) + r'))(?P<name>\b\w+\b)?' +
- r'\s*(?P<suffix>\[[^][]*\])?\Z',
- re.A | re.S)
-
- @classmethod
- def normalize_type(cls, typ: str) -> str:
- """Normalize whitespace in a type."""
- typ = re.sub(r'\s+', r' ', typ)
- typ = re.sub(r'\s*\*', r' *', typ)
- return typ
-
- def __init__(self, decl: str) -> None:
- self.decl = decl.strip()
- m = self._DECLARATION_RE.match(self.decl)
- if not m:
- raise ValueError(self.decl)
- self.type = self.normalize_type(m.group('type')) #type: str
- self.name = m.group('name') #type: Optional[str]
- self.suffix = m.group('suffix') if m.group('suffix') else '' #type: str
-
-
-class FunctionInfo:
- """Information about an API function."""
- #pylint: disable=too-few-public-methods
-
- # Regex matching the declaration of a function that returns void.
- VOID_RE = re.compile(r'\s*\bvoid\s*\Z', re.A)
-
- def __init__(self, #pylint: disable=too-many-arguments
- filename: str,
- line_number: int,
- qualifiers: Iterable[str],
- return_type: str,
- name: str,
- arguments: List[str]) -> None:
- self.filename = filename
- self.line_number = line_number
- self.qualifiers = frozenset(qualifiers)
- self.return_type = return_type
- self.name = name
- self.arguments = [ArgumentInfo(arg) for arg in arguments]
-
- def returns_void(self) -> bool:
- """Whether the function returns void."""
- return bool(self.VOID_RE.search(self.return_type))
-
-
-# Match one C comment.
-# Note that we match both comment types, so things like // in a /*...*/
-# comment are handled correctly.
-_C_COMMENT_RE = re.compile(r'//(?:[^\n]|\\\n)*|/\*.*?\*/', re.S)
-_NOT_NEWLINES_RE = re.compile(r'[^\n]+')
-
-def read_logical_lines(filename: str) -> Iterator[Tuple[int, str]]:
- """Read logical lines from a file.
-
- Logical lines are one or more physical line, with balanced parentheses.
- """
- with open(filename, encoding='utf-8') as inp:
- content = inp.read()
- # Strip comments, but keep newlines for line numbering
- content = re.sub(_C_COMMENT_RE,
- lambda m: re.sub(_NOT_NEWLINES_RE, "", m.group(0)),
- content)
- lines = enumerate(content.splitlines(), 1)
- for line_number, line in lines:
- # Read a logical line, containing balanced parentheses.
- # We assume that parentheses are balanced (this should be ok
- # since comments have been stripped), otherwise there will be
- # a gigantic logical line at the end.
- paren_level = line.count('(') - line.count(')')
- while paren_level > 0:
- _, more = next(lines) #pylint: disable=stop-iteration-return
- paren_level += more.count('(') - more.count(')')
- line += '\n' + more
- yield line_number, line
-
-_C_FUNCTION_DECLARATION_RE = re.compile(
- r'(?P<qualifiers>(?:(?:extern|inline|static)\b\s*)*)'
- r'(?P<return_type>\w[\w\s*]*?)\s*' +
- r'\b(?P<name>\w+)' +
- r'\s*\((?P<arguments>.*)\)\s*;',
- re.A | re.S)
-
-def read_function_declarations(functions: Dict[str, FunctionInfo],
- filename: str) -> None:
- """Collect function declarations from a C header file."""
- for line_number, line in read_logical_lines(filename):
- m = _C_FUNCTION_DECLARATION_RE.match(line)
- if not m:
- continue
- qualifiers = m.group('qualifiers').split()
- return_type = m.group('return_type')
- name = m.group('name')
- arguments = m.group('arguments').split(',')
- if len(arguments) == 1 and re.match(FunctionInfo.VOID_RE, arguments[0]):
- arguments = []
- # Note: we replace any existing declaration for the same name.
- functions[name] = FunctionInfo(filename, line_number,
- qualifiers,
- return_type,
- name,
- arguments)