From 257c7354d69f7fc38c7a91490b35106686bc35e2 Mon Sep 17 00:00:00 2001 From: Edouard Dupin Date: Wed, 19 Oct 2011 14:16:31 +0200 Subject: [PATCH] inport tool kit from edn project and compile the widget first implementation --- Makefile | 46 +- Sources/etk/etkDebug.cpp | 71 + Sources/etk/etkDebug.h | 96 ++ Sources/etk/etkDebugInternal.cpp | 25 + Sources/etk/etkDebugInternal.h | 65 + Sources/etk/etkFile.cpp | 244 ++++ Sources/etk/etkFile.h | 67 + Sources/etk/etkMemory.cpp | 51 + Sources/etk/etkMemory.h | 94 ++ Sources/etk/etkRegExp.cpp | 484 +++++++ Sources/etk/etkRegExp.h | 2120 ++++++++++++++++++++++++++++++ Sources/etk/etkString.cpp | 717 ++++++++++ Sources/etk/etkString.h | 93 ++ Sources/etk/etkTypes.h | 69 + Sources/etk/etkVector.h | 509 +++++++ Sources/etk/etkVectorType.h | 672 ++++++++++ Sources/ewolDebug.cpp | 28 + Sources/ewolDebug.h | 66 + Sources/ewolWidget.cpp | 18 +- Sources/ewolWidget.h | 90 +- 20 files changed, 5551 insertions(+), 74 deletions(-) create mode 100644 Sources/etk/etkDebug.cpp create mode 100644 Sources/etk/etkDebug.h create mode 100644 Sources/etk/etkDebugInternal.cpp create mode 100644 Sources/etk/etkDebugInternal.h create mode 100644 Sources/etk/etkFile.cpp create mode 100644 Sources/etk/etkFile.h create mode 100644 Sources/etk/etkMemory.cpp create mode 100644 Sources/etk/etkMemory.h create mode 100644 Sources/etk/etkRegExp.cpp create mode 100644 Sources/etk/etkRegExp.h create mode 100644 Sources/etk/etkString.cpp create mode 100644 Sources/etk/etkString.h create mode 100644 Sources/etk/etkTypes.h create mode 100644 Sources/etk/etkVector.h create mode 100644 Sources/etk/etkVectorType.h create mode 100644 Sources/ewolDebug.cpp create mode 100644 Sources/ewolDebug.h diff --git a/Makefile b/Makefile index 0f4da434..009b6762 100644 --- a/Makefile +++ b/Makefile @@ -53,25 +53,27 @@ DEBUG:=1 ### Compilation Define ### ############################################################################### ifeq ("$(DEBUG)", "0") - DEFINE= -DEDN_DEBUG_LEVEL=1 -DNDEBUG -DVERSION_TAG_NAME="\"$(VERSION_TAG)-release\"" + DEFINE= -DETK_DEBUG_LEVEL=1 -DNDEBUG -DETK_VERSION_TAG_NAME="\"$(VERSION_TAG)-release\"" else - DEFINE= -DEDN_DEBUG_LEVEL=3 -DVERSION_TAG_NAME="\"$(VERSION_TAG)-debug\"" + DEFINE= -DETK_DEBUG_LEVEL=3 -DETK_VERSION_TAG_NAME="\"$(VERSION_TAG)-debug\"" endif DEFINE+= -DVERSION_BUILD_TIME="\"$(VERSION_BUILD_TIME)\"" X11FLAGS= -lX11 -lGL -lGLU -lXrandr ############################################################################### -### Basic Cfags ### +### Basic C flags ### ############################################################################### -# basic GTK librairy +# basic X11 librairy ==> show if we can une under lib ... CXXFLAGS= $(X11FLAGS) -# Linux thread system -#CXXFLAGS+= -lpthread -# Enable debug (cgdb edn) -CXXFLAGS+= -g -O0 -#CXXFLAGS+= -O2 + +ifeq ("$(DEBUG)", "0") + # Enable debug (cgdb ***) + CXXFLAGS+= -g -O0 +else + CXXFLAGS+= -O2 +endif # display all flags CXXFLAGS+= -Wall # ... @@ -81,10 +83,9 @@ CXXFLAGS+= $(DEFINE) CFLAGS= $(CXXFLAGS) -std=c99 -# basic GTK librairy +# basic X11 librairy LDFLAGS= $(X11FLAGS) -# Linux thread system -#LDFLAGS+= -lpthread + # Dynamic connection of the CALLBACK of the GUI LDFLAGS+= -Wl,--export-dynamic @@ -120,15 +121,30 @@ MAKE_DEPENDENCE=Makefile ### Files Listes ### ############################################################################### -# tiny XML (extern OPEN Sources) : -CXXFILES = Main.cpp \ - ewol.cpp +# Ewol Tool Kit : +CXXFILES = etk/etkDebug.cpp \ + etk/etkDebugInternal.cpp \ + etk/etkMemory.cpp \ + etk/etkString.cpp \ + etk/etkFile.cpp \ + etk/etkRegExp.cpp + +# Ewol Sources : +CXXFILES += ewol.cpp \ + ewolDebug.cpp \ + ewolWidget.cpp + + +# Ewol Test Software : +CXXFILES += Main.cpp + ############################################################################### ### Liste of folder where .h can be ### ############################################################################### LISTE_MODULES = $(dir $(CXXFILES)) +$(info listeModule=$(LISTE_MODULES)) INCLUDE_DIRECTORY = $(addprefix -I$(FILE_DIRECTORY)/, $(LISTE_MODULES)) ############################################################################### diff --git a/Sources/etk/etkDebug.cpp b/Sources/etk/etkDebug.cpp new file mode 100644 index 00000000..560f8b34 --- /dev/null +++ b/Sources/etk/etkDebug.cpp @@ -0,0 +1,71 @@ +/** + ******************************************************************************* + * @file etkDebug.h + * @brief Ewol Tool Kit : log implementation + * @author Edouard DUPIN + * @date 08/06/2010 + * @par Project + * Ewol TK + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + +#include +#include + +// Max string size : (wide screan console nb caractere) +#define EDN_LOG_MAX_LENGTH 250 + + +#define FUNCTION_NAME_SIZE (50) + +void TOOLS_DisplayFuncName(int32_t ligne, const char* className, const char* funcName, const char* libName) +{ + char tmpName[FUNCTION_NAME_SIZE] = ""; + + if (NULL == className) { + if (NULL == libName) { + snprintf(tmpName, FUNCTION_NAME_SIZE, "???????? | (l=%5d) %s ",ligne, funcName); + } else { + snprintf(tmpName, FUNCTION_NAME_SIZE, "%s | (l=%5d) %s ",libName, ligne, funcName); + } + } else { + if (NULL == libName) { + snprintf(tmpName, FUNCTION_NAME_SIZE, "???????? | (l=%5d) %s::%s ",ligne, className, funcName); + } else { + snprintf(tmpName, FUNCTION_NAME_SIZE, "%s | (l=%5d) %s::%s ", libName, ligne, className, funcName); + } + + } + tmpName[FUNCTION_NAME_SIZE-4] = ' '; + tmpName[FUNCTION_NAME_SIZE-3] = '|'; + tmpName[FUNCTION_NAME_SIZE-2] = ' '; + tmpName[FUNCTION_NAME_SIZE-1] = '\0'; + std::cout << tmpName; +} + + +void TOOLS_DisplayTime(void) +{ + time_t rawtime; + struct tm * timeinfo; + char tmpdata[50]; + + time ( &rawtime ); + timeinfo = localtime ( &rawtime ); + sprintf(tmpdata, " %2dh %2dmin %2ds | ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); + std::cout << tmpdata ; +} + diff --git a/Sources/etk/etkDebug.h b/Sources/etk/etkDebug.h new file mode 100644 index 00000000..58cb6001 --- /dev/null +++ b/Sources/etk/etkDebug.h @@ -0,0 +1,96 @@ +/** + ******************************************************************************* + * @file etkDebug.h + * @brief Ewol Tool Kit : log implementation + * @author Edouard DUPIN + * @date 08/06/2010 + * @par Project + * Ewol TK + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + +#ifndef __ETK_DEBUG_H__ +#define __ETK_DEBUG_H__ + +#include +#include + +// Log Message System For EDN +void TOOLS_DisplayFuncName(int32_t ligne, const char* className, const char* funcName, const char* libName); +void TOOLS_DisplayTime(void); + +//regular colors +#define ETK_BASH_COLOR_BLACK "\e[0;30m" +#define ETK_BASH_COLOR_RED "\e[0;31m" +#define ETK_BASH_COLOR_GREEN "\e[0;32m" +#define ETK_BASH_COLOR_YELLOW "\e[0;33m" +#define ETK_BASH_COLOR_BLUE "\e[0;34m" +#define ETK_BASH_COLOR_MAGENTA "\e[0;35m" +#define ETK_BASH_COLOR_CYAN "\e[0;36m" +#define ETK_BASH_COLOR_WHITE "\e[0;37m" +//emphasized (bolded) colors +#define ETK_BASH_COLOR_BOLD_BLACK "\e[1;30m" +#define ETK_BASH_COLOR_BOLD_RED "\e[1;31m" +#define ETK_BASH_COLOR_BOLD_GREEN "\e[1;32m" +#define ETK_BASH_COLOR_BOLD_YELLOW "\e[1;33m" +#define ETK_BASH_COLOR_BOLD_BLUE "\e[1;34m" +#define ETK_BASH_COLOR_BOLD_MAGENTA "\e[1;35m" +#define ETK_BASH_COLOR_BOLD_CYAN "\e[1;36m" +#define ETK_BASH_COLOR_BOLD_WHITE "\e[1;37m" +//background colors +#define ETK_BASH_COLOR_BG_BLACK "\e[40m" +#define ETK_BASH_COLOR_BG_RED "\e[41m" +#define ETK_BASH_COLOR_BG_GREEN "\e[42m" +#define ETK_BASH_COLOR_BG_YELLOW "\e[43m" +#define ETK_BASH_COLOR_BG_BLUE "\e[44m" +#define ETK_BASH_COLOR_BG_MAGENTA "\e[45m" +#define ETK_BASH_COLOR_BG_CYAN "\e[46m" +#define ETK_BASH_COLOR_BG_WHITE "\e[47m" +// Return to the normal color setings +#define ETK_BASH_COLOR_NORMAL "\e[0m" +//go to the Top of bash +#define ETK_BASH_GO_TOP "\e[0;0f" + +#undef __class__ +#define __class__ (NULL) + +#define ETK_DBG_COMMON(libName, color, info, data) do { \ + std::cout << color; \ + TOOLS_DisplayTime(); \ + TOOLS_DisplayFuncName(__LINE__, __class__, __func__, libName); \ + std::cout << "[" << info << "] " << data; \ + std::cout << ETK_BASH_COLOR_NORMAL < 0 +# define TK_WARNING(data) ETK_WARNING(etkLibName, data) +# define TK_ERROR(data) ETK_ERROR(etkLibName, data) +#else +# define TK_WARNING(data) do {}while(0) +# define TK_ERROR(data) do {}while(0) +#endif + +#if ETK_DEBUG_LEVEL > 1 +# define TK_INFO(data) ETK_INFO(etkLibName, data) +#else +# define TK_INFO(data) do {}while(0) +#endif + +#if ETK_DEBUG_LEVEL > 2 +# define TK_DEBUG(data) ETK_DEBUG(etkLibName, data) +#else +# define TK_DEBUG(data) do {}while(0) +#endif + +#define TK_ASSERT(cond, data) ETK_ASSERT(etkLibName, cond, data) + +#if ETK_DEBUG_LEVEL > 1 +# define TK_CHECK_INOUT(cond) ETK_CHECK_INOUT_ASSERT(etkLibName, cond) +#elif ETK_DEBUG_LEVEL > 0 +# define TK_CHECK_INOUT(cond) ETK_CHECK_INOUT_WARNING(etkLibName, cond) +#else +# define TK_CHECK_INOUT(cond) do { } while (0) +#endif + +#endif + diff --git a/Sources/etk/etkFile.cpp b/Sources/etk/etkFile.cpp new file mode 100644 index 00000000..dbd73225 --- /dev/null +++ b/Sources/etk/etkFile.cpp @@ -0,0 +1,244 @@ +/** + ******************************************************************************* + * @file etkFile.cpp + * @brief Ewol Tool Kit : File folder and name abstraction (Sources) + * @author Edouard DUPIN + * @date 16/07/2011 + * @par Project + * Ewol TK + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + + +#include +#include + + +#undef __class__ +#define __class__ "etk::File" + + +std::ostream& etk::operator <<(std::ostream &os, const etk::File &obj) +{ + os << obj.m_folder; + os << "/"; + os << obj.m_shortFilename; + return os; +} + +etk::File::File(etk::String &filename, int32_t LineNumber) +{ + m_lineNumberOpen = LineNumber; + SetCompleateName(filename); +} + + +etk::File::File(const char *filename, int32_t LineNumber) +{ + etk::String tmpString = filename; + m_lineNumberOpen = LineNumber; + SetCompleateName(tmpString); +} + + +etk::File::File(etk::String &filename, etk::String &folder, int32_t lineNumber) +{ + etk::String tmpString = folder; + tmpString += '/'; + tmpString += filename; + SetCompleateName(tmpString); + m_lineNumberOpen = lineNumber; +} + +etk::File::~File(void) +{ + // nothing to do ... +} + + +etk::String etk::File::GetFolder(void) const +{ + return m_folder; +} + +etk::String etk::File::GetShortFilename(void) const +{ + return m_shortFilename; +} + +etk::String etk::File::GetCompleateName(void) const +{ + etk::String out; + out = m_folder; + out += '/'; + out += m_shortFilename; + return out; +} + +const etk::File& etk::File::operator= (const etk::File &etkF ) +{ + if( this != &etkF ) // avoid copy to itself + { + m_folder = etkF.m_folder; + m_shortFilename = etkF.m_shortFilename; + m_lineNumberOpen = etkF.m_lineNumberOpen; + } + return *this; +} + + +/** + * @brief + * + * @param[in,out] + * + * @return + * + */ +bool etk::File::operator== (const etk::File &etkF) const +{ + if( this != &etkF ) { + if (etkF.GetCompleateName() == GetCompleateName() ) { + return true; + } else { + return false; + } + return true; + } + return true; +} + +/** + * @brief + * + * @param[in,out] + * + * @return + * + */ +bool etk::File::operator!= (const etk::File &etkF) const +{ + return !(*this == etkF); +} + + +void etk::File::SetCompleateName(etk::String &newFilename) +{ + char buf[MAX_FILE_NAME]; + memset(buf, 0, MAX_FILE_NAME); + char * ok; + // Reset ALL DATA : + m_folder = ""; + m_shortFilename = ""; + m_lineNumberOpen = 0; + TK_DEBUG("1 :Set Name : " << newFilename ); + etk::String destFilename; + if (newFilename.Size() == 0) { + destFilename = "no-name"; + } else { + destFilename = newFilename; + } + TK_DEBUG("2 : Get file Name : " << destFilename ); + if ('/' != *destFilename.c_str()) { + // Get the command came from the running of the program : + char cCurrentPath[FILENAME_MAX]; + if (!getcwd(cCurrentPath, FILENAME_MAX)) { + return; + } + cCurrentPath[FILENAME_MAX - 1] = '\0'; + etk::String tmpFilename = destFilename; + destFilename = cCurrentPath; + destFilename += '/'; + destFilename += tmpFilename; + } + TK_DEBUG("3 : Get file Name : " << destFilename ); + + // Get the real Path of the current File + ok = realpath(destFilename.c_str(), buf); + if (!ok) { + int32_t lastPos = destFilename.FindBack('/'); + if (-1 != lastPos) { + // Get the FileName + etk::String tmpFilename = destFilename.Extract(lastPos+1); + destFilename.Remove(lastPos, destFilename.Size() - lastPos); + TK_DEBUG("try to find :\"" << destFilename << "\" / \"" << tmpFilename << "\" "); + ok = realpath(destFilename.c_str(), buf); + if (!ok) { + TK_ERROR("Can not find real Path name of \"" << destFilename << "\""); + m_shortFilename = tmpFilename; + m_folder = destFilename; + } else { + // ALL is OK ... + m_shortFilename = tmpFilename; + m_folder = destFilename; + } + } else { + TK_WARNING("file : \"" << destFilename << "\" ==> No data???"); + // Basic ERROR ... + m_shortFilename = destFilename; + } + } else { + destFilename = buf; + int32_t lastPos = destFilename.FindBack('/'); + if (-1 != lastPos) { + m_shortFilename = destFilename.Extract(lastPos+1); + m_folder = destFilename.Extract(0, lastPos); + } else { + // Basic ERROR ... + TK_WARNING("file : \"" << destFilename << "\" ==> No data???"); + m_shortFilename = destFilename; + } + } + TK_DEBUG("Set FileName :\"" << m_folder << "\" / \"" << m_shortFilename << "\" "); +} + +int32_t etk::File::GetLineNumber(void) +{ + return m_lineNumberOpen; +} + +void etk::File::SetLineNumber(int32_t newline) +{ + m_lineNumberOpen = newline; +} + +bool etk::File::HasExtention(void) +{ + int32_t lastPos = m_shortFilename.FindBack('.'); + if( -1 != lastPos // not find the . + && 0 != lastPos // Find a . at the fist position .jdlskjdfklj ==> hiden file + && m_shortFilename.Size() != lastPos ) // Remove file ended with . + { + return true; + } else { + return false; + } +} + + +etk::String etk::File::GetExtention(void) +{ + etk::String tmpExt = ""; + int32_t lastPos = m_shortFilename.FindBack('.'); + if( -1 != lastPos // not find the . + && 0 != lastPos // Find a . at the fist position .jdlskjdfklj ==> hiden file + && m_shortFilename.Size() != lastPos ) // Remove file ended with . + { + // Get the FileName + tmpExt = m_shortFilename.Extract(lastPos+1); + } + return tmpExt; +} diff --git a/Sources/etk/etkFile.h b/Sources/etk/etkFile.h new file mode 100644 index 00000000..82a95b24 --- /dev/null +++ b/Sources/etk/etkFile.h @@ -0,0 +1,67 @@ +/** + ******************************************************************************* + * @file etkFile.h + * @brief Ewol Tool Kit : File folder and name abstraction (header) + * @author Edouard DUPIN + * @date 16/07/2011 + * @par Project + * Ewol TK + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + +#ifndef __ETK_FILE_H__ +#define __ETK_FILE_H__ + +#include + +#define MAX_FILE_NAME (10240) + +namespace etk +{ + class File + { + public: + File(void) { m_lineNumberOpen=0; } + File(etk::String &filename, int32_t LineNumber = 0); + File(const char *filename, int32_t LineNumber = 0); + File(etk::String &filename, etk::String &folder, int32_t lineNumber = 0); + ~File(void); + etk::String GetFolder(void) const; + etk::String GetShortFilename(void) const; + etk::String GetCompleateName(void) const; + bool HasExtention(void); + etk::String GetExtention(void); + int32_t GetLineNumber(void); + void SetLineNumber(int32_t newline); + void SetCompleateName(etk::String &newFilename); + + const etk::File& operator= (const etk::File &etkF ); + bool operator== (const etk::File &etkF ) const; + bool operator!= (const etk::File &etkF ) const; + friend std::ostream& operator <<( std::ostream &os,const etk::File &obj); + + private : + etk::String m_folder; + etk::String m_shortFilename; + int32_t m_lineNumberOpen; + }; + + std::ostream& operator <<(std::ostream &os, const etk::File &obj); + +} + +#endif + diff --git a/Sources/etk/etkMemory.cpp b/Sources/etk/etkMemory.cpp new file mode 100644 index 00000000..cb28f8a7 --- /dev/null +++ b/Sources/etk/etkMemory.cpp @@ -0,0 +1,51 @@ +/** + ******************************************************************************* + * @file etkMemory.cpp + * @brief Ewol Tool Kit : Memory implementation (Sources) + * @author Edouard DUPIN + * @date 19/10/2011 + * @par Project + * Ewol TK + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + +#include +#include + +// General +#if ETK_MEMORY_CHECKER > 0 + +void etk::MemFree( void * pointerData, const char * variableName, const char * functionName, int32_t line, const char * fileName ) +{ + TK_CRITICAL(" MEM FREE is not written ==> TODO..."); + if (NULL != pointerData) { + free(pointerData); + } +} + +void * etk::MemMalloc( size_t num, size_t size, uint8_t init, const char * variableName, const char * functionName, int32_t line, const char * fileName ) +{ + TK_CRITICAL(" MEM ALLOCATOR is not written ==> TODO..."); + return calloc(num, size); +} + +void etk::MemShowLogs( void ) +{ + TK_CRITICAL(" MEM DISPLAY is not written ==> TODO..."); +} + +#endif + diff --git a/Sources/etk/etkMemory.h b/Sources/etk/etkMemory.h new file mode 100644 index 00000000..b1fa43ef --- /dev/null +++ b/Sources/etk/etkMemory.h @@ -0,0 +1,94 @@ +/** + ******************************************************************************* + * @file etkMemory.h + * @brief Ewol Tool Kit : Memory implementation (headers) + * @author Edouard DUPIN + * @date 12/01/2011 + * @par Project + * Ewol TK + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + +#ifndef __TOOLS_MEMORY_H__ +#define __TOOLS_MEMORY_H__ + + + +// General +#if ETK_MEMORY_CHECKER > 0 +namespace etk { + void MemFree( void * pointerData, const char * variableName, const char * functionName, int32_t line, const char * fileName ); + void * MemMalloc( size_t num, size_t size, uint8_t init, const char * variableName, const char * functionName, int32_t line, const char * fileName ); + void MemShowLogs( void ); +}; +# define ETK_MALLOC(pointerData, nbElements, dataType) do { \ + pointerData = (dataType *)etk::MemMalloc( (nbElements), sizeof(dataType), 0, #pointerData, __func__, __LINE__, __FILE__); \ + }while(0) +# define ETK_MALLOC_CAST(pointerData, nbElements, dataType, cast) do { \ + pointerData = (cast)etk::MemMalloc( (nbElements), sizeof(dataType), 0, #pointerData, __func__, __LINE__, __FILE__); \ + }while(0) +# define ETK_CALLOC(pointerData, nbElements, dataType) do { \ + pointerData = (dataType *)etk::MemMalloc( (nbElements), sizeof(dataType), 1, #pointerData, __func__, __LINE__, __FILE__); \ + }while(0) +# define ETK_CALLOC_CAST(pointerData, nbElements, dataType, cast) do { \ + pointerData = (cast)etk::MemMalloc( (nbElements), sizeof(dataType), 1, #pointerData, __func__, __LINE__, __FILE__); \ + }while(0) +# define ETK_FREE(pointerData) do { \ + etk::MemFree( (pointerData) , #pointerData, __func__, __LINE__, __FILE__); \ + (pointerData) = NULL; \ + }while(0) +# define ETK_MEM_SHOW_LOG() do { \ + etk::MemShowLogs(); \ + }while(0) +#else + +# define ETK_MALLOC(pointerData, nbElements, dataType) do { \ + (pointerData) = (dataType *)malloc( (nbElements) * sizeof(dataType) ); \ + }while(0) + +# define ETK_MALLOC_CAST(pointerData, nbElements, dataType, cast) do { \ + (pointerData) = (cast)malloc( (nbElements) * sizeof(dataType) ); \ + }while(0) + +# define ETK_CALLOC(pointerData, nbElements, dataType) do { \ + (pointerData) = (dataType *)calloc( (nbElements), sizeof(dataType) ); \ + }while(0) + +# define ETK_CALLOC_CAST(pointerData, nbElements, dataType, cast) do { \ + (pointerData) = (cast)calloc( (nbElements), sizeof(dataType) ); \ + }while(0) + +# define ETK_REALLOC(pointerData, nbElements, dataType) do { \ + (pointerData) = (dataType *)realloc( (pointerData), (nbElements)* sizeof(dataType) ); \ + }while(0) + +# define ETK_REALLOC_CAST(pointerData, nbElements, dataType, cast) do { \ + (pointerData) = (cast)realloc( (pointerData), (nbElements) * sizeof(dataType) ); \ + }while(0) + +# define ETK_FREE(pointerData) do { \ + free( pointerData ); \ + (pointerData) = NULL; \ + }while(0) + +# define ETK_MEM_SHOW_LOG() do { \ + TK_DEBUG("No Memory check availlable"); \ + }while(0) +#endif + + +#endif + diff --git a/Sources/etk/etkRegExp.cpp b/Sources/etk/etkRegExp.cpp new file mode 100644 index 00000000..26d7dfa0 --- /dev/null +++ b/Sources/etk/etkRegExp.cpp @@ -0,0 +1,484 @@ +/** + ******************************************************************************* + * @file etkExp.cpp + * @brief Ewol Tool Kit : Regular expression annalyser (sources) + * @author Edouard DUPIN + * @date 04/04/2011 + * @par Project + * Ewol TK + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + +#include + + + +const etk::convertionTable_ts etk::constConvertionTable[] = { + // haveBackSlash, inputValue, newValue + { false , '(' , REGEXP_OPCODE_PTHESE_IN}, + { true , '(' , (int16_t)'('}, + { false , ')' , REGEXP_OPCODE_PTHESE_OUT}, + { true , ')' , (int16_t)')'}, + { false , '[' , REGEXP_OPCODE_BRACKET_IN}, + { true , '[' , (int16_t)'['}, + { false , ']' , REGEXP_OPCODE_BRACKET_OUT}, + { true , ']' , (int16_t)']'}, + { false , '{' , REGEXP_OPCODE_BRACE_IN}, + { true , '{' , (int16_t)'{'}, + { false , '}' , REGEXP_OPCODE_BRACE_OUT}, + { true , '}' , (int16_t)'}'}, + { false , '-' , REGEXP_OPCODE_TO}, + { true , '-' , (int16_t)'-'}, + { false , '*' , REGEXP_OPCODE_STAR}, + { true , '*' , (int16_t)'*'}, + { false , '.' , REGEXP_OPCODE_DOT}, + { true , '.' , (int16_t)'.'}, + { false , '?' , REGEXP_OPCODE_QUESTION}, + { true , '?' , (int16_t)'?'}, + { false , '+' , REGEXP_OPCODE_PLUS}, + { true , '+' , (int16_t)'+'}, + { false , '|' , REGEXP_OPCODE_PIPE}, + { true , '|' , (int16_t)'|'}, + { false , '^' , REGEXP_OPCODE_START_OF_LINE}, + { true , '^' , (int16_t)'^'}, + { false , '$' , REGEXP_OPCODE_END_OF_LINE}, + { true , '$' , (int16_t)'$'}, + { true , 'd' , REGEXP_OPCODE_DIGIT}, + { true , 'D' , REGEXP_OPCODE_DIGIT_NOT}, + { true , 'l' , REGEXP_OPCODE_LETTER}, + { true , 'L' , REGEXP_OPCODE_LETTER_NOT}, + { true , 's' , REGEXP_OPCODE_SPACE}, + { true , 'S' , REGEXP_OPCODE_SPACE_NOT}, + { true , 'w' , REGEXP_OPCODE_WORD}, + { true , 'W' , REGEXP_OPCODE_WORD_NOT}, + { true , 'a' , (int16_t)'\a'}, + { true , 'b' , (int16_t)'\b'}, + { true , 'e' , 0x001B}, // Escape character + { true , 'f' , (int16_t)'\f'}, + { true , 'n' , (int16_t)'\n'}, + { true , 'r' , (int16_t)'\r'}, + { true , 't' , (int16_t)'\t'}, + { true , 'v' , (int16_t)'\v'}, + { true , '\\' , (int16_t)'\\'}, + { true , '&' , (int16_t)'&'}, + { true , '0' , (int16_t)'\0'}, + { true , '@' , REGEXP_OPCODE_NO_CHAR}, +}; +const int32_t etk::constConvertionTableSize = sizeof(etk::constConvertionTable) / sizeof(etk::convertionTable_ts) ; + + +/** + * @brief Display the internal data of a node + * + * @param[in] data element do display in the console + * + * @return --- + * + */ +void etk::DisplayData(etk::VectorType &data) +{ + int32_t i; + for (i=0; i<(int32_t)data.Size() ; i++) { + std::cout<< (char)(data[i]&0x00FF ); + } +} + +/** + * @brief Display of a part of the Regexp element + * + * @param[in] data Vector where data is constain + * @param[in] start Position where the display might start + * @param[in] stop Position where the display might stop + * + * @return --- + * + */ +void etk::DisplayElem(etk::VectorType &data, int32_t start, int32_t stop) +{ + int32_t i; + std::cout<< ETK_BASH_COLOR_NORMAL; + for (i=start; i<(int32_t)data.Size() && i &data, int32_t startPos) +{ + int32_t pos = startPos; + int32_t nbOpen = 0; + // special case of the (...) or | ==> we search '|' or ')' + if( REGEXP_OPCODE_PTHESE_OUT == data[pos] + || REGEXP_OPCODE_PIPE == data[pos]) { + return 0; + } + // find size ... + while (pos < (int32_t)data.Size() ) { + if(REGEXP_OPCODE_PTHESE_IN == data[pos]) { + // find a sub section : + nbOpen++; + } else if(0 < nbOpen) { + if (REGEXP_OPCODE_PTHESE_OUT == data[pos]) + { + nbOpen--; + if (0 > nbOpen) { + TK_ERROR("Error in the (...) find element at "<< pos); + return -1; + } + } + } else if( REGEXP_OPCODE_PTHESE_OUT == data[pos] + || REGEXP_OPCODE_PIPE == data[pos]) + { + // Find the end of the (...) + // just return the size inside + int32_t sizeInside = pos - startPos; + if (0 >= sizeInside) { + TK_ERROR("Error in the (...) no data at "<< pos-1); + return -1; + } else { + return sizeInside; + } + } + pos++; + } + return pos - startPos; +} + +/** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ +int32_t etk::GetLenOfPThese(etk::VectorType &data, int32_t startPos) +{ + int32_t pos = startPos; + int32_t nbOpen = 0; + // special case of the (...) or | ==> we search '|' or ')' + if( REGEXP_OPCODE_PTHESE_OUT == data[pos]) { + return 0; + } else if( REGEXP_OPCODE_PTHESE_IN == data[pos]) + { + pos++; + // find size ... + while (pos < (int32_t)data.Size() ) { + if(REGEXP_OPCODE_PTHESE_IN == data[pos]) { + // find a sub section : + nbOpen++; + } else if(0 < nbOpen) { + if (REGEXP_OPCODE_PTHESE_OUT == data[pos]) + { + nbOpen--; + if (0 > nbOpen) { + TK_ERROR("Error in the (...) find element at "<< pos); + return -1; + } + } + } else if( REGEXP_OPCODE_PTHESE_OUT == data[pos]) + { + // Find the end of the (...) + // just return the size inside + int32_t sizeInside = pos - startPos-1; + if (0 >= sizeInside) { + TK_ERROR("Error in the (...) no data at "<< pos-1); + return -1; + } else { + return sizeInside; + } + } + pos++; + } + } else { + return -1; + } + return 0; +} + + +/** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ +int32_t etk::GetLenOfBracket(etk::VectorType &data, int32_t startPos) +{ + int32_t pos = startPos; + // special case of the (...) or | ==> we search '|' or ')' + if( REGEXP_OPCODE_BRACKET_OUT == data[pos]) { + return 0; + } else if( REGEXP_OPCODE_BRACKET_IN == data[pos]) { + pos++; + // find size ... + while (pos < (int32_t)data.Size() ) { + if(REGEXP_OPCODE_BRACKET_OUT == data[pos]) { + // Find the end of the [...] + // just return the size inside + int32_t sizeInside = pos - startPos -1 ; + if (0 >= sizeInside) { + TK_ERROR("Error in the [...] no data at "<< pos-1); + return sizeInside; + } else { + return sizeInside; + } + } else if( REGEXP_OPCODE_TO != data[pos] + && ( 0 > data[pos] + || 0xFF < data[pos]) ) + { + TK_ERROR("Error in the [...] not permited element at "<< pos << " '" << (char)data[pos] << "'"); + return false; + } + pos++; + } + } else { + return -1; + } + return 0; +} + + +/** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ +int32_t etk::GetLenOfBrace(etk::VectorType &data, int32_t startPos) +{ + int32_t pos = startPos; + // special case of the (...) or | ==> we search '|' or ')' + if( REGEXP_OPCODE_BRACE_OUT == data[pos]) { + return 0; + } else if( REGEXP_OPCODE_BRACE_IN == data[pos]) { + pos++; + // find size ... + while (pos < (int32_t)data.Size() ) { + if(REGEXP_OPCODE_BRACE_OUT == data[pos]) { + // Find the end of the [...] + // just return the size inside + int32_t sizeInside = pos - startPos -1 ; + if (0 >= sizeInside) { + TK_ERROR("Error in the {...} no data at "<< pos-1); + return sizeInside; + } else { + return sizeInside; + } + } else if( ',' != data[pos] + && ( '0' > data[pos] + || '9' < data[pos]) ) + { + TK_ERROR("Error in the {...} not permited element at "<< pos << " '" << (char)data[pos] << "'"); + return false; + } + pos++; + } + } else { + return -1; + } + return 0; +} + + +/** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ +int32_t etk::GetLenOfNormal(etk::VectorType &data, int32_t startPos) +{ + int32_t pos = startPos; + + // find size ... + while (pos < (int32_t)data.Size() ) { + switch(data[pos]) + { + case REGEXP_OPCODE_PTHESE_IN: + case REGEXP_OPCODE_PTHESE_OUT: + case REGEXP_OPCODE_BRACKET_IN: + case REGEXP_OPCODE_BRACKET_OUT: + case REGEXP_OPCODE_BRACE_IN: + case REGEXP_OPCODE_BRACE_OUT: + case REGEXP_OPCODE_TO: + case REGEXP_OPCODE_STAR: + case REGEXP_OPCODE_DOT: + case REGEXP_OPCODE_QUESTION: + case REGEXP_OPCODE_PLUS: + case REGEXP_OPCODE_PIPE: + case REGEXP_OPCODE_START_OF_LINE: + case REGEXP_OPCODE_END_OF_LINE: + case REGEXP_OPCODE_DIGIT: + case REGEXP_OPCODE_DIGIT_NOT: + case REGEXP_OPCODE_LETTER: + case REGEXP_OPCODE_LETTER_NOT: + case REGEXP_OPCODE_SPACE: + case REGEXP_OPCODE_SPACE_NOT: + case REGEXP_OPCODE_WORD: + case REGEXP_OPCODE_WORD_NOT: + { + // just return the size inside + int32_t sizeInside = pos - startPos; + if (0 >= sizeInside) { + TK_ERROR("Error in the normal data : no data ..."); + } + return sizeInside; + } + break; + default : + // nothing to do ... + break; + } + pos++; + } + return pos - startPos ; +} + + +/** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ +bool etk::ParseBrace(etk::VectorType &data, int32_t &min, int32_t &max) +{ + //TK_INFO("parse {...} in "; DisplayElem(data); ); + int32_t k=0; + + int32_t firstElement = 0; + int32_t SecondElement = 0; + + while(k= (char)data[k]) { + firstElement *=10; + firstElement += (char)data[k] - '0'; + } else { + TK_ERROR("Can not parse this element " << (char)data[k] << " at pos " << k); + return false; + } + k++; + } + if (k==data.Size()) { + SecondElement = firstElement; + } + while(k= (char)data[k]) { + SecondElement *=10; + SecondElement += (char)data[k] - '0'; + } else { + TK_ERROR("Can not parse this element " << (char)data[k] << " at pos " << k); + return false; + } + k++; + } + +allIsSet: + if (SecondElement == 0 && firstElement != 0) { + min = 0; + max = firstElement; + } else { + min = firstElement; + max = SecondElement; + } + if (min > max) { + TK_ERROR("Minimum=" << min << " can not be < maximum=" << max ); + return false; + } + return true; +} + + diff --git a/Sources/etk/etkRegExp.h b/Sources/etk/etkRegExp.h new file mode 100644 index 00000000..68e32133 --- /dev/null +++ b/Sources/etk/etkRegExp.h @@ -0,0 +1,2120 @@ +/** + ******************************************************************************* + * @file etkExp.h + * @brief Ewol Tool Kit : Regular expression annalyser (header) + * @author Edouard DUPIN + * @date 04/04/2011 + * @par Project + * Ewol TK + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + +#ifndef __TK_REG_EXP_H__ +#define __TK_REG_EXP_H__ + +#include +#include +#include +#include +#include + +namespace etk { + +/* +normal mode : + (...) sub element is separate with | + \d Digits [0-9] + \D NOT a digit [^0-9] + \l Letters [a-zA-Z] + \L NOT a Letter [^a-zA-Z] + \s Whitespace [ \t\n\r\f\v] + \S NOT Whitespace [^ \t\n\r\f\v] + \w "Word" character [a-zA-Z0-9_] + \W NOT a "Word" character [^a-zA-Z0-9_] + \@ at the start or the end not in the parsing of element ==> check if \w is not present (other regExp will be <> ...) + [anjdi] or [a-gt-j] range + . dot [^\x00-\x08\x0A-\x1F\x7F] +==> TODO : + $ End / Start of line of line ==> ce sera un truc suplémentaire comme le \@ + ^in the [] invertion of the range element + +multiplicity : + * ==> {0, 2147483647} + ? ==> {0, 1} + + ==> {1, 2147483647} + {x} ==> {x, x} + {x,y} ==> {x, y} +*/ + + +// internal define to permit to have all neeed system +#define REGEXP_OPCODE_PTHESE_IN (-300) /* ( */ +#define REGEXP_OPCODE_PTHESE_OUT ( 300) /* ) */ +#define REGEXP_OPCODE_BRACKET_IN (-301) /* [ */ +#define REGEXP_OPCODE_BRACKET_OUT ( 301) /* ] */ +#define REGEXP_OPCODE_BRACE_IN (-302) /* { */ +#define REGEXP_OPCODE_BRACE_OUT ( 302) /* } */ +#define REGEXP_OPCODE_TO (-305) /* - */ +#define REGEXP_OPCODE_STAR (-306) /* * */ +#define REGEXP_OPCODE_DOT (-307) /* . */ +#define REGEXP_OPCODE_QUESTION (-308) /* ? */ +#define REGEXP_OPCODE_PLUS (-309) /* + */ +#define REGEXP_OPCODE_PIPE (-310) /* | */ +#define REGEXP_OPCODE_START_OF_LINE (-311) /* ^ this is also NOT, but not manage */ +#define REGEXP_OPCODE_END_OF_LINE (-312) /* $ */ +#define REGEXP_OPCODE_DIGIT ( 313) /* \d */ +#define REGEXP_OPCODE_DIGIT_NOT (-313) /* \D */ +#define REGEXP_OPCODE_LETTER ( 314) /* \l */ +#define REGEXP_OPCODE_LETTER_NOT (-314) /* \L */ +#define REGEXP_OPCODE_SPACE ( 315) /* \s */ +#define REGEXP_OPCODE_SPACE_NOT (-315) /* \S */ +#define REGEXP_OPCODE_WORD ( 316) /* \w */ +#define REGEXP_OPCODE_WORD_NOT (-316) /* \W */ +#define REGEXP_OPCODE_NO_CHAR (-317) /* \@ */ + +typedef struct { + bool haveBackSlash; + char inputValue; + int16_t newValue; +}convertionTable_ts; + +extern const convertionTable_ts constConvertionTable[]; +extern const int32_t constConvertionTableSize; + +void DisplayData(etk::VectorType &data); +void DisplayElem(etk::VectorType &data, int32_t start=0, int32_t stop=0x7FFFFFFF); +char * levelSpace(int32_t level); +int32_t GetLenOfPTheseElem(etk::VectorType &data, int32_t startPos); +int32_t GetLenOfPThese(etk::VectorType &data, int32_t startPos); +int32_t GetLenOfBracket(etk::VectorType &data, int32_t startPos); +int32_t GetLenOfBrace(etk::VectorType &data, int32_t startPos); +int32_t GetLenOfNormal(etk::VectorType &data, int32_t startPos); +bool ParseBrace(etk::VectorType &data, int32_t &min, int32_t &max); + + +#undef __class__ +#define __class__ "etk::RegExpNode" + +/** + * @brief Node Elements for every-one + */ +template class RegExpNode{ + public : + + /** + * @brief + * @param[in,out] + * @return + */ + RegExpNode(void) + { + SetMult(1,1); + }; + + /** + * @brief + * @param[in,out] + * @return + */ + virtual ~RegExpNode(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + virtual int32_t Generate(etk::VectorType &data, int32_t startPos, int32_t nbElement) + { + return 0; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + virtual bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + virtual void Display(int32_t level) + { + TK_INFO("Find NODE : " << levelSpace(level) << "@???@ {" << GetMultMin() << "," << GetMultMax() << "} subdata="; DisplayElem(m_RegExpData);); + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void SetMult(int32_t min, int32_t max) + { + m_multipleMin = etk_max(min, 0); + m_multipleMax = etk_max(max, 1); + } + protected: + /** + * @brief + * @param[in,out] + * @return + */ + int32_t GetMultMin(void) + { + return m_multipleMin; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + int32_t GetMultMax(void) + { + return m_multipleMax; + }; + protected : + int32_t m_multipleMin; //!< minimum repetition (included) + int32_t m_multipleMax; //!< maximum repetition (included) + // Data Section ... (can have no data...) + etk::VectorType m_RegExpData; //!< data to parse and compare in some case ... +}; + +#undef __class__ +#define __class__ "etk::RegExpNodeValue" + +template class RegExpNodeValue : public RegExpNode { + public : + + /** + * @brief + * @param[in,out] + * @return + */ + RegExpNodeValue(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + ~RegExpNodeValue(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + int32_t Generate(etk::VectorType &data) + { + RegExpNode::m_RegExpData = data; + //TK_DEBUG("Request Parse \"Value\" data="; DisplayElem(RegExpNode::m_RegExpData);); + m_data.Clear(); + for (int32_t i=0; i::m_RegExpData.Size(); i++) { + m_data.PushBack((char)RegExpNode::m_RegExpData[i]); + } + return data.Size(); + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + //TK_INFO("Parse node : Value{" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "}"); + if (0==m_data.Size()) { + TK_ERROR("No data inside type elemTypeValue"); + return false; + } + //TK_DEBUG("check element value : '" << m_data[0] << "'"); + bool tmpFind = true; + int32_t j; + for (j=0; j::m_multipleMax && tmpFind == true; j++) { + int32_t ofset = 0; + int32_t k; + for (k=0; findLen+k=RegExpNode::m_multipleMin + && j<=RegExpNode::m_multipleMax + && findLen>0 ) + { + //TK_DEBUG("find " << findLen); + return true; + } else if( 0 == RegExpNode::m_multipleMin ) { + //TK_DEBUG("find size=0"); + return true; + } + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(int32_t level) + { + TK_INFO("Find NODE : " << levelSpace(level) << "@Value@ {" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} subdata="; DisplayElem(RegExpNode::m_RegExpData); std::cout<< " data: "; DisplayData(m_data); ); + }; + protected : + // SubNodes : + etk::VectorType m_data; +}; +#undef __class__ +#define __class__ "etk::RegExpNodeBracket" + +template class RegExpNodeBracket : public RegExpNode { + public : + + /** + * @brief + * @param[in,out] + * @return + */ + RegExpNodeBracket(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + ~RegExpNodeBracket(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + int32_t Generate(etk::VectorType &data) + { + RegExpNode::m_RegExpData = data; + //TK_DEBUG("Request Parse [...] data="; DisplayElem(RegExpNode::m_RegExpData);); + m_data.Clear(); + + char lastElement = 'a'; + bool multipleElement = false; + // + for (int32_t k=0; k::m_RegExpData.Size(); k++) { + if (RegExpNode::m_RegExpData[k] == REGEXP_OPCODE_TO && multipleElement == true) { + TK_ERROR("Can not have 2 consecutive - in [...]"); + return 0; + } else if (multipleElement == true) { + char j='\0'; + for (j=lastElement+1; j <= (char)RegExpNode::m_RegExpData[k]; j++) { + m_data.PushBack(j); + } + multipleElement = false; + } else if(RegExpNode::m_RegExpData[k] == REGEXP_OPCODE_TO) { + multipleElement = true; + } else { + lastElement = (char)RegExpNode::m_RegExpData[k]; + m_data.PushBack(lastElement); + } + } + // check size ... + if (m_data.Size() == 0) { + TK_ERROR("No data inside [...] "); + return 0; + } + return data.Size(); + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + //TK_INFO("Parse node : [...]{" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "}"); + if (0==m_data.Size()) { + TK_ERROR("No data inside type elemTypeValue"); + return false; + } + //TK_DEBUG("one of element value List : "; DisplayData(element->m_data);); + bool tmpFind = true; + int32_t j; + for (j=0; j::m_multipleMax && tmpFind ==true && j < lenMax; j++) { + int32_t i; + tmpFind=false; + for (i=0; i=RegExpNode::m_multipleMin + && j<=RegExpNode::m_multipleMax + && findLen>0 ) + { + //TK_DEBUG("find " << findLen); + return true; + } else if( 0 == RegExpNode::m_multipleMin ) { + //TK_DEBUG("find size=0"); + return true; + } + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(int32_t level) + { + TK_INFO("Find NODE : " << levelSpace(level) << "@[...]@ {" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} subdata="; DisplayElem(RegExpNode::m_RegExpData); std::cout<< " data: "; DisplayData(m_data); ); + }; + protected : + // SubNodes : + etk::VectorType m_data; +}; +#undef __class__ +#define __class__ "etk::RegExpNodeDigit" + +template class RegExpNodeDigit : public RegExpNode { + public : + /** + * @brief + * @param[in,out] + * @return + */ + RegExpNodeDigit(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + ~RegExpNodeDigit(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + //TK_INFO("Parse node : Digit{" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} : "<< data[currentPos] << " lenMax=" << lenMax); + bool tmpFind = true; + int32_t j; + for (j=0; j::m_multipleMax && tmpFind ==true && j < lenMax; j++) { + char tmpVal = data[currentPos+j]; + //TK_DEBUG("compare : " << tmpVal); + if( '0' <= tmpVal + && '9' >= tmpVal) + { + //TK_DEBUG("find ++"); + findLen += 1; + } else { + tmpFind=false; + } + } + if( j>=RegExpNode::m_multipleMin + && j<=RegExpNode::m_multipleMax + && findLen>0 ) + { + //TK_DEBUG("find " << findLen); + return true; + } else if( 0 == RegExpNode::m_multipleMin ) { + //TK_DEBUG("find size=0"); + return true; + } + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(int32_t level) + { + TK_INFO("Find NODE : " << levelSpace(level) << "@Digit@ {" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} subdata="; DisplayElem(RegExpNode::m_RegExpData);); + }; +}; +#undef __class__ +#define __class__ "etk::RegExpNodeDigitNot" + +template class RegExpNodeDigitNot : public RegExpNode { + public : + RegExpNodeDigitNot(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + ~RegExpNodeDigitNot(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + //TK_INFO("Parse node : DigitNot{" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "}"); + bool tmpFind = true; + int32_t j; + for (j=0; j::m_multipleMax && tmpFind ==true && j < lenMax; j++) { + char tmpVal = data[currentPos+j]; + if( '0' > tmpVal + || '9' < tmpVal) + { + findLen += 1; + } else { + tmpFind=false; + } + } + if( j>=RegExpNode::m_multipleMin + && j<=RegExpNode::m_multipleMax + && findLen>0 ) + { + //TK_DEBUG("find " << findLen); + return true; + } else if( 0 == RegExpNode::m_multipleMin ) { + //TK_DEBUG("find size=0"); + return true; + } + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(int32_t level) + { + TK_INFO("Find NODE : " << levelSpace(level) << "@DigitNot@ {" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} subdata="; DisplayElem(RegExpNode::m_RegExpData);); + }; +}; +#undef __class__ +#define __class__ "etk::RegExpNodeLetter" + +template class RegExpNodeLetter : public RegExpNode { + public : + + /** + * @brief + * @param[in,out] + * @return + */ + RegExpNodeLetter(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + ~RegExpNodeLetter(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + //TK_INFO("Parse node : Letter{" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "}"); + bool tmpFind = true; + int32_t j; + for (j=0; j::m_multipleMax && tmpFind ==true && j < lenMax; j++) { + char tmpVal = data[currentPos+j]; + if( ( 'a' <= tmpVal + && 'z' >= tmpVal ) + || ( 'A' <= tmpVal + && 'Z' >= tmpVal )) + { + findLen += 1; + } else { + tmpFind=false; + } + } + if( j>=RegExpNode::m_multipleMin + && j<=RegExpNode::m_multipleMax + && findLen>0 ) + { + //TK_DEBUG("find " << findLen); + return true; + } else if( 0 == RegExpNode::m_multipleMin ) { + //TK_DEBUG("find size=0"); + return true; + } + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(int32_t level) + { + TK_INFO("Find NODE : " << levelSpace(level) << "@Letter@ {" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} subdata="; DisplayElem(RegExpNode::m_RegExpData);); + }; +}; +#undef __class__ +#define __class__ "etk::RegExpNodeLetterNot" + +template class RegExpNodeLetterNot : public RegExpNode { + public : + + /** + * @brief + * @param[in,out] + * @return + */ + RegExpNodeLetterNot(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + ~RegExpNodeLetterNot(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + //TK_INFO("Parse node : LetterNot{" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "}"); + bool tmpFind = true; + int32_t j; + for (j=0; j::m_multipleMax && tmpFind ==true && j < lenMax; j++) { + char tmpVal = data[currentPos+j]; + if( ( 'a' > tmpVal + && 'Z' < tmpVal ) + || 'A' > tmpVal + || 'z' < tmpVal ) + { + findLen += 1; + } else { + tmpFind=false; + } + } + if( j>=RegExpNode::m_multipleMin + && j<=RegExpNode::m_multipleMax + && findLen>0 ) + { + //TK_DEBUG("find " << findLen); + return true; + } else if( 0 == RegExpNode::m_multipleMin ) { + //TK_DEBUG("find size=0"); + return true; + } + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(int32_t level) + { + TK_INFO("Find NODE : " << levelSpace(level) << "@LetterNot@ {" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} subdata="; DisplayElem(RegExpNode::m_RegExpData);); + }; +}; +#undef __class__ +#define __class__ "etk::RegExpNodeWhiteSpace" + +template class RegExpNodeWhiteSpace : public RegExpNode { + public : + + /** + * @brief + * @param[in,out] + * @return + */ + RegExpNodeWhiteSpace(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + ~RegExpNodeWhiteSpace(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + //TK_INFO("Parse node : Space{" << m_multipleMin << "," << m_multipleMax << "}"); + bool tmpFind = true; + int32_t j; + for (j=0; j::m_multipleMax && tmpFind ==true && j < lenMax; j++) { + char tmpVal = data[currentPos+j]; + if( ' ' == tmpVal + || '\t' == tmpVal + || '\n' == tmpVal + || '\r' == tmpVal + || '\f' == tmpVal + || '\v' == tmpVal ) + { + findLen += 1; + } else { + tmpFind=false; + } + } + if( j>=RegExpNode::m_multipleMin + && j<=RegExpNode::m_multipleMax + && findLen>0 ) + { + //TK_DEBUG("find " << findLen); + return true; + } else if( 0 == RegExpNode::m_multipleMin ) { + //TK_DEBUG("find size=0"); + return true; + } + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(int32_t level) + { + TK_INFO("Find NODE : " << levelSpace(level) << "@Space@ {" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} subdata="; DisplayElem(RegExpNode::m_RegExpData);); + }; +}; +#undef __class__ +#define __class__ "etk::RegExpNodeWhiteSpaceNot" + +template class RegExpNodeWhiteSpaceNot : public RegExpNode { + public : + + /** + * @brief + * @param[in,out] + * @return + */ + RegExpNodeWhiteSpaceNot(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + ~RegExpNodeWhiteSpaceNot(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + //TK_INFO("Parse node : SpaceNot{" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "}"); + bool tmpFind = true; + int32_t j; + for (j=0; j::m_multipleMax && tmpFind ==true && j < lenMax; j++) { + char tmpVal = data[currentPos+j]; + if( ' ' != tmpVal + && '\t' != tmpVal + && '\n' != tmpVal + && '\r' != tmpVal + && '\f' != tmpVal + && '\v' != tmpVal ) + { + findLen += 1; + } else { + tmpFind=false; + } + } + if( j>=RegExpNode::m_multipleMin + && j<=RegExpNode::m_multipleMax + && findLen>0 ) + { + //TK_DEBUG("find " << findLen); + return true; + } else if( 0 == RegExpNode::m_multipleMin ) { + //TK_DEBUG("find size=0"); + return true; + } + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(int32_t level) + { + TK_INFO("Find NODE : " << levelSpace(level) << "@SpaceNot@ {" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} subdata="; DisplayElem(RegExpNode::m_RegExpData);); + }; +}; +#undef __class__ +#define __class__ "etk::RegExpNodeWordChar" + +template class RegExpNodeWordChar : public RegExpNode { + public : + + /** + * @brief + * @param[in,out] + * @return + */ + RegExpNodeWordChar(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + ~RegExpNodeWordChar(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + //TK_INFO("Parse node : Word{" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "}"); + bool tmpFind = true; + int32_t j; + for (j=0; j::m_multipleMax && tmpFind ==true && j < lenMax; j++) { + char tmpVal = data[currentPos+j]; + if( ( 'a' <= tmpVal + && 'z' >= tmpVal ) + || ( 'A' <= tmpVal + && 'Z' >= tmpVal ) + || ( '0' <= tmpVal + && '9' >= tmpVal )) + { + findLen += 1; + } else { + tmpFind=false; + } + } + if( j>=RegExpNode::m_multipleMin + && j<=RegExpNode::m_multipleMax + && findLen>0 ) + { + //TK_DEBUG("find " << findLen); + return true; + } else if( 0 == RegExpNode::m_multipleMin ) { + //TK_DEBUG("find size=0"); + return true; + } + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(int32_t level) + { + TK_INFO("Find NODE : " << levelSpace(level) << "@Word@ {" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} subdata="; DisplayElem(RegExpNode::m_RegExpData);); + }; +}; +#undef __class__ +#define __class__ "etk::RegExpNodeWordCharNot" + +template class RegExpNodeWordCharNot : public RegExpNode { + public : + + /** + * @brief + * @param[in,out] + * @return + */ + RegExpNodeWordCharNot(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + ~RegExpNodeWordCharNot(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + //TK_INFO("Parse node : WordNot{" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "}"); + bool tmpFind = true; + int32_t j; + for (j=0; j::m_multipleMax && tmpFind ==true && j < lenMax; j++) { + char tmpVal = data[currentPos+j]; + if( ( 'A' > tmpVal + && '9' < tmpVal ) + || ( 'a' > tmpVal + && 'Z' < tmpVal ) + || '0' > tmpVal + || 'z' < tmpVal ) + { + findLen += 1; + } else { + tmpFind=false; + } + } + if( j>=RegExpNode::m_multipleMin + && j<=RegExpNode::m_multipleMax + && findLen>0 ) + { + //TK_DEBUG("find " << findLen); + return true; + } else if( 0 == RegExpNode::m_multipleMin ) { + //TK_DEBUG("find size=0"); + return true; + } + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(int32_t level) + { + TK_INFO("Find NODE : " << levelSpace(level) << "@WordNot@ {" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} subdata="; DisplayElem(RegExpNode::m_RegExpData);); + }; +}; +#undef __class__ +#define __class__ "etk::RegExpNodeDot" + +template class RegExpNodeDot : public RegExpNode { + public : + + /** + * @brief + * @param[in,out] + * @return + */ + RegExpNodeDot(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + ~RegExpNodeDot(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + //TK_INFO("Parse node : '.'{" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "}"); + // equivalent a : [^\x00-\x08\x0A-\x1F\x7F] + bool tmpFind = true; + int32_t j; + for (j=0; j::m_multipleMax && tmpFind ==true && j < lenMax; j++) { + char tmpVal = data[currentPos+j]; + if( ( 0x08 < tmpVal + && 0x0A > tmpVal ) + || ( 0x1F < tmpVal + && 0x7F > tmpVal ) + || ( 0x7F < tmpVal + && 0xFF > tmpVal )) + { + findLen += 1; + } else { + tmpFind=false; + } + } + if( j>=RegExpNode::m_multipleMin + && j<=RegExpNode::m_multipleMax + && findLen>0 ) + { + //TK_DEBUG("find " << findLen); + return true; + } else if( 0 == RegExpNode::m_multipleMin ) { + //TK_DEBUG("find size=0"); + return true; + } + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(int32_t level) + { + TK_INFO("Find NODE : " << levelSpace(level) << "@.@ {" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} subdata="; DisplayElem(RegExpNode::m_RegExpData);); + }; +}; + +#undef __class__ +#define __class__ "etk::RegExpNodeSOL" + +template class RegExpNodeSOL : public RegExpNode { + public : + + /** + * @brief + * @param[in,out] + * @return + */ + RegExpNodeSOL(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + ~RegExpNodeSOL(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + TK_INFO("Parse node : SOL{" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "}"); + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(int32_t level) + { + TK_INFO("Find NODE : " << levelSpace(level) << "@SOL@ {" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} subdata="; DisplayElem(RegExpNode::m_RegExpData);); + }; +}; + +#undef __class__ +#define __class__ "etk::RegExpNodeEOL" + +template class RegExpNodeEOL : public RegExpNode { + public : + + /** + * @brief + * @param[in,out] + * @return + */ + RegExpNodeEOL(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + ~RegExpNodeEOL(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + TK_INFO("Parse node : EOL{" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "}"); + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(int32_t level) + { + TK_INFO("Find NODE : " << levelSpace(level) << "@EOL@ {" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} subdata="; DisplayElem(RegExpNode::m_RegExpData);); + }; +}; + +typedef struct { + int32_t start; + int32_t stop; +}elementPos_ts; + +#undef __class__ +#define __class__ "etk::RegExpNodePTheseElem" + +template class RegExpNodePThese; + +template class RegExpNodePTheseElem : public RegExpNode { + public : + + /** + * @brief + * @param[in,out] + * @return + */ + RegExpNodePTheseElem(void) + { + + }; + + + /** + * @brief + * @param[in,out] + * @return + */ + ~RegExpNodePTheseElem(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + int32_t Generate(etk::VectorType &data) + { + RegExpNode::m_RegExpData = data; + //TK_DEBUG("Request Parse (elem) data="; DisplayElem(RegExpNode::m_RegExpData);); + + int32_t pos = 0; + int32_t elementSize = 0; + etk::VectorType tmpData; + while (pos < RegExpNode::m_RegExpData.Size()) { + tmpData.Clear(); + switch (RegExpNode::m_RegExpData[pos]) + { + case REGEXP_OPCODE_PTHESE_IN: + { + elementSize=GetLenOfPThese(RegExpNode::m_RegExpData, pos); + for (int32_t k=pos+1; k::m_RegExpData[k]); + } + RegExpNodePThese * myElem = new RegExpNodePThese(); + (void)myElem->Generate(tmpData); + // add to the subnode list : + m_subNode.PushBack(myElem); + // move current position ... + pos += elementSize+1; + } + break; + case REGEXP_OPCODE_PTHESE_OUT: + TK_ERROR("Impossible case : ')' " << pos); + return false; + + case REGEXP_OPCODE_BRACKET_IN: + { + elementSize=GetLenOfBracket(RegExpNode::m_RegExpData, pos); + for (int32_t k=pos+1; k::m_RegExpData[k]); + } + RegExpNodeBracket * myElem = new RegExpNodeBracket(); + (void)myElem->Generate(tmpData); + // add to the subnode list : + m_subNode.PushBack(myElem); + // move current position ... + pos += elementSize+1; + } + break; + case REGEXP_OPCODE_BRACKET_OUT: + TK_ERROR("Impossible case : ']' " << pos); + return false; + + case REGEXP_OPCODE_BRACE_IN: + { + elementSize=GetLenOfBrace(RegExpNode::m_RegExpData, pos); + for (int32_t k=pos+1; k::m_RegExpData[k]); + } + int32_t min = 0; + int32_t max = 0; + if (false == ParseBrace(tmpData, min, max)) { + return false; + } + SetMultiplicityOnLastNode(min, max); + pos += elementSize+1; + } + break; + case REGEXP_OPCODE_BRACE_OUT: + TK_ERROR("Impossible case : '}' " << pos); + return false; + + case REGEXP_OPCODE_TO: + TK_ERROR("Impossible case : '-' " << pos); + return false; + + case REGEXP_OPCODE_STAR: + SetMultiplicityOnLastNode(0, 0x7FFFFFFF); + break; + + case REGEXP_OPCODE_QUESTION: + SetMultiplicityOnLastNode(0, 1); + break; + + case REGEXP_OPCODE_PLUS: + SetMultiplicityOnLastNode(1, 0x7FFFFFFF); + break; + + case REGEXP_OPCODE_PIPE: + TK_ERROR("Impossible case : '|' " << pos); + return false; + + case REGEXP_OPCODE_DOT: + m_subNode.PushBack(new RegExpNodeDot()); + break; + + case REGEXP_OPCODE_START_OF_LINE: + m_subNode.PushBack(new RegExpNodeSOL()); + break; + + case REGEXP_OPCODE_END_OF_LINE: + m_subNode.PushBack(new RegExpNodeEOL()); + break; + + case REGEXP_OPCODE_DIGIT: + m_subNode.PushBack(new RegExpNodeDigit()); + break; + + case REGEXP_OPCODE_DIGIT_NOT: + m_subNode.PushBack(new RegExpNodeDigitNot()); + break; + + case REGEXP_OPCODE_LETTER: + m_subNode.PushBack(new RegExpNodeLetter()); + break; + + case REGEXP_OPCODE_LETTER_NOT: + m_subNode.PushBack(new RegExpNodeLetterNot()); + break; + + case REGEXP_OPCODE_SPACE: + m_subNode.PushBack(new RegExpNodeWhiteSpace()); + break; + + case REGEXP_OPCODE_SPACE_NOT: + m_subNode.PushBack(new RegExpNodeWhiteSpaceNot()); + break; + + case REGEXP_OPCODE_WORD: + m_subNode.PushBack(new RegExpNodeWordChar()); + break; + + case REGEXP_OPCODE_WORD_NOT: + m_subNode.PushBack(new RegExpNodeWordCharNot()); + break; + + default: + { + elementSize=GetLenOfNormal(RegExpNode::m_RegExpData, pos); + for (int32_t k=pos; k::m_RegExpData[k]); + } + RegExpNodeValue * myElem = new RegExpNodeValue(); + (void)myElem->Generate(tmpData); + // add to the subnode list : + m_subNode.PushBack(myElem); + // move current position ... + pos += elementSize-1; + } + break; + } + pos++; + } + return data.Size(); + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + //TK_INFO("Parse node : (Elem){" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "}"); + // NOTE 1 : Must done only one time in EVERY case ... + // NOTE 2 : All element inside must be OK + if (0 == m_subNode.Size()) { + return false; + } + int32_t tmpCurrentPos = currentPos; + for (int32_t i=0; iParse(data, tmpCurrentPos, lenMax, tmpFindLen)) { + findLen = 0; + return false; + } else { + tmpCurrentPos += tmpFindLen; + } + } + findLen = tmpCurrentPos - currentPos; + return true; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(int32_t level) + { + TK_INFO("Find NODE : " << levelSpace(level) << "@(Elem)@ {" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} subdata="; DisplayElem(RegExpNode::m_RegExpData);); + for(int32_t i=0; iDisplay(level+1); + } + }; + protected : + // SubNodes : + etk::VectorType*> m_subNode; + private : + /** + * @brief Set the number of repeate time on a the last node in the list ... + * + * @param[in] min Minimum of the multiplicity + * @param[in] max Maximum of the multiplicity + * + * @return true if we find the node, false otherwise + * + */ + bool SetMultiplicityOnLastNode(int32_t min, int32_t max) + { + if (0==m_subNode.Size()) { + TK_ERROR("Set multiplicity on an inexistant element ...."); + return false; + } + RegExpNode * myNode = m_subNode[m_subNode.Size()-1]; + if (NULL==myNode) { + TK_ERROR("INTERNAL error ==> node not generated"); + return false; + } + myNode->SetMult(min, max); + return true; + } +}; + +#undef __class__ +#define __class__ "etk::RegExpNodePThese" + +template class RegExpNodePThese : public RegExpNode { + public : + /** + * @brief + * @param[in,out] + * @return + */ + RegExpNodePThese(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + ~RegExpNodePThese(void) + { + + }; + + /** + * @brief + * @param[in,out] + * @return + */ + int32_t Generate(etk::VectorType &data) + { + RegExpNode::m_RegExpData = data; + //TK_DEBUG("Request Parse (...) data="; DisplayElem(RegExpNode::m_RegExpData);); + //Find all the '|' in the string (and at the good level ...) + int32_t pos = 0; + int32_t elementSize = GetLenOfPTheseElem(RegExpNode::m_RegExpData, pos); + // generate all the "elemTypePTheseElem" of the Node + while (elementSize>0) { + // geerate output deta ... + etk::VectorType tmpData; + for (int32_t k=pos; k::m_RegExpData[k]); + } + RegExpNodePTheseElem * myElem = new RegExpNodePTheseElem(); + (void)myElem->Generate(tmpData); + // add to the subnode list : + m_subNode.PushBack(myElem); + pos += elementSize+1; + //TK_DEBUG("plop="; DisplayElem(data, pos, pos+1);); + elementSize = GetLenOfPTheseElem(RegExpNode::m_RegExpData, pos); + //TK_DEBUG("find " << elementSize << " elements"); + } + if (0 == pos && 0 == elementSize) { + TK_ERROR("No data in the (...) element at " << pos); + return false; + } + return data.Size(); + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool Parse(CLASS_TYPE &data, int32_t currentPos, int32_t lenMax, int32_t &findLen) + { + findLen = 0; + //TK_INFO("Parse node : (...){" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "}"); + if (0 == m_subNode.Size()) { + return false; + } + bool tmpFind = true; + int32_t j; + for (j=0; j::m_multipleMax && tmpFind == true ; j++) { + tmpFind = false; + for (int32_t i=0; iParse(data, currentPos+findLen, lenMax, tmpFindLen)) { + findLen += tmpFindLen; + tmpFind = true; + } + } + } + if( j>=RegExpNode::m_multipleMin + && j<=RegExpNode::m_multipleMax + && findLen>0 ) + { + //TK_DEBUG("find " << findLen); + return true; + } else if( 0 == RegExpNode::m_multipleMin ) { + //TK_DEBUG("find size=0"); + return true; + } + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(int32_t level) + { + if (-1 == level) { + TK_INFO("regExp :"; DisplayElem(RegExpNode::m_RegExpData);); + } else { + TK_INFO("Find NODE : " << levelSpace(level) << "@(...)@ {" << RegExpNode::m_multipleMin << "," << RegExpNode::m_multipleMax << "} subdata="; DisplayElem(RegExpNode::m_RegExpData);); + for(int32_t i=0; iDisplay(level+1); + } + } + }; + + protected : + // SubNodes : + etk::VectorType*> m_subNode; + //int32_t m_posPthese; //!< position of the element is detected in the output element +}; +#undef __class__ +#define __class__ "etk::RegExp" + +// Regular expression manager +template class etkRegExp { + // public API : + public: + // create the regular expression + + /** + * @brief + * @param[in,out] + * @return + */ + etkRegExp(const char *exp) + { + m_isOk = false; + m_areaFind.start=0; + m_areaFind.stop=0; + m_notBeginWithChar = false; + m_notEndWithChar = false; + SetRegExp(exp); + }; + + /** + * @brief + * @param[in,out] + * @return + */ + etkRegExp(etk::String &exp) + { + m_isOk = false; + m_areaFind.start=0; + m_areaFind.stop=0; + m_notBeginWithChar = false; + m_notEndWithChar = false; + SetRegExp(exp); + }; + + /** + * @brief + * @param[in,out] + * @return + */ + etkRegExp(void) + { + m_isOk = false; + m_areaFind.start=0; + m_areaFind.stop=0; + m_notBeginWithChar = false; + m_notEndWithChar = false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + ~etkRegExp(void) + { + // TODO : remove all under nodes... + m_isOk = false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void SetRegExp(const char *exp) + { + TK_CHECK_INOUT(exp); + etk::String expressionRequested = exp; + SetRegExp(expressionRequested); + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void SetRegExp(etk::String &expressionRequested) + { + m_expressionRequested = expressionRequested; // TODO : Must be deprecated ... + etk::VectorType tmpExp; + + //TK_DEBUG("Parse RegExp : " << expressionRequested.c_str() ); + m_isOk = false; + m_areaFind.start=0; + m_areaFind.stop=0; + m_notBeginWithChar = false; + m_notEndWithChar = false; + + char * exp = expressionRequested.c_str(); + int32_t regExpLen = strlen(exp); + // change in the regular Opcode ==> replace \x with the corect element ... x if needed + int32_t iii; + int32_t countBraceIn = 0; + int32_t countBraceOut = 0; + int32_t countPTheseIn = 0; + int32_t countPTheseOut = 0; + int32_t countBracketIn = 0; + int32_t countBracketOut = 0; + for (iii=0; iii=regExpLen) { + TK_ERROR("Dangerous parse of the element pos " << iii << " \\ with nothing after"); + // TODO : Generate Exeption ... + return; + } + int32_t j; + // Find the element in the list... + for (j=0; j0 + && REGEXP_OPCODE_NO_CHAR == tmpExp[0]) + { + //TK_DEBUG("=> must not begin with char"); + m_notBeginWithChar = true; + // remove element + tmpExp.Erase(0); + } + if( tmpExp.Size()>0 + && REGEXP_OPCODE_NO_CHAR == tmpExp[tmpExp.Size()-1]) + { + //TK_DEBUG("=> must not end with char"); + m_notEndWithChar = true; + // remove element + tmpExp.Erase(tmpExp.Size()-1); + } + + if (tmpExp.Size() != m_exprRootNode.Generate(tmpExp) ) { + return; + } + // TODO : optimize node here ... + + //Display(); + + // all OK ... play again + m_isOk = true; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + etk::String GetRegExp(void) + { + return m_expressionRequested; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool GetStatus(void) + { + return m_isOk; + }; + // process the regular expression + + /** + * @brief + * @param[in,out] + * @return + */ + bool Process( CLASS_TYPE &SearchIn, + int32_t startPos, + int32_t endPos, + char escapeChar=0) + { + if (false == m_isOk) { + return false; + } + int32_t buflen = SearchIn.Size(); + if (endPos > buflen) { + endPos = buflen; + } + if (startPos > endPos) { + return false; + } + int32_t i = 0; + for (i=startPos; i0) { + char tmpVal = SearchIn[i-1]; + if( ( 'a' <= tmpVal + && 'z' >= tmpVal ) + || ( 'A' <= tmpVal + && 'Z' >= tmpVal ) + || ( '0' <= tmpVal + && '9' >= tmpVal ) + || ( '_' == tmpVal ) ) + { + // go on the next char ... + continue; + } + } + } + if (true == m_exprRootNode.Parse(SearchIn, i, maxlen, findLen)) { + if( 0!=escapeChar + && i>0) + { + if (escapeChar == (char)SearchIn[i-1]) { + //==> detected escape char ==> try find again ... + continue; + } + } + // Check end : + if (true == m_notEndWithChar) { + if (i+findLen < SearchIn.Size() ) { + char tmpVal = SearchIn[i+findLen]; + if( ( 'a' <= tmpVal + && 'z' >= tmpVal ) + || ( 'A' <= tmpVal + && 'Z' >= tmpVal ) + || ( '0' <= tmpVal + && '9' >= tmpVal ) + || ( '_' == tmpVal ) ) + { + // go on the next char ... + continue; + } + } + } + m_areaFind.start = i; + m_areaFind.stop = i + findLen; + /* + if (i == 812) { + std::cout << std::endl; + for(int32_t k=startPos; k buflen) { + endPos = buflen; + } + if (startPos > endPos) { + return false; + } + int32_t findLen=0; + int32_t maxlen = endPos-startPos; + if (true == m_notBeginWithChar) { + if (startPos>0) { + char tmpVal = SearchIn[startPos-1]; + if( ( 'a' <= tmpVal + && 'z' >= tmpVal ) + || ( 'A' <= tmpVal + && 'Z' >= tmpVal ) + || ( '0' <= tmpVal + && '9' >= tmpVal ) + || ( '_' == tmpVal ) ) + { + // go on the next char ... + return false; + } + } + } + if (true == m_exprRootNode.Parse(SearchIn, startPos, maxlen, findLen)) { + if( 0!=escapeChar + && startPos>0) + { + if (escapeChar == (char)SearchIn[startPos-1]) { + //==> detected escape char ==> try find again ... + return false; + } + } + // Check end : + if (true == m_notEndWithChar) { + if (startPos+findLen < SearchIn.Size() ) { + char tmpVal = SearchIn[startPos+findLen]; + if( ( 'a' <= tmpVal + && 'z' >= tmpVal ) + || ( 'A' <= tmpVal + && 'Z' >= tmpVal ) + || ( '0' <= tmpVal + && '9' >= tmpVal ) + || ( '_' == tmpVal ) ) + { + // go on the next char ... + return false; + } + } + } + m_areaFind.start = startPos; + m_areaFind.stop = startPos + findLen; + return true; + } + return false; + }; + + + /** + * @brief + * @param[in,out] + * @return + */ + int32_t Start(void) + { + return m_areaFind.start; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + int32_t Stop(void) + { + return m_areaFind.stop; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + void Display(void) + { + m_exprRootNode.Display(0); + }; + // internal parameters + private: + etk::String m_expressionRequested; // TODO : Remove ... + elementPos_ts m_areaFind; //!< position around selection + RegExpNodePThese m_exprRootNode; //!< The tree where data is set + bool m_isOk; //!< Known if we can process with this regExp + bool m_notBeginWithChar; //!< The regular expression must not have previously a char [a-zA-Z0-9_] + bool m_notEndWithChar; //!< The regular expression must not have after the end a char [a-zA-Z0-9_] + // internal access + private: + /** + * @brief + * @param[in,out] + * @return + */ + bool CheckGoodPosition(etk::VectorType tmpExp, int32_t &pos) + { + int16_t curentCode = tmpExp[pos]; + int16_t endCode = REGEXP_OPCODE_PTHESE_OUT; + char *input = (char*)"(...)"; + if (REGEXP_OPCODE_BRACKET_IN == curentCode) { + endCode = REGEXP_OPCODE_BRACKET_OUT; + input = (char*)"[...]"; + } else if (REGEXP_OPCODE_BRACE_IN == curentCode){ + endCode = REGEXP_OPCODE_BRACE_OUT; + input = (char*)"{x,x}"; + } + pos++; + if (pos >= (int32_t)tmpExp.Size()) { + TK_ERROR("ended with: ( or { or [ ... not permited"); + return false; + } + //TK_DEBUG(" ==> Find ELEMENT : ([{"); + // case dependent : + if( REGEXP_OPCODE_BRACKET_IN == curentCode + || REGEXP_OPCODE_BRACE_IN == curentCode) { + while(pos< (int32_t)tmpExp.Size()) { + //TK_DEBUG("check : " << tmpExp[pos]); + // if we find the end : + if (endCode == tmpExp[pos]) { + return true; + } else { + // otherwise, we check the error in the element ... + char *find = NULL; + switch (tmpExp[pos]) + { + case REGEXP_OPCODE_PTHESE_IN: find = (char*)"("; break; + case REGEXP_OPCODE_BRACKET_IN: find = (char*)"["; break; + case REGEXP_OPCODE_BRACE_IN: find = (char*)"{"; break; + case REGEXP_OPCODE_PTHESE_OUT: find = (char*)")"; break; + case REGEXP_OPCODE_BRACKET_OUT: find = (char*)"]"; break; + case REGEXP_OPCODE_BRACE_OUT: find = (char*)"}"; break; + case REGEXP_OPCODE_STAR: find = (char*)"*"; break; + case REGEXP_OPCODE_DOT: find = (char*)"."; break; + case REGEXP_OPCODE_QUESTION: find = (char*)"?"; break; + case REGEXP_OPCODE_PLUS: find = (char*)"+"; break; + case REGEXP_OPCODE_PIPE: find = (char*)"|"; break; + case REGEXP_OPCODE_START_OF_LINE: find = (char*)"^"; break; + case REGEXP_OPCODE_END_OF_LINE: find = (char*)"$"; break; + case REGEXP_OPCODE_DIGIT: find = (char*)"\\d"; break; + case REGEXP_OPCODE_DIGIT_NOT: find = (char*)"\\D"; break; + case REGEXP_OPCODE_LETTER: find = (char*)"\\l"; break; + case REGEXP_OPCODE_LETTER_NOT: find = (char*)"\\L"; break; + case REGEXP_OPCODE_SPACE: find = (char*)"\\s"; break; + case REGEXP_OPCODE_SPACE_NOT: find = (char*)"\\S"; break; + case REGEXP_OPCODE_WORD: find = (char*)"\\w"; break; + case REGEXP_OPCODE_WORD_NOT: find = (char*)"\\W"; break; + case REGEXP_OPCODE_NO_CHAR: find = (char*)"\\@"; break; + default: break; + } + if (NULL != find) { + TK_ERROR("can not have : '" << find << "' inside " << input << " element"); + return false; + } + } + pos++; + } + } else { + while(pos< (int32_t)tmpExp.Size()) { + if (endCode == tmpExp[pos]) { + // find the last element + return true; + } else if ( REGEXP_OPCODE_BRACE_OUT == tmpExp[pos]) { + TK_ERROR("find } inside a (...) without start {"); + return false; + } else if ( REGEXP_OPCODE_BRACKET_OUT == tmpExp[pos]) { + TK_ERROR("find ] inside a (...) without start ["); + return false; + } else { + if( REGEXP_OPCODE_PTHESE_IN == tmpExp[pos] + || REGEXP_OPCODE_BRACKET_IN == tmpExp[pos] + || REGEXP_OPCODE_BRACE_IN == tmpExp[pos]) + { + if (false==CheckGoodPosition(tmpExp, pos) ) { + return false; + } + } + } + pos++; + } + } + + // we did not find the cloder . ... + if (endCode == REGEXP_OPCODE_BRACKET_OUT) { + TK_ERROR("Missing ']' at the end"); + } + if (endCode == REGEXP_OPCODE_BRACE_OUT) { + TK_ERROR("Missing '}' at the end"); + } + if (endCode == REGEXP_OPCODE_PTHESE_OUT) { + TK_ERROR("Missing ')' at the end"); + } + return false; + }; + + /** + * @brief + * @param[in,out] + * @return + */ + bool CheckGoodPosition(etk::VectorType tmpExp) + { + int32_t pos = 0; + while (pos < (int32_t)tmpExp.Size()) { + //TK_DEBUG("check : " << tmpExp[pos]); + if( REGEXP_OPCODE_PTHESE_IN == tmpExp[pos] + || REGEXP_OPCODE_BRACKET_IN == tmpExp[pos] + || REGEXP_OPCODE_BRACE_IN == tmpExp[pos]) + { + // attention the i position change inside the finction... + if (false==CheckGoodPosition(tmpExp, pos) ) { + TK_ERROR("Error at position : " << pos+1 ); + return false; + } else { + //TK_DEBUG(" <== Find ELEMENT : ]})"); + } + } else if(REGEXP_OPCODE_PTHESE_OUT == tmpExp[pos]) { + TK_ERROR("can find ')' with no start : ')'"); + return false; + } else if(REGEXP_OPCODE_BRACKET_OUT == tmpExp[pos]) { + TK_ERROR("can find ']' with no start : '['"); + return false; + } else if(REGEXP_OPCODE_BRACE_OUT == tmpExp[pos]) { + TK_ERROR("can find '}' with no start : '{'"); + return false; + } + pos++; + } + return true; + }; + + +}; + +}; // end of etk namespace + +#endif diff --git a/Sources/etk/etkString.cpp b/Sources/etk/etkString.cpp new file mode 100644 index 00000000..59d3eb70 --- /dev/null +++ b/Sources/etk/etkString.cpp @@ -0,0 +1,717 @@ +/** + ******************************************************************************* + * @file etkString.cpp + * @brief Ewol Tool Kit : normal sting management... (sources) + * @author Edouard DUPIN + * @date 26/01/2011 + * @par Project + * Ewol TK + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + +#include +#include + + +#undef __class__ +#define __class__ "etk::String" + +std::ostream& etk::operator <<(std::ostream &os, const etk::String &obj) +{ + os << (char*)&obj.m_data[0]; + return os; +} + +/** + * @brief + * + * @param[in,out] + * + * @return + * + */ +etk::String::~String(void) +{ + m_data.Clear(); +} + + +/** + * @brief + * + * @param[in,out] + * + * @return + * + */ +etk::String::String(void) +{ + //TK_INFO("new etk::String()"); + m_data.Clear(); + m_data.PushBack('\0'); +} + + +/** + * @brief + * + * @param[in,out] + * + * @return + * + */ +etk::String::String(const char myInput) +{ + m_data.Clear(); + m_data.PushBack(myInput); + m_data.PushBack('\0'); +} + + +/** + * @brief + * + * @param[in,out] + * + * @return + * + */ +etk::String::String(const char* inputData, int32_t len) +{ + m_data.Clear(); + m_data.PushBack('\0'); + Set(inputData, len); +} + +void etk::String::Set(const char * inputData, int32_t len) +{ + // overwrite the len if needed : + if ((-1) == len) { + len = strlen(inputData); + } + + if (len != 0) { + // remove the last '\0' + m_data.PopBack(); + // copy the data ... + m_data.PushBack((int8_t*)inputData, len); + // add the last '\0' + m_data.PushBack('\0'); + } +} + +/** + * @brief + * + * @param[in,out] + * + * @return + * + */ +etk::String::String(int inputData) +{ + char tmpVal[256]; + // generate the string : + sprintf(tmpVal, "%d", inputData); + // set the internal data : + m_data.Clear(); + m_data.PushBack('\0'); + Set(tmpVal); +} + + +/** + * @brief + * + * @param[in,out] + * + * @return + * + */ +etk::String::String(unsigned int inputData) +{ + char tmpVal[256]; + // generate the string : + sprintf(tmpVal, "%d", inputData); + // set the internal data : + m_data.Clear(); + m_data.PushBack('\0'); + Set(tmpVal); +} + +etk::String::String(const etk::String &etkS) +{ + //etk_INFO("Constructeur de recopie"); + m_data = etkS.m_data; +} + + +/** + * @brief + * + * @param[in,out] + * + * @return + * + */ +const etk::String& etk::String::operator= (const etk::String &etkS ) +{ + //TK_INFO("OPERATOR de recopie"); + if( this != &etkS ) // avoid copy to itself + { + m_data = etkS.m_data; + } + return *this; +} + + +/** + * @brief + * + * @param[in,out] + * + * @return + * + */ +const etk::String& etk::String::operator= (const char * inputData) +{ + m_data.Clear(); + m_data.PushBack('\0'); + // calculate the size : + uint32_t len = strlen(inputData); + // check the new size ... + if (len > 0 ) { + // copy all data : + Set(inputData, len); + } + return *this; +} + + +/** + * @brief + * + * @param[in,out] + * + * @return + * + */ +const etk::String& etk::String::operator= (etk::VectorType inputData) +{ + m_data = inputData; + if (m_data.Size()>0) { + if (m_data[m_data.Size()-1] != '\0') { + m_data.PushBack('\0'); + } + } + //TK_DEBUG("m_dataLen="<= m_data.Size() ) { + return true; + } else { + return false; + } +} + + +/** + * @brief + * + * @param[in,out] + * + * @return + * + */ +int32_t etk::String::Size(void) const +{ + if (m_data.Size() == 0) { + return 0; + } else { + return m_data.Size() - 1; + } +} + + +/** + * @brief + * + * @param[in,out] + * + * @return + * + */ +void etk::String::Add(int32_t currentID, const char* inputData) +{ + // get the input lenght + int32_t len = strlen(inputData); + if (0 == len) { + TK_WARNING("no data to add on the current string"); + return; + } else if (currentID < 0) { + TK_WARNING("Curent ID(" << currentID << ") < 0 ==> Add at the start"); + currentID = 0; + } else if (currentID > Size() ) { + TK_ERROR("Curent ID(" << currentID << ") > maxSize ... (" << Size() << ") ==> add at the end ..."); + m_data.PushBack((int8_t*)inputData, len); + return; + } + m_data.Insert(currentID, (int8_t*)inputData, len); +} + + +/** + * @brief + * + * @param[in,out] + * + * @return + * + */ +void etk::String::Remove(int32_t currentID, int32_t len) +{ + if (0 >= len) { + TK_ERROR("no data to remove on the current string"); + return; + } + // TODO : check the size of the data + m_data.EraseLen(currentID, len); +} + + +/** + * @brief Remove all element in the string + * + * @param --- + * + * @return --- + * + */ +void etk::String::Clear(void) +{ + m_data.Clear(); + m_data.PushBack('\0'); +} + + + +/** + * @brief find the first accurence after the position indicated + * + * @param[in] element Element that might be find in the string + * @param[in] startPos Stert position to begin the search + * + * @return the position of the first occurence or -1 if not find... + * + */ +int32_t etk::String::FindForward(const char element, int32_t startPos) +{ + if (startPos < 0) { + startPos = 0; + } else if (startPos >= Size() ) { + return -1; + } + for (int32_t iii=startPos; iii< Size(); iii++) { + if (m_data[iii] == element) { + return iii; + } + } + return -1; +} + + +/** + * @brief find the first accurence before the position indicated. + * + * @param[in] element Element that might be find in the string + * @param[in] startPos Stert position to begin the search + * + * @return the position of the first occurence begining by the end or -1 if not find... + * + */ +int32_t etk::String::FindBack(const char element, int32_t startPos) +{ + if (startPos < 0) { + return -1; + } else if (startPos >= Size() ) { + startPos = Size(); + } + for (int32_t iii=startPos; iii>=0; iii--) { + if (m_data[iii] == element) { + return iii; + } + } + return -1; +} + + +/** + * @brief Extract data from the data between two position + * + * @param[in] posStart Start position where to extract data + * @param[in] posEnd End position where to extract data + * + * @return the extracted string + * + */ +etk::String etk::String::Extract(int32_t posStart, int32_t posEnd) +{ + etk::String out; + if (posStart < 0) { + posStart = 0; + } else if (posStart >= Size() ) { + return out; + } + if (posEnd < 0) { + return out; + } else if (posEnd >= Size() ) { + posEnd = Size(); + } + out.m_data = m_data.Extract(posStart, posEnd); + out.m_data.PushBack('\0'); + return out; +} + + +/** + * @brief Get a basic vector in int8 data with no \0 at the end of the string + * + * @param --- + * + * @return The desired vector with data + * + */ +etk::VectorType etk::String::GetVector(void) +{ + etk::VectorType out = m_data; + out.PopBack(); + return out; +} + + + +/** + * @brief Unitary test for the string system + * + * @param --- + * + * @return --- + * + */ +void etk::TestUntaire_String(void) +{ + TK_WARNING("*********************************************************"); + TK_WARNING("** Test Unitaire 'etkString' (START)"); + TK_WARNING("*********************************************************"); + + int32_t iddd = 0; + etk::String * monString = new etk::String(); + TK_INFO("phase : " << iddd++ << " : \"" << monString << "\""); + delete(monString); + + monString = new etk::String("test de direct data"); + TK_INFO("phase : " << iddd++ << " : \"" << monString << "\""); + delete(monString); + + monString = new etk::String("test de direct data", 7); + TK_INFO("phase : " << iddd++ << " : \"" << monString << "\""); + delete(monString); + + int32_t testId = -6789; + monString = new etk::String(testId); + TK_INFO("phase : " << iddd++ << " : \"" << monString << "\""); + delete(monString); + + uint32_t testId2 = 12345; + monString = new etk::String((unsigned int)testId2); + TK_INFO("phase : " << iddd++ << " : \"" << monString << "\""); + delete(monString); + + etk::String plop = "otherString"; + monString = new etk::String(plop); + TK_INFO("phase : " << iddd++ << " : \"" << monString << "\""); + delete(monString); + + + etk::String s1 = "test de base ..."; + s1 += s1; + TK_INFO("phase : " << iddd++ << " : \"" << s1 << "\""); + s1 += " plop 2 "; + TK_INFO("phase : " << iddd++ << " : \"" << s1 << "\""); + s1 += plop; + TK_INFO("phase : " << iddd++ << " : \"" << s1 << "\""); + s1 = plop; + TK_INFO("phase : " << iddd++ << " : \"" << s1 << "\""); + s1 = "test direct 44"; + TK_INFO("phase : " << iddd++ << " : \"" << s1 << "\""); + etk::VectorType vb1; + vb1.PushBack('v'); + vb1.PushBack('b'); + vb1.PushBack('1'); + s1 = vb1; + TK_INFO("phase : " << iddd++ << " : \"" << s1 << "\""); + vb1.Clear(); + vb1.PushBack('v'); + vb1.PushBack('b'); + vb1.PushBack('2'); + vb1.PushBack('\0'); + s1 = vb1; + TK_INFO("phase : " << iddd++ << " : \"" << s1 << "\""); + + if (s1 == "vb2") { + TK_INFO("phase : " << iddd++ << " : == OK"); + } else { + TK_ERROR("phase : " << iddd++ << " : == ERROR"); + } + + + if (s1 == "vb3") { + TK_ERROR("phase : " << iddd++ << " : == ERROR"); + } else { + TK_INFO("phase : " << iddd++ << " : == OK"); + } + + + if (s1 != "vb3") { + TK_INFO("phase : " << iddd++ << " : == OK"); + } else { + TK_ERROR("phase : " << iddd++ << " : == ERROR"); + } + + + if (s1 != "vb2") { + TK_ERROR("phase : " << iddd++ << " : == ERROR"); + } else { + TK_INFO("phase : " << iddd++ << " : == OK"); + } + + + etk::String s2 = "vb2"; + etk::String s3 = "vb3"; + + if (s1 == s2) { + TK_INFO("phase : " << iddd++ << " : == OK"); + } else { + TK_ERROR("phase : " << iddd++ << " : == ERROR"); + } + + + if (s1 == s3) { + TK_ERROR("phase : " << iddd++ << " : == ERROR"); + } else { + TK_INFO("phase : " << iddd++ << " : == OK"); + } + + + if (s1 != s3) { + TK_INFO("phase : " << iddd++ << " : == OK"); + } else { + TK_ERROR("phase : " << iddd++ << " : == ERROR"); + } + + + if (s1 != s2) { + TK_ERROR("phase : " << iddd++ << " : == ERROR"); + } else { + TK_INFO("phase : " << iddd++ << " : == OK"); + } + TK_WARNING("*********************************************************"); + TK_WARNING("** Test Unitaire 'etkString' (STOP)"); + TK_WARNING("*********************************************************"); +} + diff --git a/Sources/etk/etkString.h b/Sources/etk/etkString.h new file mode 100644 index 00000000..5ac1ac43 --- /dev/null +++ b/Sources/etk/etkString.h @@ -0,0 +1,93 @@ +/** + ******************************************************************************* + * @file etkString.h + * @brief Ewol Tool Kit : normal sting management... (header) + * @author Edouard DUPIN + * @date 26/01/2011 + * @par Project + * Ewol TK + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + +#ifndef __ETK_STRING_H__ +#define __ETK_STRING_H__ + +#include +#include + +namespace etk +{ + class String + { + public: + // Constructeurs + String(void); + String(const char myInput); + String(const char* inputData, int32_t len = -1);//, bool noAllocation=false); + void Set(const char* inputData, int32_t len=-1); + // basic convertion integer en string + String(int inputData); + String(unsigned int inputData); + //String(const wchar_t *inputData); + String(const etk::String &etkS); + // destructor : + ~String(void); + + const etk::String& operator= (const etk::String &etkS ); // assigment + const etk::String& operator= (const char * inputData); + const etk::String& operator= (etk::VectorType inputData); + bool operator== (const etk::String& etkS) const; // == operator + bool operator== (const char * inputData) const; + bool operator!= (const etk::String& etkS) const; // != operator + bool operator!= (const char * inputData) const; + const etk::String& operator+= (const etk::String &etkS); // += operator + const etk::String& operator+= (const char * inputData); + etk::String operator+ (const etk::String &etkS); // + operator + etk::String operator+ (const char * inputData); + //operator const char *() + friend std::ostream& operator <<( std::ostream &os,const etk::String &obj); + + bool IsEmpty(void) const; + int32_t Size(void) const; + + void Add(int32_t currentID, const char* inputData); + void Remove(int32_t currentID, int32_t len); + void Clear(void); + + etk::VectorType GetVector(void); + char * c_str(void) { return (char*)&m_data[0]; }; + + // Sting operation : + int32_t FindForward(const char element, int32_t startPos=0); + int32_t FindBack(const char element, int32_t startPos=0x7FFFFFFF); + etk::String Extract(int32_t posStart=0, int32_t posEnd=0x7FFFFFFF); + + private : + etk::VectorType m_data; + }; + + void TestUntaire_String(void); + + std::ostream& operator <<(std::ostream &os, const etk::String &obj); + +} + + + + + +#endif + diff --git a/Sources/etk/etkTypes.h b/Sources/etk/etkTypes.h new file mode 100644 index 00000000..b735147b --- /dev/null +++ b/Sources/etk/etkTypes.h @@ -0,0 +1,69 @@ +/** + ******************************************************************************* + * @file etkTypes.h + * @brief Ewol Tool Kit : generique define type + * @author Edouard DUPIN + * @date 08/06/2010 + * @par Project + * Ewol TK + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + +#ifndef __ETK_TYPES_H__ +#define __ETK_TYPES_H__ + +// includes system, malloc, EXIT_SUCCESS +#include +// includes fopen, fwrite, fseek, ftell +#include +#include +#include +#include + +#ifndef __int8_t_defined +# define __int8_t_defined + typedef signed char int8_t; + typedef signed short int int16_t; + typedef int int32_t; + typedef signed long long int int64_t; +#endif + +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned long int uint32_t; +typedef unsigned long long int uint64_t; + + +#define etk_min(elemA, elemB) ((elemA)<(elemB)) ? (elemA) : (elemB) +#define etk_max(elemA, elemB) ((elemA)<(elemB)) ? (elemB) : (elemA) +#define etk_average(minimim, elem, maximum) ((minimim)>(elem)) ? (minimim) : ((maximum)<(elem)) ? (maximum) : (elem) + +extern "C" +{ + struct etkPointAndPosition{ + double x; + double y; + }; + typedef etkPointAndPosition point_ts; + typedef etkPointAndPosition position_ts; + typedef etkPointAndPosition size_ts; +} + + + +#endif + + diff --git a/Sources/etk/etkVector.h b/Sources/etk/etkVector.h new file mode 100644 index 00000000..776a1b1e --- /dev/null +++ b/Sources/etk/etkVector.h @@ -0,0 +1,509 @@ +/** + ******************************************************************************* + * @file etkVector.h + * @brief Ewol Tool Kit : Basic etk::Vector (template) + * @author Edouard DUPIN + * @date 07/04/2011 + * @par Project + * Ewol TK + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + +#ifndef __ETK_VECTOR_H__ +#define __ETK_VECTOR_H__ + +#include +#include + +#undef __class__ +#define __class__ "etk::Vector" + +/** + * @brief etkVector classes ... + * + * @tparam[in] T The type of objects to store. + * @tparam[in] INC Incrementation mode (0 : Exponential to 200 and increment by stemp of 200) + * + * @todo : Need to add : popBack / Assign / Insert / Erase / Swap / Clear + * + * m_data + * ---------- |-----------------------| + * | 0 |-------->| Class Data | + * |--------| |-----------------------| + * | 1 |----| + * |--------| | + * | 2 |====|==============| |-----------------------| + * |--------| | --->| Class Data | + * m_count | 3 |-| | |-----------------------| + * |--------| | | + * | x | | | |-----------------------| + * |--------| | -------->| Class Data | + * | x | | |-----------------------| + * |--------| | + * | x | | + * |--------| | |-----------------------| + * | x | --------------------->| Class Data | + * |--------| |-----------------------| + * | x | + * |--------| + * | x | + * |--------| + * m_size | x | + * ---------- + * + */ +namespace rtk +{ + +template class Vector +{ + public: + class Iterator + { + // Private data : + private: + int32_t m_current; // curent Id on the vector + etk::Vector * m_Vector; // Pointer on the curent element of the vector + public: + /** + * @brief Basic itarator constructor with no link with an Vector + */ + Iterator(): + m_current(-1), + m_Vector(NULL) + { + // nothing to do ... + } + /** + * @brief Recopy constructor on a specific Vector. + * @param[in] otherIterator The Iterator that might be copy + */ + Iterator(const Iterator & otherIterator): + m_current(otherIterator.m_current), + m_Vector(otherIterator.m_Vector) + { + // nothing to do ... + } + /** + * @brief Asignation operator. + * @param[in] otherIterator The Iterator that might be copy + * @return reference on the curent Iterator + */ + Iterator& operator=(const Iterator & otherIterator) + { + m_current = otherIterator.m_current; + m_Vector = otherIterator.m_Vector; + return *this; + } + /** + * @brief Basic destructor + */ + ~Iterator() + { + m_current = -1; + m_Vector = NULL; + } + /** + * @brief basic boolean cast + * @return true if the element is present in the Vector size + */ + operator bool () + { + if( 0 <= m_current + && m_current < m_etkVector->Size() ) + { + return true; + } else { + return false; + } + } + /** + * @brief Incremental operator + * @return Reference on the current iterator incremented + */ + Iterator& operator++ () + { + if( NULL != m_etkVector + && m_current < m_etkVector->Size() ) + { + m_current++; + } + return *this; + } + /** + * @brief Decremental operator + * @return Reference on the current iterator decremented + */ + Iterator& operator-- () + { + if (m_current >= 0) { + m_current--; + } + return *this; + } + /** + * @brief Incremental operator + * @return Reference on a new iterator and increment the other one + */ + Iterator operator++ (int32_t) + { + Iterator it(*this); + ++(*this); + return it; + } + /** + * @brief Decremental operator + * @return Reference on a new iterator and decrement the other one + * + */ + Iterator operator-- (int32_t) + { + Iterator it(*this); + --(*this); + return it; + } + /** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ + T * operator-> () const + { + TK_CHECK_INOUT(m_current >= 0 && m_current < m_etkVector->Size()); + return &m_etkVector->Get(m_current); + } + /** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ + T & operator* () const + { + TK_CHECK_INOUT(m_current >= 0 && m_current < m_etkVector->Size()); + return m_etkVector->Get(m_current); + } + private: + /** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ + Iterator(etk::Vector * myVector, int pos): + m_current(pos), + m_Vector(myVector) + { + // nothing to do ... + } + friend class etk::Vector; + }; + + /** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ + Vector(int count = 0): + m_data(NULL), + m_count(0), + m_size(0) + { + Resize(count); + } + + /** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ + Vector(const etk::Vector & myVector): + m_size(myVector.m_size), + m_count(myVector.m_count), + m_data(NULL) + { + int32_t i; + ETK_MALLOC_CAST(m_data, m_size, T, reinterpret_cast); + for(i=0; i & etkVector) + { + int32_t i; + this->~etkVector(); + m_size = etkVector.m_size; + m_count = etkVector.m_count; + TK_MALLOC_CAST(m_data, m_size, T, reinterpret_cast); + for(i=0; i res + || res >= Size()) + { + return -1 + } else { + return res; + } + } + + /** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ + void PushBack(const T& item) + { + int32_t idx = Size(); + Resize(idx+1); + Get(idx) = item; + } + + /** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ + Iterator Get(int pos) + { + return Iterator(this, pos); + } + + /** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ + Iterator Begin() + { + return Get(0); + } + + /** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ + Iterator End() + { + return Get( Size()-1 ); + } + + /** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ + void Resize(int32_t count) + { + int32_t i; + // Reallocate memory + if (count > m_size) { + ChangeAllocation(count); + } + + // Remove deprecated element + for(i=count; i m_size) { + // generate new size + while(count > m_size) { + if (INC) { + m_size = (m_size + INC) + } else if (m_size==0) { + m_size = 1; + } else { + m_size = m_size * 2; + } + } + // Allocate the curent element + T * data = NULL; + ETK_MALLOC_CAST(data, m_size, T, reinterpret_cast); + for(int i=0; i +#include +#include + +#undef __class__ +#define __class__ "etk::VectorType" + +/** + * @brief VectorType classes ... + * + * @tparam[in] SIZE Size of the current element. + * + * m_data + * <------------ m_dataSize ------------> + * ---------------------------------------- + * | 0 | + * |--------------------------------------| + * | 1 | + * |--------------------------------------| + * | 2 | + * |--------------------------------------| + * m_size | 3 | + * |--------------------------------------| + * | x | + * |--------------------------------------| + * | x | + * |--------------------------------------| + * | x | + * |--------------------------------------| + * | x | + * |--------------------------------------| + * | x | + * |--------------------------------------| + * | x | + * |--------------------------------------| + * m_allocated | x | + * ---------------------------------------- + * + */ + +namespace etk +{ + +template class VectorType +{ + public: + class Iterator + { + // Private data : + private: + int32_t m_current; //!< curent Id on the vector + VectorType * m_VectorType; //!< Pointer on the curent element of the vectorBin + public: + /** + * @brief Basic itarator constructor with no link with an etkVector + */ + Iterator(): + m_current(-1), + m_VectorType(NULL) + { + // nothing to do ... + } + /** + * @brief Recopy constructor on a specific etkVector. + * @param[in] otherIterator The Iterator that might be copy + */ + Iterator(const Iterator & otherIterator): + m_current(otherIterator.m_current), + m_VectorType(otherIterator.m_VectorType) + { + // nothing to do ... + } + /** + * @brief Asignation operator. + * @param[in] otherIterator The Iterator that might be copy + * @return reference on the curent Iterator + */ + Iterator& operator=(const Iterator & otherIterator) + { + m_current = otherIterator.m_current; + m_VectorType = otherIterator.m_VectorType; + return *this; + } + /** + * @brief Basic destructor + */ + ~Iterator() + { + m_current = -1; + m_VectorType = NULL; + } + /** + * @brief basic boolean cast + * @return true if the element is present in the etkVector size + */ + operator bool () + { + if( 0 <= m_current + && m_current < m_VectorType->Size() ) + { + return true; + } else { + return false; + } + } + /** + * @brief Incremental operator + * @return Reference on the current iterator incremented + */ + Iterator& operator++ () + { + if( NULL != m_VectorType + && m_current < m_VectorType->Size() ) + { + m_current++; + } + return *this; + } + /** + * @brief Decremental operator + * @return Reference on the current iterator decremented + */ + Iterator& operator-- () + { + if (m_current >= 0) { + m_current--; + } + return *this; + } + /** + * @brief Incremental operator + * @return Reference on a new iterator and increment the other one + */ + Iterator operator++ (int32_t) + { + Iterator it(*this); + ++(*this); + return it; + } + /** + * @brief Decremental operator + * @return Reference on a new iterator and decrement the other one + */ + Iterator operator-- (int32_t) + { + Iterator it(*this); + --(*this); + return it; + } + /** + * @brief Get reference on the current Element + * @return the reference on the current Element + */ + MY_TYPE & operator-> () const + { + TK_CHECK_INOUT(m_current >= 0 && m_current < m_VectorType->Size()); + return &m_VectorType->Get(m_current); + } + /** + * @brief Get reference on the current Element + * @return the reference on the current Element + */ + MY_TYPE & operator* () const + { + TK_CHECK_INOUT(m_current >= 0 && m_current < m_VectorType->Size()); + return m_VectorType->Get(m_current); + } + private: + /** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ + Iterator(VectorType * Evb, int32_t pos): + m_current(pos), + m_VectorType(Evb) + { + // nothing to do ... + } + friend class VectorType; + }; + + private: + MY_TYPE * m_data; //!< pointer on the curetn table of Data + int32_t m_size; //!< nb Element in the buffer + int32_t m_allocated; //!< Current allocated size + int32_t m_increment; //!< methode of increment + public: + /** + * @brief Create an empty vector + * @param[in] count Minimum request size of the Buffer + */ + VectorType(int32_t count = 0): + m_data(NULL), + m_size(0), + m_allocated(0), + m_increment(1) + { + ChangeAllocation(count); + } + + /** + * @brief Re-copy constructor (copy all needed data) + * @param[in] Evb Vector that might be copy + */ + VectorType(const etk::VectorType & Evb) + { + m_allocated = Evb.m_allocated; + m_size = Evb.m_size; + m_increment = Evb.m_increment; + m_data = NULL; + //TK_DEBUG("USE Specific vector allocator ... Evb.m_size=" << Evb.m_size << " Evb.m_increment=" << Evb.m_increment); + // allocate all same data + ETK_MALLOC(m_data, m_allocated, MY_TYPE); + TK_ASSERT(NULL!=m_data, "Error in data allocation"); + // Copy all data ... + memcpy(m_data, Evb.m_data, m_allocated * sizeof(MY_TYPE) ); + } + + /** + * @brief Destructor of the current Class + */ + ~VectorType() + { + if (NULL!=m_data) { + ETK_FREE(m_data); + m_data = NULL; + m_allocated = 0; + m_size = 0; + m_increment = 0; + } + } + + /** + * @brief Re-copy operator + * @param[in] Evb Vector that might be copy + * @return reference on the curent re-copy vector + */ + VectorType& operator=(const etk::VectorType & Evb) + { + //TK_DEBUG("USE RECOPY vector ... Evb.m_size=" << Evb.m_size << " Evb.m_increment=" << Evb.m_increment); + if( this != &Evb ) // avoid copy to itself + { + if (NULL!=m_data) { + ETK_FREE(m_data); + m_data = NULL; + } + // Set the new value + m_allocated = Evb.m_allocated; + m_size = Evb.m_size; + m_increment = Evb.m_increment; + // allocate all same data + ETK_MALLOC(m_data, m_allocated, MY_TYPE); + TK_ASSERT(NULL!=m_data, "Error in data allocation"); + // Copy all data ... + memcpy(m_data, Evb.m_data, m_allocated * sizeof(MY_TYPE) ); + } + // Return the curent pointer + return *this; + } + + /** + * @brief Add at the Last position of the Vector + * @param[in] item Element to add at the end of vector + */ + VectorType& operator+= (const etk::VectorType & Evb) // += operator + { + int32_t nbElememt = Evb.Size(); + int32_t idx = m_size; + Resize(m_size+nbElememt); + memcpy(&m_data[idx], &Evb.m_data[0], nbElememt*sizeof(MY_TYPE) ); + // Return the curent pointer + return *this; + } + + /** + * @brief Set increment mode of this vector (default it match corectly with the number of element inside) + * @param[in] newIncrementNumber methode requested + */ + void SetIncrement(int32_t newIncrementNumber) + { + m_increment = newIncrementNumber; + } + + /** + * @brief Get the number of element in the vector + * @return The number requested + */ + int32_t Size() const + { + return m_size; + } + + /** + * @brief Get the Allocated size in the vector + * @return The size of allocation + */ + int32_t AllocatedSize() const + { + return m_allocated; + } + + /** + * @brief Get a current element in the vector + * @param[in] pos Desired position read + * @return Reference on the Element + */ + MY_TYPE& Get(int32_t pos) + { + return m_data[pos]; + } + + /** + * @brief Get an copy Element an a special position + * @param[in] pos Position in the vector that might be get [0..Size()] + * @return An reference on the copy of selected element + */ + MY_TYPE& operator[] (int32_t pos) + { + return Get(pos); + } + + /** + * @brief Get an Element an a special position + * @param[in] pos Position in the vector that might be get [0..Size()] + * @return An reference on the selected element + */ + const MY_TYPE& operator[] (int32_t pos) const + { + return m_data[pos]; + } + + /** + * @brief Add at the Last position of the Vector + * @param[in] item Element to add at the end of vector + */ + void PushBack(const MY_TYPE& item) + { + int32_t idx = m_size; + Resize(m_size+1); + m_data[idx] = item; + } + + /** + * @brief Add at the Last position of the Vector + * @param[in] item Element to add at the end of vector + */ + void PushBack(const MY_TYPE * item, int32_t nbElement) + { + if (NULL == item) { + return; + } + int32_t idx = m_size; + Resize(m_size+nbElement); + memcpy(&m_data[idx], item, nbElement*sizeof(MY_TYPE) ); + } + + /** + * @brief Remove the last element of the vector + */ + void PopBack(void) + { + if(m_size>0) { + Resize(m_size-1); + } + } + + /** + * @brief Remove all alement in the current vector + */ + void Clear(void) + { + if(m_size>0) { + Resize(0); + } + } + + /** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ + void Insert(int32_t pos, const MY_TYPE& item) + { + if (pos>m_size) { + TK_ERROR(" can not insert Element at this position : " << pos << " > " << m_size<< " add it at the end ... "); + PushBack(item); + return; + } + int32_t tmpSize = m_size; + // Request resize of the current buffer + Resize(m_size+1); + // move curent data + memmove((m_data + pos + 1), (m_data + pos), (tmpSize - pos)*sizeof(MY_TYPE) ); + // affectation of the current element + m_data[pos] = item; + } + + /** + * @brief + * + * @param[in,out] --- + * + * @return --- + * + */ + void Insert(int32_t pos, const MY_TYPE * item, int32_t nbElement) + { + if (pos>m_size) { + TK_WARNING(" can not insert Element at this position : " << pos << " > " << m_size << " add it at the end ... "); + PushBack(item, nbElement); + return; + } + int32_t tmpSize = m_size; + // Request resize of the current buffer + Resize(m_size+nbElement); + // move curent data (after the position) + memmove((m_data + pos + nbElement), (m_data + pos), (tmpSize - pos)*sizeof(MY_TYPE) ); + // affectation of all input element + memcpy(&m_data[pos], item, nbElement*sizeof(MY_TYPE) ); + } + + /** + * @brief Remove one element + * + * @param[in] pos Position to remove the data + * + * @return --- + * + */ + void Erase(int32_t pos) + { + if (pos>m_size) { + TK_ERROR(" can not Erase Element at this position : " << pos << " > " << m_size); + return; + } + int32_t tmpSize = m_size; + // move curent data + memmove((m_data + pos), (m_data + pos + 1), (tmpSize - (pos+1))*sizeof(MY_TYPE) ); + // Request resize of the current buffer + Resize(m_size-1); + } + + /** + * @brief Remove N elements + * + * @param[in] pos Position to remove the data + * @param[in] posEnd Last position number + * + * @return --- + * + */ + void Erase(int32_t pos, int32_t posEnd) + { + if (pos>m_size) { + TK_ERROR(" can not Erase Element at this position : " << pos << " > " << m_size); + return; + } + if (posEnd>m_size) { + posEnd = m_size; + } + int32_t nbElement = m_size - pos; + int32_t tmpSize = m_size; + // move curent data + memmove((m_data + pos), (m_data + pos + nbElement), (tmpSize - (pos+nbElement))*sizeof(MY_TYPE) ); + // Request resize of the current buffer + Resize(m_size-nbElement); + } + + /** + * @brief Remove N element + * + * @param[in] pos Position to remove the data + * @param[in] nbElement number of element to remove + * + * @return --- + * + */ + void EraseLen(int32_t pos, int32_t nbElement) + { + if (pos>m_size) { + TK_ERROR(" can not Erase Len Element at this position : " << pos << " > " << m_size); + return; + } + if (pos+nbElement>m_size) { + nbElement = m_size - pos; + } + int32_t tmpSize = m_size; + // move curent data + memmove((m_data + pos), (m_data + pos + nbElement), (tmpSize - (pos+nbElement))*sizeof(MY_TYPE) ); + // Request resize of the current buffer + Resize(m_size-nbElement); + } + + /** + * @brief extract data between two point : + * @param[in] posStart start position to extract data + * @param[in] posEnd End position to extract data + * @return the extracted vector + */ + VectorType Extract(int32_t posStart = 0, int32_t posEnd=0x7FFFFFFF) + { + VectorType out; + if (posStart < 0) { + posStart = 0; + } else if (posStart >= Size() ) { + return out; + } + if (posEnd < 0) { + return out; + } else if (posEnd >= Size() ) { + posEnd = Size(); + } + out.PushBack(&m_data[posStart], posEnd-posStart); + return out; + } + + /** + * @brief Set the minimum allocation in memory for the curent vector ==> reallocate the + * buffer to fit exactly the mumber of element needed + */ + void Fit(void) + { + if (m_size > m_allocated) { + // Reallocate the curent data to the correct size ... + ETK_REALLOC(m_data, m_size, MY_TYPE); + } + // Check result with assert : + TK_ASSERT(NULL!=m_data, "Error in data Fitting"); + m_allocated = m_size; + } + + /** + * @brief Get an iterator an an specific position + * @param[in] pos Requested position of the iterator in the vector + * @return The Iterator + */ + Iterator Position(int32_t pos) + { + return Iterator(this, pos); + } + + /** + * @brief Get an Iterator on the start position of the Vector + * @return The Iterator + */ + Iterator Begin(void) + { + return Position(0); + } + + /** + * @brief Get an Iterator on the end position of the Vector + * @return The Iterator + */ + Iterator End(void) + { + return Position( Size()-1 ); + } + + private: + /** + * @brief Change the current size of the vector + * @param[in] newSize New requested size of element in the vector + */ + void Resize(int32_t newSize) + { + // Reallocate memory + if (newSize > m_allocated) { + ChangeAllocation(newSize); + } + m_size = newSize; + } + + /** + * @brief Change the current allocation to the corect one (depend on the current size) + * @param[in] newSize Minimum number of element needed + */ + void ChangeAllocation(int32_t newSize) + { + // set the minimal size to 1 + if(newSize <= 0) { + newSize = 1; + } + int32_t requestSize = m_allocated; + // set the size with the corect chose type : + if (newSize == m_allocated) { + return; + } else if (newSize < requestSize) { + // down the size of the vector: + if (0==m_increment) { + // never down size... + } else { + int32_t devide = m_increment; + if (devide == 0) { + devide = 1; + } + int32_t numberOfStep = m_allocated / devide; + if (newSize< ((numberOfStep-2)*devide + devide/2) ) { + //Allow Reallocation of a new size shoerter + requestSize = ((newSize / devide)+1) * devide; + } + } + } else { + while(newSize > requestSize) { + if (0 == requestSize) { + requestSize = 1; + } else if (0==m_increment) { + requestSize = requestSize * 2; + } else { + requestSize = (requestSize + m_increment); + } + } + } + // No reallocation needed : + if (requestSize == m_allocated) { + return; + } + // check if something is allocated : + if (NULL == m_data) { + // no data allocated ==> request an allocation (might be the first) + ETK_MALLOC(m_data, requestSize, MY_TYPE); + } else { + // move datas + ETK_REALLOC(m_data, requestSize, MY_TYPE); + } + // Check result with assert : + TK_ASSERT(NULL!=m_data, "Error in data allocation"); + // set the new allocation size + m_allocated = requestSize; + } +}; +} + +#undef __class__ +#define __class__ NULL + +#endif + diff --git a/Sources/ewolDebug.cpp b/Sources/ewolDebug.cpp new file mode 100644 index 00000000..9a6349c3 --- /dev/null +++ b/Sources/ewolDebug.cpp @@ -0,0 +1,28 @@ +/** + ******************************************************************************* + * @file ewolDebug.h + * @brief Ewol : log wrapper (Sources) + * @author Edouard DUPIN + * @date 19/10/2010 + * @par Project + * Ewol + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + + +#include + +const char * ewolLibName = "ewol "; diff --git a/Sources/ewolDebug.h b/Sources/ewolDebug.h new file mode 100644 index 00000000..aaaaabc5 --- /dev/null +++ b/Sources/ewolDebug.h @@ -0,0 +1,66 @@ +/** + ******************************************************************************* + * @file ewolDebug.h + * @brief Ewol : log wrapper (header) + * @author Edouard DUPIN + * @date 19/10/2010 + * @par Project + * Ewol + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + +#ifndef __ETK_DEBUG_INTERNAL_H__ +#define __ETK_DEBUG_INTERNAL_H__ + +#include +#include + +extern const char * ewolLibName; + +#define EWOL_CRITICAL(data) ETK_CRITICAL(ewolLibName, data) +// General +#if EWOL_DEBUG_LEVEL > 0 +# define EWOL_WARNING(data) ETK_WARNING(ewolLibName, data) +# define EWOL_ERROR(data) ETK_ERROR(ewolLibName, data) +#else +# define EWOL_WARNING(data) do {}while(0) +# define EWOL_ERROR(data) do {}while(0) +#endif + +#if EWOL_DEBUG_LEVEL > 1 +# define EWOL_INFO(data) ETK_INFO(ewolLibName, data) +#else +# define EWOL_INFO(data) do {}while(0) +#endif + +#if EWOL_DEBUG_LEVEL > 2 +# define EWOL_DEBUG(data) ETK_DEBUG(ewolLibName, data) +#else +# define EWOL_DEBUG(data) do {}while(0) +#endif + +#define EWOL_ASSERT(cond, data) ETK_ASSERT(ewolLibName, cond, data) + +#if EWOL_DEBUG_LEVEL > 1 +# define EWOL_CHECK_INOUT(cond) ETK_CHECK_INOUT_ASSERT(ewolLibName, cond) +#elif EWOL_DEBUG_LEVEL > 0 +# define EWOL_CHECK_INOUT(cond) ETK_CHECK_INOUT_WARNING(ewolLibName, cond) +#else +# define EWOL_CHECK_INOUT(cond) do { } while (0) +#endif + +#endif + diff --git a/Sources/ewolWidget.cpp b/Sources/ewolWidget.cpp index 5ecc075e..c138d2e5 100644 --- a/Sources/ewolWidget.cpp +++ b/Sources/ewolWidget.cpp @@ -22,15 +22,19 @@ ******************************************************************************* */ -#include "ewolWidget.h" +#include ewol::Widget::Widget(void) { - m_origin = {0.0, 0.0}; - m_minSize = {-1.0, -1.0}; - m_size = {10.0, 10.0}; - m_maxSize = {-1.0, -1.0}; + m_origin.x = 0.0; + m_origin.y = 0.0; + m_minSize.x = -1.0; + m_minSize.y = -1.0; + m_size.x = 10.0; + m_size.y = 10.0; + m_maxSize.x = -1.0; + m_maxSize.y = -1.0; m_expendX = false; m_expendY = false; } @@ -91,3 +95,7 @@ bool ewol::Widget::GenericDraw(void) return true; } + +//} // ??? + + diff --git a/Sources/ewolWidget.h b/Sources/ewolWidget.h index 2ac6e828..bdcf0a0c 100644 --- a/Sources/ewolWidget.h +++ b/Sources/ewolWidget.h @@ -22,6 +22,9 @@ ******************************************************************************* */ +#include +#include +#include #ifndef __EWOL_WIDGET_H__ #define __EWOL_WIDGET_H__ @@ -32,54 +35,32 @@ namespace ewol { double x; double y; } coord; - + } typedef enum { - EVENT_INPUT_TYPE_DOWN; - EVENT_INPUT_TYPE_DOUBLE; - EVENT_INPUT_TYPE_TRIPLE; - EVENT_INPUT_TYPE_MOVE; - EVENT_INPUT_TYPE_UP; + EVENT_INPUT_TYPE_DOWN, + EVENT_INPUT_TYPE_DOUBLE, + EVENT_INPUT_TYPE_TRIPLE, + EVENT_INPUT_TYPE_MOVE, + EVENT_INPUT_TYPE_UP, } eventInputType_te; typedef enum { - EVENT_KB_TYPE_DOWN; - EVENT_KB_TYPE_UP; + EVENT_KB_TYPE_DOWN, + EVENT_KB_TYPE_UP, } eventKbType_te; typedef enum { - EVENT_KB_MOVE_TYPE_LEFT; - EVENT_KB_MOVE_TYPE_RIGHT; - EVENT_KB_MOVE_TYPE_UP; - EVENT_KB_MOVE_TYPE_DOWN; - EVENT_KB_MOVE_TYPE_PAGE_UP; - EVENT_KB_MOVE_TYPE_PAGE_DOWN; - EVENT_KB_MOVE_TYPE_START; - EVENT_KB_MOVE_TYPE_END; + EVENT_KB_MOVE_TYPE_LEFT, + EVENT_KB_MOVE_TYPE_RIGHT, + EVENT_KB_MOVE_TYPE_UP, + EVENT_KB_MOVE_TYPE_DOWN, + EVENT_KB_MOVE_TYPE_PAGE_UP, + EVENT_KB_MOVE_TYPE_PAGE_DOWN, + EVENT_KB_MOVE_TYPE_START, + EVENT_KB_MOVE_TYPE_END, } eventKbMoveType_te; - #define UTF8_MAX_SIZE (8) - /* - extern "C" { - typedef struct { - bool shift; - bool control; - bool alt; - bool pomme; - char UTF8_data[UTF8_MAX_SIZE]; - const char * generateEventId; // event generate ID (to be unique it was pointer on the string name) - int32_t widgetCall; //!< unique ID of the widget - } shortCut_ts; - } - extern "C" { - typedef struct { - coord origin; // widget specific - coord size; // widget specific - uint32_t flags; // widget specific - const char * generateEventId; // event generate ID (to be unique it was pointer on the string name) - int32_t widgetCall; //!< unique ID of the widget - } eventArea_ts; - } - */ + #define UTF8_MAX_SIZE (8) #define EWOL_EVENT_UNION (0) #define EWOL_EVENT_SHORTCUT (1) extern "C" { @@ -88,20 +69,21 @@ namespace ewol { int32_t widgetCall; //!< unique ID of the widget int32_t mode; //!< EWOL_EVENT_UNION or EWOL_EVENT_SHORTCUT union { - struct shortCut{ + struct { bool shift; bool control; bool alt; bool pomme; char UTF8_data[UTF8_MAX_SIZE]; - }; - struct Area{ + } shortCut; + struct { coord origin; // widget specific coord size; // widget specific uint32_t flags; // widget specific - }; + } area; + }; } event_ts; - } + }; class Widget; @@ -111,7 +93,7 @@ namespace ewol { virtual ~Widget(void); private: int32_t m_uniqueId; //!< UniqueId to identify the widget unicly - public; + public: int32_t GetUniqueId(void) { return m_uniqueId; }; private: @@ -134,12 +116,12 @@ namespace ewol { void SetMinSise(double x=-1, double y=-1) { m_minSize.x = x; m_minSize.y = y; }; void SetMaxSise(double x=-1, double y=-1) { m_maxSize.x = x; m_maxSize.y = y; }; void SetCurrentSise(double x=-1, double y=-1) { m_size.x = x; m_size.y = y; }; - public + public: void SetOrigin(double x, double y) { m_origin.x=x; m_origin.y=y; }; virtual bool CalculateSize(double availlableX, double availlableY); // this generate the current size ... - coord GetMinSize(void) { return m_minSize }; - coord GetMaxSize(void) { return m_maxSize }; - coord GetCurrentSize(void) { return m_size }; + coord GetMinSize(void) { return m_minSize; }; + coord GetMaxSize(void) { return m_maxSize; }; + coord GetCurrentSize(void) { return m_size; }; // ---------------------------------------------------------------------------------------------------------------- // -- Focus Area @@ -184,7 +166,7 @@ namespace ewol { // -- Shortcut: (only for computer) ==> must be manage otherwise for tablette pc // ---------------------------------------------------------------------------------------------------------------- private: - estd::VectorType m_inputEvent; //!< generic area and short-cut event + etk::VectorType m_inputEvent; //!< generic area and short-cut event public: // external acces to set an input event on this widget. bool GenEventInput(int32_t IdInput, eventInputType_te typeEvent, double X, double Y); // call when input event arrive and call OnEventInput, if no event detected @@ -232,9 +214,9 @@ namespace ewol { } else { return OnDraw(); } - } - - } -}; + }; + + }; // end of the class Widget declaration +};// end of nameSpace #endif