kicad-source/cmake/CheckBannedFunctions.cmake

54 lines
2.1 KiB
CMake
Raw Normal View History

# CheckBannedFunctions.cmake
# Usage: include(CheckBannedFunctions.cmake)
# This script scans for banned functions in io directories and fails the build if found.
# Set CMP0007 to NEW to ensure list variables are not stringified
cmake_policy(SET CMP0007 NEW)
# Usage: check_banned_functions() after setting BANNED_DIRS
macro(check_banned_functions)
set(BANNED_FUNCTIONS "strtod" "strtof" "atof")
set(BANNED_SCAN_FILES)
# Ensure BANNED_DIRS is set and not empty
if(NOT DEFINED BANNED_DIRS OR "${BANNED_DIRS}" STREQUAL "")
message(FATAL_ERROR "BANNED_DIRS variable is not set or empty.")
endif()
# Convert space-separated to semicolon-separated list
string(REPLACE " " ";" BANNED_DIRS "${BANNED_DIRS}")
foreach(dir IN LISTS BANNED_DIRS)
message(STATUS "Checking for banned functions in: ${dir}")
file(GLOB_RECURSE found_files
RELATIVE ${CMAKE_SOURCE_DIR}
${dir}/*.c
${dir}/*.cpp
${dir}/*.h
${dir}/*.hpp
)
list(APPEND BANNED_SCAN_FILES ${found_files})
endforeach()
foreach(file ${BANNED_SCAN_FILES})
# Read file into lines using file(STRINGS)
file(STRINGS ${CMAKE_SOURCE_DIR}/${file} file_lines)
foreach(line IN LISTS file_lines)
foreach(func ${BANNED_FUNCTIONS})
if(line MATCHES "\\b${func}\\b")
message(FATAL_ERROR "Banned function '${func}' found in ${file}")
endif()
endforeach()
# Only error if the line does not end with //format:allow (allow spaces between // and format)
# we allow this for specific cases where the format specifier is needed because the
# string is shown to the user and needs to be formatted in their locale e.g. error messages
if(line MATCHES "%\\d*\\.?\\d*[fg]" AND NOT line MATCHES "format:allow")
message(FATAL_ERROR "Banned format specifier '%f' or '%g' found in ${file}")
endif()
endforeach()
endforeach()
endmacro()
check_banned_functions()