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