Hello community,

here is the log from the commit of package innoextract for openSUSE:Factory 
checked in at 2016-03-26 15:29:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/innoextract (Old)
 and      /work/SRC/openSUSE:Factory/.innoextract.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "innoextract"

Changes:
--------
--- /work/SRC/openSUSE:Factory/innoextract/innoextract.changes  2016-03-17 
16:48:45.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.innoextract.new/innoextract.changes     
2016-03-26 17:28:03.000000000 +0100
@@ -1,0 +2,14 @@
+Fri Mar 25 08:30:00 UTC 2016 - mplus...@suse.com
+
+- Update to 1.6
+  * Added support for Inno Setup 5.5.7 (and 5.5.8) installers
+  * Added a --collisions=rename-all option
+  * Fixed issues with the --collisions=rename option
+  * Unsafe characters in special constant strings (ie : in 
+    {code:ā€¦}) are now replaced with $
+  * Windows: Fixed progress bar flickering while printing extracted
+    filenames
+  * Windows binaries: Fixed crash on platforms without AVX support
+- Drop upstream patch innoextract-cmake.patch
+
+-------------------------------------------------------------------

Old:
----
  innoextract-1.5.tar.gz
  innoextract-cmake.patch

New:
----
  innoextract-1.6.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ innoextract.spec ++++++
--- /var/tmp/diff_new_pack.eIhDCW/_old  2016-03-26 17:28:04.000000000 +0100
+++ /var/tmp/diff_new_pack.eIhDCW/_new  2016-03-26 17:28:04.000000000 +0100
@@ -18,15 +18,13 @@
 
 
 Name:           innoextract
-Version:        1.5
+Version:        1.6
 Release:        0
 Summary:        A tool to extract Inno Setup installers under non-windows 
systems
 License:        Zlib
 Group:          Productivity/Archiving/Backup
 Url:            http://constexpr.org/innoextract/
 Source:         
http://constexpr.org/innoextract/files/%{name}-%{version}.tar.gz
-# PATCH-FIX-UPSTREAM innoextract-cmake.patch gh#50
-Patch0:         innoextract-cmake.patch
 BuildRequires:  boost-devel
 BuildRequires:  cmake >= 2.8.0
 BuildRequires:  doxygen
@@ -44,7 +42,6 @@
 
 %prep
 %setup -q
-%patch0 -p1
 
 %build
 %cmake

++++++ innoextract-1.5.tar.gz -> innoextract-1.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/CHANGELOG 
new/innoextract-1.6/CHANGELOG
--- old/innoextract-1.5/CHANGELOG       2015-09-24 22:59:27.000000000 +0200
+++ new/innoextract-1.6/CHANGELOG       2016-03-25 00:27:22.000000000 +0100
@@ -1,4 +1,16 @@
 
+innoextract 1.6 (2016-03-24)
+ - Added support for Inno Setup 5.5.7 (and 5.5.8) installers
+ - Added a --collisions=rename-all option
+ - Changed --collisions=rename to omit the suffix for the file that would have 
been extracted with --collisions=overwrite instead of the first encountered file
+ - Fixed @lang suffix sometimes missing for the first file with the 
--collisions=rename option
+ - Fixed build error with CMake 3.5
+ - Now compiles in C++14 mode if supported
+ - Unsafe characters in special constant strings (ie ':' in {code:ā€¦}) are now 
replaced with '$'
+ - Windows: Fixed error message if the source file could not be opened
+ - Windows: Fixed progress bar flickering while printing extracted filenames
+ - Windows binaries: Fixed crash on platforms without AVX support
+
 innoextract 1.5 (2015-09-24)
  - Added support for Inno Setup 5.5.6 installers
  - Added support for a modified Inno Setup 5.5.0 variant
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/CMakeLists.txt 
new/innoextract-1.6/CMakeLists.txt
--- old/innoextract-1.5/CMakeLists.txt  2015-09-24 22:59:27.000000000 +0200
+++ new/innoextract-1.6/CMakeLists.txt  2016-03-25 00:27:22.000000000 +0100
@@ -2,9 +2,16 @@
 
 cmake_minimum_required(VERSION 2.8)
 
+if(CMAKE_VERSION VERSION_GREATER 3.4)
+       cmake_policy(VERSION 3.4)
+else()
+       cmake_policy(VERSION ${CMAKE_VERSION})
+endif()
+
 
 # Define configuration options
 
+option(STRICT_USE "Abort if there are missing optional dependencies"  OFF)
 option(USE_LZMA "Build lzma decompression support" ON)
 set(WITH_CONV CACHE STRING "The library to use for charset conversions")
 option(ENABLE_BUILTIN_CONV "Build internal charset conversion routines" ON)
@@ -172,7 +179,7 @@
 
 # Set compiler flags
 
-if(${Boost_VERSION} LESS 104800)
+if(Boost_VERSION LESS 104800)
        # Older Boost versions don't work with C++11
 elseif(USE_CXX11)
        enable_cxx11()
@@ -191,7 +198,7 @@
 
 # Older glibc versions won't provide some useful symbols by default - request 
them
 # This flag is currently also set by gcc when compiling C++, but not for plain 
C
-if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+if(CMAKE_SYSTEM_NAME MATCHES "Linux")
        set(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE=1")
        add_definitions(-D_GNU_SOURCE=1)
 endif()
@@ -422,9 +429,9 @@
 message("")
 message("Configuration:")
 set(BUILD_TYPE_SUFFIX "")
-if(DEBUG AND NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
+if(DEBUG AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
        set(BUILD_TYPE_SUFFIX "${BUILD_TYPE_SUFFIX} with debug output")
-elseif(NOT DEBUG AND NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release")
+elseif(NOT DEBUG AND NOT CMAKE_BUILD_TYPE STREQUAL "Release")
        set(BUILD_TYPE_SUFFIX "${BUILD_TYPE_SUFFIX} without debug output")
 endif()
 message(" - Build type: ${CMAKE_BUILD_TYPE}${BUILD_TYPE_SUFFIX}")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/LICENSE new/innoextract-1.6/LICENSE
--- old/innoextract-1.5/LICENSE 2015-09-24 22:59:27.000000000 +0200
+++ new/innoextract-1.6/LICENSE 2016-03-25 00:27:22.000000000 +0100
@@ -1,5 +1,5 @@
 
-Copyright (C) 2011-2015 Daniel Scharrer <dan...@constexpr.org>
+Copyright (C) 2011-2016 Daniel Scharrer <dan...@constexpr.org>
 
 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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/README.md 
new/innoextract-1.6/README.md
--- old/innoextract-1.5/README.md       2015-09-24 22:59:27.000000000 +0200
+++ new/innoextract-1.6/README.md       2016-03-25 00:27:23.000000000 +0100
@@ -31,7 +31,8 @@
 
 To compile innoextract, run:
 
-    $ mkdir -p build && cd build && cmake ..
+    $ mkdir -p build && cd build
+    $ cmake ..
     $ make
 
 To install the binaries system-wide, run as root:
@@ -58,6 +59,7 @@
 | `ZLIB_USE_STATIC_LIBS`   | `OFF`^4   | Statically link `libz`. (used via 
Boost)
 | `BZip2_USE_STATIC_LIBS`  | `OFF`^4   | Statically link `libbz2`. (used via 
Boost)
 | `iconv_USE_STATIC_LIBS`  | `OFF`^4   | Statically link `libiconv`.
+| `STRICT_USE`             | `OFF`     | Abort if there are missing optional 
dependencies
 1. The builtin charset conversion only supports Windows-1252 and UTF-16LE. 
This is normally enough for filenames, but custom message strings (which can be 
included in filenames) may use arbitrary encodings.
 2. Enabled automatically if `CMAKE_BUILD_TYPE` is set to `Debug`.
 3. Under Windows, the default is `ON`.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/VERSION new/innoextract-1.6/VERSION
--- old/innoextract-1.5/VERSION 2015-09-24 22:59:27.000000000 +0200
+++ new/innoextract-1.6/VERSION 2016-03-25 00:27:23.000000000 +0100
@@ -1,7 +1,7 @@
-innoextract 1.5
+innoextract 1.6
 
 Known working Inno Setup versions:
-Inno Setup 1.2.10 to 5.5.6
+Inno Setup 1.2.10 to 5.5.8
 
 Bug tracker:
 http://innoextract.constexpr.org/issues
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/cmake/CXX11Check.cmake 
new/innoextract-1.6/cmake/CXX11Check.cmake
--- old/innoextract-1.5/cmake/CXX11Check.cmake  2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/cmake/CXX11Check.cmake  2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 
-# Copyright (C) 2013-2015 Daniel Scharrer
+# Copyright (C) 2013-2016 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
@@ -29,7 +29,10 @@
                        set(_HAS_CXX11 1 PARENT_SCOPE)
                endif()
        else()
-               add_cxxflag("-std=c++11")
+               add_cxxflag("-std=c++14")
+               if(NOT FLAG_FOUND)
+                       add_cxxflag("-std=c++11")
+               endif()
                set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" PARENT_SCOPE)
                if(FLAG_FOUND OR NOT CMAKE_COMPILER_IS_GNUCXX)
                        if(SET_WARNING_FLAGS)
@@ -41,7 +44,7 @@
 endfunction(enable_cxx11)
 
 function(check_cxx11 CHECK RESULTVAR)
-       if(${_HAS_CXX11})
+       if(_HAS_CXX11)
                if(MSVC AND ARGC GREATER 2)
                        if(MSVC_VERSION LESS ARGV2)
                                set(result)
@@ -53,7 +56,7 @@
                        set(file "${CXX11_CHECK_DIR}/check-cxx11-${check}.cpp")
                        check_compile(result "${file}" "${CHECK}" "C++11 
feature")
                endif()
-               if("${result}" STREQUAL "")
+               if(NOT DEFINED result OR result STREQUAL "")
                        set(${RESULTVAR} OFF PARENT_SCOPE)
                else()
                        set(${RESULTVAR} ON PARENT_SCOPE)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/cmake/CompileCheck.cmake 
new/innoextract-1.6/cmake/CompileCheck.cmake
--- old/innoextract-1.5/cmake/CompileCheck.cmake        2015-09-24 
22:59:27.000000000 +0200
+++ new/innoextract-1.6/cmake/CompileCheck.cmake        2016-03-25 
00:27:23.000000000 +0100
@@ -1,5 +1,5 @@
 
-# Copyright (C) 2011-2015 Daniel Scharrer
+# Copyright (C) 2011-2016 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,6 +17,10 @@
 #    misrepresented as being the original software.
 # 3. This notice may not be removed or altered from any source distribution.
 
+# Note: In CMake before 3.0 set(var "" PARENT_SCOPE) *unsets* the variable in 
the
+# parent scope instead of setting it to the empty string.
+# This means if(var STREQUAL "") will be false since var is not defined and 
thus not expanded.
+
 function(check_compile RESULT FILE FLAG TYPE)
        
        string(REGEX REPLACE "[^a-zA-Z0-9_][^a-zA-Z0-9_]*" "-" cachevar 
"${TYPE}-${FLAG}")
@@ -60,11 +64,11 @@
        set(old_CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
        set(old_CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
        set(old_CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}")
-       if("${TYPE}" STREQUAL "linker flag")
+       if(TYPE STREQUAL "linker flag")
                set(CMAKE_EXE_LINKER_FLAGS "${old_CMAKE_EXE_LINKER_FLAGS} 
${FLAG}")
                set(CMAKE_SHARED_LINKER_FLAGS "${old_CMAKE_SHARED_LINKER_FLAGS} 
${FLAG}")
                set(CMAKE_MODULE_LINKER_FLAGS "${old_CMAKE_MODULE_LINKER_FLAGS} 
${FLAG}")
-       elseif("${TYPE}" STREQUAL "compiler flag")
+       elseif(TYPE STREQUAL "compiler flag")
                set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}")
        endif()
        
@@ -142,7 +146,7 @@
        
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RESULT}" PARENT_SCOPE)
        
-       if("${RESULT}" STREQUAL "")
+       if(NOT DEFINED RESULT OR RESULT STREQUAL "")
                set(FLAG_FOUND 0 PARENT_SCOPE)
        else()
                set(FLAG_FOUND 1 PARENT_SCOPE)
@@ -158,7 +162,7 @@
        set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${RESULT}" 
PARENT_SCOPE)
        set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${RESULT}" 
PARENT_SCOPE)
        
-       if("${RESULT}" STREQUAL "")
+       if(NOT DEFINED RESULT OR RESULT STREQUAL "")
                set(FLAG_FOUND 0 PARENT_SCOPE)
        else()
                set(FLAG_FOUND 1 PARENT_SCOPE)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/cmake/FilterList.cmake 
new/innoextract-1.6/cmake/FilterList.cmake
--- old/innoextract-1.5/cmake/FilterList.cmake  2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/cmake/FilterList.cmake  2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 
-# Copyright (C) 2013 Daniel Scharrer
+# Copyright (C) 2013-2016 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
@@ -39,11 +39,15 @@
 #
 function(filter_list LIST_NAME)
        
+       set(TOKEN_IF "if")
+       set(TOKEN_GROUP_BEGIN "{")
+       set(TOKEN_GROUP_END "}")
+       
        set(filtered)
        set(all)
        
        # the item from the previous iteration
-       set(last_item)
+       set(last_item "")
        
        # current syntax state:
        # 0 - start
@@ -62,27 +66,27 @@
                                list(APPEND filtered ${last_item})
                        endif()
                        set(mode 0)
-                       set(last_item)
+                       set(last_item "")
                        
-               elseif("${item}" STREQUAL "if")
+               elseif(item STREQUAL TOKEN_IF)
                        
                        if(NOT mode EQUAL 0)
                                message(FATAL_ERROR "bad filter_list syntax: IF 
inside { } block is forbidden")
                        endif()
                        
                        # Handle condition start
-                       if("${last_item}" STREQUAL "")
+                       if(last_item STREQUAL "")
                                message(FATAL_ERROR "bad filter_list syntax: IF 
without preceding item")
                        endif()
                        set(mode 1)
                        
-               elseif("${item}" STREQUAL "{")
+               elseif(item STREQUAL TOKEN_GROUP_BEGIN)
                        
                        if(NOT mode EQUAL 0)
                                message(FATAL_ERROR "bad filter_list syntax: 
cannot nest { } blocks")
                        endif()
                        
-                       if("${last_item}" STREQUAL "")
+                       if(last_item STREQUAL "")
                                message(FATAL_ERROR "bad filter_list syntax: { 
without preceding item")
                        endif()
                        
@@ -92,16 +96,16 @@
                        else()
                                set(mode 3)
                        endif()
-                       set(last_item)
+                       set(last_item "")
                        
                else()
                        
                        # Handle unconditional items
-                       if(NOT "${last_item}" STREQUAL "" AND NOT mode EQUAL 3)
+                       if(NOT last_item STREQUAL "" AND NOT mode EQUAL 3)
                                list(APPEND filtered ${last_item})
                        endif()
                        
-                       if("${item}" STREQUAL "}")
+                       if(item STREQUAL TOKEN_GROUP_END)
                                
                                if(mode EQUAL 0)
                                        message(FATAL_ERROR "bad filter_list 
syntax: } without open block")
@@ -131,7 +135,7 @@
        list(REMOVE_DUPLICATES filtered)
        set(${LIST_NAME} ${filtered} PARENT_SCOPE)
        
-       if(${ARGC} GREATER 1)
+       if(ARGC GREATER 1)
                list(SORT all)
                list(REMOVE_DUPLICATES all)
                set(${ARGV1} ${all} PARENT_SCOPE)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/cmake/UseStaticLibs.cmake 
new/innoextract-1.6/cmake/UseStaticLibs.cmake
--- old/innoextract-1.5/cmake/UseStaticLibs.cmake       2015-09-24 
22:59:27.000000000 +0200
+++ new/innoextract-1.6/cmake/UseStaticLibs.cmake       2016-03-25 
00:27:23.000000000 +0100
@@ -1,5 +1,5 @@
 
-# Copyright (C) 2013-2015 Daniel Scharrer
+# Copyright (C) 2013-2016 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
@@ -25,7 +25,7 @@
                else()
                        set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
                endif()
-               if(${ARGC} GREATER 1)
+               if(ARGC GREATER 1)
                        set(prefix "${ARGV1}")
                        set(${prefix}_LIBRARIES     
"${${prefix}_STATIC_LIBRARIES}")
                        set(${prefix}_LIBRARY_DIRS  
"${${prefix}_STATIC_LIBRARY_DIRS}")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/cmake/VersionScript.cmake 
new/innoextract-1.6/cmake/VersionScript.cmake
--- old/innoextract-1.5/cmake/VersionScript.cmake       2015-09-24 
22:59:27.000000000 +0200
+++ new/innoextract-1.6/cmake/VersionScript.cmake       2016-03-25 
00:27:23.000000000 +0100
@@ -1,5 +1,5 @@
 
-# Copyright (C) 2011-2014 Daniel Scharrer
+# Copyright (C) 2011-2016 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
@@ -61,7 +61,7 @@
                        set(first_space -1)
                        set(last_space ${line_length})
                        foreach(i RANGE ${line_length})
-                               if(${i} LESS ${line_length})
+                               if(i LESS line_length)
                                        string(SUBSTRING "${line}" ${i} 1 
line_char)
                                        if(line_char STREQUAL " ")
                                                set(last_space ${i})
@@ -72,7 +72,7 @@
                                endif()
                        endforeach()
                        
-                       if(${first_space} GREATER -1)
+                       if(first_space GREATER -1)
                                
                                # Get everything before the first space
                                string(SUBSTRING "${line}" 0 ${first_space} 
line_name)
@@ -87,7 +87,7 @@
                                
                        endif()
                        
-                       if("${line}" MATCHES " ([0-9]\\.[^ ]* \\+ )?[^ ]*$")
+                       if(line MATCHES " ([0-9]\\.[^ ]* \\+ )?[^ ]*$")
                                string(REGEX REPLACE " (([0-9]\\.[^ ]* \\+ )?[^ 
]*)$" ""
                                       ${var}_${${var}_COUNT}_NAME "${line}")
                                string(LENGTH ${${var}_${${var}_COUNT}_NAME} 
begin)
@@ -140,7 +140,7 @@
                
                file(READ "${GIT_DIR}/HEAD" git_head)
                
-               if("${git_head}" MATCHES "^[ \t\r\n]*ref\\:(.*)$")
+               if(git_head MATCHES "^[ \t\r\n]*ref\\:(.*)$")
                        
                        # Remove the first for characters from git_head to get 
git_ref.
                        # We can't use a length of -1 for string(SUBSTRING) as 
cmake < 2.8.5 doesn't support it.
@@ -165,7 +165,7 @@
        # Create variables for all prefixes of the git comit ID.
        string(REGEX MATCH "[0-9A-Za-z]+" git_commit "${git_head}")
        string(LENGTH "${git_commit}" git_commit_length)
-       if(NOT ${git_commit_length} LESS 40)
+       if(NOT git_commit_length LESS 40)
                string(TOLOWER "${git_commit}" GIT_COMMIT)
                foreach(i RANGE 20)
                        string(SUBSTRING "${GIT_COMMIT}" 0 ${i} 
GIT_COMMIT_PREFIX_${i})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/cmake/VersionString.cmake 
new/innoextract-1.6/cmake/VersionString.cmake
--- old/innoextract-1.5/cmake/VersionString.cmake       2015-09-24 
22:59:27.000000000 +0200
+++ new/innoextract-1.6/cmake/VersionString.cmake       2016-03-25 
00:27:23.000000000 +0100
@@ -1,5 +1,5 @@
 
-# Copyright (C) 2011-2015 Daniel Scharrer
+# Copyright (C) 2011-2016 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
@@ -47,19 +47,22 @@
 # The version file is regenerated whenever VERSION_FILE or the current commit 
changes.
 function(version_file SRC DST VERSION_SOURCES GIT_DIR)
        
-       set(mode "variable")
+       set(MODE_VARIABLE 0)
+       set(MODE_FILE 1)
+       
+       set(mode ${MODE_VARIABLE})
        
        set(args)
        set(dependencies "${VERSION_STRING_SCRIPT}")
        
        foreach(arg IN LISTS VERSION_SOURCES)
                
-               if(mode STREQUAL "variable")
-                       set(mode "file")
+               if(mode EQUAL MODE_VARIABLE)
+                       set(mode ${MODE_FILE})
                else()
                        get_filename_component(arg "${arg}" ABSOLUTE)
                        list(APPEND dependencies ${arg})
-                       set(mode "variable")
+                       set(mode ${MODE_VARIABLE})
                endif()
                
                list(APPEND args ${arg})
@@ -71,7 +74,7 @@
        get_filename_component(abs_git_dir "${GIT_DIR}" ABSOLUTE)
        
        set(defines)
-       if(${ARGC} GREATER 4)
+       if(ARGC GREATER 4)
                set(defines ${ARGV4})
        endif()
        
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/doc/innoextract.1 
new/innoextract-1.6/doc/innoextract.1
--- old/innoextract-1.5/doc/innoextract.1       2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/doc/innoextract.1       2016-03-25 00:27:23.000000000 
+0100
@@ -1,6 +1,6 @@
 .\" Manpage for innoextract.
 .\" Contact dan...@constexpr.org to correct errors or typos.
-.TH innoextract 1 "2015-09-22" "1.5"
+.TH innoextract 1 "2016-03-02" "1.6"
 .SH NAME
 innoextract - tool to extract installers created by Inno Setup
 .SH SYNOPSIS
@@ -40,7 +40,7 @@
 .TP
 .B Modifiers:
 .nf
-    \-\-collisions \fIACTION\fP  How to handle filename collisions
+    \-\-collisions \fIACTION\fP  How to handle duplicate files
     \-\-default\-language   Default language for renaming
     \-\-dump               Dump contents without converting filenames
  \-L \-\-lowercase          Convert extracted filenames to lower-case
@@ -71,13 +71,32 @@
 Treat all arguments after this one as files, even if they begin with a dash.
 .TP
 \fB\-\-collisions\fP \fIACTION\fP
-Inno Setup installers can contain multiple files with the same name. This 
option tells innoextract what to do when such a collisions is encountered. 
Valid actions are:
+Inno Setup installers can contain duplicate files with the same name. This 
option tells innoextract what to do when such a collisions is encountered. 
Valid actions are:
 
-  "\fBoverwrite\fP"  Extract only one of the colliding files. The choice is 
done similar to how Inno Setup overwrites files during installation. This is 
the default.
+.RS
+.TP
+"\fBoverwrite\fP"
+Extract only one of the colliding files. The choice is done similar to how 
Inno Setup overwrites files during installation. This is the default.
+.TP
+"\fBrename\fP"
+Rename files that would be overwritten using the "\fBoverwrite\fP" action by 
appending a suffix comprised of the file's language, the component it belongs 
to and/or a number to make the filename unique. The language suffix (if 
applicable) is also appended to the \fIdefault\fP file that would have been 
extracted with the "\fBoverwrite\fP" action.
+.TP
+"\fBrename-all\fP"
+Rename all colliding files by appending a suffix comprised of the file's 
language, the component it belongs to and/or a number to make the filename 
unique. The complete suffix is appended to both files that would have been 
overwritten using the "\fBoverwrite\fP" action and to those that would have 
overwritten other files.
+.TP
+"\fBerror\fP"
+Exit when a collision is detected.
+.RE
+.IP
+.B Rename rules:
+
+1. If the \fBcomponent\fP is not the same for all files in the collision set 
(all files with the same filename), "\fB#\fP" (without quotes) followed by the 
component id is appended to all files that are specific to a single component.
 
-  "\fBrename\fP"     Rename files in the collision set by appending 
"#\fIcomponent\fP", "@\fIlanguage\fP" and/or "$\fIid\fP" where \fIcomponent\fP 
and \fIlanguage\fP are the file's \fIunique\fP component and language and 
\fIid\fP is the lowest number to make the filename unique. If the 
\fB\-\-default\-language\fP is specified, the "@\fIlanguage\fP" component is 
omitted if it matches the default language.
+2. If the \fBlanguage\fP is not the same for all files in the collision set, 
"\fB@\fP" (without quotes) followed by the language id is appended to all files 
that are specific to a single component unless that language matches the 
default language specified by the \fB--default-language\fP. While the suffix is 
omitted for the default language, no numbered suffix is added in it's place 
unless needed to make the filename unique.
 
-  "\fBerror\fP"      Exit when a collision is detected.
+3. If no suffix was added by the previous steps, or if the filename is not yet 
unique, "\fB$\fP" (without quotes) followed by the lowest integer (starting at 
0) to make the filename unique is appended.
+
+With the "\fBrename\fP" action, steps 1 and 3 are only applied to files that 
would have been overwritten by the "\fBoverwrite\fP" action while 
"\fBrename-all\fP" applies them to all files in the collision set.
 .TP
 \fB\-\-default\-language\fP \fILANG\fP
 Set a language as the default.
@@ -92,7 +111,9 @@
 will try to detect if the terminal supports shell escape codes and enable or 
disable color output accordingly. Specifically, colors will be enabled if both 
\fBstdout\fP and \fBstderr\fP point to a TTY and the \fBTERM\fP environment 
variable is not set to "\fBdumb\fP". Pass \fB1\fP or \fBtrue\fP to 
\fB\-\-color\fP to force color output. Pass \fB0\fP or \fBfalse\fP to never 
output color codes.
 .TP
 \fB\-\-dump\fP
-Don't convert Windows paths to UNIX paths and don't substitute variables in 
paths.
+Don't convert Windows paths to UNIX paths and don't substitute constants in 
paths.
+
+When combining \fB\-\-dump\fP with \fB\-\-extract\fP innoextract will 
\fInot\fP ensure that the paths don't point outside the destination directory. 
Use this option with caution when handling untrusted files.
 .TP
 \fB\-m\fP, \fB\-\-exclude\-temp\fP
 Don't extract files that would have been deleted at the end of the install 
process. Such files are marked with [temp] in the file listing.
@@ -192,9 +213,15 @@
 
 Besides timezones, two special values are accepted:
 
-  "\fBnone\fP"    Don't preserve file times for extracted files, both for UTC 
and 'local' timestamps. The file times wil be left the way the OS set them when 
creating the output files.
-
-  "\fBlocal\fP"  Use the system timezone for 'local' timestamps. This is the 
normal Inno Setup behavior, and can be used together with the \fBTZ\fP 
environment variable.
+.RS
+.HP
+"\fBnone\fP"
+Don't preserve file times for extracted files, both for UTC and 'local' 
timestamps. The file times wil be left the way the OS set them when creating 
the output files.
+.HP
+"\fBlocal\fP"
+Use the system timezone for 'local' timestamps. This is the normal Inno Setup 
behavior, and can be used together with the \fBTZ\fP environment variable.
+.RE
+.IP
 
 The default value for this option is \fBUTC\fP, causing innoextract to not 
adjust 'local' file times. File times marked as UTC in the Inno Setup file will 
never be adjusted no matter what \fB\-\-timestamps\fP is set to.
 .TP
@@ -205,6 +232,10 @@
 .TP
 \fB\-\-no\-warn\-unused\fP
 By default, innoextract will print a warning if it encounters \fI.bin\fP files 
that look like they could be part of the setup but are not used. This option 
disables that warning.
+.SH PATH CONSTANTS
+Paths in Inno Setup installers can contain constants (variable or code 
references) that are expanded at install time. innoextract expands all such 
constants to their name  and replaces unsafe characters with \fB$\fP. For 
exmaple \fB{app}\fP is expanded to \fBapp\fP while \fB{code:Example}\fP is 
expanded to \fBcode$Example\fP.
+
+There is currently no way to configure this expansion except for disabling it 
with the \fB\-\-dump\fP option.
 .SH EXIT VALUES
 .PP
 .IP \fB0\fP
@@ -218,7 +249,7 @@
 
 Included scripts and checks are not executed.
 
-The mapping from Inno Setup variables like the application directory to 
subdirectories is hard-coded.
+The mapping from Inno Setup constants like the application directory to 
subdirectories is hard-coded.
 
 Names for data slice/disk files in multi-file installers must follow the 
standard naming scheme.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/doc/update-copyright-years 
new/innoextract-1.6/doc/update-copyright-years
--- old/innoextract-1.5/doc/update-copyright-years      1970-01-01 
01:00:00.000000000 +0100
+++ new/innoextract-1.6/doc/update-copyright-years      2016-03-25 
00:27:23.000000000 +0100
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+copyright='Daniel Scharrer'
+
+die() {
+       printf '%s\n' "$1"
+       exit 1
+}
+
+if [ -z "$1" ] || [ ! -d "$1" ]
+       then repo="$(git rev-parse --show-toplevel)"
+       else repo="$1" ; shift
+fi
+[ -d "$repo/.git" ] || die "$1 is not a git repository"
+
+if [ -z "$1" ]
+       then last_tag="$(git --git-dir="$repo/.git" rev-list --tags 
--max-count=1)"
+       else last_tag="$1"
+fi
+[ -z "$last_tag" ] && die "Could not determine last tag"
+last_tag_name="$(git --git-dir="$repo/.git" describe --tags "$last_tag")"
+printf 'Updating files modified since %s\n' "$last_tag_name"
+
+files="$(git --git-dir="$repo/.git" diff --name-only "$last_tag" HEAD | tr 
'\n' ' ')"
+eval "set -- LICENSE COPYING $files"
+
+for file ; do
+       path="$repo/$file"
+       [ -f "$path" ] || continue # File was deleted
+       
+       case "$file" in
+               *.yml|.*)
+                       # Never try to update the copyright year for these files
+                       continue ;;
+       esac
+       
+       c="$(grep -P "(^|[^a-zA-Z0-9_])Copyright( \\([cC]\\))? 
(\\d{4}\\-)?\\d{4} $copyright" "$file")"
+       
+       if [ -z "$c" ] ; then
+               case "$file" in
+                       cmake/*.cpp|*CMakeLists.txt|*.md|*.1|*.in|LICENSE.*)
+                               # These files don't have to contain copyright 
information
+                               ;;
+                       *.*|scripts/*)
+                               c="$(grep -P "(^|[^a-zA-Z0-9_])Copyright( 
\([cC]\))?[ \:].*public domain" "$file")"
+                               [ -z "$c" ] && printf 'No copyright info found 
in %s, skipping\n' "$file" ;;
+               esac
+               continue
+       fi
+       
+       if [ "$(printf '%s\n' "$c" | wc -l)" -gt 1 ] ; then
+               printf 'Multiple copyright lines found in %s, skipping\n' 
"$file"
+               continue
+       fi
+       
+       s='\(^.*Copyright\( ([cC])\)\? \([0-9]\{4\}\-\)\?\)\([0-9]\{4\}\)\( 
'"$copyright"'.*$\)'
+       old_year="$(printf '%s\n' "$c" | sed "s/$s/\\4/")"
+       if [ -z "$old_year" ] || printf '%s\n' "$old_year" | grep -P '[^0-9]' > 
/dev/null ; then
+               printf 'Could not determine new copyright year for %s, 
skipping\n' "$file"
+               continue
+       fi
+       
+       case "$file" in
+               COPYING|LICENSE)
+                       new_year="$(git --git-dir="$repo/.git" log -1 
--format=%cd --date=short)" ;;
+               *)
+                       new_year="$(git --git-dir="$repo/.git" log -1 
--format=%cd --date=short -- "$path")"
+       esac
+       new_year="${new_year%%-*}"
+       if [ -z "$new_year" ] || printf '%s\n' "$new_year" | grep -P '[^0-9]' > 
/dev/null ; then
+               printf 'Could not determine new copyright year for %s, 
skipping\n' "$file"
+               continue
+       fi
+       
+       [ "$new_year" = "$old_year" ] && continue
+       
+       if [ ! "$new_year" -gt "$old_year" ] ; then
+               printf 'Copyright downgrade in %s: %sā†’%s, skipping\n' "$file" 
"$old_year" "$new_year"
+               continue
+       fi
+       
+       first_year="$(printf '%s\n' "$c" | sed "s/$s/\\3/")"
+       if [ -z "$first_year" ] ; then
+               replacement="$old_year-$new_year"
+               old="$old_year"
+               new="$old_year-$new_year"
+       else
+               replacement="$new_year"
+               old="$first_year$old_year"
+               new="$first_year$new_year"
+       fi
+       
+       printf '%s: %s ā†’ %s\n' "$file" "$old" "$new"
+       sed -i "s/$s/\\1$replacement\\5/" "$path"
+       
+done
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/src/cli/extract.cpp 
new/innoextract-1.6/src/cli/extract.cpp
--- old/innoextract-1.5/src/cli/extract.cpp     2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/src/cli/extract.cpp     2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2015 Daniel Scharrer
+ * Copyright (C) 2011-2016 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
@@ -120,8 +120,12 @@
        util::ofstream stream;
        
        explicit file_output(const fs::path & file) : name(file) {
-               stream.open(name, std::ios_base::out | std::ios_base::binary | 
std::ios_base::trunc);
-               if(!stream.is_open()) {
+               try {
+                       stream.open(name, std::ios_base::out | 
std::ios_base::binary | std::ios_base::trunc);
+                       if(!stream.is_open()) {
+                               throw 0;
+                       }
+               } catch(...) {
                        throw std::runtime_error("Coul not open output file \"" 
+ name.string() + '"');
                }
        }
@@ -388,37 +392,50 @@
        return false;
 }
 
-static void rename_collision(const extract_options & o, FilesMap & 
processed_files,
+static bool rename_collision(const extract_options & o, FilesMap & 
processed_files,
                              const std::string & path, const processed_file & 
other,
-                             bool common_component, bool common_language) {
+                             bool common_component, bool common_language, bool 
first) {
        
        const setup::file_entry & file = other.entry();
        
+       bool require_number_suffix = !first || (o.collisions == 
RenameAllCollisions);
        std::ostringstream oss;
        
        if(!common_component && !file.components.empty()) {
                if(setup::is_simple_expression(file.components)) {
+                       require_number_suffix = false;
                        oss << '#' << file.components;
                }
        }
-       if(!common_language && !file.languages.empty() && file.languages != 
o.default_language) {
+       if(!common_language && !file.languages.empty()) {
                if(setup::is_simple_expression(file.languages)) {
-                       oss << '@' << file.languages;
+                       require_number_suffix = false;
+                       if(file.languages != o.default_language) {
+                               oss << '@' << file.languages;
+                       }
                }
        }
        
        size_t i = 0;
        std::string suffix = oss.str();
-       if(suffix.empty() && file.languages != o.default_language) {
+       if(require_number_suffix) {
                oss << '$' << i++;
        }
-       while(processed_files.find(path + oss.str()) != processed_files.end()) {
+       for(;;) {
+               std::pair<FilesMap::iterator, bool> insertion = 
processed_files.insert(std::make_pair(
+                       path + oss.str(), processed_file(&file, other.path() + 
oss.str())
+               ));
+               if(insertion.second) {
+                       // Found an available name and inserted
+                       return true;
+               }
+               if(&insertion.first->second.entry() == &file) {
+                       // File already has the desired name, abort
+                       return false;
+               }
                oss.str(suffix);
                oss << '$' << i++;
        }
-       processed_files.insert(std::make_pair(
-               path + oss.str(), processed_file(&file, other.path() + 
oss.str())
-       ));
        
 }
 
@@ -439,13 +456,15 @@
                        common_language = common_language && 
other.entry().languages == file.languages;
                }
                
-               if(common_component && !common_language && file.languages != 
o.default_language) {
-                       rename_collision(o, processed_files, path, base, 
common_component, common_language);
+               bool ignore_component = common_component || o.collisions != 
RenameAllCollisions;
+               if(rename_collision(o, processed_files, path, base,
+                                   ignore_component, common_language, true)) {
                        processed_files.erase(path);
                }
                
                BOOST_FOREACH(const processed_file & other, collision.second) {
-                       rename_collision(o, processed_files, path, other, 
common_component, common_language);
+                       rename_collision(o, processed_files, path, other,
+                                        common_component, common_language, 
false);
                }
                
        }
@@ -466,8 +485,13 @@
                throw std::runtime_error("Input file \"" + file.string() + "\" 
is a directory!");
        }
        
-       util::ifstream ifs(file, std::ios_base::in | std::ios_base::binary);
-       if(!ifs.is_open()) {
+       util::ifstream ifs;
+       try {
+               ifs.open(file, std::ios_base::in | std::ios_base::binary);
+               if(!ifs.is_open()) {
+                       throw 0;
+               }
+       } catch(...) {
                throw std::runtime_error("Could not open file \"" + 
file.string() + '"');
        }
        
@@ -685,7 +709,7 @@
                        
                        if(o.collisions == ErrorOnCollisions) {
                                throw std::runtime_error("Collision: " + path);
-                       } else if(o.collisions == RenameCollisions) {
+                       } else if(o.collisions == RenameAllCollisions) {
                                
collisions[internal_path].push_back(processed_file(&file, path));
                        } else {
                                
@@ -703,7 +727,11 @@
                                        }
                                }
                                
-                               if(!o.silent) {
+                               if(o.collisions == RenameCollisions) {
+                                       const setup::file_entry & clobberedfile 
= skip ? file : existing.entry();
+                                       const std::string & clobberedpath = 
skip ? path : existing.path();
+                                       
collisions[internal_path].push_back(processed_file(&clobberedfile, 
clobberedpath));
+                               } else if(!o.silent) {
                                        std::cout << " - ";
                                        const std::string & clobberedpath = 
skip ? path : existing.path();
                                        std::cout << '"' << color::dim_yellow 
<< clobberedpath << color::reset << '"';
@@ -728,7 +756,7 @@
                
        }
        
-       if(o.collisions == RenameCollisions) {
+       if(o.collisions == RenameCollisions || o.collisions == 
RenameAllCollisions) {
                rename_collisions(o, processed_files, collisions);
                collisions.clear();
        }
@@ -848,7 +876,7 @@
                        // Print filename and size
                        if(o.list) {
                                
-                               extract_progress.clear();
+                               extract_progress.clear(DeferredClear);
                                
                                if(!o.silent) {
                                        
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/src/cli/extract.hpp 
new/innoextract-1.6/src/cli/extract.hpp
--- old/innoextract-1.5/src/cli/extract.hpp     2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/src/cli/extract.hpp     2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014-2015 Daniel Scharrer
+ * Copyright (C) 2014-2016 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
@@ -41,6 +41,7 @@
 enum CollisionAction {
        OverwriteCollisions,
        RenameCollisions,
+       RenameAllCollisions,
        ErrorOnCollisions
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/src/cli/main.cpp 
new/innoextract-1.6/src/cli/main.cpp
--- old/innoextract-1.5/src/cli/main.cpp        2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/src/cli/main.cpp        2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2015 Daniel Scharrer
+ * Copyright (C) 2011-2016 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
@@ -138,7 +138,7 @@
        
        po::options_description modifiers("Modifiers");
        modifiers.add_options()
-               ("collisions", po::value<std::string>(), "How to handle 
filename collisions")
+               ("collisions", po::value<std::string>(), "How to handle 
duplicate files")
                ("default-language", po::value<std::string>(), "Default 
language for renaming")
                ("dump", "Dump contents without converting filenames")
                ("lowercase,L", "Convert extracted filenames to lower-case")
@@ -298,6 +298,8 @@
                                o.collisions = OverwriteCollisions;
                        } else if(collisions == "rename") {
                                o.collisions = RenameCollisions;
+                       } else if(collisions == "rename-all") {
+                               o.collisions = RenameAllCollisions;
                        } else if(collisions == "error") {
                                o.collisions = ErrorOnCollisions;
                        } else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/src/setup/filename.cpp 
new/innoextract-1.6/src/setup/filename.cpp
--- old/innoextract-1.5/src/setup/filename.cpp  2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/src/setup/filename.cpp  2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2015 Daniel Scharrer
+ * Copyright (C) 2012-2016 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
@@ -35,11 +35,36 @@
        }
 };
 
+struct is_unsafe_path_char {
+       bool operator()(char c) {
+               if(c < 32) {
+                       return true;
+               }
+               switch(c) {
+                       case '<': return true;
+                       case '>': return true;
+                       case ':': return true;
+                       case '"': return true;
+                       case '|': return true;
+                       case '?': return true;
+                       case '*': return true;
+               }
+               return false;
+       }
+};
+
+static std::string replace_unsafe_chars(const std::string & str) {
+       std::string result;
+       result.resize(str.size());
+       std::replace_copy_if(str.begin(), str.end(), result.begin(), 
is_unsafe_path_char(), '$');
+       return result;
+}
+
 } // anonymous namespace
 
-const std::string & filename_map::lookup(const std::string & key) const {
+std::string filename_map::lookup(const std::string & key) const {
        std::map<std::string, std::string>::const_iterator i = find(key);
-       return (i == end()) ? key : i->second;
+       return (i == end()) ? replace_unsafe_chars(key) : i->second;
 }
 
 std::string filename_map::expand_variables(it & begin, it end, bool close) 
const {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/src/setup/filename.hpp 
new/innoextract-1.6/src/setup/filename.hpp
--- old/innoextract-1.5/src/setup/filename.hpp  2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/src/setup/filename.hpp  2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2015 Daniel Scharrer
+ * Copyright (C) 2012-2016 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
@@ -44,7 +44,7 @@
  */
 class filename_map : public std::map<std::string, std::string> {
        
-       const std::string & lookup(const std::string & key) const;
+       std::string lookup(const std::string & key) const;
        
        bool lowercase;
        bool expand;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/src/setup/header.cpp 
new/innoextract-1.6/src/setup/header.cpp
--- old/innoextract-1.5/src/setup/header.cpp    2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/src/setup/header.cpp    2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2015 Daniel Scharrer
+ * Copyright (C) 2011-2016 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
@@ -34,6 +34,12 @@
 
 namespace {
 
+STORED_ENUM_MAP(stored_alpha_format, header::AlphaIgnored,
+       header::AlphaIgnored,
+       header::AlphaDefined,
+       header::AlphaPremultiplied
+);
+
 STORED_ENUM_MAP(stored_install_verbosity, header::NormalInstallMode,
        header::NormalInstallMode,
        header::SilentInstallMode,
@@ -298,13 +304,23 @@
        } else {
                back_color2 = 0;
        }
-       image_back_color = util::load<boost::uint32_t>(is);
+       if(version < INNO_VERSION(5, 5, 7)) {
+               image_back_color = util::load<boost::uint32_t>(is);
+       } else {
+               image_back_color = 0;
+       }
        if(version >= INNO_VERSION(2, 0, 0) && version < INNO_VERSION(5, 0, 4)) 
{
                small_image_back_color = util::load<boost::uint32_t>(is);
        } else {
                small_image_back_color = 0;
        }
        
+       if(version >= INNO_VERSION(5, 5, 7)) {
+               image_alpha_format = stored_enum<stored_alpha_format>(is).get();
+       } else {
+               image_alpha_format = AlphaIgnored;
+       }
+       
        if(version < INNO_VERSION(4, 2, 0)) {
                password.crc32 = util::load<boost::uint32_t>(is);
                password.type = crypto::CRC32;
@@ -558,6 +574,9 @@
        } else {
                options |= AllowNetworkDrive;
        }
+       if(version >= INNO_VERSION(5, 5, 7)) {
+               flagreader.add(ForceCloseApplications);
+       }
        
        options |= flagreader;
        
@@ -652,6 +671,7 @@
        "close applications",
        "restart applications",
        "allow network drive",
+       "force close applications",
        "uninstallable",
        "disable dir page",
        "disable program group page",
@@ -674,6 +694,12 @@
        "IA64",
 )
 
+NAMES(setup::header::alpha_format, "Alpha Format",
+       "ignored",
+       "defined",
+       "premultiplied",
+)
+
 NAMES(setup::header::install_verbosity, "Install Mode",
        "normal",
        "silent",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/src/setup/header.hpp 
new/innoextract-1.6/src/setup/header.hpp
--- old/innoextract-1.5/src/setup/header.hpp    2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/src/setup/header.hpp    2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2015 Daniel Scharrer
+ * Copyright (C) 2011-2016 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
@@ -98,6 +98,7 @@
                CloseApplications,
                RestartApplications,
                AllowNetworkDrive,
+               ForceCloseApplications,
                
                // Obsolete flags
                Uninstallable,
@@ -185,6 +186,13 @@
        Color image_back_color;
        Color small_image_back_color;
        
+       enum alpha_format {
+               AlphaIgnored,
+               AlphaDefined,
+               AlphaPremultiplied
+       };
+       alpha_format image_alpha_format;
+       
        crypto::checksum password;
        salt password_salt;
        
@@ -259,6 +267,7 @@
 
 NAMED_FLAGS(setup::header::flags)
 NAMED_FLAGS(setup::header::architecture_types)
+NAMED_ENUM(setup::header::alpha_format)
 NAMED_ENUM(setup::header::install_verbosity)
 NAMED_ENUM(setup::header::log_mode)
 NAMED_ENUM(setup::header::style)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/src/setup/version.cpp 
new/innoextract-1.6/src/setup/version.cpp
--- old/innoextract-1.5/src/setup/version.cpp   2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/src/setup/version.cpp   2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2015 Daniel Scharrer
+ * Copyright (C) 2011-2016 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
@@ -149,6 +149,8 @@
        { "!!! BlackBox v2?, marked as 5.5.0",  INNO_VERSION_EXT(5, 5,  0, 1), 
true  },
        { "Inno Setup Setup Data (5.5.6)",      INNO_VERSION_EXT(5, 5,  6, 0), 
false },
        { "Inno Setup Setup Data (5.5.6) (u)",  INNO_VERSION_EXT(5, 5,  6, 0), 
true  },
+       { "Inno Setup Setup Data (5.5.7)",      INNO_VERSION_EXT(5, 5,  7, 0), 
false },
+       { "Inno Setup Setup Data (5.5.7) (u)",  INNO_VERSION_EXT(5, 5,  7, 0), 
true  },
 };
 
 } // anonymous namespace
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/src/stream/block.cpp 
new/innoextract-1.6/src/stream/block.cpp
--- old/innoextract-1.5/src/stream/block.cpp    2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/src/stream/block.cpp    2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Daniel Scharrer
+ * Copyright (C) 2011-2016 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
@@ -86,7 +86,7 @@
                std::streamsize nread = boost::iostreams::read(src, temp, 
temp_size);
                if(nread == EOF) {
                        return false;
-               } else if(nread != sizeof(temp)) {
+               } else if(size_t(nread) != sizeof(temp)) {
                        throw block_error("unexpected block end");
                }
                boost::uint32_t block_crc32 = 
util::little_endian::load<boost::uint32_t>(temp);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/src/stream/lzma.cpp 
new/innoextract-1.6/src/stream/lzma.cpp
--- old/innoextract-1.5/src/stream/lzma.cpp     2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/src/stream/lzma.cpp     2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2013 Daniel Scharrer
+ * Copyright (C) 2011-2016 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
@@ -110,8 +110,8 @@
                if(properties > (9 * 5 * 5)) {
                        throw lzma_error("inno lzma1 property error", 
LZMA_FORMAT_ERROR);
                }
-               options.pb = properties / (9 * 5);
-               options.lp = (properties % (9 * 5)) / 9;
+               options.pb = boost::uint32_t(properties / (9 * 5));
+               options.lp = boost::uint32_t((properties % (9 * 5)) / 9);
                options.lc = properties % 9;
                
                options.dict_size = 
util::little_endian::load<boost::uint32_t>(header + 1);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/src/util/console.cpp 
new/innoextract-1.6/src/util/console.cpp
--- old/innoextract-1.5/src/util/console.cpp    2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/src/util/console.cpp    2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2015 Daniel Scharrer
+ * Copyright (C) 2011-2016 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
@@ -203,7 +203,7 @@
 
 static bool progress_cleared = true;
 
-void progress::clear(bool reset_only) {
+void progress::clear(ClearMode mode) {
        
        if(!show_progress) {
                return;
@@ -213,7 +213,7 @@
        
        #if defined(_WIN32)
        
-       if(reset_only) {
+       if(mode == FastClear) {
                
                /*
                 * If we overwrite the whole line with spaces, windows console 
likes to draw
@@ -229,11 +229,23 @@
                std::cout << '\r';
                
                return;
+               
+       } else if(mode == DeferredClear && isatty(1)) {
+               
+               /*
+                * Special clear mode that leaves the original line but insert 
new lines before it
+                * until the next carriage return.
+                */
+               
+               std::cout << "\r\x1b[3K";
+               
+               return;
+               
        }
        
        #else
        
-       (void)reset_only;
+       (void)mode;
        
        #endif
        
@@ -249,7 +261,7 @@
                return;
        }
        
-       clear(true);
+       clear(FastClear);
        
        int width = get_screen_width();
        
@@ -288,7 +300,7 @@
                return;
        }
        
-       clear(true);
+       clear(FastClear);
        
        int width = get_screen_width();
        
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/src/util/console.hpp 
new/innoextract-1.6/src/util/console.hpp
--- old/innoextract-1.5/src/util/console.hpp    2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/src/util/console.hpp    2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2015 Daniel Scharrer
+ * Copyright (C) 2011-2016 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
@@ -90,6 +90,13 @@
 
 } // namespace color
 
+enum ClearMode {
+       FullClear,    //!< Perform a full clear.
+       FastClear,    //!< Perform a full clear if it is cheap, otherwise only 
reset the cursor.
+       DeferredClear //!< Perform a full clear if it is cheap, otherwise leave 
the line as-is,
+                     //!< but insert new writes before it until the next 
full/fast clear.
+};
+
 //! A text-based progress bar for terminals.
 class progress {
        
@@ -149,10 +156,9 @@
        /*!
         * Clear any progress bar to make way for other output.
         *
-        * \param reset_only Only reset the cursor if cleaning the line is 
expensive.
-        *                   This should be used if the whole line will be 
written anyway.
+        * \param mode The clear mode to perform.
         */
-       static void clear(bool reset_only = false);
+       static void clear(ClearMode mode = FullClear);
        
        //! Enable or disable the progress bar.
        static void set_enabled(bool enable);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/src/util/load.hpp 
new/innoextract-1.6/src/util/load.hpp
--- old/innoextract-1.5/src/util/load.hpp       2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/src/util/load.hpp       2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Daniel Scharrer
+ * Copyright (C) 2011-2016 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
@@ -196,7 +196,7 @@
  * \param last   Index of the last desired bit (inclusive).
  */
 template <typename T>
-T get_bits(T number, int first, int last) {
+T get_bits(T number, unsigned first, unsigned last) {
        typedef typename uint_t<int(sizeof(T) * 8)>::exact UT;
        UT data = UT(number);
        data = UT(data >> first), last -= first;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/innoextract-1.5/src/util/windows.cpp 
new/innoextract-1.6/src/util/windows.cpp
--- old/innoextract-1.5/src/util/windows.cpp    2015-09-24 22:59:27.000000000 
+0200
+++ new/innoextract-1.6/src/util/windows.cpp    2016-03-25 00:27:23.000000000 
+0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2014 Daniel Scharrer
+ * Copyright (C) 2013-2016 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
@@ -25,6 +25,7 @@
 
 #include <stddef.h>
 
+#include <algorithm>
 #include <cstdlib>
 #include <clocale>
 #include <iostream>
@@ -73,9 +74,23 @@
        //! Current console display attributes
        WORD attributes;
        
+       bool deferred_clear;
+       SHORT clear_line;
+       WORD clear_attributes;
+       
+       void clear_deferred(const CONSOLE_SCREEN_BUFFER_INFO & info, SHORT 
offset = 0) {
+               COORD pos = { offset, clear_line };
+               DWORD count = DWORD(info.dwSize.X - offset);
+               DWORD ignored;
+               FillConsoleOutputCharacterW(handle, L' ', count, pos, &ignored);
+               FillConsoleOutputAttribute(handle, clear_attributes, count, 
pos, &ignored);
+               deferred_clear = false;
+       }
+       
        void erase_in_line(const char * codes, const char * end) {
                
                bool left = false, right = false;
+               bool deferred = false;
                
                do {
                        unsigned code = read_code(codes, end);
@@ -83,6 +98,7 @@
                                case 0:              right = true; break;
                                case 1: left = true;               break;
                                case 2: left = true, right = true; break;
+                               case 3: deferred = true;           break;
                                default: {
                                        #ifdef DEBUG
                                        std::ostringstream oss;
@@ -98,6 +114,18 @@
                        return;
                }
                
+               if(deferred_clear && (!deferred
+                  || clear_line != info.dwCursorPosition.Y || clear_attributes 
!= attributes)) {
+                       clear_deferred(info);
+               }
+               
+               if(deferred) {
+                       deferred_clear = true;
+                       clear_line = info.dwCursorPosition.Y;
+                       clear_attributes = attributes;
+                       return;
+               }
+               
                SHORT cbegin = left ? SHORT(0) : info.dwCursorPosition.X;
                SHORT cend = right ? info.dwSize.X : info.dwCursorPosition.X;
                
@@ -105,7 +133,7 @@
                DWORD count = DWORD(cend - cbegin);
                
                DWORD ignored;
-               FillConsoleOutputCharacterW(handle, WCHAR(' '), count, pos, 
&ignored);
+               FillConsoleOutputCharacterW(handle, L' ', count, pos, &ignored);
                FillConsoleOutputAttribute(handle, attributes, count, pos, 
&ignored);
        }
        
@@ -209,6 +237,95 @@
                }
        }
        
+       void handle_deferred_clear(wchar_t * & begin, wchar_t * end) {
+               
+               CONSOLE_SCREEN_BUFFER_INFO info;
+               if(!GetConsoleScreenBufferInfo(handle, &info)) {
+                       deferred_clear = false;
+                       return;
+               }
+               
+               while(begin != end) {
+                       
+                       if(*begin == L'\r') {
+                               // End deferred clear mode
+                               deferred_clear = false;
+                               break;
+                       }
+                       
+                       wchar_t * cr = std::find(begin, end, L'\r');
+                       wchar_t * ln = std::find(begin, cr, L'\n');
+                       
+                       // Insert an empty line before the "cleared" line
+                       if(clear_line == info.dwCursorPosition.Y) {
+                               
+                               if(info.dwCursorPosition.Y == info.dwSize.Y - 
1) {
+                                       // Cursor is at the end of the buffer
+                                       // Move buffer contents up one line 
except for the last line
+                                       SMALL_RECT source = { 0, 1, 
SHORT(info.dwSize.X), SHORT(info.dwSize.Y - 2) };
+                                       COORD dest = { 0, 0 };
+                                       CHAR_INFO fill;
+                                       fill.Char.UnicodeChar = L' ';
+                                       fill.Attributes = clear_attributes;
+                                       ScrollConsoleScreenBufferW(handle, 
&source, NULL, dest, &fill);
+                                       COORD cursor = { 0, 
SHORT(info.dwCursorPosition.Y - 1) };
+                                       SetConsoleCursorPosition(handle, 
cursor);
+                               } else {
+                                       // Move cleared line down one line
+                                       SMALL_RECT source = { 0, 
SHORT(info.dwCursorPosition.Y),
+                                                             
SHORT(info.dwSize.X), SHORT(info.dwCursorPosition.Y + 1) };
+                                       SMALL_RECT clip = { 0, 
SHORT(info.dwCursorPosition.Y + 1),
+                                                           
SHORT(info.dwSize.X), SHORT(info.dwCursorPosition.Y + 2) };
+                                       COORD dest = { 0, 
SHORT(info.dwCursorPosition.Y + 1) };
+                                       CHAR_INFO fill;
+                                       fill.Char.UnicodeChar = L' ';
+                                       fill.Attributes = clear_attributes;
+                                       ScrollConsoleScreenBufferW(handle, 
&source, &clip, dest, &fill);
+                                       clear_line = 
SHORT(info.dwCursorPosition.Y + 1);
+                                       if(info.dwCursorPosition.Y == 
info.srWindow.Bottom) {
+                                               // Cursor is at the end of the 
window
+                                               // Scroll up before overwriting 
the cleared line
+                                               SMALL_RECT window = { 0, 1, 0, 
1 };
+                                               SetConsoleWindowInfo(handle, 
FALSE, &window);
+                                       }
+                                       COORD pos = { 0, 
info.dwCursorPosition.Y };
+                                       DWORD count = DWORD(info.dwSize.X);
+                                       DWORD ignored;
+                                       FillConsoleOutputCharacterW(handle, L' 
', count, pos, &ignored);
+                                       FillConsoleOutputAttribute(handle, 
clear_attributes, count, pos, &ignored);
+                               }
+                               
+                               info.dwCursorPosition.X = 0;
+                               
+                       }
+                       
+                       // Write at most one line!
+                       DWORD len = DWORD(std::min(ln + 1 - begin, cr - begin));
+                       len = std::min(len, DWORD(info.dwSize.X - 
info.dwCursorPosition.X));
+                       
+                       DWORD count;
+                       WriteConsoleW(handle, begin, len, &count, NULL);
+                       begin += len;
+                       
+                       if(!GetConsoleScreenBufferInfo(handle, &info)) {
+                               deferred_clear = false;
+                               break;
+                       }
+                       
+                       if(info.dwCursorPosition.Y > clear_line) {
+                               // Line completely overwritten with text
+                               deferred_clear = false;
+                               break;
+                       } else if(info.dwCursorPosition.Y == clear_line && 
info.dwCursorPosition.X > 0) {
+                               // Line partially overwritten with text - clear 
the rest
+                               clear_deferred(info, info.dwCursorPosition.X);
+                               break;
+                       }
+                       
+               }
+               
+       }
+       
        void handle_text(const char * s, size_t n) {
                
                const char * end = s + n;
@@ -226,8 +343,12 @@
                        std::codecvt_base::result res;
                        res = codecvt->in(codecvt_state, s, end, s, obegin, 
oend, onext);
                        
+                       if(deferred_clear) {
+                               handle_deferred_clear(obegin, onext);
+                       }
+                       
                        DWORD count;
-                       WriteConsoleW(handle, &buffer.front(), DWORD(onext - 
obegin), &count, NULL);
+                       WriteConsoleW(handle, obegin, DWORD(onext - obegin), 
&count, NULL);
                        
                        if(res != std::codecvt_base::partial) {
                                break;
@@ -250,9 +371,18 @@
                , initial_attributes(get_attributes())
                , default_attributes(get_default_attributes())
                , attributes(initial_attributes)
+               , deferred_clear(false)
+               , clear_line(0)
+               , clear_attributes(0)
        { }
        
        ~windows_console_sink() {
+               if(deferred_clear) {
+                       CONSOLE_SCREEN_BUFFER_INFO info;
+                       if(GetConsoleScreenBufferInfo(handle, &info)) {
+                               clear_deferred(info);
+                       }
+               }
                set_attributes(initial_attributes);
        }
        


Reply via email to