2011-07-20 10:33:24 +02:00
/**
* @ author Edouard DUPIN
2012-11-25 11:55:06 +01:00
*
* @ copyright 2010 , Edouard DUPIN , all right reserved
*
* @ license GPL v3 ( see license file )
2011-07-20 10:33:24 +02:00
*/
2013-10-25 20:49:26 +02:00
# include <appl/debug.h>
2012-04-24 09:42:14 +02:00
# include <appl/global.h>
2013-11-23 18:30:52 +01:00
# include <appl/Highlight.h>
2013-06-26 23:48:23 +02:00
# include <exml/exml.h>
2014-10-06 23:22:14 +02:00
# include <ewol/ewol.h>
2015-08-11 23:21:41 +02:00
# include <gale/resource/Manager.h>
2011-07-20 10:33:24 +02:00
# undef __class__
2013-10-25 22:12:34 +02:00
# define __class__ "Highlight"
2011-07-20 10:33:24 +02:00
2013-12-05 22:16:04 +01:00
// first pass
//#define HL_DEBUG APPL_INFO
# define HL_DEBUG APPL_VERBOSE
// second pass
//#define HL2_DEBUG APPL_INFO
# define HL2_DEBUG APPL_VERBOSE
2011-07-20 10:33:24 +02:00
2014-08-07 23:41:48 +02:00
appl : : Highlight : : Highlight ( ) {
2015-08-11 23:21:41 +02:00
addResourceType ( " appl::Highlight " ) ;
2014-08-07 23:41:48 +02:00
}
void appl : : Highlight : : init ( const std : : string & _xmlFilename , const std : : string & _colorFile ) {
2015-08-11 23:21:41 +02:00
gale : : Resource : : init ( _xmlFilename ) ;
2014-08-07 23:41:48 +02:00
2013-10-25 22:12:34 +02:00
// keep color propertiy file :
2014-08-07 23:41:48 +02:00
m_paintingProperties = appl : : GlyphPainting : : create ( _colorFile ) ;
2013-10-25 22:12:34 +02:00
2013-06-24 21:17:45 +02:00
exml : : Document doc ;
2013-10-07 22:04:21 +02:00
if ( doc . load ( _xmlFilename ) = = false ) {
2013-06-26 23:48:23 +02:00
APPL_ERROR ( " can not load file XML : " < < _xmlFilename ) ;
return ;
2012-01-31 18:26:04 +01:00
}
2015-01-14 21:10:23 +01:00
std : : shared_ptr < exml : : Element > root = doc . getNamed ( " EdnLang " ) ;
if ( root = = nullptr ) {
2013-06-26 23:48:23 +02:00
APPL_ERROR ( " (l ?) main node not find: \" EdnLang \" ... " ) ;
return ;
2011-07-20 10:33:24 +02:00
}
2013-10-27 11:34:45 +01:00
m_typeName = root - > getAttribute ( " lang " ) ;
2011-07-20 10:33:24 +02:00
int32_t level1 = 0 ;
int32_t level2 = 0 ;
2013-06-24 21:17:45 +02:00
// parse all the elements :
2014-06-02 21:04:35 +02:00
for ( size_t iii = 0 ; iii < root - > size ( ) ; + + iii ) {
2015-01-14 21:10:23 +01:00
std : : shared_ptr < exml : : Element > child = root - > getElement ( iii ) ;
2014-06-05 22:01:24 +02:00
if ( child = = nullptr ) {
2013-06-26 23:48:23 +02:00
// trash here all that is not element ...
2013-06-24 21:17:45 +02:00
continue ;
}
2013-10-07 22:04:21 +02:00
if ( child - > getValue ( ) = = " ext " ) {
2013-11-14 21:57:10 +01:00
std : : string myData = child - > getText ( ) ;
2013-10-07 22:04:21 +02:00
if ( myData . size ( ) ! = 0 ) {
2013-12-05 22:16:04 +01:00
//HL_DEBUG("(l %d) node fined : %s=\"%s\"", child->Row(), child->Value() , myData);
2013-11-14 21:57:10 +01:00
m_listExtentions . push_back ( myData ) ;
2011-07-20 10:33:24 +02:00
}
2013-10-07 22:04:21 +02:00
} else if ( child - > getValue ( ) = = " pass1 " ) {
// get sub Nodes ...
2014-06-02 21:04:35 +02:00
for ( size_t jjj = 0 ; jjj < child - > size ( ) ; jjj + + ) {
2015-01-14 21:10:23 +01:00
std : : shared_ptr < exml : : Element > passChild = child - > getElement ( jjj ) ;
2014-06-05 22:01:24 +02:00
if ( passChild = = nullptr ) {
2013-06-24 21:17:45 +02:00
continue ;
2011-07-20 10:33:24 +02:00
}
2013-10-07 22:04:21 +02:00
if ( passChild - > getValue ( ) ! = " rule " ) {
2013-10-09 22:00:24 +02:00
APPL_ERROR ( " (l " < < passChild - > getPos ( ) < < " ) node not suported : \" " < < passChild - > getValue ( ) < < " \" must be [rule] " ) ;
2013-06-24 21:17:45 +02:00
continue ;
}
2014-10-13 22:39:49 +02:00
// Create the patern in list
m_listHighlightPass1 . push_back ( HighlightPattern ( m_paintingProperties , passChild , level1 + + ) ) ;
2011-07-20 10:33:24 +02:00
}
2013-10-07 22:04:21 +02:00
} else if ( child - > getValue ( ) = = " pass2 " ) {
// get sub Nodes ...
2014-06-02 21:04:35 +02:00
for ( size_t jjj = 0 ; jjj < child - > size ( ) ; jjj + + ) {
2015-01-14 21:10:23 +01:00
std : : shared_ptr < exml : : Element > passChild = child - > getElement ( jjj ) ;
2014-06-05 22:01:24 +02:00
if ( passChild = = nullptr ) {
2013-06-24 21:17:45 +02:00
continue ;
}
2013-10-07 22:04:21 +02:00
if ( passChild - > getValue ( ) ! = " rule " ) {
2013-10-09 22:00:24 +02:00
APPL_ERROR ( " (l " < < passChild - > getPos ( ) < < " ) node not suported : \" " < < passChild - > getValue ( ) < < " \" must be [rule] " ) ;
2013-06-24 21:17:45 +02:00
continue ;
2011-07-20 10:33:24 +02:00
}
2014-10-13 22:39:49 +02:00
// Create the patern in list
m_listHighlightPass2 . push_back ( HighlightPattern ( m_paintingProperties , passChild , level2 + + ) ) ;
}
} else if ( child - > getValue ( ) = = " pass " ) {
std : : string attributeName = child - > getAttribute ( " name " ) ;
if ( attributeName = = " " ) {
APPL_ERROR ( " Can not parse an element pass with no attribute name ... ligne= " < < child - > getPos ( ) ) ;
continue ;
}
m_listHighlightNamed . insert ( std : : pair < std : : string , std : : vector < HighlightPattern > > ( attributeName , std : : vector < HighlightPattern > ( ) ) ) ;
auto it = m_listHighlightNamed . find ( attributeName ) ;
int32_t level3 = 0 ;
// get sub Nodes ...
for ( size_t jjj = 0 ; jjj < child - > size ( ) ; jjj + + ) {
2015-01-14 21:10:23 +01:00
std : : shared_ptr < exml : : Element > passChild = child - > getElement ( jjj ) ;
2014-10-13 22:39:49 +02:00
if ( passChild = = nullptr ) {
continue ;
}
if ( passChild - > getValue ( ) ! = " rule " ) {
APPL_ERROR ( " (l " < < passChild - > getPos ( ) < < " ) node not suported : \" " < < passChild - > getValue ( ) < < " \" must be [rule] " ) ;
continue ;
}
// add element in the list
it - > second . push_back ( HighlightPattern ( m_paintingProperties , passChild , level3 + + ) ) ;
2011-07-20 10:33:24 +02:00
}
} else {
2013-10-09 22:00:24 +02:00
APPL_ERROR ( " (l " < < child - > getPos ( ) < < " ) node not suported : \" " < < child - > getValue ( ) < < " \" must be [ext,pass1,pass2] " ) ;
2011-07-20 10:33:24 +02:00
}
2012-01-31 18:26:04 +01:00
}
2011-07-20 10:33:24 +02:00
}
2014-05-15 21:37:39 +02:00
appl : : Highlight : : ~ Highlight ( ) {
2011-08-08 14:06:11 +02:00
// clear the compleate list
2013-10-07 22:04:21 +02:00
m_listHighlightPass1 . clear ( ) ;
2011-07-20 10:33:24 +02:00
// clear the compleate list
2014-05-27 21:43:02 +02:00
m_listHighlightPass2 . clear ( ) ;
// clear the compleate list
2013-10-07 22:04:21 +02:00
m_listExtentions . clear ( ) ;
2011-07-20 10:33:24 +02:00
}
2014-10-09 21:23:19 +02:00
bool appl : : Highlight : : isCompatible ( const std : : string & _name ) {
2014-06-02 21:04:35 +02:00
for ( auto & it : m_listExtentions ) {
2014-10-09 21:23:19 +02:00
APPL_VERBOSE ( " check : " < < it < < " =?= " < < _name ) ;
std : : regex expression ;
try {
expression . assign ( it , std : : regex_constants : : optimize | std : : regex_constants : : ECMAScript ) ;
} catch ( std : : regex_error e ) {
APPL_ERROR ( " can not parse regex : ' " < < e . what ( ) < < " ' for : " < < it ) ;
continue ;
}
std : : smatch resultMatch ;
std : : regex_search ( _name . begin ( ) , _name . end ( ) , resultMatch , expression , std : : regex_constants : : match_continuous ) ;
if ( resultMatch . size ( ) < = 0 ) {
continue ;
}
if ( resultMatch [ 0 ] . first ! = _name . begin ( ) ) {
continue ;
}
if ( resultMatch [ 0 ] . second ! = _name . end ( ) ) {
continue ;
2011-07-20 10:33:24 +02:00
}
2014-10-09 21:23:19 +02:00
return true ;
2011-07-20 10:33:24 +02:00
}
return false ;
}
2013-11-14 21:57:10 +01:00
bool appl : : Highlight : : fileNameCompatible ( const std : : string & _fileName ) {
std : : string extention ;
2013-10-25 22:12:34 +02:00
etk : : FSNode file ( _fileName ) ;
if ( true = = file . fileHasExtention ( ) ) {
2011-08-07 10:47:06 +02:00
extention = " *. " ;
2013-10-25 22:12:34 +02:00
extention + = file . fileGetExtention ( ) ;
2011-07-20 10:33:24 +02:00
} else {
2013-10-25 22:12:34 +02:00
extention = file . getNameFile ( ) ;
2011-07-20 10:33:24 +02:00
}
2013-10-25 22:12:34 +02:00
APPL_DEBUG ( " try to find : in \" " < < file < < " \" extention: \" " < < extention < < " \" " ) ;
2011-07-20 10:33:24 +02:00
2014-06-02 21:04:35 +02:00
for ( auto & it : m_listExtentions ) {
if ( extention = = it ) {
2011-07-20 10:33:24 +02:00
return true ;
}
}
return false ;
}
2014-05-15 21:37:39 +02:00
void appl : : Highlight : : display ( ) {
2012-04-23 10:15:43 +02:00
APPL_INFO ( " List of ALL Highlight : " ) ;
2014-06-02 21:04:35 +02:00
for ( auto & it : m_listExtentions ) {
APPL_INFO ( " Extention : " < < it ) ;
2011-07-20 10:33:24 +02:00
}
2013-10-07 22:04:21 +02:00
// display all elements
2014-06-02 21:04:35 +02:00
for ( auto & it : m_listHighlightPass1 ) {
2014-10-13 22:39:49 +02:00
APPL_INFO ( " Pass 1 : " < < it . getName ( ) ) ;
//it.display();
2011-07-20 10:33:24 +02:00
}
2014-06-02 21:04:35 +02:00
for ( auto & it : m_listHighlightPass2 ) {
2014-10-13 22:39:49 +02:00
APPL_INFO ( " pass 2 : " < < it . getName ( ) ) ;
//it.display();
}
for ( auto & it : m_listHighlightNamed ) {
APPL_INFO ( " pass * : " < < it . first < < " : " ) ;
for ( auto & it2 : it . second ) {
APPL_INFO ( " " < < it2 . getName ( ) ) ;
//it.display();
}
//it.display();
2011-07-20 10:33:24 +02:00
}
}
2013-11-20 21:57:00 +01:00
/* TODO : Celui qui appelle suprime des element pour rien ... Enfin c'est pas très grave...
* Il suffirait juste de suprimer celui d ' avant si il n ' est pas terminer . . .
2013-10-25 22:12:34 +02:00
*/
2013-12-05 22:16:04 +01:00
void appl : : Highlight : : parse ( int64_t _start ,
int64_t _stop ,
std : : vector < appl : : HighlightInfo > & _metaData ,
int64_t _addingPos ,
2014-10-05 23:46:57 +02:00
std : : string & _buffer ) {
2013-12-05 22:16:04 +01:00
if ( 0 > _addingPos ) {
_addingPos = 0 ;
2011-07-20 10:33:24 +02:00
}
2013-12-05 22:16:04 +01:00
HL_DEBUG ( " Parse element 0 => " < < m_listHighlightPass1 . size ( ) < < " == > position search: ( " < < _start < < " , " < < _stop < < " ) " ) ;
int64_t elementStart = _start ;
int64_t elementStop = _stop ;
2013-10-27 11:34:45 +01:00
appl : : HighlightInfo resultat ;
2014-10-06 23:22:14 +02:00
int64_t startTime = ewol : : getTime ( ) ;
2013-12-05 22:16:04 +01:00
while ( elementStart < = elementStop ) {
2014-10-08 21:32:41 +02:00
//HL_DEBUG("Parse element in the buffer pos=" << elementStart);
2014-10-06 23:22:14 +02:00
int64_t currentTime = ewol : : getTime ( ) ;
2011-08-08 10:24:24 +02:00
//try to fond the HL in ALL of we have
2014-06-02 21:04:35 +02:00
for ( int64_t jjj = 0 ; jjj < ( int64_t ) m_listHighlightPass1 . size ( ) ; jjj + + ) {
2016-01-15 00:01:58 +01:00
bool ret = true ;
2014-10-06 23:22:14 +02:00
/*
if ( _buffer [ elementStart ] = = ' \n ' ) {
2014-10-13 22:39:49 +02:00
HL_DEBUG ( " Parse HL id= " < < jjj < < " position search: ( " < < elementStart < < " , " < < _stop < < " ) input start=' \\ n' " < < m_listHighlightPass1 [ jjj ] . getPaternString ( ) ) ;
2014-10-06 23:22:14 +02:00
} else {
2014-10-13 22:39:49 +02:00
HL_DEBUG ( " Parse HL id= " < < jjj < < " position search: ( " < < elementStart < < " , " < < _stop < < " ) input start=' " < < _buffer [ elementStart ] < < " ' " < < m_listHighlightPass1 [ jjj ] . getPaternString ( ) ) ;
2014-10-06 23:22:14 +02:00
}
*/
2011-08-08 10:24:24 +02:00
// Stop the search to the end (to get the end of the pattern)
2014-10-13 22:39:49 +02:00
ret = m_listHighlightPass1 [ jjj ] . find ( elementStart , _buffer . size ( ) , resultat , _buffer ) ;
2016-01-15 00:01:58 +01:00
if ( ret = = true ) {
2014-10-08 21:32:41 +02:00
int64_t currentTimeEnd = ewol : : getTime ( ) ;
int64_t deltaTime = currentTimeEnd - currentTime ;
2014-10-13 22:39:49 +02:00
HL_DEBUG ( " Find Pattern in the Buffer : time= " < < ( float ) deltaTime / 1000.0f < < " ms ( " < < resultat . start < < " , " < < resultat . stop < < " ) startPos= " < < elementStart < < " for= " < < m_listHighlightPass1 [ jjj ] . getPaternString ( ) ) ;
2014-10-08 21:32:41 +02:00
// remove element in the current List where the current Element have a end inside the next...
int64_t kkk = _addingPos ;
while ( kkk < ( int64_t ) _metaData . size ( ) ) {
if ( _metaData [ kkk ] . start < = resultat . stop ) {
// remove element
HL_DEBUG ( " Erase element= " < < kkk ) ;
_metaData . erase ( _metaData . begin ( ) + kkk , _metaData . begin ( ) + kkk + 1 ) ;
// Increase the end of search
if ( kkk < ( int64_t ) _metaData . size ( ) ) {
// just before the end of the next element
elementStop = _metaData [ kkk ] . start - 1 ;
} else {
// end of the buffer
elementStop = _buffer . size ( ) ;
}
2011-07-20 10:33:24 +02:00
} else {
2014-10-08 21:32:41 +02:00
// Not find == > exit the cycle :
break ;
2011-07-20 10:33:24 +02:00
}
}
2014-10-08 21:32:41 +02:00
// add curent element in the list ...
_metaData . insert ( _metaData . begin ( ) + _addingPos , resultat ) ;
HL_DEBUG ( " INSERT at " < < _addingPos < < " S= " < < resultat . start < < " E= " < < resultat . stop ) ;
// update the current research starting element: (set position at the end of the current element
elementStart = resultat . stop - 1 ;
// increment the position of insertion:
_addingPos + + ;
// We find a pattern == > Stop search for the current element
break ;
2011-07-20 10:33:24 +02:00
}
}
2011-08-08 10:24:24 +02:00
// Go to the next element (and search again ...).
elementStart + + ;
2011-07-20 10:33:24 +02:00
}
2014-10-06 23:22:14 +02:00
int64_t stopTime = ewol : : getTime ( ) ;
int64_t deltaTimeGlobal = stopTime - startTime ;
APPL_DEBUG ( " parse in time= " < < ( float ) deltaTimeGlobal / 1000.0f < < " ms " ) ;
2011-07-20 10:33:24 +02:00
}
2011-08-08 10:24:24 +02:00
2011-07-20 10:33:24 +02:00
/**
* @ brief second pass of the hightlight
2014-10-13 22:39:49 +02:00
* @ param [ in ] _start Start searching data
* @ param [ in ] _stop End searching data
* @ param [ out ] _metaData Output list of all find patern
* @ param [ in ] _buffer buffer where we need to search data
2011-07-20 10:33:24 +02:00
*/
2013-12-05 22:16:04 +01:00
void appl : : Highlight : : parse2 ( int64_t _start ,
int64_t _stop ,
2016-01-15 00:01:58 +01:00
std : : vector < appl : : HighlightInfo > & _metaData ,
std : : string & _buffer ) {
2013-12-05 22:16:04 +01:00
HL2_DEBUG ( " Parse element 0 => " < < m_listHighlightPass2 . size ( ) < <
" == > position search: ( " < < _start < < " , " < < _stop < < " ) " ) ;
int64_t elementStart = _start ;
int64_t elementStop = _stop ;
2013-10-27 11:34:45 +01:00
appl : : HighlightInfo resultat ;
2013-12-05 22:16:04 +01:00
while ( elementStart < elementStop ) {
2014-07-30 23:24:26 +02:00
if ( elementStart = = 306 ) {
2016-03-10 22:37:37 +01:00
//elog::setLevel(elog::logLevelVerbose);
2014-07-30 23:24:26 +02:00
}
2013-12-05 22:16:04 +01:00
//HL2_DEBUG("Parse element in the buffer pos=" << elementStart << "," << _buffer.size() << ")" );
2011-08-08 10:24:24 +02:00
//try to fond the HL in ALL of we have
2016-01-15 00:01:58 +01:00
for ( int64_t jjj = 0 ; jjj < int64_t ( m_listHighlightPass2 . size ( ) ) ; jjj + + ) {
2014-10-08 21:32:41 +02:00
HL2_DEBUG ( " Parse HL id= " < < jjj < < " position search: ( " < <
2014-10-06 23:22:14 +02:00
elementStart < < " , " < < elementStop < < " ) in=' "
2016-01-15 00:01:58 +01:00
< < /*_buffer[elementStart]*/ std : : string ( _buffer . begin ( ) + elementStart , _buffer . begin ( ) + elementStop ) < < " ' " < < m_listHighlightPass2 [ jjj ] . getPaternString ( ) ) ;
2011-08-08 10:24:24 +02:00
// Stop the search to the end (to get the end of the pattern)
2016-01-15 00:01:58 +01:00
bool ret = m_listHighlightPass2 [ jjj ] . find ( elementStart , elementStop , resultat , _buffer ) ;
if ( ret = = true ) {
// find an element:
2014-10-08 21:32:41 +02:00
_metaData . push_back ( resultat ) ;
2016-01-15 00:01:58 +01:00
HL2_DEBUG ( " data=' " < < std : : string ( _buffer . begin ( ) + elementStart , _buffer . begin ( ) + resultat . stop ) < < " ' " ) ;
2014-10-08 21:32:41 +02:00
elementStart = resultat . stop - 1 ;
break ;
2011-08-08 10:24:24 +02:00
}
2011-07-20 10:33:24 +02:00
}
2011-08-08 10:24:24 +02:00
// Go to the next element (and search again ...).
elementStart + + ;
2011-07-20 10:33:24 +02:00
}
}
2014-10-13 22:39:49 +02:00
/**
* @ brief second pass of the hightlight pattern ( have found something before )
* @ param [ in ] _upper upper pattern to find the data
* @ param [ out ] _metaData Output list of all find patern
* @ param [ in ] _buffer buffer where we need to search data
*/
void appl : : Highlight : : parseSubElement ( const appl : : HighlightInfo & _upper ,
std : : vector < appl : : HighlightInfo > & _metaData ,
std : : string & _buffer ) {
if ( _upper . patern - > getSubPatternName ( ) . size ( ) = = 0 ) {
return ;
}
HL2_DEBUG ( " Parse element 0 => " < < m_listHighlightNamed . size ( ) < <
" == > position search: ( " < < _upper . start < < " , " < < _upper . stop < < " ) " ) ;
int64_t elementStart = _upper . start ;
int64_t elementStop = _upper . stop ;
appl : : HighlightInfo resultat ;
// Find element in the list:
auto itHL = m_listHighlightNamed . find ( _upper . patern - > getSubPatternName ( ) ) ;
if ( itHL = = m_listHighlightNamed . end ( ) ) {
APPL_ERROR ( " Patern does not exist : " < < _upper . patern - > getSubPatternName ( ) < < " note : Removing it ... " ) ;
_upper . patern - > setSubPatternName ( " " ) ;
return ;
}
while ( elementStart < elementStop ) {
//try to fond the HL in ALL of we have
for ( auto & it : itHL - > second ) {
HL2_DEBUG ( " Parse HL position search: ( " < < elementStart < < " , " < < elementStop < < " ) in=' " < < _buffer [ elementStart ] < < " ' " < < it . getPaternString ( ) ) ;
// Stop the search to the end (to get the end of the pattern)
2016-01-15 00:01:58 +01:00
bool ret = it . find ( elementStart , elementStop , resultat , _buffer ) ;
if ( ret = = true ) {
2014-10-13 22:39:49 +02:00
_metaData . push_back ( resultat ) ;
elementStart = resultat . stop - 1 ;
break ;
}
}
// Go to the next element (and search again ...).
elementStart + + ;
}
}