closes https://github.com/assimp/assimp/issues/3831 : update zip
parent
96d0524fab
commit
feeb89a1dd
|
@ -1,58 +0,0 @@
|
||||||
/build/
|
|
||||||
/test/build/
|
|
||||||
/xcodeproj/
|
|
||||||
.vscode/
|
|
||||||
|
|
||||||
# Object files
|
|
||||||
*.o
|
|
||||||
*.ko
|
|
||||||
*.obj
|
|
||||||
*.elf
|
|
||||||
|
|
||||||
# Precompiled Headers
|
|
||||||
*.gch
|
|
||||||
*.pch
|
|
||||||
|
|
||||||
# Libraries
|
|
||||||
*.lib
|
|
||||||
*.a
|
|
||||||
*.la
|
|
||||||
*.lo
|
|
||||||
|
|
||||||
# Shared objects (inc. Windows DLLs)
|
|
||||||
*.dll
|
|
||||||
*.so
|
|
||||||
*.so.*
|
|
||||||
*.dylib
|
|
||||||
*.suo
|
|
||||||
|
|
||||||
# Executables
|
|
||||||
*.exe
|
|
||||||
*.out
|
|
||||||
*.app
|
|
||||||
*.i*86
|
|
||||||
*.x86_64
|
|
||||||
*.hex
|
|
||||||
|
|
||||||
# Temporary
|
|
||||||
*.swp
|
|
||||||
.DS_Store
|
|
||||||
|
|
||||||
# CMake
|
|
||||||
CMakeScripts
|
|
||||||
*.cmake
|
|
||||||
|
|
||||||
# Xcode
|
|
||||||
*.build
|
|
||||||
*.xcodeproj
|
|
||||||
zip.sln
|
|
||||||
zip.vcxproj.filters
|
|
||||||
zip.vcxproj
|
|
||||||
ALL_BUILD.vcxproj.filters
|
|
||||||
ALL_BUILD.vcxproj
|
|
||||||
CMakeFiles/
|
|
||||||
zip.dir/
|
|
||||||
test/test.exe.vcxproj.filters
|
|
||||||
test/test.exe.vcxproj
|
|
||||||
test/test.exe.dir/
|
|
||||||
|
|
|
@ -1,26 +1,29 @@
|
||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.4)
|
||||||
|
|
||||||
project(zip
|
project(zip
|
||||||
LANGUAGES C
|
LANGUAGES C
|
||||||
VERSION "0.1.18")
|
VERSION "0.1.19")
|
||||||
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||||
|
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||||
option(CMAKE_DISABLE_TESTING "Disable test creation" OFF)
|
option(CMAKE_DISABLE_TESTING "Disable test creation" OFF)
|
||||||
|
|
||||||
if (MSVC)
|
|
||||||
# Use secure functions by default and suppress warnings about "deprecated" functions
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
|
|
||||||
elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR
|
|
||||||
"${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
|
|
||||||
"${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wextra -Werror -pedantic")
|
|
||||||
endif (MSVC)
|
|
||||||
|
|
||||||
# zip
|
# zip
|
||||||
set(SRC src/miniz.h src/zip.h src/zip.c)
|
set(SRC src/miniz.h src/zip.h src/zip.c)
|
||||||
add_library(${PROJECT_NAME} ${SRC})
|
|
||||||
|
# this is the "object library" target: compiles the sources only once
|
||||||
|
add_library(OBJLIB OBJECT ${SRC})
|
||||||
|
# shared libraries need PIC
|
||||||
|
set_property(TARGET OBJLIB PROPERTY POSITION_INDEPENDENT_CODE 1)
|
||||||
|
|
||||||
|
# static and shared libraries built from the same object files
|
||||||
|
if (BUILD_SHARED_LIBS)
|
||||||
|
add_library(${PROJECT_NAME} SHARED $<TARGET_OBJECTS:OBJLIB>)
|
||||||
|
include(GenerateExportHeader)
|
||||||
|
generate_export_header(${PROJECT_NAME})
|
||||||
|
else()
|
||||||
|
add_library(${PROJECT_NAME} STATIC $<TARGET_OBJECTS:OBJLIB>)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC
|
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||||
$<INSTALL_INTERFACE:include>
|
$<INSTALL_INTERFACE:include>
|
||||||
|
@ -34,6 +37,17 @@ if (NOT CMAKE_DISABLE_TESTING)
|
||||||
add_sanitizers(${PROJECT_NAME} ${test_out})
|
add_sanitizers(${PROJECT_NAME} ${test_out})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
# Use secure functions by default and suppress warnings about "deprecated" functions
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
|
||||||
|
elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR
|
||||||
|
"${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
|
||||||
|
"${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -Werror -pedantic -Wno-deprecated")
|
||||||
|
endif (MSVC)
|
||||||
|
|
||||||
####
|
####
|
||||||
# Installation (https://github.com/forexample/package-example) {
|
# Installation (https://github.com/forexample/package-example) {
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
This is done by hacking awesome [miniz](https://code.google.com/p/miniz) library and layering functions on top of the miniz v1.15 API.
|
This is done by hacking awesome [miniz](https://code.google.com/p/miniz) library and layering functions on top of the miniz v1.15 API.
|
||||||
|
|
||||||
[![Build](https://github.com/kuba--/zip/workflows/build/badge.svg)](https://github.com/kuba--/zip/actions?query=workflow%3Abuild)
|
[![Build](https://github.com/kuba--/zip/workflows/build/badge.svg)](https://github.com/kuba--/zip/actions?query=workflow%3Abuild)
|
||||||
[![Version](https://badge.fury.io/gh/kuba--%2Fzip.svg)](https://github.com/kuba--/zip/releases)
|
|
||||||
|
|
||||||
|
|
||||||
# The Idea
|
# The Idea
|
||||||
|
@ -155,10 +154,52 @@ struct zip_t *zip = zip_open("foo.zip", 0, 'r');
|
||||||
zip_close(zip);
|
zip_close(zip);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* Create a new zip archive in memory (stream API).
|
||||||
|
|
||||||
|
```c
|
||||||
|
char *outbuf = NULL;
|
||||||
|
size_t outbufsize = 0;
|
||||||
|
|
||||||
|
const char *inbuf = "Append some data here...\0";
|
||||||
|
struct zip_t *zip = zip_stream_open(NULL, 0, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||||
|
{
|
||||||
|
zip_entry_open(zip, "foo-1.txt");
|
||||||
|
{
|
||||||
|
zip_entry_write(zip, inbuf, strlen(inbuf));
|
||||||
|
}
|
||||||
|
zip_entry_close(zip);
|
||||||
|
|
||||||
|
/* copy compressed stream into outbuf */
|
||||||
|
zip_stream_copy(zip, (void **)&outbuf, &outbufsize);
|
||||||
|
}
|
||||||
|
zip_stream_close(zip);
|
||||||
|
|
||||||
|
free(outbuf);
|
||||||
|
```
|
||||||
|
|
||||||
|
* Extract a zip entry into a memory (stream API).
|
||||||
|
|
||||||
|
```c
|
||||||
|
char *buf = NULL;
|
||||||
|
ssize_t bufsize = 0;
|
||||||
|
|
||||||
|
struct zip_t *zip = zip_stream_open(zipstream, zipstreamsize, 0, 'r');
|
||||||
|
{
|
||||||
|
zip_entry_open(zip, "foo-1.txt");
|
||||||
|
{
|
||||||
|
zip_entry_read(zip, (void **)&buf, &bufsize);
|
||||||
|
}
|
||||||
|
zip_entry_close(zip);
|
||||||
|
}
|
||||||
|
zip_stream_close(zip);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
```
|
||||||
|
|
||||||
* List of all zip entries
|
* List of all zip entries
|
||||||
```c
|
```c
|
||||||
struct zip_t *zip = zip_open("foo.zip", 0, 'r');
|
struct zip_t *zip = zip_open("foo.zip", 0, 'r');
|
||||||
int i, n = zip_total_entries(zip);
|
int i, n = zip_entries_total(zip);
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
zip_entry_openbyindex(zip, i);
|
zip_entry_openbyindex(zip, i);
|
||||||
{
|
{
|
||||||
|
@ -172,6 +213,49 @@ for (i = 0; i < n; ++i) {
|
||||||
zip_close(zip);
|
zip_close(zip);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* Compress folder (recursively)
|
||||||
|
```c
|
||||||
|
void zip_walk(struct zip_t *zip, const char *path) {
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent *entry;
|
||||||
|
char fullpath[MAX_PATH];
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
memset(fullpath, 0, MAX_PATH);
|
||||||
|
dir = opendir(path);
|
||||||
|
assert(dir);
|
||||||
|
|
||||||
|
while ((entry = readdir(dir))) {
|
||||||
|
// skip "." and ".."
|
||||||
|
if (!strcmp(entry->d_name, ".\0") || !strcmp(entry->d_name, "..\0"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);
|
||||||
|
stat(fullpath, &s);
|
||||||
|
if (S_ISDIR(s.st_mode))
|
||||||
|
zip_walk(zip, fullpath);
|
||||||
|
else {
|
||||||
|
zip_entry_open(zip, fullpath);
|
||||||
|
zip_entry_fwrite(zip, fullpath);
|
||||||
|
zip_entry_close(zip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Deletes zip archive entries.
|
||||||
|
```c
|
||||||
|
char *entries[] = {"unused.txt", "remove.ini", "delete.me"};
|
||||||
|
|
||||||
|
struct zip_t *zip = zip_open("foo.zip", 0, 'd');
|
||||||
|
{
|
||||||
|
zip_entries_delete(zip, entries, 3);
|
||||||
|
}
|
||||||
|
zip_close(zip);
|
||||||
|
```
|
||||||
|
|
||||||
# Bindings
|
# Bindings
|
||||||
Compile zip library as a dynamic library.
|
Compile zip library as a dynamic library.
|
||||||
```shell
|
```shell
|
||||||
|
@ -181,7 +265,7 @@ $ cmake -DBUILD_SHARED_LIBS=true ..
|
||||||
$ make
|
$ make
|
||||||
```
|
```
|
||||||
|
|
||||||
### Go (cgo)
|
### [Go](https://golang.org) (cgo)
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
@ -211,7 +295,7 @@ func main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Rust (ffi)
|
### [Rust](https://www.rust-lang.org) (ffi)
|
||||||
```rust
|
```rust
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
@ -236,7 +320,7 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let path = CString::new("/tmp/test.zip").unwrap();
|
let path = CString::new("/tmp/rust.zip").unwrap();
|
||||||
let mode: libc::c_char = 'w' as libc::c_char;
|
let mode: libc::c_char = 'w' as libc::c_char;
|
||||||
|
|
||||||
let entryname = CString::new("test.txt").unwrap();
|
let entryname = CString::new("test.txt").unwrap();
|
||||||
|
@ -258,7 +342,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Ruby (ffi)
|
### [Ruby](http://www.ruby-lang.org) (ffi)
|
||||||
Install _ffi_ gem.
|
Install _ffi_ gem.
|
||||||
```shell
|
```shell
|
||||||
$ gem install ffi
|
$ gem install ffi
|
||||||
|
@ -291,7 +375,7 @@ Zip.zip_entry_close(ptr)
|
||||||
Zip.zip_close(ptr)
|
Zip.zip_close(ptr)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Python (cffi)
|
### [Python](https://www.python.org) (cffi)
|
||||||
Install _cffi_ package
|
Install _cffi_ package
|
||||||
```shell
|
```shell
|
||||||
$ pip install cffi
|
$ pip install cffi
|
||||||
|
@ -325,7 +409,36 @@ Zip.zip_entry_close(ptr)
|
||||||
Zip.zip_close(ptr)
|
Zip.zip_close(ptr)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Ring
|
### [Never](https://never-lang.readthedocs.io/) (ffi)
|
||||||
|
```never
|
||||||
|
extern "libzip.so" func zip_open(zipname: string, level: int, mode: char) -> c_ptr
|
||||||
|
extern "libzip.so" func zip_close(zip: c_ptr) -> void
|
||||||
|
|
||||||
|
extern "libzip.so" func zip_entry_open(zip: c_ptr, entryname: string) -> int
|
||||||
|
extern "libzip.so" func zip_entry_close(zip: c_ptr) -> int
|
||||||
|
extern "libzip.so" func zip_entry_write(zip: c_ptr, buf: string, bufsize: int) -> int
|
||||||
|
extern "libzip.so" func zip_entry_fwrite(zip: c_ptr, filename: string) -> int
|
||||||
|
|
||||||
|
func main() -> int
|
||||||
|
{
|
||||||
|
let content = "Test content"
|
||||||
|
|
||||||
|
let zip = zip_open("/tmp/never.zip", 6, 'w');
|
||||||
|
|
||||||
|
zip_entry_open(zip, "test.file");
|
||||||
|
zip_entry_fwrite(zip, "/tmp/test.txt");
|
||||||
|
zip_entry_close(zip);
|
||||||
|
|
||||||
|
zip_entry_open(zip, "test.content");
|
||||||
|
zip_entry_write(zip, content, length(content));
|
||||||
|
zip_entry_close(zip);
|
||||||
|
|
||||||
|
zip_close(zip);
|
||||||
|
0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### [Ring](http://ring-lang.net)
|
||||||
The language comes with RingZip based on this library
|
The language comes with RingZip based on this library
|
||||||
```ring
|
```ring
|
||||||
load "ziplib.ring"
|
load "ziplib.ring"
|
||||||
|
@ -342,13 +455,15 @@ new Zip {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
# Contribution Rules/Coding Standards
|
# Check out more cool projects which use this library:
|
||||||
No need to throw away your coding style, just do your best to follow default clang-format style.
|
- [Filament](https://github.com/google/filament): Filament is a real-time physically based rendering engine for Android, iOS, Linux, macOS, Windows, and WebGL. It is designed to be as small as possible and as efficient as possible on Android.
|
||||||
Apply `clang-format` to the source files before commit:
|
- [Hermes JS Engine](https://github.com/facebook/hermes): Hermes is a JavaScript engine optimized for fast start-up of React Native apps on Android. It features ahead-of-time static optimization and compact bytecode.
|
||||||
```sh
|
- [Open Asset Import Library](https://github.com/assimp/assimp): A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
|
||||||
for file in $(git ls-files | \grep -E '\.(c|h)$' | \grep -v -- '#')
|
- [PowerToys](https://github.com/microsoft/PowerToys): Set of utilities for power users to tune and streamline their Windows 10 experience for greater productivity.
|
||||||
do
|
- [The Ring Programming Language](https://ring-lang.github.io): Innovative and practical general-purpose multi-paradigm language.
|
||||||
clang-format -i $file
|
- [The V Programming Language](https://github.com/vlang/v): Simple, fast, safe, compiled. For developing maintainable software.
|
||||||
done
|
- [TIC-80](https://github.com/nesbox/TIC-80): TIC-80 is a FREE and OPEN SOURCE fantasy computer for making, playing and sharing tiny games.
|
||||||
```
|
- [Urho3D](https://github.com/urho3d/Urho3D): Urho3D is a free lightweight, cross-platform 2D and 3D game engine implemented in C++ and released under the MIT license. Greatly inspired by OGRE and Horde3D.
|
||||||
|
- [Vcpkg](https://github.com/microsoft/vcpkg): Vcpkg helps you manage C and C++ libraries on Windows, Linux and MacOS.
|
||||||
|
- [and more...](https://grep.app/search?q=kuba--/zip)
|
||||||
|
|
||||||
|
|
|
@ -400,7 +400,7 @@ typedef enum {
|
||||||
#ifndef MINIZ_NO_ZLIB_APIS
|
#ifndef MINIZ_NO_ZLIB_APIS
|
||||||
|
|
||||||
// Heap allocation callbacks.
|
// Heap allocation callbacks.
|
||||||
// Note that mz_alloc_func parameter types purpsosely differ from zlib's:
|
// Note that mz_alloc_func parameter types purposely differ from zlib's:
|
||||||
// items/size is size_t, not unsigned long.
|
// items/size is size_t, not unsigned long.
|
||||||
typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
|
typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
|
||||||
typedef void (*mz_free_func)(void *opaque, void *address);
|
typedef void (*mz_free_func)(void *opaque, void *address);
|
||||||
|
@ -2194,7 +2194,8 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r,
|
||||||
} else
|
} else
|
||||||
tree_cur = pTable->m_tree[-tree_cur - 1];
|
tree_cur = pTable->m_tree[-tree_cur - 1];
|
||||||
}
|
}
|
||||||
tree_cur -= ((rev_code >>= 1) & 1);
|
rev_code >>= 1;
|
||||||
|
tree_cur -= (rev_code & 1);
|
||||||
pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
|
pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
|
||||||
}
|
}
|
||||||
if (r->m_type == 2) {
|
if (r->m_type == 2) {
|
||||||
|
@ -3970,6 +3971,7 @@ mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits,
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4121 4127 4244)
|
||||||
#pragma warning(disable : 4204) // nonstandard extension used : non-constant
|
#pragma warning(disable : 4204) // nonstandard extension used : non-constant
|
||||||
// aggregate initializer (also supported by GNU
|
// aggregate initializer (also supported by GNU
|
||||||
// C and C99, so no big deal)
|
// C and C99, so no big deal)
|
||||||
|
@ -4098,10 +4100,6 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h,
|
||||||
pLen_out, 6, MZ_FALSE);
|
pLen_out, 6, MZ_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ------------------- .ZIP archive reading
|
// ------------------- .ZIP archive reading
|
||||||
|
|
||||||
#ifndef MINIZ_NO_ARCHIVE_APIS
|
#ifndef MINIZ_NO_ARCHIVE_APIS
|
||||||
|
@ -4112,18 +4110,39 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h,
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
static wchar_t *str2wstr(const char *str) {
|
||||||
|
int len = (int) strlen(str) + 1;
|
||||||
|
wchar_t *wstr = malloc(len * sizeof(wchar_t));
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, str, len * sizeof(char), wstr, len);
|
||||||
|
return wstr;
|
||||||
|
}
|
||||||
|
|
||||||
static FILE *mz_fopen(const char *pFilename, const char *pMode) {
|
static FILE *mz_fopen(const char *pFilename, const char *pMode) {
|
||||||
FILE *pFile = NULL;
|
wchar_t *wFilename = str2wstr(pFilename);
|
||||||
fopen_s(&pFile, pFilename, pMode);
|
wchar_t *wMode = str2wstr(pMode);
|
||||||
|
FILE *pFile = _wfopen(wFilename, wMode);
|
||||||
|
|
||||||
|
free(wFilename);
|
||||||
|
free(wMode);
|
||||||
|
|
||||||
return pFile;
|
return pFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) {
|
static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) {
|
||||||
FILE *pFile = NULL;
|
wchar_t *wPath = str2wstr(pPath);
|
||||||
if (freopen_s(&pFile, pPath, pMode, pStream))
|
wchar_t *wMode = str2wstr(pMode);
|
||||||
return NULL;
|
FILE *pFile = _wfreopen(wPath, wMode, pStream);
|
||||||
|
|
||||||
|
free(wPath);
|
||||||
|
free(wMode);
|
||||||
|
|
||||||
return pFile;
|
return pFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MINIZ_NO_TIME
|
#ifndef MINIZ_NO_TIME
|
||||||
#include <sys/utime.h>
|
#include <sys/utime.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -4144,7 +4163,7 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) {
|
||||||
#include <sys/utime.h>
|
#include <sys/utime.h>
|
||||||
#endif
|
#endif
|
||||||
#define MZ_FILE FILE
|
#define MZ_FILE FILE
|
||||||
#define MZ_FOPEN(f, m) fopen(f, m)
|
#define MZ_FOPEN(f, m) mz_fopen
|
||||||
#define MZ_FCLOSE fclose
|
#define MZ_FCLOSE fclose
|
||||||
#define MZ_FREAD fread
|
#define MZ_FREAD fread
|
||||||
#define MZ_FWRITE fwrite
|
#define MZ_FWRITE fwrite
|
||||||
|
@ -4153,7 +4172,7 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) {
|
||||||
#define MZ_FILE_STAT_STRUCT _stat
|
#define MZ_FILE_STAT_STRUCT _stat
|
||||||
#define MZ_FILE_STAT _stat
|
#define MZ_FILE_STAT _stat
|
||||||
#define MZ_FFLUSH fflush
|
#define MZ_FFLUSH fflush
|
||||||
#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
|
#define MZ_FREOPEN(f, m, s) mz_freopen
|
||||||
#define MZ_DELETE_FILE remove
|
#define MZ_DELETE_FILE remove
|
||||||
#elif defined(__TINYC__)
|
#elif defined(__TINYC__)
|
||||||
#ifndef MINIZ_NO_TIME
|
#ifndef MINIZ_NO_TIME
|
||||||
|
@ -5361,13 +5380,9 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip,
|
||||||
} else {
|
} else {
|
||||||
// Temporarily allocate a read buffer.
|
// Temporarily allocate a read buffer.
|
||||||
read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
|
read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
|
||||||
if (((0, sizeof(size_t) == sizeof(mz_uint32))) &&
|
|
||||||
(read_buf_size > 0x7FFFFFFF))
|
|
||||||
#else
|
|
||||||
if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
|
if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
|
||||||
#endif
|
|
||||||
return MZ_FALSE;
|
return MZ_FALSE;
|
||||||
|
|
||||||
if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
|
if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
|
||||||
(size_t)read_buf_size)))
|
(size_t)read_buf_size)))
|
||||||
return MZ_FALSE;
|
return MZ_FALSE;
|
||||||
|
@ -5454,11 +5469,7 @@ void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index,
|
||||||
uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
|
uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
|
||||||
|
|
||||||
alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
|
alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
|
||||||
if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
|
|
||||||
#else
|
|
||||||
if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
|
if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
|
||||||
#endif
|
|
||||||
return NULL;
|
return NULL;
|
||||||
if (NULL ==
|
if (NULL ==
|
||||||
(pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size)))
|
(pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size)))
|
||||||
|
@ -5560,14 +5571,10 @@ mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip,
|
||||||
if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) {
|
if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) {
|
||||||
// The file is stored or the caller has requested the compressed data.
|
// The file is stored or the caller has requested the compressed data.
|
||||||
if (pZip->m_pState->m_pMem) {
|
if (pZip->m_pState->m_pMem) {
|
||||||
#if defined (_MSC_VER) && !defined(__clang__)
|
|
||||||
if (((0, sizeof(size_t) == sizeof(mz_uint32))) &&
|
|
||||||
(file_stat.m_comp_size > 0xFFFFFFFF))
|
|
||||||
#else
|
|
||||||
if (((sizeof(size_t) == sizeof(mz_uint32))) &&
|
if (((sizeof(size_t) == sizeof(mz_uint32))) &&
|
||||||
(file_stat.m_comp_size > 0xFFFFFFFF))
|
(file_stat.m_comp_size > 0xFFFFFFFF))
|
||||||
#endif
|
|
||||||
return MZ_FALSE;
|
return MZ_FALSE;
|
||||||
|
|
||||||
if (pCallback(pOpaque, out_buf_ofs, pRead_buf,
|
if (pCallback(pOpaque, out_buf_ofs, pRead_buf,
|
||||||
(size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
|
(size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
|
||||||
status = TINFL_STATUS_FAILED;
|
status = TINFL_STATUS_FAILED;
|
||||||
|
@ -6085,7 +6092,7 @@ mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip) {
|
||||||
if (!pZip->m_file_offset_alignment)
|
if (!pZip->m_file_offset_alignment)
|
||||||
return 0;
|
return 0;
|
||||||
n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
|
n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
|
||||||
return (mz_uint)(pZip->m_file_offset_alignment - n) &
|
return (pZip->m_file_offset_alignment - n) &
|
||||||
(pZip->m_file_offset_alignment - 1);
|
(pZip->m_file_offset_alignment - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6289,7 +6296,10 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name,
|
||||||
mz_uint32 ext_attributes) {
|
mz_uint32 ext_attributes) {
|
||||||
mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
|
mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
|
||||||
mz_uint16 method = 0, dos_time = 0, dos_date = 0;
|
mz_uint16 method = 0, dos_time = 0, dos_date = 0;
|
||||||
|
#ifndef MINIZ_NO_TIME
|
||||||
time_t file_modified_time;
|
time_t file_modified_time;
|
||||||
|
#endif
|
||||||
|
|
||||||
mz_uint64 local_dir_header_ofs, cur_archive_file_ofs, uncomp_size = 0,
|
mz_uint64 local_dir_header_ofs, cur_archive_file_ofs, uncomp_size = 0,
|
||||||
comp_size = 0;
|
comp_size = 0;
|
||||||
size_t archive_name_size;
|
size_t archive_name_size;
|
||||||
|
@ -6326,10 +6336,12 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name,
|
||||||
comment_size + archive_name_size) > 0xFFFFFFFF))
|
comment_size + archive_name_size) > 0xFFFFFFFF))
|
||||||
return MZ_FALSE;
|
return MZ_FALSE;
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_TIME
|
||||||
memset(&file_modified_time, 0, sizeof(file_modified_time));
|
memset(&file_modified_time, 0, sizeof(file_modified_time));
|
||||||
if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time))
|
if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time))
|
||||||
return MZ_FALSE;
|
return MZ_FALSE;
|
||||||
mz_zip_time_t_to_dos_time(file_modified_time, &dos_time, &dos_date);
|
mz_zip_time_t_to_dos_time(file_modified_time, &dos_time, &dos_date);
|
||||||
|
#endif
|
||||||
|
|
||||||
pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
|
pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
|
||||||
if (!pSrc_file)
|
if (!pSrc_file)
|
||||||
|
@ -6814,6 +6826,10 @@ void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename,
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // #ifndef MINIZ_NO_STDIO
|
#endif // #ifndef MINIZ_NO_STDIO
|
||||||
|
|
||||||
#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
|
#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,19 +15,11 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable : 4127 )
|
|
||||||
#endif //_MSC_VER
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(_SSIZE_T_DEFINED) && !defined(_SSIZE_T_DEFINED_) && \
|
#if !defined(_POSIX_C_SOURCE) && defined(_MSC_VER)
|
||||||
!defined(__DEFINED_ssize_t) && !defined(__ssize_t_defined) && \
|
|
||||||
!defined(_SSIZE_T) && !defined(_SSIZE_T_) && !defined(_SSIZE_T_DECLARED)
|
|
||||||
|
|
||||||
// 64-bit Windows is the only mainstream platform
|
// 64-bit Windows is the only mainstream platform
|
||||||
// where sizeof(long) != sizeof(void*)
|
// where sizeof(long) != sizeof(void*)
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
@ -35,15 +27,6 @@ typedef long long ssize_t; /* byte count or error */
|
||||||
#else
|
#else
|
||||||
typedef long ssize_t; /* byte count or error */
|
typedef long ssize_t; /* byte count or error */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define _SSIZE_T_DEFINED
|
|
||||||
#define _SSIZE_T_DEFINED_
|
|
||||||
#define __DEFINED_ssize_t
|
|
||||||
#define __ssize_t_defined
|
|
||||||
#define _SSIZE_T
|
|
||||||
#define _SSIZE_T_
|
|
||||||
#define _SSIZE_T_DECLARED
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MAX_PATH
|
#ifndef MAX_PATH
|
||||||
|
@ -64,9 +47,49 @@ typedef long ssize_t; /* byte count or error */
|
||||||
/**
|
/**
|
||||||
* Default zip compression level.
|
* Default zip compression level.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ZIP_DEFAULT_COMPRESSION_LEVEL 6
|
#define ZIP_DEFAULT_COMPRESSION_LEVEL 6
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error codes
|
||||||
|
*/
|
||||||
|
#define ZIP_ENOINIT -1 // not initialized
|
||||||
|
#define ZIP_EINVENTNAME -2 // invalid entry name
|
||||||
|
#define ZIP_ENOENT -3 // entry not found
|
||||||
|
#define ZIP_EINVMODE -4 // invalid zip mode
|
||||||
|
#define ZIP_EINVLVL -5 // invalid compression level
|
||||||
|
#define ZIP_ENOSUP64 -6 // no zip 64 support
|
||||||
|
#define ZIP_EMEMSET -7 // memset error
|
||||||
|
#define ZIP_EWRTENT -8 // cannot write data to entry
|
||||||
|
#define ZIP_ETDEFLINIT -9 // cannot initialize tdefl compressor
|
||||||
|
#define ZIP_EINVIDX -10 // invalid index
|
||||||
|
#define ZIP_ENOHDR -11 // header not found
|
||||||
|
#define ZIP_ETDEFLBUF -12 // cannot flush tdefl buffer
|
||||||
|
#define ZIP_ECRTHDR -13 // cannot create entry header
|
||||||
|
#define ZIP_EWRTHDR -14 // cannot write entry header
|
||||||
|
#define ZIP_EWRTDIR -15 // cannot write to central dir
|
||||||
|
#define ZIP_EOPNFILE -16 // cannot open file
|
||||||
|
#define ZIP_EINVENTTYPE -17 // invalid entry type
|
||||||
|
#define ZIP_EMEMNOALLOC -18 // extracting data using no memory allocation
|
||||||
|
#define ZIP_ENOFILE -19 // file not found
|
||||||
|
#define ZIP_ENOPERM -20 // no permission
|
||||||
|
#define ZIP_EOOMEM -21 // out of memory
|
||||||
|
#define ZIP_EINVZIPNAME -22 // invalid zip archive name
|
||||||
|
#define ZIP_EMKDIR -23 // make dir error
|
||||||
|
#define ZIP_ESYMLINK -24 // symlink error
|
||||||
|
#define ZIP_ECLSZIP -25 // close archive error
|
||||||
|
#define ZIP_ECAPSIZE -26 // capacity size too small
|
||||||
|
#define ZIP_EFSEEK -27 // fseek error
|
||||||
|
#define ZIP_EFREAD -28 // fread error
|
||||||
|
#define ZIP_EFWRITE -29 // fwrite error
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks up the error message string coresponding to an error number.
|
||||||
|
* @param errnum error number
|
||||||
|
* @return error message string coresponding to errnum or NULL if error is not
|
||||||
|
* found.
|
||||||
|
*/
|
||||||
|
extern const char *zip_strerror(int errnum);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct zip_t
|
* @struct zip_t
|
||||||
*
|
*
|
||||||
|
@ -242,8 +265,8 @@ extern ssize_t zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize);
|
||||||
*
|
*
|
||||||
* @note ensure supplied output buffer is large enough.
|
* @note ensure supplied output buffer is large enough.
|
||||||
* zip_entry_size function (returns uncompressed size for the current
|
* zip_entry_size function (returns uncompressed size for the current
|
||||||
* entry) can be handy to estimate how big buffer is needed. for large
|
* entry) can be handy to estimate how big buffer is needed.
|
||||||
* entries, please take a look at zip_entry_extract function.
|
* For large entries, please take a look at zip_entry_extract function.
|
||||||
*
|
*
|
||||||
* @return the return code - the number of bytes actually read on success.
|
* @return the return code - the number of bytes actually read on success.
|
||||||
* Otherwise a -1 on error (e.g. bufsize is not large enough).
|
* Otherwise a -1 on error (e.g. bufsize is not large enough).
|
||||||
|
@ -285,7 +308,71 @@ zip_entry_extract(struct zip_t *zip,
|
||||||
* @return the return code - the number of entries on success, negative number
|
* @return the return code - the number of entries on success, negative number
|
||||||
* (< 0) on error.
|
* (< 0) on error.
|
||||||
*/
|
*/
|
||||||
extern int zip_total_entries(struct zip_t *zip);
|
extern int zip_entries_total(struct zip_t *zip);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes zip archive entries.
|
||||||
|
*
|
||||||
|
* @param zip zip archive handler.
|
||||||
|
* @param entries array of zip archive entries to be deleted.
|
||||||
|
* @param len the number of entries to be deleted.
|
||||||
|
* @return the number of deleted entries, or negative number (< 0) on error.
|
||||||
|
*/
|
||||||
|
extern int zip_entries_delete(struct zip_t *zip, char *const entries[],
|
||||||
|
size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts a zip archive stream into directory.
|
||||||
|
*
|
||||||
|
* If on_extract is not NULL, the callback will be called after
|
||||||
|
* successfully extracted each zip entry.
|
||||||
|
* Returning a negative value from the callback will cause abort and return an
|
||||||
|
* error. The last argument (void *arg) is optional, which you can use to pass
|
||||||
|
* data to the on_extract callback.
|
||||||
|
*
|
||||||
|
* @param stream zip archive stream.
|
||||||
|
* @param size stream size.
|
||||||
|
* @param dir output directory.
|
||||||
|
* @param on_extract on extract callback.
|
||||||
|
* @param arg opaque pointer.
|
||||||
|
*
|
||||||
|
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||||
|
*/
|
||||||
|
extern int zip_stream_extract(const char *stream, size_t size, const char *dir,
|
||||||
|
int (*on_extract)(const char *filename,
|
||||||
|
void *arg),
|
||||||
|
void *arg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens zip archive stream into memory.
|
||||||
|
*
|
||||||
|
* @param stream zip archive stream.
|
||||||
|
* @param size stream size.
|
||||||
|
*
|
||||||
|
* @return the zip archive handler or NULL on error
|
||||||
|
*/
|
||||||
|
extern struct zip_t *zip_stream_open(const char *stream, size_t size, int level,
|
||||||
|
char mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy zip archive stream output buffer.
|
||||||
|
*
|
||||||
|
* @param zip zip archive handler.
|
||||||
|
* @param buf output buffer. User should free buf.
|
||||||
|
* @param bufsize output buffer size (in bytes).
|
||||||
|
*
|
||||||
|
* @return copy size
|
||||||
|
*/
|
||||||
|
extern ssize_t zip_stream_copy(struct zip_t *zip, void **buf, ssize_t *bufsize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close zip archive releases resources.
|
||||||
|
*
|
||||||
|
* @param zip zip archive handler.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
extern void zip_stream_close(struct zip_t *zip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new archive and puts files into a single zip archive.
|
* Creates a new archive and puts files into a single zip archive.
|
||||||
|
@ -319,11 +406,6 @@ extern int zip_extract(const char *zipname, const char *dir,
|
||||||
void *arg);
|
void *arg);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif //_MSC_VER
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,11 +1,38 @@
|
||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.4)
|
||||||
|
|
||||||
# test
|
# tests
|
||||||
set(test_out test.out)
|
set(test_write_out test_write.out)
|
||||||
|
add_executable(${test_write_out} test_write.c)
|
||||||
|
target_link_libraries(${test_write_out} zip)
|
||||||
|
add_test(NAME ${test_write_out} COMMAND ${test_write_out})
|
||||||
|
set(test_write_out ${test_write_out} PARENT_SCOPE)
|
||||||
|
|
||||||
add_executable(${test_out} test.c)
|
set(test_append_out test_append.out)
|
||||||
target_link_libraries(${test_out} zip)
|
add_executable(${test_append_out} test_append.c)
|
||||||
|
target_link_libraries(${test_append_out} zip)
|
||||||
|
add_test(NAME ${test_append_out} COMMAND ${test_append_out})
|
||||||
|
set(test_append_out ${test_append_out} PARENT_SCOPE)
|
||||||
|
|
||||||
add_test(NAME ${test_out} COMMAND ${test_out})
|
set(test_read_out test_read.out)
|
||||||
|
add_executable(${test_read_out} test_read.c)
|
||||||
|
target_link_libraries(${test_read_out} zip)
|
||||||
|
add_test(NAME ${test_read_out} COMMAND ${test_read_out})
|
||||||
|
set(test_read_out ${test_read_out} PARENT_SCOPE)
|
||||||
|
|
||||||
set(test_out ${test_out} PARENT_SCOPE)
|
set(test_extract_out test_extract.out)
|
||||||
|
add_executable(${test_extract_out} test_extract.c)
|
||||||
|
target_link_libraries(${test_extract_out} zip)
|
||||||
|
add_test(NAME ${test_extract_out} COMMAND ${test_extract_out})
|
||||||
|
set(test_extract_out ${test_extract_out} PARENT_SCOPE)
|
||||||
|
|
||||||
|
set(test_entry_out test_entry.out)
|
||||||
|
add_executable(${test_entry_out} test_entry.c)
|
||||||
|
target_link_libraries(${test_entry_out} zip)
|
||||||
|
add_test(NAME ${test_entry_out} COMMAND ${test_entry_out})
|
||||||
|
set(test_entry_out ${test_entry_out} PARENT_SCOPE)
|
||||||
|
|
||||||
|
set(test_permissions_out test_permissions.out)
|
||||||
|
add_executable(${test_permissions_out} test_permissions.c)
|
||||||
|
target_link_libraries(${test_permissions_out} zip)
|
||||||
|
add_test(NAME ${test_permissions_out} COMMAND ${test_permissions_out})
|
||||||
|
set(test_permissions_out ${test_permissions_out} PARENT_SCOPE)
|
||||||
|
|
Loading…
Reference in New Issue