Skip to content

Commit

Permalink
TODO Generate definitions from configuration files
Browse files Browse the repository at this point in the history
TODO
- Add a section to the README about the yaml parsing package used by the
  Python script
  • Loading branch information
jrvollmer committed Oct 28, 2023
1 parent b0f509f commit b705efa
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
BUILD
cmake_build
mbed-os
definitions.h
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR)

# Create definitions.h, a header file with definitions generated from setup.yml and tests.yml
execute_process(COMMAND ./parseConfigs.py
COMMAND_ERROR_IS_FATAL ANY)

set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "")
set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "")
set(APP_TARGET embedded-mbed)
Expand All @@ -12,6 +16,12 @@ add_subdirectory(${MBED_PATH})

add_executable(${APP_TARGET} testRunner.cpp)

# Precompile the definitions header. The generated header will be force included in all source files, so they don't need `#include "definitions.h"`
target_precompile_headers(${APP_TARGET}
PRIVATE
definitions.h
)

target_sources(${APP_TARGET}
PRIVATE
testRunner.cpp
Expand Down
55 changes: 55 additions & 0 deletions parseConfigs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/python3

import yaml


# Get information from configuration files
with open('tests.yml', 'r') as testFile, open('setup.yml', 'r') as setupFile:
testCfg = yaml.safe_load(testFile)
setupCfg = yaml.safe_load(setupFile)


# Get target and ensure that it is consistent across the configuration files
target = setupCfg['setup']['target']
assert target == list(testCfg.keys())[0], "Target in setup.yml ({}) does not match the root key in tests.yml ({})".format(target, list(testCfg.keys())[0])


# Stores lines of generated definitions header file
definitions=[]
lineNum = 1


# Insert definitions for devices and drivers macros
# These macros will be used throughout the project whenever test setup-related info is needed
for setupCat in ['devices', 'drivers']:
if isinstance(setupCfg['setup'][setupCat], dict):
definitions.insert(lineNum, '{}// Define macros for {}\n'.format('\n' if setupCat != 'devices' else '', setupCat))
lineNum += 1
for setup, setupInfo in setupCfg['setup'][setupCat].items():
for attr, val in setupInfo.items():
# If val is a list, make it a string and reformat it as a C array (i.e. {...} instead of [...])
if isinstance(val, list):
val = '{' + str(val)[1:-1] + '}'
definitions.insert(lineNum, '#define {}_{} {}\n'.format(setup.upper(), attr.upper(), val))
lineNum += 1

# Insert definitions for test macros
# These macros will be used in testRunner.cpp to determine what tests should be run,
# as well as in any source files that have test-dependent configurations
if isinstance(testCfg[target], dict):
definitions.insert(lineNum, '\n// Define macros for tests\n')
lineNum += 1
for testCat, tests in testCfg[target].items():
startLine=lineNum
for test, testType in tests.items():
if testType != 'disabled':
definitions.insert(lineNum, '#define {}_{} \"{}\"\n'.format(testCat.upper(), test.upper(), testType.upper()))
lineNum += 1
# Only insert the TEST_<TEST_CAT> line if one or more of the tests within that category are not disabled
if startLine < lineNum:
definitions.insert(startLine - 1, '// Start {} test definitions\n#define TEST_{}\n'.format(testCat, testCat.upper()))
lineNum += 1

# Create/Replace the contents of definitions.h with the generated lines
with open('definitions.h', 'w') as definitionsFile:
definitionsFile.writelines(definitions)

0 comments on commit b705efa

Please sign in to comment.