Browse Source

CMake: Update version file parser

pull/114/head
Daniel Scharrer 6 years ago
parent
commit
401ac25496
  1. 91
      cmake/VersionScript.cmake
  2. 224
      cmake/VersionString.cmake
  3. 2
      doc/innoextract.1.in
  4. 4
      src/release.cpp.in

91
cmake/VersionScript.cmake

@ -1,5 +1,5 @@
# Copyright (C) 2011-2016 Daniel Scharrer
# Copyright (C) 2011-2020 Daniel Scharrer
#
# This software is provided 'as-is', without any express or implied
# warranty. In no event will the author(s) be held liable for any damages
@ -26,102 +26,29 @@ if((NOT DEFINED INPUT) OR (NOT DEFINED OUTPUT) OR (NOT DEFINED VERSION_SOURCES)
message(SEND_ERROR "Invalid arguments.")
endif()
include("${CMAKE_CURRENT_LIST_DIR}/VersionString.cmake")
# configure_file doesn't handle newlines correctly - pre-escape variables
function(escape_var VAR)
macro(_version_escape var string)
# Escape the escape character and quotes
string(REGEX REPLACE "([\\\\\"])" "\\\\\\1" escaped "${${VAR}}")
string(REGEX REPLACE "([\\\\\"])" "\\\\\\1" ${var} "${string}")
# Pull newlines out of string
string(REGEX REPLACE "\n" "\\\\n\"\n\t\"" escaped "${escaped}")
set(${VAR} "${escaped}" PARENT_SCOPE)
endfunction(escape_var)
string(REGEX REPLACE "\n" "\\\\n\"\n\t\"" ${var} "${${var}}")
endmacro()
set(var "")
foreach(arg IN LISTS VERSION_SOURCES)
if(var STREQUAL "")
set(var ${arg})
else()
file(READ "${arg}" ${var})
string(STRIP "${${var}}" ${var})
string(REGEX REPLACE "\r\n" "\n" ${var} "${${var}}")
string(REGEX REPLACE "\r" "\n" ${var} "${${var}}")
# Split the version file into lines.
string(REGEX MATCHALL "[^\r\n]+" lines "${${var}}")
set(${var}_COUNT 0)
foreach(line IN LISTS lines)
set(${var}_${${var}_COUNT} "${line}")
escape_var(${var}_${${var}_COUNT})
# Find the first and last spaces
string(STRIP "${line}" line)
string(LENGTH "${line}" line_length)
set(first_space -1)
set(last_space ${line_length})
foreach(i RANGE ${line_length})
if(i LESS line_length)
string(SUBSTRING "${line}" ${i} 1 line_char)
if(line_char STREQUAL " ")
set(last_space ${i})
if(first_space EQUAL -1)
set(first_space ${i})
endif()
endif()
endif()
endforeach()
if(first_space GREATER -1)
# Get everything before the first space
string(SUBSTRING "${line}" 0 ${first_space} line_name)
string(STRIP "${line_name}" ${var}_${${var}_COUNT}_SHORTNAME)
escape_var(${var}_${${var}_COUNT}_SHORTNAME)
# Get everything after the first space
math(EXPR num_length "${line_length} - ${first_space}")
string(SUBSTRING "${line}" ${first_space} ${num_length} line_num)
string(STRIP "${line_num}" ${var}_${${var}_COUNT}_STRING)
escape_var(${var}_${${var}_COUNT}_STRING)
endif()
if(line MATCHES " ([0-9]\\.[^ ]* \\+ )?[^ ]*$")
string(REGEX REPLACE " (([0-9]\\.[^ ]* \\+ )?[^ ]*)$" ""
${var}_${${var}_COUNT}_NAME "${line}")
string(LENGTH ${${var}_${${var}_COUNT}_NAME} begin)
math(EXPR begin "${begin} + 1")
math(EXPR length "${line_length} - ${begin}")
string(SUBSTRING "${line}" "${begin}" "${length}" ${var}_${${var}_COUNT}_NUMBER)
else()
set(${var}_${${var}_COUNT}_NAME "${line}")
set(${var}_${${var}_COUNT}_NUMBER)
endif()
escape_var(${var}_${${var}_COUNT}_NAME)
escape_var(${var}_${${var}_COUNT}_NUMBER)
math(EXPR ${var}_COUNT "${${var}_COUNT} + 1")
endforeach()
string(REGEX REPLACE "\n\n.*$" "" ${var}_HEAD "${${var}}")
string(STRIP "${${var}_HEAD}" ${var}_HEAD)
string(REGEX MATCH "\n\n.*" ${var}_TAIL "${${var}}")
string(STRIP "${${var}_TAIL}" ${var}_TAIL)
escape_var(${var})
escape_var(${var}_HEAD)
escape_var(${var}_TAIL)
parse_version_file(${var} "${arg}" ON)
set(var "")
endif()
endforeach()
# Check for a git directory and fill in the git commit hash if one exists.
unset(GIT_COMMIT)
if(EXISTS "${GIT_DIR}")
if(NOT GIT_DIR STREQUAL "")
unset(git_head)

224
cmake/VersionString.cmake

@ -1,5 +1,5 @@
# Copyright (C) 2011-2016 Daniel Scharrer
# Copyright (C) 2011-2020 Daniel Scharrer
#
# This software is provided 'as-is', without any express or implied
# warranty. In no event will the author(s) be held liable for any damages
@ -17,8 +17,7 @@
# misrepresented as being the original software.
# 3. This notice may not be removed or altered from any source distribution.
get_filename_component(VERSION_STRING_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
set(VERSION_STRING_SCRIPT "${VERSION_STRING_DIR}/VersionScript.cmake")
set(VERSION_STRING_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/VersionScript.cmake")
# Create a rule to generate a version string at compile time.
#
@ -33,11 +32,20 @@ set(VERSION_STRING_SCRIPT "${VERSION_STRING_DIR}/VersionScript.cmake")
# for each variable ${var}
# - ${var}: The contents of the associated file
# - ${var}_COUNT: Number of lines in the associated file
# - ${var}_${i}: The ${i}-th line of the associated file
# - ${var}_${i}_SHORTNAME: The first component of the ${i}-th line of the associated file
# - ${var}_${i}_STRING: Everything except the first component of the ${i}-th line of the associated file
# - ${var}_${i}_NAME: Everything except the last component of the ${i}-th line of the associated file
# - ${var}_${i}_NUMBER: The last component of the ${i}-th line of the associated file
# - For each line ${i}:
# - ${var}_${i}: The ${i}-th line of the associated file
# - ${var}_${i}_PREFIX: The first component in the line
# - ${var}_${i}_LINE: Everything except the first component of the line
# - ${var}_${i}_NAME: Everything except the last component of the line
# - ${var}_${i}_STRING: The last component (excluding optional suffix) of the line
# - ${var}_${i}_SUFFIX: Suffix (seperated by " + ") of the line
# - ${var}_${i}_MAJOR: First version component in ${var}_${i}_STRING
# - ${var}_${i}_MINOR: Second version component in ${var}_${i}_STRING
# - ${var}_${i}_PATCH: Third version component in ${var}_${i}_STRING
# - ${var}_${i}_BUILD: Fourth version component in ${var}_${i}_STRING
# - ${var}_${i}_NUMBER: Reassembled verion components
# - ${var}_${i}_PRERELEASE: If the version indicates a prerelease build
# - ${var}_${i}_PRIVATE: If the version indicates a private build
# - ${var}_HEAD: The first paragraph of the associated file
# - ${var}_TAIL: The remaining paragraphs of the associated file
#
@ -92,6 +100,8 @@ function(version_file SRC DST VERSION_SOURCES GIT_DIR)
if(EXISTS "${abs_git_dir}/logs/HEAD")
list(APPEND dependencies "${abs_git_dir}/logs/HEAD")
endif()
else()
set(abs_git_dir "")
endif()
add_custom_command(
@ -106,6 +116,8 @@ function(version_file SRC DST VERSION_SOURCES GIT_DIR)
"-DGIT_COMMAND=${GIT_COMMAND}"
${defines}
-P "${VERSION_STRING_SCRIPT}"
COMMAND
${CMAKE_COMMAND} -E touch "${abs_dst}"
MAIN_DEPENDENCY
"${abs_src}"
DEPENDS
@ -114,4 +126,198 @@ function(version_file SRC DST VERSION_SOURCES GIT_DIR)
VERBATIM
)
endfunction(version_file)
endfunction()
macro(_version_escape var string)
set(${var} "${string}")
endmacro()
macro(_define_version_var_nostrip suffix contents)
_version_escape(${var}_${suffix} "${${contents}}")
list(APPEND variables ${var}_${suffix})
endmacro()
macro(_define_version_var suffix contents)
string(STRIP "${${contents}}" tmp)
_define_version_var_nostrip(${suffix} tmp)
endmacro()
macro(_define_version_line_var_nostrip suffix contents)
_define_version_var_nostrip(${i}_${suffix} ${contents})
if(line_name)
set(${line_name}_${suffix} "${${var}_${i}_${suffix}}")
list(APPEND variables ${line_name}_${suffix})
endif()
endmacro()
macro(_define_version_line_var suffix contents)
string(STRIP "${${contents}}" tmp)
_define_version_line_var_nostrip(${suffix} tmp)
endmacro()
function(parse_version_file names file)
list(GET names 0 var)
list(LENGTH names names_count)
set(variables)
file(READ "${file}" contents)
string(STRIP "${contents}" contents)
string(REGEX REPLACE "\r\n" "\n" contents "${contents}")
string(REGEX REPLACE "\r" "\n" contents "${contents}")
_version_escape(${var} "${contents}")
list(APPEND variables ${var})
# Split the version file into lines.
string(REGEX MATCHALL "[^\r\n]+" lines "${contents}")
set(i 0)
foreach(line IN LISTS lines)
if(i LESS names_count)
list(GET names ${i} line_name)
else()
set(line_name)
endif()
_define_version_var(${i} line)
if(line MATCHES "^([^ ]*) (.*)$")
set(prefix "${CMAKE_MATCH_1}")
set(notprefix "${CMAKE_MATCH_2}")
_define_version_line_var(PREFIX prefix)
_define_version_line_var(LINE notprefix)
else()
_define_version_line_var(PREFIX line)
endif()
if(line MATCHES "^(.*[^+] )?([^ ]+)( \\+ [^ ]+)?$")
set(name "${CMAKE_MATCH_1}")
set(string "${CMAKE_MATCH_2}")
set(suffix "${CMAKE_MATCH_3}")
_define_version_line_var(NAME name)
_define_version_line_var(STRING string)
_define_version_line_var_nostrip(SUFFIX suffix)
if(i GREATER 0 AND line_name)
set(${line_name} "${${var}_${i}_STRING}")
list(APPEND variables ${line_name})
endif()
if(string MATCHES "^([0-9]+)(\\.([0-9]+)(\\.([0-9]+)(\\.([0-9]+))?)?)?(.*)?$")
set(major "${CMAKE_MATCH_1}")
set(minor "${CMAKE_MATCH_3}")
set(patch "${CMAKE_MATCH_5}")
set(build "${CMAKE_MATCH_7}")
set(release "${CMAKE_MATCH_8}")
set(error 0)
set(newpatch)
set(newbuild)
set(prerelease 0)
set(private 0)
if(release MATCHES "^\\-dev\\-([2-9][0-9][0-9][0-9]+)\\-([0-9][0-9])\\-([0-9][0-9])$")
set(prerelease 1)
set(newpatch "${CMAKE_MATCH_1}")
set(newbuild "${CMAKE_MATCH_2}${CMAKE_MATCH_3}")
elseif(release MATCHES "^\\-rc([0-9]+)$")
set(prerelease 1)
set(newpatch "9999")
set(newbuild "${CMAKE_MATCH_1}")
elseif(release MATCHES "^\\-r([0-9]+)$")
if(build STREQUAL "")
set(build "${CMAKE_MATCH_1}")
else()
set(error 1)
endif()
elseif(release OR suffix)
set(prerelease 1)
set(private 1)
set(newpatch 9999)
set(newbuild 9999)
endif()
foreach(component IN ITEMS major minor patch build newpatch newbuild)
string(REGEX REPLACE "^0+" "" ${component} "${${component}}")
if(NOT ${component})
set(${component} 0)
endif()
endforeach()
if(newpatch)
set(prerelease 1)
if(build)
set(error 1)
else()
if(patch)
if(newpatch EQUAL 9999)
math(EXPR patch "${patch} - 1")
if(newbuild EQUAL 9999)
set(build 9999)
else()
math(EXPR build "${newbuild} + 1000")
endif()
else()
set(error 1)
endif()
else()
if(minor)
math(EXPR minor "${minor} - 1")
else()
if(major)
math(EXPR major "${major} - 1")
else()
set(error 1)
endif()
set(minor 9999)
endif()
set(patch "${newpatch}")
set(build "${newbuild}")
endif()
endif()
endif()
set(number "${major}")
if(minor OR patch OR build)
set(number "${number}.${minor}")
if(patch OR build)
set(number "${number}.${patch}")
if(build)
set(number "${number}.${build}")
endif()
endif()
endif()
_define_version_line_var(MAJOR major)
_define_version_line_var(MINOR minor)
_define_version_line_var(PATCH patch)
_define_version_line_var(BUILD build)
_define_version_line_var(PRERELEASE prerelease)
_define_version_line_var(PRIVATE private)
_define_version_line_var(NUMBER number)
_define_version_line_var(ERROR error)
endif()
endif()
math(EXPR i "${i} + 1")
endforeach()
set(${var}_COUNT ${i} PARENT_SCOPE)
string(REGEX REPLACE "\n\n.*$" "" head "${contents}")
_define_version_var(HEAD head)
string(REGEX MATCH "\n\n.*" tail "${contents}")
_define_version_var(TAIL tail)
foreach(var IN LISTS variables)
set(${var} "${${var}}" PARENT_SCOPE)
endforeach()
endfunction()

2
doc/innoextract.1.in

@ -1,6 +1,6 @@
.\" Manpage for innoextract.
.\" Contact daniel@constexpr.org to correct errors or typos.
.TH innoextract 1 "@CHANGELOG_0_NUMBER@" "@VERSION_0_NUMBER@@GIT_SUFFIX_7@"
.TH innoextract 1 "@CHANGELOG_0_STRING@" "@VERSION_0_STRING@@VERSION_SUFFIX@@GIT_SUFFIX_7@"
.SH NAME
innoextract - tool to extract installers created by Inno Setup
.SH SYNOPSIS

4
src/release.cpp.in

@ -38,12 +38,12 @@
const char innoextract_name[] = "${VERSION_0_NAME}";
const char innoextract_version[] = "${VERSION_0_NUMBER}${GIT_SUFFIX_7}";
const char innoextract_version[] = "${VERSION_0_STRING}${VERSION_SUFFIX}${GIT_SUFFIX_7}";
const char innosetup_versions[] = "${VERSION_2}";
const char innoextract_bugs[] = "${VERSION_4}";
const char innoextract_copyright[] = "${LICENSE_0_STRING}";
const char innoextract_copyright[] = "${LICENSE_0_LINE}";
const char innoextract_license[] = "${LICENSE_TAIL}";

Loading…
Cancel
Save