Libvterm-tbl2inc_c.cmake 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. cmake_minimum_required(VERSION 2.8.12)
  2. set(HEX_ALPHABET "0123456789abcdef")
  3. function(ConvertToHex dec hex)
  4. while(dec GREATER 0)
  5. math(EXPR _val "${dec} % 16")
  6. math(EXPR dec "${dec} / 16")
  7. string(SUBSTRING ${HEX_ALPHABET} ${_val} 1 _val)
  8. set(_res "${_val}${_res}")
  9. endwhile()
  10. # Pad the result with the number of zeros
  11. # specified by the optional third argument
  12. if(${ARGC} EQUAL 3)
  13. set(padding ${ARGV2})
  14. string(LENGTH ${_res} _resLen)
  15. if(_resLen LESS ${padding})
  16. math(EXPR _neededPadding "${padding} - ${_resLen}")
  17. foreach(i RANGE 1 ${_neededPadding})
  18. set(_res "0${_res}")
  19. endforeach()
  20. endif()
  21. endif()
  22. set(${hex} "0x${_res}" PARENT_SCOPE)
  23. endfunction()
  24. function(ConvertFromHex hex dec)
  25. string(TOLOWER ${hex} hex)
  26. string(LENGTH "${hex}" _strlen)
  27. set(_res 0)
  28. while(_strlen GREATER 0)
  29. math(EXPR _res "${_res} * 16")
  30. string(SUBSTRING "${hex}" 0 1 NIBBLE)
  31. string(SUBSTRING "${hex}" 1 -1 hex)
  32. string(FIND ${HEX_ALPHABET} ${NIBBLE} value)
  33. if(value EQUAL -1)
  34. message(FATAL_ERROR "Invalid hex character '${NIBBLE}'")
  35. endif()
  36. math(EXPR _res "${_res} + ${value}")
  37. string(LENGTH "${hex}" _strlen)
  38. endwhile()
  39. set(${dec} ${_res} PARENT_SCOPE)
  40. endfunction()
  41. # Based on http://www.json.org/JSON_checker/utf8_decode.c
  42. function(DecodeUtf8 hexBytes codePoint)
  43. string(SUBSTRING ${hexBytes} 0 2 hexByte1)
  44. ConvertFromHex(${hexByte1} byte1)
  45. # Zero continuations (0 to 127)
  46. math(EXPR out "${byte1} & 128")
  47. if(out EQUAL 0)
  48. set(${codePoint} ${byte1} PARENT_SCOPE)
  49. return()
  50. endif()
  51. # One continuation (128 to 2047)
  52. math(EXPR out "${byte1} & 224")
  53. if(out EQUAL 192)
  54. string(SUBSTRING ${hexBytes} 2 2 hexByte2)
  55. ConvertFromHex(${hexByte2} byte2)
  56. math(EXPR result "((${byte1} & 31) << 6) | ${byte2}")
  57. if(result GREATER 127)
  58. set(${codePoint} ${result} PARENT_SCOPE)
  59. return()
  60. endif()
  61. else()
  62. # Two continuations (2048 to 55295 and 57344 to 65535)
  63. math(EXPR result "${byte1} & 240")
  64. if(result EQUAL 224)
  65. string(SUBSTRING ${hexBytes} 2 2 hexByte2)
  66. string(SUBSTRING ${hexBytes} 4 2 hexByte3)
  67. ConvertFromHex(${hexByte2} byte2)
  68. ConvertFromHex(${hexByte3} byte3)
  69. math(EXPR result "${byte2} | ${byte3}")
  70. if(result GREATER -1)
  71. math(EXPR result "((${byte1} & 15) << 12) | (${byte2} << 6) | ${byte3}")
  72. if((result GREATER 2047) AND (result LESS 55296 OR result GREATER 57343))
  73. set(${codePoint} ${result} PARENT_SCOPE)
  74. return()
  75. endif()
  76. endif()
  77. else()
  78. # Three continuations (65536 to 1114111)
  79. math(EXPR result "${byte1} & 248")
  80. if(result EQUAL 224)
  81. string(SUBSTRING ${hexBytes} 2 2 hexByte2)
  82. string(SUBSTRING ${hexBytes} 4 2 hexByte3)
  83. string(SUBSTRING ${hexBytes} 6 2 hexByte4)
  84. ConvertFromHex(${hexByte2} byte2)
  85. ConvertFromHex(${hexByte3} byte3)
  86. ConvertFromHex(${hexByte4} byte4)
  87. math(EXPR result "${byte2} | ${byte3} | ${byte4}")
  88. if(result GREATER -1)
  89. math(EXPR result "((c & 7) << 18) | (c1 << 12) | (c2 << 6) | c3")
  90. if((result GREATER 65535) AND (result LESS 1114112))
  91. set(${codePoint} ${result} PARENT_SCOPE)
  92. return()
  93. endif()
  94. endif()
  95. endif()
  96. endif()
  97. endif()
  98. message(FATAL_ERROR "Invalid UTF-8 encoding")
  99. endfunction()
  100. set(inputFile ${CMAKE_ARGV3})
  101. set(outputFile ${CMAKE_ARGV4})
  102. # Get the file contents in text and hex-encoded format because
  103. # CMake doesn't provide functions for converting between the two
  104. file(READ "${inputFile}" contents)
  105. file(READ "${inputFile}" hexContents HEX)
  106. # Convert the text contents into a list of lines by escaping
  107. # the list separator ';' and then replacing new line characters
  108. # with the list separator
  109. string(REGEX REPLACE ";" "\\\\;" contents ${contents})
  110. string(REGEX REPLACE "\n" ";" contents ${contents})
  111. get_filename_component(encname ${inputFile} NAME_WE)
  112. set(output
  113. "static const struct StaticTableEncoding encoding_${encname} = {\n"
  114. " { .decode = &decode_table },\n"
  115. " {")
  116. set(hexIndex 0)
  117. foreach(line ${contents})
  118. string(LENGTH ${line} lineLength)
  119. # Convert "A" to 0x41
  120. string(FIND ${line} "\"" beginQuote)
  121. if(NOT ${beginQuote} EQUAL -1)
  122. string(FIND ${line} "\"" endQuote REVERSE)
  123. if(${beginQuote} EQUAL ${endQuote})
  124. message(FATAL_ERROR "Line contains only one quote")
  125. endif()
  126. math(EXPR beginHexQuote "${hexIndex} + (${beginQuote} + 1)*2")
  127. math(EXPR endHexQuote "${hexIndex} + (${endQuote} + 1)*2")
  128. math(EXPR quoteLen "${endHexQuote} - ${beginHexQuote} - 1")
  129. string(SUBSTRING ${hexContents} ${beginHexQuote} ${quoteLen} hexQuote)
  130. DecodeUtf8(${hexQuote} codePoint)
  131. ConvertToHex(${codePoint} hexCodePoint 4)
  132. STRING(REGEX REPLACE "\"(.+)\"" ${hexCodePoint} line ${line})
  133. endif()
  134. # Strip comment
  135. string(REGEX REPLACE "[ \t\n]*#.*" "" line ${line})
  136. # Convert 3/1 to [0x31]
  137. string(REGEX REPLACE "^([0-9]+)/([0-9]+).*" "\\1;\\2" numbers ${line})
  138. list(GET numbers 0 upperBits)
  139. list(GET numbers 1 lowerBits)
  140. math(EXPR res "${upperBits}*16 + ${lowerBits}")
  141. ConvertToHex(${res} hex 2)
  142. string(REGEX REPLACE "^([0-9]+)/([0-9]+)" "[${hex}]" line ${line})
  143. # Convert U+0041 to 0x0041
  144. string(REPLACE "U+" "0x" line ${line})
  145. # Indent and append a comma
  146. set(line " ${line},")
  147. set(output "${output}\n${line}")
  148. # Increment the index by the number of characters in the line,
  149. # plus one for the new line character then multiple by two for the hex digit index
  150. math(EXPR hexIndex "${hexIndex} + 2*(${lineLength} + 1)")
  151. endforeach()
  152. set(output "${output}\n"
  153. " }\n"
  154. "}\;\n")
  155. file(WRITE ${outputFile} ${output})