Compare commits
No commits in common. "dev" and "main" have entirely different histories.
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,7 +1 @@
|
||||
__pycache__
|
||||
.bck
|
||||
out
|
||||
target
|
||||
build
|
||||
*.pyc
|
||||
build/
|
||||
|
@ -1,34 +0,0 @@
|
||||
{
|
||||
"type":"LIBRARY",
|
||||
"group-id":"com.atria-soft",
|
||||
"description":"ETK cxx abi simple interface",
|
||||
"license":"MPL-2",
|
||||
"license-file":"file://../LICENCE.txt",
|
||||
"maintainer":"file://../authors.txt",
|
||||
"author":"file://../authors.txt",
|
||||
"version":"file://../version.txt",
|
||||
"code-quality":"MEDIUM",
|
||||
"comment": {
|
||||
"source": [
|
||||
"cxx-abi/cppabi.cpp"
|
||||
],
|
||||
"compilation-version": {
|
||||
"c++": 1999
|
||||
},
|
||||
"dependency": [
|
||||
"c"
|
||||
]
|
||||
},
|
||||
"compilator": {
|
||||
"gcc": {
|
||||
"flag":{
|
||||
"link": "-lgcc_s"
|
||||
}
|
||||
},
|
||||
"clang": {
|
||||
"flag":{
|
||||
"link": "-lclang"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,421 +0,0 @@
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace __cxxabiv1 {
|
||||
struct __class_type_info {
|
||||
virtual void foo() {}
|
||||
} ti;
|
||||
}
|
||||
|
||||
#define EXCEPTION_BUFF_SIZE (1024*1024)
|
||||
|
||||
char exception_buff[EXCEPTION_BUFF_SIZE];
|
||||
|
||||
extern "C" {
|
||||
|
||||
void* __cxa_allocate_exception(size_t thrown_size) {
|
||||
if (thrown_size > EXCEPTION_BUFF_SIZE) {
|
||||
printf("Exception too big");
|
||||
}
|
||||
return &exception_buff;
|
||||
}
|
||||
|
||||
void __cxa_free_exception(void *thrown_exception) {
|
||||
// nothing to do ==> static allocation
|
||||
}
|
||||
|
||||
#include <unwind.h>
|
||||
#include <typeinfo>
|
||||
|
||||
typedef void (*unexpected_handler)(void);
|
||||
typedef void (*terminate_handler)(void);
|
||||
|
||||
struct __cxa_exception {
|
||||
std::type_info * exceptionType;
|
||||
void (*exceptionDestructor) (void *);
|
||||
unexpected_handler unexpectedHandler;
|
||||
terminate_handler terminateHandler;
|
||||
__cxa_exception * nextException;
|
||||
int handlerCount;
|
||||
int handlerSwitchValue;
|
||||
const char * actionRecord;
|
||||
const char * languageSpecificData;
|
||||
void * catchTemp;
|
||||
void * adjustedPtr;
|
||||
_Unwind_Exception unwindHeader;
|
||||
};
|
||||
|
||||
void __cxa_throw(void* thrown_exception,
|
||||
std::type_info *tinfo,
|
||||
void (*dest)(void*)) {
|
||||
__cxa_exception *header = ((__cxa_exception *) thrown_exception - 1);
|
||||
// We need to save the type info in the exception header _Unwind_ will
|
||||
// receive, otherwise we won't be able to know it when unwinding
|
||||
header->exceptionType = tinfo;
|
||||
_Unwind_RaiseException(&header->unwindHeader);
|
||||
// __cxa_throw never returns
|
||||
printf("no one handled __cxa_throw, terminate!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
void __cxa_begin_catch() {
|
||||
printf("begin FTW\n");
|
||||
}
|
||||
|
||||
void __cxa_end_catch() {
|
||||
printf("end FTW\n");
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int readSLEB128(const uint8_t* data) {
|
||||
uintptr_t result = 0;
|
||||
uintptr_t shift = 0;
|
||||
unsigned char byte;
|
||||
const uint8_t *p = data;
|
||||
do {
|
||||
byte = *p++;
|
||||
result |= static_cast<uintptr_t>(byte & 0x7F) << shift;
|
||||
shift += 7;
|
||||
} while (byte & 0x80);
|
||||
|
||||
if ((byte & 0x40) && (shift < (sizeof(result) << 3))) {
|
||||
result |= static_cast<uintptr_t>(~0) << shift;
|
||||
}
|
||||
return static_cast<int>(result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The LSDA is a read only place in memory; we'll create a typedef for
|
||||
* this to avoid a const mess later on; LSDA_ptr refers to readonly and
|
||||
* &LSDA_ptr will be a non-const pointer to a const place in memory
|
||||
*/
|
||||
typedef const uint8_t* LSDA_ptr;
|
||||
|
||||
struct LSDA_Header {
|
||||
/**
|
||||
* Read the LSDA table into a struct; advances the lsda pointer
|
||||
* as many bytes as read
|
||||
*/
|
||||
LSDA_Header(LSDA_ptr *lsda) {
|
||||
LSDA_ptr read_ptr = *lsda;
|
||||
// Copy the LSDA fields
|
||||
start_encoding = read_ptr[0];
|
||||
type_encoding = read_ptr[1];
|
||||
type_table_offset = read_ptr[2];
|
||||
// Advance the lsda pointer
|
||||
*lsda = read_ptr + sizeof(LSDA_Header);
|
||||
}
|
||||
uint8_t start_encoding;
|
||||
uint8_t type_encoding;
|
||||
// This is the offset, from the end of the header, to the types table
|
||||
uint8_t type_table_offset;
|
||||
};
|
||||
|
||||
struct Call_Site_Header {
|
||||
// Same as other LSDA constructors
|
||||
Call_Site_Header(LSDA_ptr *lsda) {
|
||||
LSDA_ptr read_ptr = *lsda;
|
||||
encoding = read_ptr[0];
|
||||
length = read_ptr[1];
|
||||
*lsda = read_ptr + sizeof(Call_Site_Header);
|
||||
}
|
||||
uint8_t encoding;
|
||||
uint8_t length;
|
||||
};
|
||||
|
||||
struct Call_Site {
|
||||
// Same as other LSDA constructors
|
||||
Call_Site(LSDA_ptr *lsda) {
|
||||
LSDA_ptr read_ptr = *lsda;
|
||||
start = read_ptr[0];
|
||||
len = read_ptr[1];
|
||||
lp = read_ptr[2];
|
||||
action = read_ptr[3];
|
||||
*lsda = read_ptr + sizeof(Call_Site);
|
||||
}
|
||||
Call_Site() { }
|
||||
// Note start, len and lp would be void*'s, but they are actually relative
|
||||
// addresses: start and lp are relative to the start of the function, len
|
||||
// is relative to start
|
||||
// Offset into function from which we could handle a throw
|
||||
uint8_t start;
|
||||
// Length of the block that might throw
|
||||
uint8_t len;
|
||||
// Landing pad
|
||||
uint8_t lp;
|
||||
// Offset into action table + 1 (0 means no action)
|
||||
// Used to run destructors
|
||||
uint8_t action;
|
||||
bool has_landing_pad() const {
|
||||
return lp;
|
||||
}
|
||||
/**
|
||||
* Returns true if the instruction pointer for this call frame
|
||||
* (throw_ip) is in the range of the landing pad for this call
|
||||
* site; if true that means the exception was thrown from within
|
||||
* this try/catch block
|
||||
*/
|
||||
bool valid_for_throw_ip(uintptr_t func_start, uintptr_t throw_ip) const {
|
||||
// Calculate the range of the instruction pointer valid for this
|
||||
// landing pad; if this LP can handle the current exception then
|
||||
// the IP for this stack frame must be in this range
|
||||
uintptr_t try_start = func_start + this->start;
|
||||
uintptr_t try_end = func_start + this->start + this->len;
|
||||
// Check if this is the correct LP for the current try block
|
||||
if (throw_ip < try_start) {
|
||||
return false;
|
||||
}
|
||||
if (throw_ip > try_end) {
|
||||
return false;
|
||||
}
|
||||
// The current exception was thrown from this landing pad
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A class to read the language specific data for a function
|
||||
*/
|
||||
struct LSDA {
|
||||
LSDA_Header header;
|
||||
// The types_table_start holds all the types this stack frame
|
||||
// could handle (this table will hold pointers to struct
|
||||
// type_info so this is actually a pointer to a list of ptrs
|
||||
const void** types_table_start;
|
||||
// With the call site header we can calculate the lenght of the
|
||||
// call site table
|
||||
Call_Site_Header cs_header;
|
||||
// A pointer to the start of the call site table
|
||||
const LSDA_ptr cs_table_start;
|
||||
// A pointer to the end of the call site table
|
||||
const LSDA_ptr cs_table_end;
|
||||
// A pointer to the start of the action table, where an action is
|
||||
// defined for each call site
|
||||
const LSDA_ptr action_tbl_start;
|
||||
LSDA(LSDA_ptr raw_lsda) :
|
||||
// Read LSDA header for the LSDA, advance the ptr
|
||||
header(&raw_lsda),
|
||||
|
||||
// Get the start of the types table (it's actually the end of the
|
||||
// table, but since the action index will hold a negative index
|
||||
// for this table we can say it's the beginning
|
||||
types_table_start( (const void**)(raw_lsda + header.type_table_offset) ),
|
||||
|
||||
// Read the LSDA CS header
|
||||
cs_header(&raw_lsda),
|
||||
|
||||
// The call site table starts immediatelly after the CS header
|
||||
cs_table_start(raw_lsda),
|
||||
|
||||
// Calculate where the end of the LSDA CS table is
|
||||
cs_table_end(raw_lsda + cs_header.length),
|
||||
|
||||
// Get the start of action tables
|
||||
action_tbl_start( cs_table_end )
|
||||
{
|
||||
}
|
||||
|
||||
Call_Site next_cs_entry;
|
||||
LSDA_ptr next_cs_entry_ptr;
|
||||
const Call_Site* next_call_site_entry(bool start=false) {
|
||||
if (start) {
|
||||
next_cs_entry_ptr = cs_table_start;
|
||||
}
|
||||
// If we went over the end of the table return NULL
|
||||
if (next_cs_entry_ptr >= cs_table_end) {
|
||||
return NULL;
|
||||
}
|
||||
// Copy the call site table and advance the cursor by sizeof(Call_Site).
|
||||
// We need to copy the struct here because there might be alignment
|
||||
// issues otherwise
|
||||
next_cs_entry = Call_Site(&next_cs_entry_ptr);
|
||||
return &next_cs_entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pointer to the action entry for a call site entry or
|
||||
* null if the CS has no action
|
||||
*/
|
||||
const LSDA_ptr get_action_for_call_site(const Call_Site *cs) const
|
||||
{
|
||||
if (cs->action == 0) {
|
||||
return NULL;
|
||||
}
|
||||
const size_t action_offset = cs->action - 1;
|
||||
return this->action_tbl_start + action_offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* An entry in the action table
|
||||
*/
|
||||
struct Action {
|
||||
// An index into the types table
|
||||
int type_index;
|
||||
// Offset for the next action, relative from this byte (this means
|
||||
// that the next action will begin exactly at the address of
|
||||
// &next_offset - next_offset itself
|
||||
int next_offset;
|
||||
// A pointer to the raw action, which we need to get the next
|
||||
// action:
|
||||
// next_action_offset = raw_action_ptr[1]
|
||||
// next_action_ptr = &raw_action_ptr[1] + next_action_offset
|
||||
LSDA_ptr raw_action_ptr;
|
||||
} current_action;
|
||||
|
||||
/**
|
||||
* Gets the first action for a specific call site
|
||||
*/
|
||||
const Action* get_first_action_for_cs(const Call_Site *cs)
|
||||
{
|
||||
// The call site may have no associated action (in that case
|
||||
// it should be a cleanup)
|
||||
if (cs->action == 0) {
|
||||
return NULL;
|
||||
}
|
||||
// The action in the CS is 1 based: 0 means no action and
|
||||
// 1 is the element 0 on the action table
|
||||
const size_t action_offset = cs->action - 1;
|
||||
LSDA_ptr action_raw = this->action_tbl_start + action_offset;
|
||||
current_action.type_index = action_raw[0];
|
||||
current_action.next_offset = readSLEB128( &action_raw[1] );
|
||||
current_action.raw_action_ptr = &action_raw[0];
|
||||
return ¤t_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next action, if any, for a CS (after calling
|
||||
* get_first_action_for_cs)
|
||||
*/
|
||||
const Action* get_next_action() {
|
||||
// If the current_action is the last one then the
|
||||
// offset for the next one will be 0
|
||||
if (current_action.next_offset == 0) {
|
||||
return NULL;
|
||||
}
|
||||
// To move to the next action we must use raw_action_ptr + 1
|
||||
// because the offset is from the next_offset place itself and
|
||||
// not from the start of the struct:
|
||||
LSDA_ptr action_raw = current_action.raw_action_ptr + 1 + current_action.next_offset;
|
||||
current_action.type_index = action_raw[0];
|
||||
current_action.next_offset = readSLEB128( &action_raw[1] );
|
||||
current_action.raw_action_ptr = &action_raw[0];
|
||||
return ¤t_action;
|
||||
}
|
||||
/**
|
||||
* Returns the type from the types table defined for an action
|
||||
*/
|
||||
const std::type_info* get_type_for(const Action* action) const {
|
||||
// The index starts at the end of the types table
|
||||
int idx = -1 * action->type_index;
|
||||
const void* catch_type_info = this->types_table_start[idx];
|
||||
return (const std::type_info *) catch_type_info;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**********************************************/
|
||||
bool can_handle(const std::type_info *thrown_exception,
|
||||
const std::type_info *catch_type) {
|
||||
// If the catch has no type specifier we're dealing with a catch(...)
|
||||
// and we can handle this exception regardless of what it is
|
||||
if (not catch_type) {
|
||||
return true;
|
||||
}
|
||||
// Naive type comparisson: only check if the type name is the same
|
||||
// This won't work with any kind of inheritance
|
||||
if (thrown_exception->name() == catch_type->name()) {
|
||||
return true;
|
||||
}
|
||||
// If types don't match just don't handle the exception
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
_Unwind_Reason_Code run_landing_pad(
|
||||
_Unwind_Exception* unwind_exception,
|
||||
_Unwind_Context* context,
|
||||
int exception_type_idx,
|
||||
uintptr_t lp_address) {
|
||||
int r0 = __builtin_eh_return_data_regno(0);
|
||||
int r1 = __builtin_eh_return_data_regno(1);
|
||||
|
||||
_Unwind_SetGR(context, r0, (uintptr_t)(unwind_exception));
|
||||
_Unwind_SetGR(context, r1, (uintptr_t)(exception_type_idx));
|
||||
_Unwind_SetIP(context, lp_address);
|
||||
|
||||
return _URC_INSTALL_CONTEXT;
|
||||
}
|
||||
|
||||
_Unwind_Reason_Code __gxx_personality_v0 (
|
||||
int version,
|
||||
_Unwind_Action actions,
|
||||
uint64_t exceptionClass,
|
||||
_Unwind_Exception* unwind_exception,
|
||||
_Unwind_Context* context) {
|
||||
// Calculate what the instruction pointer was just before the
|
||||
// exception was thrown for this stack frame
|
||||
uintptr_t throw_ip = _Unwind_GetIP(context) - 1;
|
||||
// Get a ptr to the start of the function for this stack frame;
|
||||
// this is needed because a lot of the addresses in the LSDA are
|
||||
// actually offsets from func_start
|
||||
uintptr_t func_start = _Unwind_GetRegionStart(context);
|
||||
// Get a pointer to the type_info of the exception being thrown
|
||||
__cxa_exception *exception_header =(__cxa_exception*)(unwind_exception+1)-1;
|
||||
std::type_info *thrown_exception_type = exception_header->exceptionType;
|
||||
// Get a pointer to the raw memory address of the LSDA
|
||||
LSDA_ptr raw_lsda = (LSDA_ptr) _Unwind_GetLanguageSpecificData(context);
|
||||
// Create an object to hide some part of the LSDA processing
|
||||
LSDA lsda(raw_lsda);
|
||||
// Go through each call site in this stack frame to check whether
|
||||
// the current exception can be handled here
|
||||
for(const Call_Site *cs = lsda.next_call_site_entry(true);
|
||||
cs != NULL;
|
||||
cs = lsda.next_call_site_entry()) {
|
||||
// If there's no landing pad we can't handle this exception
|
||||
if (not cs->has_landing_pad()) {
|
||||
continue;
|
||||
}
|
||||
// Calculate the range of the instruction pointer valid for this
|
||||
// landing pad; if this LP can handle the current exception then
|
||||
// the IP for this stack frame must be in this range
|
||||
if (not cs->valid_for_throw_ip(func_start, throw_ip)) {
|
||||
continue;
|
||||
}
|
||||
// Iterate all the actions for this call site
|
||||
for (const LSDA::Action* action = lsda.get_first_action_for_cs(cs);
|
||||
action != NULL;
|
||||
action = lsda.get_next_action()){
|
||||
if (action->type_index == 0) {
|
||||
// If there is an action entry but it doesn't point to any
|
||||
// type, it means this is actually a cleanup block and we
|
||||
// should run it anyway
|
||||
//
|
||||
// Of course the cleanup should only run on the cleanup phase
|
||||
if (actions & _UA_CLEANUP_PHASE) {
|
||||
return run_landing_pad(unwind_exception, context, action->type_index, func_start + cs->lp);
|
||||
}
|
||||
} else {
|
||||
// Get the types this action can handle
|
||||
const std::type_info *catch_type = lsda.get_type_for(action);
|
||||
if (can_handle(catch_type, thrown_exception_type)) {
|
||||
// If we are on search phase, tell _Unwind_ we can handle this one
|
||||
if (actions & _UA_SEARCH_PHASE) {
|
||||
return _URC_HANDLER_FOUND;
|
||||
}
|
||||
// If we are not on search phase then we are on _UA_CLEANUP_PHASE
|
||||
// and we need to install the context
|
||||
return run_landing_pad(unwind_exception, context, action->type_index, func_start + cs->lp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return _URC_CONTINUE_UNWIND;
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
{
|
||||
"type":"LIBRARY",
|
||||
"group-id":"com.atria-soft",
|
||||
"description":"Ewol tool kit (test: test framework)",
|
||||
"license":"MPL-2",
|
||||
"license-file":"file://../LICENSE.txt",
|
||||
"maintainer":"file://../authors.txt",
|
||||
"author":"file://../authors.txt",
|
||||
"version":"file://../version.txt",
|
||||
|
||||
"source": [
|
||||
"etest/etest.cpp",
|
||||
"etest/debug.cpp"
|
||||
],
|
||||
"header": [
|
||||
"etest/etest.hpp",
|
||||
"etest/debug.hpp"
|
||||
],
|
||||
"path":[
|
||||
"."
|
||||
],
|
||||
"dependency": [
|
||||
"etk-core",
|
||||
"echrono",
|
||||
"elog",
|
||||
"cxx"
|
||||
]
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
include(GLDBuilder)
|
||||
|
||||
GLD_import("./" "etk-core")
|
||||
|
||||
GLD_instanciate()
|
@ -1,235 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
if (WIN32)
|
||||
set(CPACK_GENERATOR "ZIP")
|
||||
else()
|
||||
set(CPACK_GENERATOR "TGZ")
|
||||
endif()
|
||||
set(CPACK_VERBATIM_VARIABLES YES)
|
||||
include(CPack)
|
||||
|
||||
function(json_get_list OUT_VAR INPUT_JSON VARIABLE)
|
||||
string(JSON LIST_JSON_ELEMENTS ERROR_VARIABLE ${VARIABLE} GET ${INPUT_JSON} ${VARIABLE})
|
||||
if (${LIST_JSON_ELEMENTS} EQUAL ${VARIABLE}-NOTFOUND)
|
||||
set("${OUT_VAR}" PARENT_SCOPE)
|
||||
retrun()
|
||||
endif()
|
||||
#message("LIST_JSON_ELEMENTS : ${LIST_JSON_ELEMENTS}")
|
||||
|
||||
string(JSON LENGTH_VALUE LENGTH ${LIST_JSON_ELEMENTS})
|
||||
#message("LENGTH_VALUE : ${LENGTH_VALUE}")
|
||||
if (${LENGTH_VALUE} EQUAL 0)
|
||||
set("${OUT_VAR}" PARENT_SCOPE)
|
||||
retrun()
|
||||
endif()
|
||||
set(OUT_LIST)
|
||||
MATH(EXPR LENGTH_VALUE "${LENGTH_VALUE}-1")
|
||||
foreach(IDX RANGE ${LENGTH_VALUE})
|
||||
string(JSON ELEM GET ${LIST_JSON_ELEMENTS} ${IDX})
|
||||
#message(" - : ${ELEM}")
|
||||
list(APPEND OUT_LIST ${ELEM})
|
||||
endforeach()
|
||||
#message("OUT_LIST : ${OUT_LIST}")
|
||||
set("${OUT_VAR}" ${OUT_LIST} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
|
||||
function(json_get_element OUT_VAR INPUT_JSON VARIABLE)
|
||||
string(JSON ELEMENT ERROR_VARIABLE ${VARIABLE} GET ${INPUT_JSON} ${VARIABLE})
|
||||
if (${ELEMENT} EQUAL ${VARIABLE}-NOTFOUND)
|
||||
set("${OUT_VAR}" PARENT_SCOPE)
|
||||
retrun()
|
||||
endif()
|
||||
set("${OUT_VAR}" ${ELEMENT} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
|
||||
function(GLD_import FOLDER LIBRARY_NAME)
|
||||
# add the executable
|
||||
# add_executable(Tutorial tutorial.cxx)
|
||||
|
||||
set(LIBRARY_NAME "etk-core")
|
||||
set_property(
|
||||
DIRECTORY
|
||||
APPEND
|
||||
PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/GLD_${LIBRARY_NAME}.json
|
||||
)
|
||||
# Read the JSON file.
|
||||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/GLD_${LIBRARY_NAME}.json MY_JSON_STRING)
|
||||
|
||||
# Loop through each element of the JSON array (indices 0 though 1).
|
||||
|
||||
json_get_element(LIBRARY_TYPE ${MY_JSON_STRING} "type")
|
||||
json_get_element(LIBRARY_GROUP_ID ${MY_JSON_STRING} "group-id")
|
||||
json_get_element(LIBRARY_DECRIPTION ${MY_JSON_STRING} "description")
|
||||
json_get_element(LIBRARY_LICENCE ${MY_JSON_STRING} "licence")
|
||||
json_get_element(LIBRARY_LICENCE_FILE ${MY_JSON_STRING} "licence-file")
|
||||
json_get_element(LIBRARY_MAINTAINER ${MY_JSON_STRING} "maintainer")
|
||||
json_get_element(LIBRARY_AUTHORS ${MY_JSON_STRING} "authors")
|
||||
json_get_element(LIBRARY_VERSION ${MY_JSON_STRING} "version")
|
||||
json_get_element(LIBRARY_SOURCES ${MY_JSON_STRING} "sources")
|
||||
json_get_element(LIBRARY_HEADERS ${MY_JSON_STRING} "headers")
|
||||
json_get_list(LIBRARY_PATH ${MY_JSON_STRING} "path")
|
||||
json_get_element(LIBRARY_COMPILATION_VERSION ${MY_JSON_STRING} "compilation-version")
|
||||
json_get_list(LIBRARY_DEPENDENCY ${MY_JSON_STRING} "dependency")
|
||||
json_get_element(LIBRARY_PLATFORM ${MY_JSON_STRING} "platform")
|
||||
|
||||
json_get_element(LIBRARY_COMPILATION_VERSION_LANGUAGE ${MY_JSON_STRING} "language")
|
||||
json_get_element(LIBRARY_COMPILATION_VERSION_VALUE ${MY_JSON_STRING} "version")
|
||||
|
||||
message("LIBRARY_NAME : ${LIBRARY_NAME}")
|
||||
message("LIBRARY_TYPE : ${LIBRARY_TYPE}")
|
||||
message("LIBRARY_GROUP_ID : ${LIBRARY_GROUP_ID}")
|
||||
message("LIBRARY_DECRIPTION : ${LIBRARY_DECRIPTION}")
|
||||
message("LIBRARY_LICENCE : ${LIBRARY_LICENCE}")
|
||||
message("LIBRARY_LICENCE_FILE : ${LIBRARY_LICENCE_FILE}")
|
||||
message("LIBRARY_MAINTAINER : ${LIBRARY_MAINTAINER}")
|
||||
message("LIBRARY_AUTHORS : ${LIBRARY_AUTHORS}")
|
||||
message("LIBRARY_VERSION : ${LIBRARY_VERSION}")
|
||||
message("LIBRARY_COMPILATION_VERSION : ${LIBRARY_COMPILATION_VERSION_LANGUAGE} : ${LIBRARY_COMPILATION_VERSION_VALUE}")
|
||||
|
||||
#message("LIBRARY_SOURCES: ${LIBRARY_SOURCES}")
|
||||
#message("LIBRARY_HEADERS: ${LIBRARY_HEADERS}")
|
||||
message("LIBRARY_PATH: ${LIBRARY_PATH}")
|
||||
#message("LIBRARY_COMPILATION_VERSION: ${LIBRARY_COMPILATION_VERSION}")
|
||||
message("LIBRARY_DEPENDENCY: ${LIBRARY_DEPENDENCY}")
|
||||
#message("LIBRARY_PLATFORM: ${LIBRARY_PLATFORM}")
|
||||
|
||||
|
||||
json_get_list(SOURCES_LIST ${LIBRARY_SOURCES} "list")
|
||||
message("SOURCES_LIST: ${SOURCES_LIST}")
|
||||
|
||||
json_get_list(EXPORT_HEADER_LIST ${LIBRARY_HEADERS} "list")
|
||||
json_get_element(EXPORT_HEADER_LIST_PATH ${LIBRARY_HEADERS} "destination-path")
|
||||
message("EXPORT_HEADER_LIST: ${EXPORT_HEADER_LIST}")
|
||||
message("EXPORT_HEADER_LIST_PATH: ${EXPORT_HEADER_LIST_PATH}")
|
||||
|
||||
|
||||
|
||||
string(JSON LIBRARY_PLOP ERROR_VARIABLE "qsdfqsdfqsdf" GET ${MY_JSON_STRING} "qsdfqsdfqsdf")
|
||||
#string(JSON LIBRARY_MEMBERS MEMBER ${MY_JSON_STRING} )
|
||||
#message("LIBRARY_MEMBERS : ${LIBRARY_MEMBERS}")
|
||||
message("LIBRARY_PLOP : ${LIBRARY_PLOP}")
|
||||
|
||||
string(REPLACE "-" "_" LIBRARY_NAME222 ${LIBRARY_NAME})
|
||||
set(LIBRARY_NAME222 ${LIBRARY_NAME})
|
||||
project(${LIBRARY_NAME222} VERSION ${LIBRARY_VERSION})
|
||||
set(${LIBRARY_NAME222} PROPERTIES CPACK_PACKAGE_VERSION ${LIBRARY_VERSION})
|
||||
add_library(${LIBRARY_NAME222}_OBJ OBJECT ${SOURCES_LIST})
|
||||
# shared libraries need PIC
|
||||
set_property(TARGET ${LIBRARY_NAME222}_OBJ PROPERTY POSITION_INDEPENDENT_CODE 1)
|
||||
|
||||
|
||||
#set_target_properties(${LIBRARY_NAME222} PROPERTIES PUBLIC_HEADER ${EXPORT_HEADER_LIST})
|
||||
target_include_directories(${LIBRARY_NAME222}_OBJ PUBLIC
|
||||
${LIBRARY_PATH}
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
add_library(${LIBRARY_NAME222}_dynamic SHARED $<TARGET_OBJECTS:${LIBRARY_NAME222}_OBJ>)
|
||||
add_library(${LIBRARY_NAME222}_static STATIC $<TARGET_OBJECTS:${LIBRARY_NAME222}_OBJ>)
|
||||
|
||||
set_target_properties(${LIBRARY_NAME222}_dynamic PROPERTIES OUTPUT_NAME ${LIBRARY_NAME222})
|
||||
if (NOT WIN32)
|
||||
set_target_properties(${LIBRARY_NAME222}_static PROPERTIES OUTPUT_NAME ${LIBRARY_NAME222})
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
set_target_properties(${LIBRARY_NAME222}_dynamic PROPERTIES VERSION ${LIBRARY_VERSION})
|
||||
set_target_properties(${LIBRARY_NAME222}_dynamic PROPERTIES SOVERSION ${LIBRARY_VERSION})
|
||||
set_target_properties(${LIBRARY_NAME222}_dynamic PROPERTIES DESCRIPTION ${LIBRARY_DECRIPTION})
|
||||
|
||||
# install dynamic & static library
|
||||
install(TARGETS ${LIBRARY_NAME222}_dynamic EXPORT ${LIBRARY_NAME222}Targets
|
||||
RUNTIME DESTINATION lib
|
||||
)
|
||||
install(TARGETS ${LIBRARY_NAME222}_static
|
||||
RUNTIME DESTINATION lib)
|
||||
|
||||
|
||||
#install(TARGETS ${LIBRARY_NAME222} EXPORT ${LIBRARY_NAME222}Targets
|
||||
# LIBRARY DESTINATION lib
|
||||
# ARCHIVE DESTINATION lib
|
||||
# RUNTIME DESTINATION bin
|
||||
# INCLUDES DESTINATION include
|
||||
#)
|
||||
# install exported headers
|
||||
# this copy all the headers in a single folder:
|
||||
#install(FILES ${EXPORT_HEADER_LIST} DESTINATION include)
|
||||
# this keep the basic path for each folders:
|
||||
set(BASE "${PROJECT_SOURCE_DIR}/install")
|
||||
foreach(ITEM ${EXPORT_HEADER_LIST})
|
||||
get_filename_component(ITEM_PATH ${ITEM} PATH)
|
||||
string(REPLACE ${BASE} "" ITEM_PATH ${ITEM_PATH})
|
||||
install(FILES ${ITEM}
|
||||
DESTINATION "include/${ITEM_PATH}"
|
||||
COMPONENT Devel)
|
||||
endforeach()
|
||||
|
||||
|
||||
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
#write_basic_package_version_file(
|
||||
# "${CMAKE_CURRENT_BINARY_DIR}/${LIBRARY_NAME222}/${LIBRARY_NAME222}ConfigVersion.cmake"
|
||||
# VERSION ${LIBRARY_VERSION}
|
||||
# COMPATIBILITY AnyNewerVersion
|
||||
#)
|
||||
#
|
||||
#export(EXPORT ${LIBRARY_NAME222}Targets
|
||||
# FILE "${CMAKE_CURRENT_BINARY_DIR}/${LIBRARY_NAME222}/${LIBRARY_NAME222}Targets.cmake"
|
||||
# NAMESPACE Upstream::
|
||||
#)
|
||||
##configure_file(cmake/${LIBRARY_NAME222}Config.cmake
|
||||
## "${CMAKE_CURRENT_BINARY_DIR}/${LIBRARY_NAME222}/${LIBRARY_NAME222}Config.cmake"
|
||||
## COPYONLY
|
||||
##)
|
||||
|
||||
set(CONFIG_PACKAGE_LOCATION cmake/${LIBRARY_NAME222})
|
||||
install(EXPORT ${LIBRARY_NAME222}Targets
|
||||
FILE
|
||||
${LIBRARY_NAME222}Targets.cmake
|
||||
NAMESPACE
|
||||
${LIBRARY_NAME222}::
|
||||
DESTINATION
|
||||
${CONFIG_PACKAGE_LOCATION}
|
||||
)
|
||||
#install(
|
||||
# FILES
|
||||
# cmake/${LIBRARY_NAME222}Config.cmake
|
||||
# "${CMAKE_CURRENT_BINARY_DIR}/${LIBRARY_NAME222}/${LIBRARY_NAME222}ConfigVersion.cmake"
|
||||
# DESTINATION
|
||||
# ${CONFIG_PACKAGE_LOCATION}
|
||||
# COMPONENT
|
||||
# Devel
|
||||
#)
|
||||
message("CMAKE_INSTALL_LIBDIR===${CMAKE_INSTALL_LIBDIR}")
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
configure_package_config_file(cmake/${LIBRARY_NAME222}Config.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/${LIBRARY_NAME222}Config.cmake"
|
||||
INSTALL_DESTINATION ${CONFIG_PACKAGE_LOCATION}
|
||||
NO_SET_AND_CHECK_MACRO
|
||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO)
|
||||
write_basic_package_version_file(
|
||||
"${PROJECT_BINARY_DIR}/${LIBRARY_NAME222}ConfigVersion.cmake"
|
||||
VERSION ${LIBRARY_VERSION}
|
||||
COMPATIBILITY SameMajorVersion)
|
||||
install(
|
||||
FILES
|
||||
"${PROJECT_BINARY_DIR}/${LIBRARY_NAME222}Config.cmake"
|
||||
"${PROJECT_BINARY_DIR}/${LIBRARY_NAME222}ConfigVersion.cmake"
|
||||
DESTINATION ${CONFIG_PACKAGE_LOCATION}
|
||||
COMPONENT Devel)
|
||||
|
||||
endfunction()
|
||||
|
||||
|
||||
function(GLD_instanciate)
|
||||
|
||||
endfunction()
|
||||
|
@ -1,70 +0,0 @@
|
||||
{
|
||||
"type":"LIBRARY",
|
||||
"group-id":"com.atria-soft",
|
||||
"description":"Ewol tool kit (base: container)",
|
||||
"license":"MPL-2",
|
||||
"license-file":"file://../LICENCE.txt",
|
||||
"maintainer":"file://../authors.txt",
|
||||
"author":"file://../authors.txt",
|
||||
"version":"file://../version.txt",
|
||||
"code-quality":"MEDIUM",
|
||||
|
||||
"source": [
|
||||
"etk/String.cpp",
|
||||
"etk/UString.cpp",
|
||||
"etk/utf8.cpp",
|
||||
"etk/stdTools.cpp",
|
||||
"etk/Stream.cpp",
|
||||
"etk/Function.cpp",
|
||||
"etk/Allocator.cpp",
|
||||
"etk/typeInfo.cpp",
|
||||
"etk/Exception.cpp",
|
||||
"etk/system.cpp",
|
||||
"etk/Number.cpp"
|
||||
],
|
||||
"header": [
|
||||
"etk/algorithm.hpp",
|
||||
"etk/Allocator.hpp",
|
||||
"etk/types.hpp",
|
||||
"etk/stdTools.hpp",
|
||||
"etk/String.hpp",
|
||||
"etk/UString.hpp",
|
||||
"etk/utf8.hpp",
|
||||
"etk/Array.hpp",
|
||||
"etk/Vector.hpp",
|
||||
"etk/Stream.hpp",
|
||||
"etk/Pair.hpp",
|
||||
"etk/Map.hpp",
|
||||
"etk/Set.hpp",
|
||||
"etk/move.hpp",
|
||||
"etk/typeTrait.hpp",
|
||||
"etk/Function.hpp",
|
||||
"etk/NullPtr.hpp",
|
||||
"etk/typeInfo.hpp",
|
||||
"etk/Exception.hpp",
|
||||
"etk/system.hpp",
|
||||
"etk/Number.hpp"
|
||||
],
|
||||
"path":[
|
||||
"."
|
||||
],
|
||||
"compilation-version": {
|
||||
"c++": 2017
|
||||
},
|
||||
"dependency": [
|
||||
"c",
|
||||
"m",
|
||||
"pthread"
|
||||
],
|
||||
"target": {
|
||||
"Android": {
|
||||
"dependency": "SDK"
|
||||
},
|
||||
"MacOs": {
|
||||
"dependency": "cxx"
|
||||
},
|
||||
"Linux": {
|
||||
"dependency": "cxx"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
{
|
||||
"type":"BINARY_SHARED",
|
||||
"group-id":"com.atria-soft",
|
||||
"description":"Ewol tool kit test software",
|
||||
"license":"MPL-2",
|
||||
"license-file":"file://../LICENSE.txt",
|
||||
"maintainer":"file://../authors.txt",
|
||||
"author":"file://../authors.txt",
|
||||
"version":"file://../version.txt",
|
||||
"code-quality":"MEDIUM",
|
||||
"source": [
|
||||
"test/main.cpp",
|
||||
"test/testFileSystem.cpp",
|
||||
"test/testPath.cpp",
|
||||
"test/testPermissions.cpp",
|
||||
"test/testTheme.cpp",
|
||||
"test/testUri.cpp",
|
||||
"test/testQuery.cpp",
|
||||
"test/testUriProvider.cpp",
|
||||
"test/ConstructDestruct.cpp",
|
||||
"test/testColor.cpp",
|
||||
"test/testFunction.cpp",
|
||||
"test/testMapUnordered.cpp",
|
||||
"test/testMap.cpp",
|
||||
"test/testSet.cpp",
|
||||
"test/testMatrix3x3.cpp",
|
||||
"test/testRegExp.cpp",
|
||||
"test/testTransform.cpp",
|
||||
"test/testArray.cpp",
|
||||
"test/testVector.cpp",
|
||||
"test/testVector3_f.cpp",
|
||||
"test/testMatrix2x2.cpp",
|
||||
"test/testQuaternion.cpp",
|
||||
"test/testVector2_f.cpp",
|
||||
"test/testString.cpp",
|
||||
"test/testTrait.cpp",
|
||||
"test/testThrow.cpp",
|
||||
"test/testUTF8.cpp"
|
||||
],
|
||||
"dependency": [
|
||||
"etk",
|
||||
"etest",
|
||||
"test-debug"
|
||||
],
|
||||
"copy": [
|
||||
{
|
||||
"path":"data/*",
|
||||
"to":""
|
||||
}, {
|
||||
"path":"data/data/*",
|
||||
"to":"data/"
|
||||
}, {
|
||||
"path":"data/data/dir_A/*",
|
||||
"to":"data/dir_A/"
|
||||
}, {
|
||||
"path":"data/data/dir_B/*",
|
||||
"to":"data/dir_B/"
|
||||
}, {
|
||||
"path":"data/data/dir_B/dir_C/*",
|
||||
"to":"data/dir_B/dir_C/"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
# CMakeCpp CMake configuration file
|
||||
|
||||
#include(CMakeFindDependencyMacro)
|
||||
#find_dependency(Foo REQUIRED NO_MODULE)
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/etk-coreTargets.cmake")
|
114
etk/GLD_etk.json
114
etk/GLD_etk.json
@ -1,114 +0,0 @@
|
||||
{
|
||||
"type":"LIBRARY",
|
||||
"group-id":"com.atria-soft",
|
||||
"description":"Ewol tool kit",
|
||||
"license":"MPL-2",
|
||||
"license-file":"file://../LICENSE.txt",
|
||||
"maintainer":"file://../authors.txt",
|
||||
"author":"file://../authors.txt",
|
||||
"version":"file://../version.txt",
|
||||
|
||||
"source": [
|
||||
"etk/debug.cpp",
|
||||
"etk/etk.cpp",
|
||||
"etk/tool.cpp",
|
||||
"etk/Noise.cpp",
|
||||
"etk/Color.cpp",
|
||||
"etk/RegEx.cpp",
|
||||
"etk/path/fileSystem.cpp",
|
||||
"etk/path/Path.cpp",
|
||||
"etk/path/Permissions.cpp",
|
||||
"etk/io/OpenMode.cpp",
|
||||
"etk/io/SeekMode.cpp",
|
||||
"etk/io/Interface.cpp",
|
||||
"etk/io/File.cpp",
|
||||
"etk/io/ZipFile.cpp",
|
||||
"etk/theme/theme.cpp",
|
||||
"etk/theme/ProviderTheme.cpp",
|
||||
"etk/math/Matrix2x2.cpp",
|
||||
"etk/math/Matrix2x3.cpp",
|
||||
"etk/math/Matrix3x3.cpp",
|
||||
"etk/math/Matrix4x4.cpp",
|
||||
"etk/math/Vector2D.cpp",
|
||||
"etk/math/Vector3D.cpp",
|
||||
"etk/math/Vector4D.cpp",
|
||||
"etk/math/Quaternion.cpp",
|
||||
"etk/math/Transform3D.cpp",
|
||||
"etk/archive/Archive.cpp",
|
||||
"etk/archive/Zip.cpp",
|
||||
"etk/uri/Uri.cpp",
|
||||
"etk/uri/uri.cpp",
|
||||
"etk/uri/Query.cpp",
|
||||
"etk/uri/provider/provider.cpp",
|
||||
"etk/uri/provider/Interface.cpp",
|
||||
"etk/uri/provider/ProviderFile.cpp",
|
||||
"etk/uri/provider/ProviderFileZip.cpp"
|
||||
],
|
||||
"header": [
|
||||
"etk/etk.hpp",
|
||||
"etk/debug.hpp",
|
||||
"etk/Buffer.hpp",
|
||||
"etk/tool.hpp",
|
||||
"etk/Noise.hpp",
|
||||
"etk/Color.hpp",
|
||||
"etk/RegEx.hpp",
|
||||
"etk/path/fileSystem.hpp",
|
||||
"etk/path/Path.hpp",
|
||||
"etk/path/Permissions.hpp",
|
||||
"etk/io/OpenMode.hpp",
|
||||
"etk/io/SeekMode.hpp",
|
||||
"etk/io/Interface.hpp",
|
||||
"etk/io/File.hpp",
|
||||
"etk/io/ZipFile.hpp",
|
||||
"etk/theme/theme.hpp",
|
||||
"etk/theme/ProviderTheme.hpp",
|
||||
"etk/math/Matrix2x2.hpp",
|
||||
"etk/math/Matrix2x3.hpp",
|
||||
"etk/math/Matrix3x3.hpp",
|
||||
"etk/math/Matrix4x4.hpp",
|
||||
"etk/math/Vector2D.hpp",
|
||||
"etk/math/Vector3D.hpp",
|
||||
"etk/math/Vector4D.hpp",
|
||||
"etk/math/Quaternion.hpp",
|
||||
"etk/math/Transform3D.hpp",
|
||||
"etk/os/Fifo.hpp",
|
||||
"etk/archive/Archive.hpp",
|
||||
"etk/archive/Zip.hpp",
|
||||
"etk/TreeNode.hpp",
|
||||
"etk/FlatTree.hpp",
|
||||
"etk/uri/Uri.hpp",
|
||||
"etk/uri/uri.hpp",
|
||||
"etk/uri/Query.hpp",
|
||||
"etk/uri/provider/provider.hpp",
|
||||
"etk/uri/provider/Interface.hpp",
|
||||
"etk/uri/provider/ProviderFile.hpp",
|
||||
"etk/uri/provider/ProviderFileZip.hpp"
|
||||
],
|
||||
"path":[
|
||||
"."
|
||||
],
|
||||
"compilation-version": {
|
||||
"c++": 2017
|
||||
},
|
||||
"dependency": [
|
||||
"c",
|
||||
"cxx",
|
||||
"m",
|
||||
"elog",
|
||||
"ememory",
|
||||
"etk-core",
|
||||
{
|
||||
"name":"minizip",
|
||||
"optional":true,
|
||||
"export":true
|
||||
}, {
|
||||
"name": "linearmath",
|
||||
"optional": true,
|
||||
"export": true,
|
||||
"flag": {
|
||||
"c++": "-DETK_BUILD_LINEARMATH"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -84,10 +84,11 @@ etk::Number::Number(uint64_t _value) :
|
||||
}
|
||||
etk::Number::Number(float _value) :
|
||||
m_negative(false),
|
||||
m_unit(_value),
|
||||
m_unit(0),
|
||||
m_lessZero(0),
|
||||
m_numberLessZero(0),
|
||||
m_exponent(0) {
|
||||
m_unit(_value);
|
||||
_value -= int64_t(_value);
|
||||
_value *= 10.0;
|
||||
for (size_t iii=0; iii<64; ++iii) {
|
||||
@ -103,10 +104,11 @@ etk::Number::Number(float _value) :
|
||||
}
|
||||
etk::Number::Number(double _value) :
|
||||
m_negative(false),
|
||||
m_unit(_value),
|
||||
m_unit(0),
|
||||
m_lessZero(0),
|
||||
m_numberLessZero(0),
|
||||
m_exponent(0) {
|
||||
m_unit(_value);
|
||||
_value -= int64_t(_value);
|
||||
_value *= 10.0;
|
||||
for (size_t iii=0; iii<64; ++iii) {
|
||||
@ -122,10 +124,11 @@ etk::Number::Number(double _value) :
|
||||
}
|
||||
etk::Number::Number(long double _value) :
|
||||
m_negative(false),
|
||||
m_unit(_value),
|
||||
m_unit(0),
|
||||
m_lessZero(0),
|
||||
m_numberLessZero(0),
|
||||
m_exponent(0) {
|
||||
m_unit(_value);
|
||||
_value -= int64_t(_value);
|
||||
_value *= 10.0;
|
||||
for (size_t iii=0; iii<64; ++iii) {
|
||||
@ -219,7 +222,7 @@ bool etk::Number::parse(const etk::UString& _value) {
|
||||
section = type::numberLessZero;
|
||||
continue;
|
||||
}
|
||||
//TK_ERROR("Can not parse the Number '" << _value << "':" << iii << " '.' can not parse");
|
||||
TK_ERROR("Can not parse the Number '" << _value << "':" << iii << " '.' can not parse");
|
||||
return false;
|
||||
}
|
||||
if (_value[iii] == 'e') {
|
||||
@ -228,7 +231,7 @@ bool etk::Number::parse(const etk::UString& _value) {
|
||||
section = type::numberExponent;
|
||||
continue;
|
||||
}
|
||||
//TK_ERROR("Can not parse the Number '" << _value << "':" << iii << " 'e' ==> can not parse ...");
|
||||
TK_ERROR("Can not parse the Number '" << _value << "':" << iii << " 'e' ==> can not parse ...");
|
||||
return false;
|
||||
}
|
||||
if (isDigit(_value[iii], section) == true) {
|
||||
@ -260,9 +263,9 @@ bool etk::Number::parse(const etk::UString& _value) {
|
||||
long double etk::Number::getDouble() {
|
||||
long double out = 0;
|
||||
out = m_lessZero;
|
||||
out *= pow(10.0,-m_numberLessZero);
|
||||
out *= pow(10,-m_numberLessZero);
|
||||
out += m_unit;
|
||||
out *= pow(10.0,m_exponent);
|
||||
out *= pow(10,m_exponent);
|
||||
if (m_negative == true) {
|
||||
out *= -1.0;
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#ifdef ETK_BUILD_MINIZIP
|
||||
|
||||
#include <etk/archive/Archive.hpp>
|
||||
#include <etk/archive/Zip.hpp>
|
||||
@ -219,3 +220,5 @@ etk::Vector<etk::Path> etk::Archive::listRecursive(const etk::Path& _path) {
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@ -5,6 +5,8 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifdef ETK_BUILD_MINIZIP
|
||||
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/Map.hpp>
|
||||
#include <ethread/Mutex.hpp>
|
||||
@ -213,3 +215,4 @@ namespace etk {
|
||||
etk::Vector<etk::Path> listRecursive(const etk::Path& _path);
|
||||
};
|
||||
}
|
||||
#endif
|
@ -4,6 +4,8 @@
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifdef ETK_BUILD_MINIZIP
|
||||
|
||||
#include <etk/archive/Zip.hpp>
|
||||
#include <etk/types.hpp>
|
||||
#include <etk/debug.hpp>
|
||||
@ -14,7 +16,6 @@ ETK_DECLARE_TYPE(etk::archive::Zip);
|
||||
etk::archive::Zip::Zip(const etk::Path& _fileName, uint64_t _offset) :
|
||||
etk::Archive(_fileName),
|
||||
m_ctx(null) {
|
||||
#if 0
|
||||
/* Open the zip file */
|
||||
m_ctx = unzOpenOffset(m_fileName.getNative().c_str(), _offset);
|
||||
if(!m_ctx) {
|
||||
@ -50,13 +51,11 @@ etk::archive::Zip::Zip(const etk::Path& _fileName, uint64_t _offset) :
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// TODO: Support the correct URI... ==> do a structure in unzip to manage the read and write of data with a callback...
|
||||
etk::archive::Zip::Zip(const etk::Uri& _uri) :
|
||||
etk::Archive(_uri.getPath()),
|
||||
m_ctx(null) {
|
||||
#if 0
|
||||
if (_uri.getScheme() != "") {
|
||||
TK_ERROR("Can not read and uri that is not with a scheme != of RAW, we have " << _uri);
|
||||
return;
|
||||
@ -96,20 +95,16 @@ etk::archive::Zip::Zip(const etk::Uri& _uri) :
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
etk::archive::Zip::~Zip() {
|
||||
#if 0
|
||||
if (m_ctx!= null) {
|
||||
unzClose(m_ctx);
|
||||
m_ctx = null;
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
void etk::archive::Zip::loadFile(const etk::Map<etk::Path, ememory::SharedPtr<ArchiveContent>>::Iterator& it) {
|
||||
#if 0
|
||||
TK_VERBOSE("Real load file : '" << it->first << "'");
|
||||
|
||||
unzGoToFirstFile(m_ctx);
|
||||
@ -160,5 +155,5 @@ void etk::archive::Zip::loadFile(const etk::Map<etk::Path, ememory::SharedPtr<Ar
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
50
etk/archive/Zip.hpp
Normal file
50
etk/archive/Zip.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/archive/Archive.hpp>
|
||||
#include <etk/uri/Uri.hpp>
|
||||
#ifdef ETK_BUILD_MINIZIP
|
||||
extern "C" {
|
||||
#include <minizip/unzip.h>
|
||||
}
|
||||
namespace etk {
|
||||
/**
|
||||
* @brief Zip file acces are set in a archive namespace
|
||||
*/
|
||||
namespace archive {
|
||||
/**
|
||||
* @brief Zip acces interface (wrapper)
|
||||
*/
|
||||
class Zip : public etk::Archive {
|
||||
private:
|
||||
unzFile m_ctx; //!< mini zip context
|
||||
unz_global_info m_info; //!< global information of the Zip
|
||||
public:
|
||||
/**
|
||||
* @brief constructor of a zip file access
|
||||
* @param[in] _fileName File to parse (.zip / .apk)
|
||||
* @param[in] _offset Offset in the file where to start the parsing of the "zip"
|
||||
*/
|
||||
Zip(const etk::Path& _fileName, uint64_t _offset = 0LL);
|
||||
/**
|
||||
* @brief constructor of a zip file access
|
||||
* @param[in] _uri URI of the file to parse (.zip / .apk)
|
||||
*/
|
||||
Zip(const etk::Uri& _uri);
|
||||
/**
|
||||
* @brief basic destructor
|
||||
*/
|
||||
virtual ~Zip();
|
||||
protected:
|
||||
void loadFile(const etk::Map<etk::Path, ememory::SharedPtr<ArchiveContent>>::Iterator& _it) override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,433 +0,0 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL-2(see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/types.hpp>
|
||||
//#include <etk/debug.hpp>
|
||||
#include <etk/Stream.hpp>
|
||||
|
||||
template<typename T> class TreeRedBlack {
|
||||
private:
|
||||
class TreeRedBlackNode {
|
||||
public:
|
||||
enum Color {
|
||||
RED = 0,
|
||||
BLACK = 1,
|
||||
};
|
||||
enum Side {
|
||||
LEFT = 0,
|
||||
RIGHT = 1,
|
||||
};
|
||||
TreeRedBlackNode(long long _k, T* _obj, TreeRedBlack* _tree):
|
||||
obj(_obj),
|
||||
key(_k),
|
||||
color(RED),
|
||||
parent(null),
|
||||
tree(_tree) {
|
||||
this->link[LEFT] = TreeRedBlack<T>::nil;
|
||||
this->link[RIGHT] = TreeRedBlack<T>::nil;
|
||||
if(null == o) {
|
||||
this->color = BLACK;
|
||||
this->link[LEFT] = null;
|
||||
this->link[RIGHT] = null;
|
||||
}
|
||||
}
|
||||
~TreeRedBlackNode() {
|
||||
if(this->link[LEFT]->isNil() == false) {
|
||||
delete this->link[LEFT];
|
||||
}
|
||||
if(this->link[RIGHT]->isNil() == false) {
|
||||
delete this->link[RIGHT];
|
||||
}
|
||||
}
|
||||
inline bool isNil() {
|
||||
return(this->obj == null);
|
||||
}
|
||||
inline void swapColor(TreeRedBlackNode &node) {
|
||||
Color c = this->color;
|
||||
this->color = node.color;
|
||||
node.color = c;
|
||||
}
|
||||
inline T * getObj() {
|
||||
return this->obj;
|
||||
}
|
||||
inline void setBlack() {
|
||||
this->color = BLACK;
|
||||
}
|
||||
inline void setRed() {
|
||||
this->color = RED;
|
||||
}
|
||||
inline Color getColor() {
|
||||
return this->color;
|
||||
}
|
||||
inline bool isBlack() {
|
||||
return this->color == BLACK;
|
||||
}
|
||||
inline bool isRed() {
|
||||
return(this->color == RED);
|
||||
}
|
||||
inline Side whichSide(TreeRedBlackNode& _node) {
|
||||
if(this->link[LEFT] == &_node){
|
||||
return LEFT;
|
||||
} else if(this->link[RIGHT] == &_node) {
|
||||
return RIGHT;
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
inline Side otherSide(Side _side) {
|
||||
assert(s == LEFT || _side == RIGHT);
|
||||
return(s == LEFT ? RIGHT : LEFT);
|
||||
}
|
||||
inline TreeRedBlackNode * getBrother() {
|
||||
if(this->parent == null) {
|
||||
return null;
|
||||
}
|
||||
assert( this->parent->link[LEFT] == this
|
||||
|| this->parent->link[RIGHT] == this);
|
||||
if this->parent->link[LEFT] == this) {
|
||||
return this->parent->link[RIGHT];
|
||||
} else {
|
||||
return this->parent->link[LEFT];
|
||||
}
|
||||
}
|
||||
inline void attach(TreeRedBlackNode &node) {
|
||||
assert(this->key != node.key);
|
||||
Side s =(node.key < this->key ? LEFT : RIGHT);
|
||||
this->attach(s, node);
|
||||
}
|
||||
inline void attach(Side s, TreeRedBlackNode &node) {
|
||||
assert(s == LEFT || s == RIGHT);
|
||||
assert(this != &node);
|
||||
assert(this->link[s]->isNil());
|
||||
this->link[s] = &node;
|
||||
if(! node.isNil()) {
|
||||
node.parent = this;
|
||||
}
|
||||
}
|
||||
inline TreeRedBlackNode * detach(Side s) {
|
||||
assert(s == LEFT || s == RIGHT);
|
||||
if(this->isNil() || this->link[s]->isNil())
|
||||
return TreeRedBlack<T>::nil;
|
||||
TreeRedBlackNode * node = this->link[s];
|
||||
this->link[s]->parent = null;
|
||||
this->link[s] = TreeRedBlack<T>::nil;
|
||||
return node;
|
||||
}
|
||||
inline TreeRedBlackNode * detach(TreeRedBlackNode &node) {
|
||||
if(this->link[RIGHT] == &node)
|
||||
return this->detach(RIGHT);
|
||||
else if(this->link[LEFT] == &node)
|
||||
return this->detach(LEFT);
|
||||
else
|
||||
assert(0);
|
||||
return null;
|
||||
}
|
||||
inline TreeRedBlackNode * searchMax() {
|
||||
if(! this->link[RIGHT]->isNil()) {
|
||||
return this->link[RIGHT]->searchMax();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
inline TreeRedBlackNode * searchMin() {
|
||||
if(! this->link[LEFT]->isNil())
|
||||
return this->link[LEFT]->searchMin();
|
||||
return this;
|
||||
}
|
||||
void rotate(Side s) {
|
||||
TreeRedBlackNode * nLeaf; // New leaf
|
||||
TreeRedBlackNode * nParent; // New parent
|
||||
TreeRedBlackNode * nGrand; // New grand father
|
||||
Side r = otherSide(s);
|
||||
nGrand = this->parent;
|
||||
nParent = this->detach(r);
|
||||
assert(nParent);
|
||||
nLeaf = nParent->detach(s);
|
||||
if(nGrand) {
|
||||
Side ps = nGrand->whichSide(*this);
|
||||
nGrand->detach(ps);
|
||||
nGrand->attach(ps, *nParent);
|
||||
} else {
|
||||
this->tree->root = nParent;
|
||||
}
|
||||
nParent->attach(s, *this);
|
||||
if(! nLeaf->isNil())
|
||||
this->attach(r, *nLeaf);
|
||||
}
|
||||
void adjustInsert() {
|
||||
if(this->parent == null) {
|
||||
// this node is root
|
||||
this->setBlack();
|
||||
return;
|
||||
}
|
||||
if(this->parent->isRed()) {
|
||||
assert(this->parent->parent);
|
||||
assert(this->parent->parent->isBlack());
|
||||
TreeRedBlackNode * cParent = this->parent;
|
||||
TreeRedBlackNode * grand = this->parent->parent;
|
||||
TreeRedBlackNode * uncle = this->parent->getBrother();
|
||||
Side s;
|
||||
if(uncle->isRed()) {
|
||||
uncle->setBlack();
|
||||
this->parent->setBlack();
|
||||
grand->setRed();
|
||||
grand->adjustInsert();
|
||||
} else {
|
||||
if(this->parent->whichSide(*this) != grand->whichSide(*this->parent)) {
|
||||
s = otherSide(cParent->whichSide(*this));
|
||||
cParent->rotate(s);
|
||||
cParent = this;
|
||||
}
|
||||
s = otherSide(grand->whichSide(*cParent));
|
||||
grand->rotate(s);
|
||||
assert(grand->isBlack() && cParent->isRed());
|
||||
grand->swapColor(*cParent);
|
||||
}
|
||||
}
|
||||
}
|
||||
bool insert(TreeRedBlackNode &node) {
|
||||
if(this->key == node.key) {
|
||||
// duplicated
|
||||
return false;
|
||||
}
|
||||
Side s =(node.key < this->key ? LEFT : RIGHT);
|
||||
if(! this->link[s]->isNil()) {
|
||||
return this->link[s]->insert(node);
|
||||
} else {
|
||||
this->attach(s, node);
|
||||
}
|
||||
node.adjustInsert();
|
||||
return true;
|
||||
}
|
||||
TreeRedBlackNode * lookup(long long k) {
|
||||
if(this->key == k) {
|
||||
return this;
|
||||
} else {
|
||||
Side s =(k < this->key ? LEFT : RIGHT);
|
||||
return(this->link[s]->isNil() ? null : this->link[s]->lookup(k));
|
||||
}
|
||||
}
|
||||
void leave() {
|
||||
// only detach from tree, balancing color & tree in adjustLeave()
|
||||
TreeRedBlackNode * cParent = this->parent;
|
||||
if(this->link[LEFT]->isNil() && this->link[RIGHT]->isNil()) {
|
||||
if(cParent) {
|
||||
Side s = cParent->whichSide(*this);
|
||||
cParent->detach(*this);
|
||||
if(this->isBlack()) {
|
||||
cParent->link[s]->adjustLeave(cParent);
|
||||
}
|
||||
} else {
|
||||
this->tree->root = null;
|
||||
}
|
||||
} else if((this->link[LEFT]->isNil()) ^(this->link[RIGHT]->isNil())) {
|
||||
Side s =(this->link[LEFT]->isNil() ? RIGHT : LEFT);
|
||||
TreeRedBlackNode * cTarget = this->detach(s);
|
||||
if(cParent) {
|
||||
cParent->detach(*this);
|
||||
cParent->attach(*cTarget);
|
||||
} else {
|
||||
this->tree->root = cTarget;
|
||||
}
|
||||
if(this->isBlack()) {
|
||||
cTarget->adjustLeave(cParent);
|
||||
}
|
||||
} else {
|
||||
// swap target node & maximum node in left subtree
|
||||
assert(! this->link[LEFT]->isNil() && ! this->link[RIGHT]->isNil());
|
||||
TreeRedBlackNode * cMax = this->link[LEFT]->searchMax();
|
||||
TreeRedBlackNode * mParent = cMax->parent;
|
||||
TreeRedBlackNode * cLeft = this->detach(LEFT);
|
||||
TreeRedBlackNode * cRight = this->detach(RIGHT);
|
||||
TreeRedBlackNode * mLeft = cMax->detach(LEFT);
|
||||
this->attach(*mLeft);
|
||||
if(cParent) {
|
||||
cParent->detach(*this);
|
||||
} else {
|
||||
this->tree->root = null;
|
||||
}
|
||||
if(cMax != cLeft) {
|
||||
// cMax have more 1 hop from THIS
|
||||
mParent->detach(*cMax);
|
||||
mParent->attach(*this);
|
||||
cMax->attach(LEFT, *cLeft);
|
||||
cMax->attach(RIGHT, *cRight);
|
||||
} else {
|
||||
// cMax == cLeft(cMax is left node of THIS)
|
||||
assert(cMax->link[RIGHT]->isNil());
|
||||
cMax->attach(RIGHT, *cRight);
|
||||
cMax->attach(LEFT, *this);
|
||||
}
|
||||
if(cParent) {
|
||||
cParent->attach(*cMax);
|
||||
} else {
|
||||
this->tree->root = cMax;
|
||||
}
|
||||
this->swapColor(*cMax);
|
||||
this->leave();
|
||||
}
|
||||
}
|
||||
void adjustLeave(TreeRedBlackNode * cParent) {
|
||||
// nothing to do when node is root
|
||||
if(null == cParent) {
|
||||
this->setBlack();
|
||||
return;
|
||||
}
|
||||
if(this->isRed()) {
|
||||
this->setBlack();
|
||||
return;
|
||||
}
|
||||
TreeRedBlackNode * cNeighbor = cParent->link[otherSide(cParent->whichSide(*this))];
|
||||
assert(cNeighbor) ;
|
||||
// cParent->tree->dumpTree("Adjusting by Leave");
|
||||
if(cNeighbor->isRed()) {
|
||||
Side s = cParent->whichSide(*this);
|
||||
assert(cParent->isBlack());
|
||||
cParent->swapColor(*cNeighbor);
|
||||
cParent->rotate(s);
|
||||
cNeighbor = cParent->link[otherSide(s)];
|
||||
} else if( cParent->isBlack()
|
||||
&& cNeighbor->link[LEFT]->isBlack()
|
||||
&& cNeighbor->link[RIGHT]->isBlack()) {
|
||||
assert(cNeighbor->isBlack());
|
||||
cNeighbor->setRed();
|
||||
return cParent->adjustLeave(cParent->parent);
|
||||
}
|
||||
if( cParent->isRed()
|
||||
&& cNeighbor->link[LEFT]->isBlack()
|
||||
&& cNeighbor->link[RIGHT]->isBlack()) {
|
||||
assert(cNeighbor->isBlack());
|
||||
cParent->swapColor(*cNeighbor);
|
||||
} else {
|
||||
Side ns = cParent->whichSide(*cNeighbor); // Neighbor side
|
||||
Side os = otherSide(ns); // Other side
|
||||
if( cNeighbor->link[os]->isRed()
|
||||
&& cNeighbor->link[ns]->isBlack()) {
|
||||
cNeighbor->swapColor(*cNeighbor->link[os]);
|
||||
cNeighbor->rotate(ns);
|
||||
cNeighbor = cParent->link[ns];
|
||||
}
|
||||
if(cNeighbor->link[ns]->isRed()) {
|
||||
cNeighbor->link[ns]->setBlack();
|
||||
cParent->swapColor(*cNeighbor);
|
||||
cParent->rotate(os);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
int checkBalance() {
|
||||
if(this->isNil())
|
||||
return 1;
|
||||
if( this->isRed()
|
||||
&& (this->link[LEFT]->isRed() || this->link[RIGHT]->isRed()))
|
||||
{
|
||||
debug(DEBUG, "Detected double RED, around key=%lld", this->key);
|
||||
assert(0);
|
||||
}
|
||||
int lCount = this->link[LEFT]->checkBalance();
|
||||
int rCount = this->link[RIGHT]->checkBalance();
|
||||
if(lCount != rCount) {
|
||||
debug(DEBUG, "Detected broken balance, around key=%lld", this->key);
|
||||
assert(0);
|
||||
}
|
||||
return(this->isBlack() ? rCount + 1 : rCount);
|
||||
}
|
||||
void printNode(int depth) {
|
||||
char space[] = " ";
|
||||
char header[0x1000] = "";
|
||||
if(this->link[RIGHT]) {
|
||||
this->link[RIGHT]->printNode(depth + 1);
|
||||
}
|
||||
for(int i = 0; i < depth ; i++) {
|
||||
strncat(header, space, sizeof(header) - 1);
|
||||
}
|
||||
debug(DEBUG, "%s[%s:%lld %p]\n", header,(this->color == RED ? "R" : "B"), this->key, this->obj);
|
||||
if(this->link[LEFT]) {
|
||||
this->link[LEFT]->printNode(depth + 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
private:
|
||||
T * obj;
|
||||
long long key;
|
||||
Color color;
|
||||
TreeRedBlackNode* parent;
|
||||
TreeRedBlackNode* link[2];
|
||||
TreeRedBlack* tree;
|
||||
} * root;
|
||||
static TreeRedBlackNode * nil ;
|
||||
static bool DEBUG;
|
||||
#ifdef DEBUG
|
||||
void dumpTree(std::string title) {
|
||||
debug(DEBUG, "======= %s ==============================================", title.c_str());
|
||||
if(this->root) {
|
||||
this->root->printNode(0);
|
||||
} else {
|
||||
debug(true, " !! No tree");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
public:
|
||||
TreeRedBlack() :
|
||||
root(null) {
|
||||
|
||||
}
|
||||
|
||||
~TreeRedBlack() {
|
||||
delete this->root;
|
||||
}
|
||||
bool insert(long long key, T *p) {
|
||||
TreeRedBlackNode * node = new TreeRedBlackNode(key, p, this);
|
||||
assert(key >= 0);
|
||||
#ifdef DEBUG
|
||||
this->dumpTree("Before insertion");
|
||||
#endif
|
||||
if(this->root) {
|
||||
if(! this->root->insert(*node)) {
|
||||
delete node;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
this->root = node;
|
||||
node->setBlack();
|
||||
}
|
||||
#ifdef DEBUG
|
||||
this->dumpTree("After insertion");
|
||||
this->root->checkBalance();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
T * lookup(long long key) {
|
||||
if(null == this->root) {
|
||||
return null;
|
||||
}
|
||||
TreeRedBlackNode * node = this->root->lookup(key);
|
||||
return(node ? node->getObj() : null);
|
||||
}
|
||||
bool remove(long long key) {
|
||||
if(null == this->root) {
|
||||
return false;
|
||||
}
|
||||
TreeRedBlackNode * node = this->root->lookup(key);
|
||||
if(null == node) {
|
||||
return false;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
this->dumpTree("Before removing");
|
||||
#endif
|
||||
node->leave();
|
||||
delete node;
|
||||
#ifdef DEBUG
|
||||
this->dumpTree("After removing");
|
||||
this->root->checkBalance();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> class TreeRedBlack<T>::TreeRedBlackNode * TreeRedBlack<T>::nil = new TreeRedBlackNode(-1,0,0);
|
||||
template <typename T> bool TreeRedBlack<T>::DEBUG = true;
|
||||
|
@ -1,47 +0,0 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <etk/archive/Archive.hpp>
|
||||
#include <etk/uri/Uri.hpp>
|
||||
|
||||
extern "C" {
|
||||
#include <minizip/unzip.h>
|
||||
}
|
||||
namespace etk {
|
||||
/**
|
||||
* @brief Zip file acces are set in a archive namespace
|
||||
*/
|
||||
namespace archive {
|
||||
/**
|
||||
* @brief Zip acces interface (wrapper)
|
||||
*/
|
||||
class Zip : public etk::Archive {
|
||||
private:
|
||||
unzFile m_ctx; //!< mini zip context
|
||||
unz_global_info m_info; //!< global information of the Zip
|
||||
public:
|
||||
/**
|
||||
* @brief constructor of a zip file access
|
||||
* @param[in] _fileName File to parse (.zip / .apk)
|
||||
* @param[in] _offset Offset in the file where to start the parsing of the "zip"
|
||||
*/
|
||||
Zip(const etk::Path& _fileName, uint64_t _offset = 0LL);
|
||||
/**
|
||||
* @brief constructor of a zip file access
|
||||
* @param[in] _uri URI of the file to parse (.zip / .apk)
|
||||
*/
|
||||
Zip(const etk::Uri& _uri);
|
||||
/**
|
||||
* @brief basic destructor
|
||||
*/
|
||||
virtual ~Zip();
|
||||
protected:
|
||||
void loadFile(const etk::Map<etk::Path, ememory::SharedPtr<ArchiveContent>>::Iterator& _it) override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user