genheader.cmake 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. if (__genheader_included)
  2. return ()
  3. endif ()
  4. set ( __genheader_included YES )
  5. # stuff to automatically generate c++ headers from template and plain text files/templates
  6. # retrieve result of php ubertest.php show <NAME> and put it to outvar
  7. function ( GETTESTVAR parname outvar )
  8. execute_process ( COMMAND php ubertest.php show ${parname}
  9. WORKING_DIRECTORY "${MANTICORE_SOURCE_DIR}/test"
  10. RESULT_VARIABLE res
  11. OUTPUT_VARIABLE _CONTENT
  12. ERROR_QUIET
  13. OUTPUT_STRIP_TRAILING_WHITESPACE )
  14. set ( "${outvar}" "${_CONTENT}" PARENT_SCOPE )
  15. endfunction ()
  16. # check if TEXT contains config variables from test suite and substitute them
  17. function ( TESTVARS TEXT )
  18. set ( LITERAL "${${TEXT}}" )
  19. foreach (it searchd_settings;sql_settings;odbc_settings;my_address;agent0_address;my_port;agent_address;agent1_address;agent2_address)
  20. string ( TOUPPER "${it}" _it )
  21. string ( FIND "${LITERAL}" "@${_it}@" _need )
  22. if (_need GREATER -1)
  23. gettestvar ( ${it} ${_it} )
  24. set ( NEED_REPLACE TRUE )
  25. endif ()
  26. endforeach (it)
  27. if (NEED_REPLACE)
  28. string ( CONFIGURE "${LITERAL}" _REPLACED @ONLY )
  29. set ( "${TEXT}" "${_REPLACED}" PARENT_SCOPE )
  30. endif ()
  31. endfunction ()
  32. # generate custom header NAME.h from given text file placed on TEXTPATH
  33. # if 'file' doesnt exist, but 'file.in' exists, it will be loaded and configured
  34. function ( HSNIPPET NAME TEXTPATH )
  35. set ( _SRCFILE "${CMAKE_CURRENT_SOURCE_DIR}/${TEXTPATH}" )
  36. message ( STATUS "Generate ${NAME}.h from ${_SRCFILE}" )
  37. if (EXISTS "${_SRCFILE}")
  38. # just copy content as-is
  39. FILE ( READ "${_SRCFILE}" _SNIPPET )
  40. elseif (EXISTS "${_SRCFILE}.in")
  41. set ( _SRCFILE "${_SRCFILE}.in" )
  42. # file is the template - need to configure it first
  43. FILE ( READ "${_SRCFILE}" _SN )
  44. testvars ( _SN )
  45. string ( CONFIGURE "${_SN}" _SNIPPET @ONLY )
  46. else ()
  47. message ( FATAL_ERROR "Could not find ${TEXTPATH} to configure literal ${NAME}" )
  48. endif ()
  49. SET ( SNIPPETNAME "${NAME}" )
  50. string ( TOUPPER "${NAME}" UPNAME )
  51. configure_file ( "${MANTICORE_SOURCE_DIR}/src/literal.h.in"
  52. "${MANTICORE_BINARY_DIR}/config/${NAME}.h" @ONLY )
  53. set ( HAVE_${UPNAME}_H TRUE PARENT_SCOPE )
  54. endfunction ()
  55. # if filepath tailed with '.in', remove that extension
  56. function ( STRIP_IN FILEPATH OUTVAR )
  57. string ( FIND "${FILEPATH}" ".in" _need REVERSE )
  58. string ( LENGTH "${FILEPATH}" _len )
  59. math ( EXPR _diff "${_len}-${_need}-3" )
  60. if (${_diff} EQUAL 0)
  61. string ( SUBSTRING "${FILEPATH}" 0 ${_need} _TEMPLATE )
  62. set ( "${OUTVAR}" "${_TEMPLATE}" PARENT_SCOPE )
  63. endif ()
  64. endfunction ()
  65. # generate custom header folderpath.h from given text files of FOLDERGLOB using
  66. # template file (like myheader.h.in) inside.
  67. # Example usage:
  68. # hsnippetfolder ( "charsets/*.txt" "charsets/globalaliases.h.in" )
  69. # will use globalaliases.h.in, fill it with content of *.txt files and
  70. # save globalaliases.h as result (and set HAVE_GLOBALALIASES_H def for compiler)
  71. function ( HSNIPPETFOLDER FOLDERGLOB TEMPLATE )
  72. # variable for verbose output
  73. set ( DIAGNOSTIC 0 )
  74. # prepare path of final generated file and internal name
  75. STRIP_IN ( "${TEMPLATE}" TARGET_FILE )
  76. GET_FILENAME_COMPONENT ( TARGET_FILE ${TARGET_FILE} NAME )
  77. # snippetname is config variable
  78. GET_FILENAME_COMPONENT ( SNIPPETNAME ${TARGET_FILE} NAME_WE )
  79. SET ( TARGET_HDR "${MANTICORE_BINARY_DIR}/config/${TARGET_FILE}" )
  80. # snippetnameupper is config variable
  81. string ( TOUPPER "${SNIPPETNAME}" SNIPPETNAMEUPPER )
  82. # _SRCFILE is config variable
  83. SET ( _SRCFILE "${TEMPLATE}" )
  84. diags ( "Configured variables available for substitution are:" )
  85. diag ( SNIPPETNAME )
  86. diag ( SNIPPETNAMEUPPER )
  87. diag ( _SRCFILE )
  88. message ( STATUS "Generate ${TARGET_FILE} from ${FOLDERGLOB}" )
  89. # now parse the template and extract lines end with @DELIMITER@
  90. FILE ( READ "${TEMPLATE}" _SNIPPET )
  91. SET ( TEMPLATE "${_SNIPPET}" )
  92. # escape ';' (if any), lf into ';' (it makes list from the line)
  93. STRING ( REGEX REPLACE "\\\\\n" " " _SNIPPET "${_SNIPPET}" )
  94. STRING ( REGEX REPLACE ";" "\\\\;" _SNIPPET "${_SNIPPET}" )
  95. STRING ( REGEX REPLACE "\n" ";" _SNIPPET "${_SNIPPET}" )
  96. set ( CLAUSES "" )
  97. set ( NUMCLAUSE 0 )
  98. FOREACH (LINE ${_SNIPPET})
  99. IF ("${LINE}" MATCHES "@DELIMITER@$")
  100. set ( CLAUSE "CLAUSE${NUMCLAUSE}" )
  101. set ( ${CLAUSE} "" )
  102. string ( REPLACE "${LINE}" "@${CLAUSE}@" TEMPLATE "${TEMPLATE}" )
  103. math ( EXPR NUMCLAUSE "${NUMCLAUSE}+1" )
  104. string ( REPLACE "@DELIMITER@" "" LINE "${LINE}" )
  105. list ( APPEND CLAUSES "${LINE}" )
  106. # diag (LINE)
  107. endif ()
  108. endforeach ()
  109. # diag ( CLAUSES )
  110. # diag ( TEMPLATE )
  111. # here TEMPLATE contains all lines ended with @DELIMITER@ replaced to @CLAUSE<NUM>@
  112. # CLAUSES is the list of that lines with original text, but without '@DELIMITER@' trailer.
  113. # now we can walk over the files and generate actual clauses from them.
  114. file ( GLOB MEMBERS "${FOLDERGLOB}" )
  115. FOREACH (MEMBER ${MEMBERS})
  116. GET_FILENAME_COMPONENT ( _SNIPPETNAME ${MEMBER} NAME_WE )
  117. string ( TOUPPER "${_SNIPPETNAME}" _SNIPPETNAMEUPPER )
  118. # string ( TOLOWER "${_SNIPPETNAME}" _SNIPPETNAME )
  119. FILE ( READ "${MEMBER}" _SNIPPET )
  120. # diag ( _SNIPPET )
  121. # diag ( _SNIPPETNAME )
  122. # diag ( _SNIPPETNAMEUPPER )
  123. # split _SNIPPET into a list of 1k chunks
  124. string ( LENGTH "${_SNIPPET}" _SNIPPETLEN )
  125. set ( _SNIPPET2 "" )
  126. if (NOT _SNIPPETLEN EQUAL 0)
  127. set ( _CHUNKSIZE 1024 )
  128. math ( EXPR _NUMCHUNKS "${_SNIPPETLEN}/${_CHUNKSIZE}" )
  129. math ( EXPR _LEFTOVER "${_SNIPPETLEN}%${_CHUNKSIZE}" )
  130. if (_LEFTOVER GREATER 0)
  131. math ( EXPR _NUMCHUNKS "${_NUMCHUNKS}+1" )
  132. endif ()
  133. # diag ( _SNIPPETLEN )
  134. # diag ( _NUMCHUNKS )
  135. math ( EXPR _NUMCHUNKS "${_NUMCHUNKS}-1" )
  136. FOREACH (_CHUNK RANGE "${_NUMCHUNKS}")
  137. math ( EXPR _CHUNK_START "${_CHUNK}*${_CHUNKSIZE}" )
  138. SET ( _CUR_CHUNK_SIZE ${_CHUNKSIZE} )
  139. if (_CHUNK EQUAL ${_NUMCHUNKS} AND _LEFTOVER GREATER 0)
  140. SET ( _CUR_CHUNK_SIZE "${_LEFTOVER}" )
  141. endif ()
  142. STRING ( SUBSTRING "${_SNIPPET}" "${_CHUNK_START}" ${_CUR_CHUNK_SIZE} _SUBSTR )
  143. SET ( _SNIPPET2 "${_SNIPPET2}R\"${SNIPPETNAME}(${_SUBSTR})${SNIPPETNAME}\", " )
  144. ENDFOREACH ()
  145. endif ()
  146. SET ( _SNIPPET2 "${_SNIPPET2}nullptr" )
  147. SET ( _SNIPPET "${_SNIPPET2}" )
  148. set ( NUMCLAUSE 0 )
  149. FOREACH (EXPRESSION ${CLAUSES})
  150. set ( CLAUSE "CLAUSE${NUMCLAUSE}" )
  151. math ( EXPR NUMCLAUSE "${NUMCLAUSE}+1" )
  152. string ( CONFIGURE "${EXPRESSION}" _REPLACED @ONLY )
  153. set ( ${CLAUSE} "${${CLAUSE}}${_REPLACED},\n" )
  154. # diag ( ${CLAUSE} )
  155. ENDFOREACH ()
  156. ENDFOREACH ()
  157. string ( CONFIGURE "${TEMPLATE}" FINALHEADER @ONLY )
  158. # diag ( FINALHEADER )
  159. diag ( TARGET_HDR )
  160. file ( WRITE "${TARGET_HDR}1" "${FINALHEADER}" )
  161. configure_file ( "${TARGET_HDR}1" "${TARGET_HDR}" COPYONLY )
  162. file ( REMOVE "${TARGET_HDR}1" )
  163. set ( HAVE_${SNIPPETNAMEUPPER}_H TRUE PARENT_SCOPE )
  164. endfunction ()