1# Copyright (c) 2019 - 2024 David Guibert
4# SPDX-License-Identifier: Apache-2.0
7# https://raw.githubusercontent.com/sbellus/json-cmake/master/JSONParser.cmake
8cmake_minimum_required(VERSION 3.1)
10if(DEFINED JSonParserGuard)
14set(JSonParserGuard yes)
16macro(sbeParseJson prefix jsonString)
19 set(json_string "${${jsonString}}")
20 string(LENGTH "${json_string}" json_jsonLen)
22 set(json_AllVariables ${prefix})
23 set(json_ArrayNestingLevel 0)
24 set(json_MaxArrayNestingLevel 0)
29 unset(json_AllVariables)
37 unset(json_reservedWord)
38 unset(json_arrayIndex)
41 unset(json_ArrayNestingLevel)
42 foreach(json_nestingLevel RANGE ${json_MaxArrayNestingLevel})
43 unset(json_${json_nestingLevel}_arrayIndex)
45 unset(json_nestingLevel)
46 unset(json_MaxArrayNestingLevel)
51macro(sbeClearJson prefix)
52 foreach(json_var ${${prefix}})
60macro(sbePrintJson prefix)
61 foreach(json_var ${${prefix}})
62 message("${json_var} = ${${json_var}}")
66macro(_sbeParse prefix)
68 while(${json_index} LESS ${json_jsonLen})
69 string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
71 if("\"" STREQUAL "${json_char}")
72 _sbeparsenamevalue(${prefix})
73 elseif("{" STREQUAL "${json_char}")
74 _sbemovetonextnonemptycharacter()
75 _sbeparseobject(${prefix})
76 elseif("[" STREQUAL "${json_char}")
77 _sbemovetonextnonemptycharacter()
78 _sbeparsearray(${prefix})
81 if(${json_index} LESS ${json_jsonLen})
82 string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
87 if("}" STREQUAL "${json_char}" OR "]" STREQUAL "${json_char}")
91 _sbemovetonextnonemptycharacter()
95macro(_sbeParseNameValue prefix)
99 while(${json_index} LESS ${json_jsonLen})
100 string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
103 if("\"" STREQUAL "${json_char}" AND json_inName)
105 _sbemovetonextnonemptycharacter()
106 if(NOT ${json_index} LESS ${json_jsonLen})
109 string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
110 set(json_newPrefix ${prefix}.${json_name})
113 if(":" STREQUAL "${json_char}")
114 _sbemovetonextnonemptycharacter()
115 if(NOT ${json_index} LESS ${json_jsonLen})
118 string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
120 if("\"" STREQUAL "${json_char}")
121 _sbeparsevalue(${json_newPrefix})
123 elseif("{" STREQUAL "${json_char}")
124 _sbemovetonextnonemptycharacter()
125 _sbeparseobject(${json_newPrefix})
127 elseif("[" STREQUAL "${json_char}")
128 _sbemovetonextnonemptycharacter()
129 _sbeparsearray(${json_newPrefix})
132 # reserved word starts
133 _sbeparsereservedword(${json_newPrefix})
138 list(APPEND ${json_AllVariables} ${json_newPrefix})
139 set(${json_newPrefix} "")
146 if("\\" STREQUAL "${json_char}")
147 math(EXPR json_index "${json_index} + 1")
148 if(NOT ${json_index} LESS ${json_jsonLen})
151 string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
154 set(json_name "${json_name}${json_char}")
157 # check if name starts
158 if("\"" STREQUAL "${json_char}" AND NOT json_inName)
162 _sbemovetonextnonemptycharacter()
166macro(_sbeParseReservedWord prefix)
167 set(json_reservedWord "")
169 while(${json_index} LESS ${json_jsonLen} AND NOT json_end)
170 string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
172 if("," STREQUAL "${json_char}"
173 OR "}" STREQUAL "${json_char}"
174 OR "]" STREQUAL "${json_char}")
177 set(json_reservedWord "${json_reservedWord}${json_char}")
178 math(EXPR json_index "${json_index} + 1")
182 list(APPEND ${json_AllVariables} ${prefix})
183 string(STRIP "${json_reservedWord}" json_reservedWord)
184 set(${prefix} ${json_reservedWord})
187macro(_sbeParseValue prefix)
188 cmake_policy(SET CMP0054 NEW) # turn off implicit expansions in if statement
193 while(${json_index} LESS ${json_jsonLen})
194 # fast path for copying strings
196 # attempt to gobble up to 128 bytes of string
197 string(SUBSTRING "${json_string}" ${json_index} 128 try_gobble)
198 # consume a piece of string we can just straight copy before encountering
200 string(REGEX MATCH "^[^\"\\\\]+" simple_copy "${try_gobble}")
201 string(CONCAT json_value "${json_value}" "${simple_copy}")
202 string(LENGTH "${simple_copy}" copy_length)
203 math(EXPR json_index "${json_index} + ${copy_length}")
206 string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
208 # check if json_value ends, it is ended by "
209 if("\"" STREQUAL "${json_char}" AND json_inValue)
212 set(${prefix} ${json_value})
213 list(APPEND ${json_AllVariables} ${prefix})
214 _sbemovetonextnonemptycharacter()
219 # if " is escaped consume
220 if("\\" STREQUAL "${json_char}")
221 math(EXPR json_index "${json_index} + 1")
222 if(NOT ${json_index} LESS ${json_jsonLen})
225 string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
226 if(NOT "\"" STREQUAL "${json_char}")
227 # if it is not " then copy also escape character
228 set(json_char "\\${json_char}")
232 _sbeaddescapedcharacter("${json_char}")
235 # check if value starts
236 if("\"" STREQUAL "${json_char}" AND NOT json_inValue)
237 set(json_inValue yes)
240 math(EXPR json_index "${json_index} + 1")
244macro(_sbeAddEscapedCharacter char)
245 string(CONCAT json_value "${json_value}" "${char}")
248macro(_sbeParseObject prefix)
250 _sbemovetonextnonemptycharacter()
253macro(_sbeParseArray prefix)
254 math(EXPR json_ArrayNestingLevel "${json_ArrayNestingLevel} + 1")
255 set(json_${json_ArrayNestingLevel}_arrayIndex 0)
258 list(APPEND ${json_AllVariables} ${prefix})
260 while(${json_index} LESS ${json_jsonLen})
261 string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
263 if("\"" STREQUAL "${json_char}")
265 list(APPEND ${prefix} ${json_${json_ArrayNestingLevel}_arrayIndex})
266 _sbeparsevalue(${prefix}_${json_${json_ArrayNestingLevel}_arrayIndex})
267 elseif("{" STREQUAL "${json_char}")
269 _sbemovetonextnonemptycharacter()
270 list(APPEND ${prefix} ${json_${json_ArrayNestingLevel}_arrayIndex})
271 _sbeparseobject(${prefix}_${json_${json_ArrayNestingLevel}_arrayIndex})
273 list(APPEND ${prefix} ${json_${json_ArrayNestingLevel}_arrayIndex})
274 _sbeparsereservedword(
275 ${prefix}_${json_${json_ArrayNestingLevel}_arrayIndex})
278 if(NOT ${json_index} LESS ${json_jsonLen})
282 string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
284 if("]" STREQUAL "${json_char}")
285 _sbemovetonextnonemptycharacter()
287 elseif("," STREQUAL "${json_char}")
288 math(EXPR json_${json_ArrayNestingLevel}_arrayIndex
289 "${json_${json_ArrayNestingLevel}_arrayIndex} + 1")
292 _sbemovetonextnonemptycharacter()
295 if(${json_MaxArrayNestingLevel} LESS ${json_ArrayNestingLevel})
296 set(json_MaxArrayNestingLevel ${json_ArrayNestingLevel})
298 math(EXPR json_ArrayNestingLevel "${json_ArrayNestingLevel} - 1")
301macro(_sbeMoveToNextNonEmptyCharacter)
302 math(EXPR json_index "${json_index} + 1")
303 if(${json_index} LESS ${json_jsonLen})
304 string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
305 while(${json_char} MATCHES "[ \t\n\r]" AND ${json_index} LESS
307 math(EXPR json_index "${json_index} + 1")
308 string(SUBSTRING "${json_string}" ${json_index} 1 json_char)