1# Copyright (c) 2024 Arduino SA 2# SPDX-License-Identifier: Apache-2.0 3 4# Second stage filter for YAML generation, called when generator expressions 5# have been used in some of the data and cleanup needs to happen after CMake 6# has completed processing. 7# 8# Two issues are addressed here: 9# 10# - the intermediate YAML may have non-escaped single quotes in its strings. 11# These may have been introduced directly via yaml_set() in the main CMake 12# script or by some generator expressions; at this stage they are however 13# finalized and can be escaped in one single pass. 14# 15# - in the input YAML, lists have been stored as a CMake-format string to 16# allow generator expressions to seamlessly expand into multiple items. 17# These now need to be converted back into a proper YAML list. 18# 19# This scripts expects as input the following variables: 20# 21# - EXPANDED_FILE: the name of the file that contains the expanded generator 22# expressions. 23# - OUTPUT_FILE: the name of the final output YAML file. 24# - TEMP_FILES: a list of temporary files that need to be removed after 25# the conversion is done. 26 27cmake_minimum_required(VERSION 3.20.0) 28 29set(ZEPHYR_BASE ${CMAKE_CURRENT_LIST_DIR}/../) 30list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules") 31include(yaml) 32 33# Fix all quotes in the input YAML file. Strings in it will be in one of the 34# following formats: 35# 36# name: 'string with 'single quotes' in it' 37# - 'string with 'single quotes' in it' 38# 39# To address this, every single quote is duplicated, then the first and last 40# occurrences of two single quotes are removed (they are the string beginning 41# and end markers). The result is written to a temporary file. 42file(STRINGS ${EXPANDED_FILE} yaml_content) 43foreach(line ${yaml_content}) 44 string(REPLACE "'" "''" line "${line}") # escape every single quote in the string 45 string(REGEX REPLACE "^([^']* )''" "\\1'" line "${line}") # fix opening quote 46 string(REGEX REPLACE "''$" "'" line "${line}") # fix closing quote 47 # semicolons in the string are not to be confused with string separators 48 string(REPLACE ";" "\\;" line "${line}") 49 list(APPEND tmp_content "${line}") 50endforeach() 51list(JOIN tmp_content "\n" tmp_content) 52file(WRITE ${EXPANDED_FILE}.tmp "${tmp_content}") 53 54# Load the now-fixed YAML file and convert the CMake-format lists back into 55# proper YAML format using the to_yaml() function. The result is written to 56# the final destination file. 57yaml_load(FILE ${EXPANDED_FILE}.tmp NAME yaml_saved) 58zephyr_get_scoped(json_content yaml_saved JSON) 59to_yaml("${json_content}" 0 yaml_out FINAL_GENEX) 60file(WRITE ${OUTPUT_FILE} "${yaml_out}") 61 62# Remove unused temporary files. EXPANDED_FILE needs to be kept, or the 63# build system will complain there is no rule to rebuild it, but the 64# .tmp file that was just created can be removed. 65list(REMOVE_ITEM TEMP_FILES ${EXPANDED_FILE}) 66list(APPEND TEMP_FILES ${EXPANDED_FILE}.tmp) 67foreach(file ${TEMP_FILES}) 68 file(REMOVE ${file}) 69endforeach() 70