Kevin Peng | d65629d | 2021-02-23 09:53:54 +0800 | [diff] [blame] | 1 | #! /usr/bin/env python3 |
| 2 | # |
| 3 | # ----------------------------------------------------------------------------- |
Sherry Zhang | ae25f05 | 2021-05-13 14:49:48 +0800 | [diff] [blame] | 4 | # Copyright (c) 2019-2021, Arm Limited. All rights reserved. |
Kevin Peng | d65629d | 2021-02-23 09:53:54 +0800 | [diff] [blame] | 5 | # |
| 6 | # SPDX-License-Identifier: BSD-3-Clause |
| 7 | # |
| 8 | # ----------------------------------------------------------------------------- |
| 9 | |
| 10 | |
| 11 | import re |
| 12 | import os |
| 13 | |
Sherry Zhang | ae25f05 | 2021-05-13 14:49:48 +0800 | [diff] [blame] | 14 | # Match (((x) + (y))) mode and ((x) + (y)) mode. x, y can be HEX or DEC value. |
| 15 | expression_re = re.compile(r"([(]?[(]?[(]?(([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*([\+\-]\s*([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*)*)[)]?\s*([\+\-])\s*[(]?(([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*([\+\-]\s*([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*)*)[)]?[)]?[)]?)|([(]?[(]?[(]?(([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*([\+\-]\s*([(]?(((0x)[0-9a-fA-F]+)|([0-9]+))[)]?)\s*)*)[)]?[)]?[)]?)") |
Kevin Peng | d65629d | 2021-02-23 09:53:54 +0800 | [diff] [blame] | 16 | |
| 17 | # Simple parser that takes a string and evaluates an expression from it. |
| 18 | # The expression might contain additions and subtractions amongst numbers that |
| 19 | # are written in decimal or hexadecimal form. |
| 20 | # The parses can process expressions in which the parentheses does not change |
| 21 | # the sign of the following number or numbers in an expression. |
| 22 | # Thus the parser can process the following expression: (x + y) |
| 23 | # However it will not calculate the correct sum for the expression below: |
| 24 | # (x - (y + z)) |
| 25 | def parse_and_sum(text): |
| 26 | m = expression_re.match(text) |
| 27 | if m is None: |
| 28 | msg = "The script was probably invoked manually" |
| 29 | msg += " with having certain macros nested in flash_layouts.h.\n" |
| 30 | msg += "Please revisit the flash_layout.h file and hardcode values" |
| 31 | msg += " for the (NON-)SECURE_IMAGE_OFFSET and" |
| 32 | msg += " (NON-)SECURE_IMAGE_MAX_SIZE macros" |
| 33 | raise Exception(msg) |
| 34 | |
Ludovic Barre | 9ccd1d8 | 2021-10-29 14:35:24 +0200 | [diff] [blame] | 35 | nums = re.findall(r'0x[A-Fa-f0-9]+|[\d]+', m.group(0)) |
Kevin Peng | d65629d | 2021-02-23 09:53:54 +0800 | [diff] [blame] | 36 | for i in range(len(nums)): |
| 37 | nums[i] = int(nums[i], 0) |
| 38 | ops = re.findall(r'\+|\-', m.group(0)) |
| 39 | sum = nums[0] |
| 40 | for i in range(len(ops)): |
| 41 | if ops[i] == '+': |
| 42 | sum += nums[i+1] |
| 43 | else: |
| 44 | sum -= nums[i+1] |
| 45 | return sum |
| 46 | |
| 47 | |
| 48 | # Opens a file that contains the macro of interest, then finds the macro with |
| 49 | # a regular expression, parses the expression that is defined for the given |
| 50 | # macro. Lastly it evaluates the expression with the parse_and_sum function |
| 51 | def evaluate_macro(file, regexp, matchGroupKey, matchGroupData, bracketless=False): |
| 52 | regexp_compiled = re.compile(regexp) |
| 53 | |
| 54 | if os.path.isabs(file): |
| 55 | configFile = file |
| 56 | else: |
| 57 | scriptsDir = os.path.dirname(os.path.abspath(__file__)) |
| 58 | configFile = os.path.join(scriptsDir, file) |
| 59 | |
| 60 | macroValue = {} |
| 61 | with open(configFile, 'r') as macros_preprocessed_file: |
| 62 | for line in macros_preprocessed_file: |
| 63 | if bracketless: |
| 64 | line=line.replace("(","") |
| 65 | line=line.replace(")","") |
| 66 | m = regexp_compiled.match(line) |
| 67 | if m is not None: |
| 68 | macroValue[m.group(matchGroupKey)] = \ |
| 69 | parse_and_sum(m.group(matchGroupData)) |
| 70 | |
| 71 | if (matchGroupKey == 0 and not macroValue): |
| 72 | macroValue["None"] = None |
| 73 | |
| 74 | return list(macroValue.values())[0] if (matchGroupKey == 0) else macroValue |