1# CMake implementation of AutoGen 2# Copyright (C) 2017 Anonymous Maarten <anonymous.maarten@gmail.com> 3 4set(WS " \t\r\n") 5 6function(cutoff_first_occurrence TEXT OCCURRENCE RESULT) 7 string(FIND "${TEXT}" "${OCCURRENCE}" OCCURRENCE_INDEX) 8 if (OCCURRENCE_INDEX EQUAL -1) 9 set(${TEXT} "" PARENT_SCOPE) 10 return() 11 endif() 12 13 string(LENGTH "${OCCURRENCE}" OCCURRENCE_LENGTH) 14 math(EXPR CUTOFF_INDEX "${OCCURRENCE_INDEX}+${OCCURRENCE_LENGTH}") 15 string(SUBSTRING "${TEXT}" ${CUTOFF_INDEX} -1 TEXT_REMAINDER) 16 set(${RESULT} "${TEXT_REMAINDER}" PARENT_SCOPE) 17 18 endfunction() 19 20function(read_definition DEFINITION_FILENAME TEMPLATE_FILENAME DATA) 21 file(READ "${DEFINITION_FILENAME}" DEFINITION_CONTENTS) 22 23 string(REGEX MATCH "autogen definitions ([a-zA-Z\\._-]+);[${WS}]*" TEMPLATE_MATCH "${DEFINITION_CONTENTS}") 24 if (NOT TEMPLATE_MATCH) 25 message(FATAL_ERROR "${DEFINITION_FILENAME} doest not contain an AutoGen definition.") 26 endif() 27 28 get_filename_component(DEFINITION_DIR "${DEFINITION_FILENAME}" PATH) 29 set(${TEMPLATE_FILENAME} "${DEFINITION_DIR}/${CMAKE_MATCH_1}" PARENT_SCOPE) 30 if (DEBUG) 31 message("found: TEMPLATE_FILENAME=${CMAKE_MATCH_1}") 32 endif() 33 34 cutoff_first_occurrence("${DEFINITION_CONTENTS}" "${TEMPLATE_MATCH}" DEFINITION_CONTENTS) 35 36 set(DEFINITION "") 37 38 while (1) 39 string(REGEX MATCH "([a-zA-Z_][a-zA-Z0-9_]*)[${WS}]*=[${WS}]*{[${WS}]*" GROUPSTART_MATCH "${DEFINITION_CONTENTS}") 40 if (NOT GROUPSTART_MATCH) 41 break() 42 endif() 43 set(GROUPNAME "${CMAKE_MATCH_1}") 44 cutoff_first_occurrence("${DEFINITION_CONTENTS}" "${GROUPSTART_MATCH}" DEFINITION_CONTENTS) 45 if (DEBUG) 46 message("found: GROUPNAME=${GROUPNAME}") 47 endif() 48 set(NBKEYS 0) 49 set(GROUP_KEY_VALUES "") 50 while (1) 51 string(REGEX MATCH "^([a-zA-Z_][a-zA-Z0-9_]*)[${WS}]*=[${WS}]*(([\"']([${WS}a-zA-Z0-9_%\\\"<>\(\)\\.*+/?:,\\-]+)[\"'])|([a-zA-Z0-9_%\\]+))[${WS}]*;[${WS}]*" KEY_VALUE_MATCH "${DEFINITION_CONTENTS}") 52 if (NOT KEY_VALUE_MATCH) 53 break() 54 endif() 55 set(KEY "${CMAKE_MATCH_1}") 56 if ("${CMAKE_MATCH_4}" STREQUAL "") 57 set(VALUE "${CMAKE_MATCH_5}") 58 else() 59 string(REPLACE "\\\"" "\"" VALUE "${CMAKE_MATCH_4}") 60 #set(VALUE "${CMAKE_MATCH_4}") 61 endif() 62 63 if (DEBUG) 64 message("found: KEY=${KEY}, VALUE=${VALUE}") 65 endif() 66 math(EXPR NBKEYS "${NBKEYS}+1") 67 list(APPEND GROUP_KEY_VALUES "${KEY}" "${VALUE}") 68 cutoff_first_occurrence("${DEFINITION_CONTENTS}" "${KEY_VALUE_MATCH}" DEFINITION_CONTENTS) 69 endwhile() 70 string(REGEX MATCH "^[${WS}]*}[${WS}]*;[${WS}]*" GROUPEND_MATCH "${DEFINITION_CONTENTS}") 71 if (NOT GROUPEND_MATCH) 72 message(FATAL_ERROR "Group ${GROUPNAME} did not finish.") 73 endif() 74 cutoff_first_occurrence("${DEFINITION_CONTENTS}" "${GROUPEND_MATCH}" DEFINITION_CONTENTS) 75 list(APPEND DEFINITION "${GROUPNAME}" ${NBKEYS} ${GROUP_KEY_VALUES}) 76 endwhile() 77 set(${DATA} "${DEFINITION}" PARENT_SCOPE) 78endfunction() 79 80function(match_autogen_group TEXT START POS0 POS1 MATCH FOUND) 81 string(SUBSTRING "${TEXT}" "${START}" -1 TEXT) 82 string(REGEX MATCH "\\[\\+[${WS}]*([ a-zA-Z0-9=_$%\\(\\)\"\\+\\-]+)[${WS}]*\\+\\]" MATCH_GROUP "${TEXT}") 83 if ("${MATCH_GROUP}" STREQUAL "") 84 set(${FOUND} 0 PARENT_SCOPE) 85 return() 86 endif() 87 string(FIND "${TEXT}" "${MATCH_GROUP}" START_TEXT) 88 math(EXPR POS0_var "${START}+${START_TEXT}") 89 string(LENGTH "${MATCH_GROUP}" MATCH_LENGTH) 90 math(EXPR POS1_var "${POS0_var}+${MATCH_LENGTH}") 91 set(${POS0} "${POS0_var}" PARENT_SCOPE) 92 set(${POS1} "${POS1_var}" PARENT_SCOPE) 93 set(${FOUND} 1 PARENT_SCOPE) 94 string(STRIP "${CMAKE_MATCH_1}" CONTENT) 95 set("${MATCH}" "${CONTENT}" PARENT_SCOPE) 96endfunction() 97 98function(append_output SUFFICES_FILENAMES TEXT POS0 POS1 FILTER) 99 math(EXPR POS_LENGTH "${POS1}-${POS0}") 100 string(LENGTH "${TEXT}" TEXT_LENGTH) 101 string(SUBSTRING "${TEXT}" "${POS0}" "${POS_LENGTH}" TEXT_APPEND) 102 if (DEBUG) 103 message("appending ${POS0}:${POS1}, length=${POS_LENGTH}") 104 endif() 105 append_output_text("${SUFFICES_FILENAMES}" "${TEXT_APPEND}" "${FILTER}") 106endfunction() 107 108function(append_output_text SUFFICES_FILENAMES TEXT_APPEND FILTER) 109 string(LENGTH "${TEXT_APPEND}" TEXT_LENGTH) 110 list(LENGTH SUFFICES_FILENAMES NB) 111 math(EXPR NB_END "${NB}-1") 112 foreach(INDEX RANGE 0 ${NB_END} 3) 113 math(EXPR INDEX_1 "${INDEX}+1") 114 math(EXPR INDEX_2 "${INDEX}+2") 115 list(GET SUFFICES_FILENAMES ${INDEX} SUFFIX) 116 list(GET SUFFICES_FILENAMES ${INDEX_1} FILENAME) 117 list(GET SUFFICES_FILENAMES ${INDEX_2} TEMPFILENAME) 118 set(WRITE_OK 1) 119 if (FILTER) 120 if (NOT "${SUFFIX}" STREQUAL "${FILTER}") 121 set(WRITE_OK 0) 122 endif() 123 endif() 124 if (WRITE_OK) 125 if (DEBUG) 126 message("Write: ${TEXT_LENGTH} characters to ${FILENAME}") 127 endif() 128 file(APPEND "${TEMPFILENAME}" "${TEXT_APPEND}") 129 endif() 130 endforeach() 131endfunction() 132 133function(output_finish SUFFICES_FILENAMES) 134 list(LENGTH SUFFICES_FILENAMES NB) 135 math(EXPR NB_END "${NB}-1") 136 foreach(INDEX RANGE 0 ${NB_END} 3) 137 math(EXPR INDEX_1 "${INDEX}+1") 138 math(EXPR INDEX_2 "${INDEX}+2") 139 list(GET SUFFICES_FILENAMES ${INDEX_1} FILENAME) 140 list(GET SUFFICES_FILENAMES ${INDEX_2} TEMPFILENAME) 141 file(RENAME "${TEMPFILENAME}" "${FILENAME}") 142 endforeach() 143endfunction() 144 145function(stack_push STACK_ARG) 146 set(STACK_LIST "${${STACK_ARG}}") 147 string(REPLACE ";" " " NEWITEM "${ARGN}") 148 if (DEBUG) 149 list(LENGTH STACK_LIST STACK_LENGTH) 150 message("Pushing \"${NEWITEM}\" onto stack (length=${STACK_LENGTH})") 151 endif() 152 list(APPEND STACK_LIST "${NEWITEM}") 153 set(${STACK_ARG} "${STACK_LIST}" PARENT_SCOPE) 154endfunction() 155 156function(stack_pop STACK_ARG ITEM) 157 set(STACK_LIST "${${STACK_ARG}}") 158 list(LENGTH STACK_LIST STACK_LENGTH) 159 if (STACK_LENGTH EQUAL 0) 160 message(FATAL_ERROR "ENDFOR: stack is empty") 161 endif() 162 math(EXPR LAST_ITEM_INDEX "${STACK_LENGTH}-1") 163 list(GET STACK_LIST "${LAST_ITEM_INDEX}" LAST_ITEM) 164 list(REMOVE_AT STACK_LIST "${LAST_ITEM_INDEX}") 165 string(REPLACE " " ";" LAST_ITEM_LIST "${LAST_ITEM}") 166 if (DEBUG) 167 message("Popping \"${LAST_ITEM}\" from stack (length=${STACK_LENGTH})") 168 endif() 169 set(${ITEM} "${LAST_ITEM_LIST}" PARENT_SCOPE) 170 set(${STACK_ARG} "${STACK_LIST}" PARENT_SCOPE) 171endfunction() 172 173function(stack_top STACK_ARG ITEM) 174 set(STACK_LIST "${${STACK_ARG}}") 175 list(LENGTH STACK_LIST STACK_LENGTH) 176 if (STACK_LENGTH EQUAL 0) 177 message(FATAL_ERROR "ENDFOR: stack is empty") 178 endif() 179 math(EXPR LAST_ITEM_INDEX "${STACK_LENGTH}-1") 180 list(GET STACK_LIST "${LAST_ITEM_INDEX}" LAST_ITEM) 181 string(REPLACE " " ";" LAST_ITEM_LIST "${LAST_ITEM}") 182 if (DEBUG) 183 message("Top of stack: \"${LAST_ITEM}\" from stack (length=${STACK_LENGTH})") 184 endif() 185 set(${ITEM} "${LAST_ITEM_LIST}" PARENT_SCOPE) 186endfunction() 187 188function(stack_find_key STACK_LIST TEMPLATE_PARAMETERS KEY VALUE) 189 list(REVERSE STACK_LIST) 190 foreach(STACK_ITEM ${STACK_LIST}) 191 string(REPLACE " " ";" STACK_ITEM_LIST "${STACK_ITEM}") 192 list(GET STACK_ITEM_LIST 3 TP_INDEX) 193 math(EXPR TP_SIZE_INDEX "${TP_INDEX}+1") 194 list(GET TEMPLATE_PARAMETERS ${TP_SIZE_INDEX} TP_SIZE) 195 math(EXPR TP_KV_INDEX_START "${TP_INDEX}+2") 196 math(EXPR TP_KV_INDEX_END "${TP_KV_INDEX_START}+2*${TP_SIZE}-1") 197 foreach(TP_KV_INDEX RANGE ${TP_KV_INDEX_START} ${TP_KV_INDEX_END} 2) 198 list(GET TEMPLATE_PARAMETERS ${TP_KV_INDEX} TP_KEY) 199 if("${TP_KEY}" STREQUAL "${KEY}") 200 math(EXPR TP_VALUE_INDEX "${TP_KV_INDEX}+1") 201 list(GET TEMPLATE_PARAMETERS ${TP_VALUE_INDEX} TP_VALUE) 202 set(${VALUE} "${TP_VALUE}" PARENT_SCOPE) 203 return() 204 endif() 205 endforeach() 206 endforeach() 207 message(FATAL_ERROR "Unknown KEY=${KEY}") 208endfunction() 209 210function(template_parameters_find_next_groupname_index TEMPLATE_PARAMETERS GROUPNAME INDEX_LAST INDEX_NEXT) 211 if (${INDEX_LAST} LESS 0) 212 set(INDEX 0) 213 else () 214 math(EXPR INDEX_1 "1+(${INDEX_LAST})") 215 list(GET TEMPLATE_PARAMETERS ${INDEX_1} GROUPNAME_INDEX_SIZE) 216 math(EXPR INDEX "${INDEX_LAST}+1+2*${GROUPNAME_INDEX_SIZE}+1") 217 endif() 218 list(LENGTH TEMPLATE_PARAMETERS PARAMETERS_LENGTH) 219 while (${INDEX} LESS ${PARAMETERS_LENGTH}) 220 list(GET TEMPLATE_PARAMETERS ${INDEX} GROUPNAME_AT_INDEX) 221 if ("${GROUPNAME}" STREQUAL "${GROUPNAME_AT_INDEX}") 222 set("${INDEX_NEXT}" ${INDEX} PARENT_SCOPE) 223 return() 224 endif() 225 math(EXPR INDEX_1 "${INDEX}+1") 226 list(GET TEMPLATE_PARAMETERS ${INDEX_1} GROUPNAME_INDEX_SIZE) 227 math(EXPR INDEX "${INDEX}+1+2*${GROUPNAME_INDEX_SIZE}+1") 228 endwhile() 229 set("${INDEX_NEXT}" -1 PARENT_SCOPE) 230endfunction() 231 232function(calculate_line_number TEXT POSITION LINENUMBER_ARG) 233 #math(EXPR INDEX_MAX "${POSITION}-1") 234 string(SUBSTRING "${TEXT}" 0 ${POSITION} SUBTEXT) 235 string(REGEX MATCHALL "\n" MATCH_NEWLINES "${SUBTEXT}") 236 list(LENGTH MATCH_NEWLINES NBLINES) 237 math(EXPR NBLINES "${NBLINES}+1") 238 set(${LINENUMBER_ARG} ${NBLINES} PARENT_SCOPE) 239endfunction() 240 241function(parse_template TEMPLATE_FILENAME OUTPUT_DIR TEMPLATE_PARAMETERS) 242 file(READ ${TEMPLATE_FILENAME} TEMPLATE_CONTENTS) 243 set(POSITION 0) 244 match_autogen_group("${TEMPLATE_CONTENTS}" "${POSITION}" POS0 POS1 AUTOGEN FOUND) 245 if (NOT FOUND) 246 message(FATAL_ERROR "Header of template not found") 247 endif() 248 string(REGEX MATCH "AutoGen5 template ([ a-zA-Z0-9]*)" SUFFICES_MATCH "${AUTOGEN}") 249 if (NOT SUFFICES_MATCH) 250 message(FATAL_ERROR "No output suffices found") 251 endif() 252 string(STRIP "${CMAKE_MATCH_1}" SUFFICES) 253 string(REPLACE " " ";" SUFFICES "${SUFFICES}") 254 set(SUFFICES_FILENAMES "") 255 get_filename_component(TEMPLATE_NAME_WE "${TEMPLATE_FILENAME}" NAME_WE) 256 foreach(SUFFIX ${SUFFICES}) 257 if ("${OUTPUT_DIR}" STREQUAL "") 258 set(DIR_PREFIX "") 259 else() 260 set(DIR_PREFIX "${OUTPUT_DIR}/") 261 endif() 262 string(RANDOM LENGTH 64 RANDOMSTRING) 263 set(FILENAME "${DIR_PREFIX}${TEMPLATE_NAME_WE}.${SUFFIX}") 264 set(TEMPFILENAME "${DIR_PREFIX}${TEMPLATE_NAME_WE}${RANDOMSTRING}.${SUFFIX}") 265 list(APPEND SUFFICES_FILENAMES "${SUFFIX}" "${FILENAME}" "${TEMPFILENAME}") 266 file(WRITE "${FILENAME}" "") 267 endforeach() 268 if (DEBUG) 269 message("Output files: ${SUFFICES_FILENAMES}") 270 endif() 271 set(WRITE_FILTER "") 272 append_output("${SUFFICES_FILENAMES}" "${TEMPLATE_CONTENTS}" 0 "${POS0}" "${WRITE_FILTER}") 273 math(EXPR POS1 "${POS1}+1") 274 set(POSITION "${POS1}") 275 if (DEBUG) 276 message("Output: ${SUFFICES_FILENAMES}") 277 endif() 278 279 set(STACK "") 280 while (1) 281 match_autogen_group("${TEMPLATE_CONTENTS}" "${POSITION}" POS0 POS1 GROUP_MATCH FOUND) 282 if (NOT FOUND) 283 if (DEBUG) 284 message("No group found. Dumping rest of file.") 285 endif() 286 if (NOT "${STACK}" STREQUAL "") 287 message(FATAL_ERROR "Stack not empty at end of file") 288 endif() 289 string(LENGTH "${TEMPLATE_CONTENTS}" TEXT_LENGTH) 290 append_output("${SUFFICES_FILENAMES}" "${TEMPLATE_CONTENTS}" ${POSITION} ${TEXT_LENGTH} "${WRITE_FILTER}") 291 break() 292 endif() 293 append_output("${SUFFICES_FILENAMES}" "${TEMPLATE_CONTENTS}" ${POSITION} ${POS0} "${WRITE_FILTER}") 294 set(POSITION "${POS1}") 295 296 if (GROUP_MATCH MATCHES "^FOR") 297 string(REPLACE " " ";" GROUP_MATCH_LIST "${GROUP_MATCH}") 298 list(GET GROUP_MATCH_LIST 1 FOR_KEY) 299 template_parameters_find_next_groupname_index("${TEMPLATE_PARAMETERS}" "${FOR_KEY}" -1 FOR_INDEX) 300 if (DEBUG) 301 message("FOR_KEY: ${FOR_KEY}") 302 message("FOR_INDEX: ${FOR_INDEX}") 303 endif() 304 if (${FOR_KEY} LESS 0) 305 message(FATAL_ERROR "FOR has key with empty list. Not implemented yet..") 306 endif() 307 stack_push(STACK FOR ${POSITION} ${FOR_KEY} ${FOR_INDEX}) 308 elseif (GROUP_MATCH MATCHES "^ENDFOR") 309 string(REPLACE " " ";" GROUP_MATCH_LIST "${GROUP_MATCH}") 310 list(GET GROUP_MATCH_LIST 1 ENDFOR_KEY) 311 stack_pop(STACK FOR_ITEM) 312 list(GET FOR_ITEM 0 FOR_FOR) 313 if (NOT "${FOR_FOR}" STREQUAL "FOR") 314 message(FATAL_ERROR "ENDFOR does not match last item: ${FOR_FOR}") 315 endif() 316 list(GET FOR_ITEM 1 FOR_POSITION) 317 list(GET FOR_ITEM 2 FOR_KEY) 318 if (NOT "${FOR_KEY}" STREQUAL "${ENDFOR_KEY}") 319 calculate_line_number("${TEMPLATE_CONTENTS}" "${POSITION}" LINENUMBER) 320 message("FOR and ENDFOR do not match. (line number ${LINENUMBER}) (FOR:${FOR_KEY}, ENDFOR:${ENDFOR_KEY})") 321 endif() 322 list(GET FOR_ITEM 3 FOR_INDEX_PREV) 323 template_parameters_find_next_groupname_index("${TEMPLATE_PARAMETERS}" "${FOR_KEY}" ${FOR_INDEX_PREV} FOR_INDEX) 324 if (DEBUG) 325 message("FOR_INDEX was ${FOR_INDEX_PREV}, is now ${FOR_INDEX}") 326 endif() 327 if (${FOR_INDEX} LESS 0) 328 if (DEBUG) 329 message("ENDFOR: FOR_INDEX < 0 (no more key) ==> Continue") 330 endif() 331 else() 332 set(POSITION ${FOR_POSITION}) 333 stack_push(STACK FOR ${FOR_POSITION} ${FOR_KEY} ${FOR_INDEX}) 334 if (DEBUG) 335 message("ENDFOR: FOR_INDEX >= 0 (more keys available) ==> Back to position=${FOR_POSITION}") 336 endif() 337 endif() 338 elseif (GROUP_MATCH MATCHES "^CASE") 339 string(REGEX MATCH "^CASE[${WS}]+\\(([a-zA-Z]+)\\)" CASE_MATCH "${GROUP_MATCH}") 340 if ("${CASE_MATCH}" STREQUAL "") 341 message(FATAL_ERROR "Wrong CASE syntax") 342 endif() 343 set(CASE_KEY "${CMAKE_MATCH_1}") 344 if (DEBUG) 345 message("CASE: KEY=${CASE_KEY}") 346 endif() 347 stack_push(STACK CASE "${CASE_KEY}" ${POSITION}) 348 elseif (GROUP_MATCH MATCHES "^==") 349 math(EXPR POSITION "${POSITION}+1") 350 string(REGEX MATCH "^==[${WS}]+([a-zA-Z_][a-zA-Z0-9_]*)" CASE_MATCH "${GROUP_MATCH}") 351 if ("${CASE_MATCH}" STREQUAL "") 352 message(FATAL_ERROR "Wrong == syntax") 353 endif() 354 stack_top(STACK CASE_ITEM) 355 list(GET CASE_ITEM 0 CASE_CASE) 356 if(NOT "${CASE_CASE}" STREQUAL "CASE") 357 message(FATAL_ERROR "== block must be in CASE. Top of stack=${CASE_CASE}") 358 endif() 359 set(CASE_VALUE "${CMAKE_MATCH_1}") 360 if (DEBUG) 361 message("case: == VALUE=${CASE_VALUE}") 362 endif() 363 list(GET CASE_ITEM 1 CASE_KEY) 364 if ("${CASE_KEY}" STREQUAL "suffix") 365 if (DEBUG) 366 message("Setting write filter to ${CASE_VALUE}") 367 endif() 368 set(WRITE_FILTER "${CASE_VALUE}") 369 else() 370 message(FATAL_ERROR "CASE: unsupported argument ${CASE_KEY}") 371 endif() 372 elseif (GROUP_MATCH MATCHES "^ESAC") 373 stack_pop(STACK CASE_ITEM) 374 if (DEBUG) 375 message("ESAC") 376 endif() 377 list(GET CASE_ITEM 0 CASE_CASE) 378 if (NOT "${CASE_CASE}" STREQUAL "CASE") 379 message(FATAL_ERROR "ESAC does not match last item: ${CASE_CASE}") 380 endif() 381 if ("${CASE_KEY}" STREQUAL "suffix") 382 if (DEBUG) 383 message("Removing write filter") 384 endif() 385 set(WRITE_FILTER "") 386 else() 387 message(FATAL_ERROR "CASE: unsupported argument ${CASE_KEY}") 388 endif() 389 else() 390 string(REGEX MATCH "\\(([a-zA-Z0-9_$%\"${WS}\\+\\-]+)\\)" PARENTHESE_MATCH "${GROUP_MATCH}") 391 if (NOT "${PARENTHESE_MATCH}" STREQUAL "") 392 set(PARENTHESE_CONTENT "${CMAKE_MATCH_1}") 393 string(REPLACE " " ";" PARENTHESE_LIST "${PARENTHESE_CONTENT}") 394 list(GET PARENTHESE_LIST 0 PARENTHESE_COMMAND) 395 if ("${PARENTHESE_COMMAND}" STREQUAL "get") 396 list(GET PARENTHESE_LIST 1 KEY_QUOTED) 397 string(REGEX MATCH "\\\"([a-zA-Z_${WS}]+)\\\"" KEY_MATCH "${KEY_QUOTED}") 398 if ("${KEY_MATCH}" STREQUAL "") 399 message(FATAL_ERROR "get: empty key") 400 endif() 401 set(KEY "${CMAKE_MATCH_1}") 402 if (DEBUG) 403 message("Get: key=${KEY}") 404 endif() 405 stack_find_key("${STACK}" "${TEMPLATE_PARAMETERS}" "${KEY}" VALUE) 406 if (DEBUG) 407 message("Get key=${KEY} ==> value=${VALUE}") 408 endif() 409 append_output_text("${SUFFICES_FILENAMES}" "${VALUE}" "${WRITE_FILTER}") 410 elseif("${PARENTHESE_COMMAND}" STREQUAL "tpl-file-line") 411 list(GET PARENTHESE_LIST 1 FORMAT_LINE) 412 calculate_line_number("${TEMPLATE_CONTENTS}" "${POSITION}" LINENUMBER) 413 append_output_text("${SUFFICES_FILENAMES}" "${LINENUMBER}" "${WRITE_FILTER}") 414 else() 415 message(FATAL_ERROR "Unknown parenthese command: ${PARENTHESE_COMMAND}") 416 endif() 417 else() 418 message(FATAL_ERROR "Unknown command: ${GROUP_MATCH}") 419 endif() 420 endif() 421 422 endwhile() 423 if (NOT "${STACK}" STREQUAL "") 424 message(FATAL_ERROR "STACK was not empty at EOF") 425 endif() 426 output_finish("${SUFFICES_FILENAMES}") 427endfunction() 428 429if ("${DEFINITION}" STREQUAL "") 430 message(FATAL_ERROR "Need definition file") 431endif() 432if (NOT EXISTS "${DEFINITION}") 433 message(FATAL_ERROR "Definition file does not exist (${DEFINITION})") 434endif() 435 436read_definition("${DEFINITION}" TEMPLATE_FILENAME DATA) 437if (DEBUG) 438 message("${TEMPLATE_FILENAME}") 439 message("${DATA}") 440endif() 441 442parse_template("${TEMPLATE_FILENAME}" "${OUTPUTDIR}" "${DATA}") 443