aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--third-party/cmake/BuildLibvterm.cmake9
-rw-r--r--third-party/cmake/Libvterm-tbl2inc_c.cmake163
-rw-r--r--third-party/cmake/LibvtermCMakeLists.txt43
3 files changed, 200 insertions, 15 deletions
diff --git a/third-party/cmake/BuildLibvterm.cmake b/third-party/cmake/BuildLibvterm.cmake
index f37fca56dd..e4649986af 100644
--- a/third-party/cmake/BuildLibvterm.cmake
+++ b/third-party/cmake/BuildLibvterm.cmake
@@ -42,9 +42,12 @@ if(WIN32)
${CMAKE_CURRENT_SOURCE_DIR}/patches/libvterm-Remove-VLAs-for-MSVC.patch)
endif()
set(LIBVTERM_CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy
- ${CMAKE_CURRENT_SOURCE_DIR}/cmake/LibvtermCMakeLists.txt
- ${DEPS_BUILD_DIR}/src/libvterm/CMakeLists.txt
- COMMAND ${CMAKE_COMMAND} ${DEPS_BUILD_DIR}/src/libvterm
+ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/LibvtermCMakeLists.txt
+ ${DEPS_BUILD_DIR}/src/libvterm/CMakeLists.txt
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Libvterm-tbl2inc_c.cmake
+ ${DEPS_BUILD_DIR}/src/libvterm/tbl2inc_c.cmake
+ COMMAND ${CMAKE_COMMAND} ${DEPS_BUILD_DIR}/src/libvterm
-DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
"-DCMAKE_C_FLAGS:STRING=${CMAKE_C_COMPILER_ARG1} -fPIC"
diff --git a/third-party/cmake/Libvterm-tbl2inc_c.cmake b/third-party/cmake/Libvterm-tbl2inc_c.cmake
new file mode 100644
index 0000000000..b1ee0246f1
--- /dev/null
+++ b/third-party/cmake/Libvterm-tbl2inc_c.cmake
@@ -0,0 +1,163 @@
+cmake_minimum_required(VERSION 2.8.7)
+
+set(HEX_ALPHABET "0123456789abcdef")
+
+function(ConvertToHex dec hex)
+ while(dec GREATER 0)
+ math(EXPR _val "${dec} % 16")
+ math(EXPR dec "${dec} / 16")
+ string(SUBSTRING ${HEX_ALPHABET} ${_val} 1 _val)
+ set(_res "${_val}${_res}")
+ endwhile()
+ # Pad the result with the number of zeros
+ # specified by the optional third argument
+ if(${ARGC} EQUAL 3)
+ set(padding ${ARGV2})
+ string(LENGTH ${_res} _resLen)
+ if(_resLen LESS ${padding})
+ math(EXPR _neededPadding "${padding} - ${_resLen}")
+ foreach(i RANGE 1 ${_neededPadding})
+ set(_res "0${_res}")
+ endforeach()
+ endif()
+ endif()
+ set(${hex} "0x${_res}" PARENT_SCOPE)
+endfunction()
+
+function(ConvertFromHex hex dec)
+ string(TOLOWER ${hex} hex)
+ string(LENGTH "${hex}" _strlen)
+ set(_res 0)
+ while(_strlen GREATER 0)
+ math(EXPR _res "${_res} * 16")
+ string(SUBSTRING "${hex}" 0 1 NIBBLE)
+ string(SUBSTRING "${hex}" 1 -1 hex)
+ string(FIND ${HEX_ALPHABET} ${NIBBLE} value)
+ if(value EQUAL -1)
+ message(FATAL_ERROR "Invalid hex character '${NIBBLE}'")
+ endif()
+ math(EXPR _res "${_res} + ${value}")
+ string(LENGTH "${hex}" _strlen)
+ endwhile()
+ set(${dec} ${_res} PARENT_SCOPE)
+endfunction()
+
+# Based on http://www.json.org/JSON_checker/utf8_decode.c
+function(DecodeUtf8 hexBytes codePoint)
+ string(SUBSTRING ${hexBytes} 0 2 hexByte1)
+ ConvertFromHex(${hexByte1} byte1)
+ # Zero continuations (0 to 127)
+ math(EXPR out "${byte1} & 128")
+ if(out EQUAL 0)
+ set(${codePoint} ${byte1} PARENT_SCOPE)
+ return()
+ endif()
+ # One continuation (128 to 2047)
+ math(EXPR out "${byte1} & 224")
+ if(out EQUAL 192)
+ string(SUBSTRING ${hexBytes} 2 2 hexByte2)
+ ConvertFromHex(${hexByte2} byte2)
+ math(EXPR result "((${byte1} & 31) << 6) | ${byte2}")
+ if(result GREATER 127)
+ set(${codePoint} ${result} PARENT_SCOPE)
+ return()
+ endif()
+ else()
+ # Two continuations (2048 to 55295 and 57344 to 65535)
+ math(EXPR result "${byte1} & 240")
+ if(result EQUAL 224)
+ string(SUBSTRING ${hexBytes} 2 2 hexByte2)
+ string(SUBSTRING ${hexBytes} 4 2 hexByte3)
+ ConvertFromHex(${hexByte2} byte2)
+ ConvertFromHex(${hexByte3} byte3)
+ math(EXPR result "${byte2} | ${byte3}")
+ if(result GREATER -1)
+ math(EXPR result "((${byte1} & 15) << 12) | (${byte2} << 6) | ${byte3}")
+ if((result GREATER 2047) AND (result LESS 55296 OR result GREATER 57343))
+ set(${codePoint} ${result} PARENT_SCOPE)
+ return()
+ endif()
+ endif()
+ else()
+ # Three continuations (65536 to 1114111)
+ math(EXPR result "${byte1} & 248")
+ if(result EQUAL 224)
+ string(SUBSTRING ${hexBytes} 2 2 hexByte2)
+ string(SUBSTRING ${hexBytes} 4 2 hexByte3)
+ string(SUBSTRING ${hexBytes} 6 2 hexByte4)
+ ConvertFromHex(${hexByte2} byte2)
+ ConvertFromHex(${hexByte3} byte3)
+ ConvertFromHex(${hexByte4} byte4)
+ math(EXPR result "${byte2} | ${byte3} | ${byte4}")
+ if(result GREATER -1)
+ math(EXPR result "((c & 7) << 18) | (c1 << 12) | (c2 << 6) | c3")
+ if((result GREATER 65535) AND (result LESS 1114112))
+ set(${codePoint} ${result} PARENT_SCOPE)
+ return()
+ endif()
+ endif()
+ endif()
+ endif()
+ endif()
+ message(FATAL_ERROR "Invalid UTF-8 encoding")
+endfunction()
+
+set(inputFile ${CMAKE_ARGV3})
+set(outputFile ${CMAKE_ARGV4})
+# Get the file contents in text and hex-encoded format because
+# CMake doesn't provide functions for converting between the two
+file(READ "${inputFile}" contents)
+file(READ "${inputFile}" hexContents HEX)
+
+# Convert the text contents into a list of lines by escaping
+# the list separator ';' and then replacing new line characters
+# with the list separator
+string(REGEX REPLACE ";" "\\\\;" contents ${contents})
+string(REGEX REPLACE "\n" ";" contents ${contents})
+
+get_filename_component(encname ${inputFile} NAME_WE)
+set(output
+ "static const struct StaticTableEncoding encoding_${encname} = {\n"
+ " { .decode = &decode_table },\n"
+ " {")
+set(hexIndex 0)
+foreach(line ${contents})
+ string(LENGTH ${line} lineLength)
+ # Convert "A" to 0x41
+ string(FIND ${line} "\"" beginQuote)
+ if(NOT ${beginQuote} EQUAL -1)
+ string(FIND ${line} "\"" endQuote REVERSE)
+ if(${beginQuote} EQUAL ${endQuote})
+ message(FATAL_ERROR "Line contains only one quote")
+ endif()
+ math(EXPR beginHexQuote "${hexIndex} + (${beginQuote} + 1)*2")
+ math(EXPR endHexQuote "${hexIndex} + (${endQuote} + 1)*2")
+ math(EXPR quoteLen "${endHexQuote} - ${beginHexQuote} - 1")
+ string(SUBSTRING ${hexContents} ${beginHexQuote} ${quoteLen} hexQuote)
+ DecodeUtf8(${hexQuote} codePoint)
+ ConvertToHex(${codePoint} hexCodePoint 4)
+ STRING(REGEX REPLACE "\"(.+)\"" ${hexCodePoint} line ${line})
+ endif()
+ # Strip comment
+ string(REGEX REPLACE "[ \t\n]*#.*" "" line ${line})
+ # Convert 3/1 to [0x31]
+ string(REGEX REPLACE "^([0-9]+)/([0-9]+).*" "\\1;\\2" numbers ${line})
+ list(GET numbers 0 upperBits)
+ list(GET numbers 1 lowerBits)
+ math(EXPR res "${upperBits}*16 + ${lowerBits}")
+ ConvertToHex(${res} hex 2)
+ string(REGEX REPLACE "^([0-9]+)/([0-9]+)" "[${hex}]" line ${line})
+ # Convert U+0041 to 0x0041
+ string(REPLACE "U+" "0x" line ${line})
+ # Indent and append a comma
+ set(line " ${line},")
+ set(output "${output}\n${line}")
+ # Increment the index by the number of characters in the line,
+ # plus one for the new line character then multiple by two for the hex digit index
+ math(EXPR hexIndex "${hexIndex} + 2*(${lineLength} + 1)")
+endforeach()
+set(output "${output}\n"
+ " }\n"
+ "}\;\n")
+
+file(WRITE ${outputFile} ${output})
diff --git a/third-party/cmake/LibvtermCMakeLists.txt b/third-party/cmake/LibvtermCMakeLists.txt
index 72183e4b4c..27d0d11e9f 100644
--- a/third-party/cmake/LibvtermCMakeLists.txt
+++ b/third-party/cmake/LibvtermCMakeLists.txt
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8.11)
project(libvterm LANGUAGES C)
include(GNUInstallDirs)
-find_package(Perl REQUIRED)
+find_package(Perl)
if(MSVC)
add_definitions(/W3 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
@@ -18,11 +18,19 @@ foreach(file ${TBL_FILES})
set(tname encoding/${basename}.inc)
add_custom_command(OUTPUT
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/encoding/
- COMMAND ${PERL_EXECUTABLE} -CSD ${CMAKE_SOURCE_DIR}/tbl2inc_c.pl ${file} > ${CMAKE_BINARY_DIR}/${tname}
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/tbl2inc_c.cmake ${file} ${CMAKE_BINARY_DIR}/${tname}
COMMENT "Generating ${tname}"
OUTPUT ${CMAKE_BINARY_DIR}/${tname}
)
list(APPEND TBL_FILES_HEADERS ${tname})
+ # Only used for verifying that the output of tbl2inc_c.cmake is correct
+ set(tname encoding-test/${basename}.inc)
+ add_custom_command(OUTPUT
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/encoding-test/
+ COMMAND ${PERL_EXECUTABLE} -CSD ${CMAKE_SOURCE_DIR}/tbl2inc_c.pl ${file} > ${CMAKE_BINARY_DIR}/${tname}
+ COMMENT "Generating ${tname}"
+ OUTPUT ${CMAKE_BINARY_DIR}/${tname}
+ )
endforeach()
include_directories(${CMAKE_SOURCE_DIR}/include)
@@ -60,13 +68,24 @@ set_target_properties(harness PROPERTIES
# run-test.pl expects to find the harness in t/.libs/
RUNTIME_OUTPUT_DIRECTORY t/.libs)
-file(GLOB TESTFILES ${CMAKE_SOURCE_DIR}/t/*.test)
-add_custom_target(check)
-foreach(testfile ${TESTFILES})
- get_filename_component(target_name ${testfile} NAME_WE)
- add_custom_target(${target_name}
- COMMAND ${PERL_EXECUTABLE} ${CMAKE_SOURCE_DIR}/t/run-test.pl ${testfile}
- COMMENT "**${target_name} **"
- DEPENDS harness)
- add_dependencies(check ${target_name})
-endforeach()
+if(Perl_FOUND)
+ file(GLOB TESTFILES ${CMAKE_SOURCE_DIR}/t/*.test)
+ add_custom_target(check)
+ foreach(testfile ${TESTFILES})
+ get_filename_component(target_name ${testfile} NAME_WE)
+ add_custom_target(${target_name}
+ COMMAND ${PERL_EXECUTABLE} ${CMAKE_SOURCE_DIR}/t/run-test.pl ${testfile}
+ COMMENT "**${target_name} **"
+ DEPENDS harness)
+ add_dependencies(check ${target_name})
+ endforeach()
+
+ foreach(header_path ${TBL_FILES_HEADERS})
+ get_filename_component(header_name ${header_path} NAME)
+ set(perl_header_path ${CMAKE_BINARY_DIR}/encoding-test/${header_name})
+ add_custom_target(test-${header_name}
+ COMMAND ${CMAKE_COMMAND} -E compare_files
+ ${header_path} ${perl_header_path}
+ DEPENDS ${header_path} ${perl_header_path})
+ endforeach()
+endif()