edn/sources/appl/Highlight.cpp

279 lines
9.3 KiB
C++
Raw Normal View History

/**
* @author Edouard DUPIN
2012-11-25 11:55:06 +01:00
*
* @copyright 2010, Edouard DUPIN, all right reserved
*
* @license GPL v3 (see license file)
*/
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>
#include <exml/exml.h>
#include <ewol/ewol.h>
2013-12-13 21:50:40 +01:00
#include <ewol/resource/Manager.h>
#undef __class__
2013-10-25 22:12:34 +02:00
#define __class__ "Highlight"
// first pass
//#define HL_DEBUG APPL_INFO
#define HL_DEBUG APPL_VERBOSE
// second pass
//#define HL2_DEBUG APPL_INFO
#define HL2_DEBUG APPL_VERBOSE
2013-10-25 22:12:34 +02:00
void appl::Highlight::parseRules(exml::Element* _child,
std::vector<std::unique_ptr<HighlightPattern>>& _mListPatern,
int32_t _level,
bool forceMaximize) {
// Create the patern ...
2013-10-25 22:12:34 +02:00
HighlightPattern *myPattern = new HighlightPattern(m_paintingProperties);
// parse under Element
myPattern->parseRules(_child, _level, forceMaximize);
// add element in the list
_mListPatern.push_back(std::unique_ptr<HighlightPattern>(myPattern));
}
appl::Highlight::Highlight() {
addObjectType("appl::Highlight");
}
void appl::Highlight::init(const std::string& _xmlFilename, const std::string& _colorFile) {
ewol::Resource::init(_xmlFilename);
2013-10-25 22:12:34 +02:00
// keep color propertiy file :
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) {
APPL_ERROR(" can not load file XML : " << _xmlFilename);
return;
}
2013-10-25 22:12:34 +02:00
exml::Element* root = doc.getNamed("EdnLang");
2014-06-05 22:01:24 +02:00
if (nullptr == root ) {
APPL_ERROR("(l ?) main node not find: \"EdnLang\" ...");
return;
}
2013-10-27 11:34:45 +01:00
m_typeName = root->getAttribute("lang");
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) {
2013-10-07 22:04:21 +02:00
exml::Element* child = root->getElement(iii);
2014-06-05 22:01:24 +02:00
if (child == nullptr) {
// 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) {
//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);
}
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++) {
2013-10-07 22:04:21 +02:00
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;
}
2013-10-09 22:00:24 +02:00
parseRules(passChild, m_listHighlightPass1, level1++);
}
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++) {
2013-10-07 22:04:21 +02:00
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;
}
parseRules(passChild, m_listHighlightPass2, level2++, true);
}
} else {
2013-10-09 22:00:24 +02:00
APPL_ERROR("(l "<< child->getPos() << ") node not suported : \""<< child->getValue() << "\" must be [ext,pass1,pass2]" );
}
}
}
appl::Highlight::~Highlight() {
// clear the compleate list
2013-10-07 22:04:21 +02:00
m_listHighlightPass1.clear();
// clear the compleate list
m_listHighlightPass2.clear();
// clear the compleate list
2013-10-07 22:04:21 +02:00
m_listExtentions.clear();
}
2013-11-14 21:57:10 +01:00
bool appl::Highlight::hasExtention(const std::string& _ext) {
2014-06-02 21:04:35 +02:00
for (auto &it : m_listExtentions) {
APPL_VERBOSE(" check : " << it << "=?=" << _ext);
if ( it == "*." + _ext
|| it == _ext) {
return true;
}
}
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();
} else {
2013-10-25 22:12:34 +02:00
extention = file.getNameFile();
}
2013-10-25 22:12:34 +02:00
APPL_DEBUG(" try to find : in \"" << file << "\" extention:\"" << extention << "\" ");
2014-06-02 21:04:35 +02:00
for (auto &it : m_listExtentions) {
if (extention == it ) {
return true;
}
}
return false;
}
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 );
}
2013-10-07 22:04:21 +02:00
// display all elements
2014-06-02 21:04:35 +02:00
for (auto &it : m_listHighlightPass1) {
APPL_INFO(" Pass 1 : " << it->getName() );
2013-10-25 22:12:34 +02:00
//m_listHighlightPass1[iii]->display();
}
2013-10-07 22:04:21 +02:00
// display all elements
2014-06-02 21:04:35 +02:00
for (auto &it : m_listHighlightPass2) {
APPL_INFO(" pass 2 : " << it->getName() );
2013-10-25 22:12:34 +02:00
//m_listHighlightPass2[iii]->display();
}
}
/* 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
*/
void appl::Highlight::parse(int64_t _start,
int64_t _stop,
std::vector<appl::HighlightInfo> & _metaData,
int64_t _addingPos,
std::string& _buffer) {
if (0 > _addingPos) {
_addingPos = 0;
}
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;
int64_t startTime = ewol::getTime();
while (elementStart <= elementStop) {
//HL_DEBUG("Parse element in the buffer pos=" << elementStart);
int64_t currentTime = ewol::getTime();
//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++){
2013-11-11 20:20:25 +01:00
enum resultFind ret = HLP_FIND_OK;
/*
if (_buffer[elementStart] == '\n') {
HL_DEBUG("Parse HL id=" << jjj << " position search: (" << elementStart << "," << _stop << ") input start='\\n' " << m_listHighlightPass1[jjj]->getPaternString());
} else {
HL_DEBUG("Parse HL id=" << jjj << " position search: (" << elementStart << "," << _stop << ") input start='" << _buffer[elementStart] << "' " << m_listHighlightPass1[jjj]->getPaternString());
}
*/
// Stop the search to the end (to get the end of the pattern)
ret = m_listHighlightPass1[jjj]->find(elementStart, _buffer.size(), resultat, _buffer);
if (HLP_FIND_ERROR != ret) {
int64_t currentTimeEnd = ewol::getTime();
int64_t deltaTime = currentTimeEnd - currentTime;
HL_DEBUG("Find Pattern in the Buffer : time=" << (float)deltaTime/1000.0f << " ms (" << resultat.start << "," << resultat.stop << ") startPos=" << elementStart << " for=" << m_listHighlightPass1[jjj]->getPaternString());
// 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();
}
} else {
// Not find == > exit the cycle :
break;
}
}
// 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;
}
}
// Go to the next element (and search again ...).
elementStart++;
}
int64_t stopTime = ewol::getTime();
int64_t deltaTimeGlobal = stopTime - startTime;
APPL_DEBUG("parse in time=" << (float)deltaTimeGlobal/1000.0f << " ms ");
}
/**
* @brief second pass of the hightlight
*
*/
void appl::Highlight::parse2(int64_t _start,
int64_t _stop,
std::vector<appl::HighlightInfo> &_metaData,
std::string&_buffer) {
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;
while (elementStart < elementStop) {
2014-07-30 23:24:26 +02:00
if (elementStart == 306) {
//etk::log::setLevel(etk::log::logLevelVerbose);
}
//HL2_DEBUG("Parse element in the buffer pos=" << elementStart << "," << _buffer.size() << ")" );
//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_listHighlightPass2.size(); jjj++){
enum resultFind ret;
HL2_DEBUG("Parse HL id=" << jjj << " position search: (" <<
elementStart << "," << elementStop << ") in='"
<< _buffer[elementStart] << "' " << m_listHighlightPass2[jjj]->getPaternString());
// Stop the search to the end (to get the end of the pattern)
ret = m_listHighlightPass2[jjj]->find(elementStart, elementStop, resultat, _buffer);
2014-07-30 23:24:26 +02:00
if (ret != HLP_FIND_ERROR) {
_metaData.push_back(resultat);
elementStart = resultat.stop-1;
break;
}
}
// Go to the next element (and search again ...).
elementStart++;
}
}