/** ******************************************************************************* * @file Highlight.c * @brief Editeur De N'ours : Hightlightning Specific * @author Edouard DUPIN * @date 14/12/2010 * @par Project * Edn * * @par Copyright * Copyright 2010 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 * You can not earn money with this Software (if the source extract from Edn * represent less than 50% of original Sources) * Term of the licence in in the file licence.txt. * ******************************************************************************* */ #include "tools_debug.h" #include "tools_globals.h" #include "Highlight.h" #include "tinyxml.h" #undef __class__ #define __class__ "Highlight" void Highlight::ParseRules(TiXmlNode *child, std::vector &mListPatern, int32_t level) { // Create the patern ... HighlightPattern *myPattern = new HighlightPattern(); // parse under Element myPattern->ParseRules(child, level); // add element in the list mListPatern.push_back(myPattern); } Highlight::Highlight(Edn::String &xmlFilename) { TiXmlDocument XmlDocument; // open the curent File bool loadError = XmlDocument.LoadFile(xmlFilename.c_str()); if (false == loadError) { EDN_ERROR( "can not load Hightlight XML: PARSING error: \"" << xmlFilename.c_str() << "\""); return; } TiXmlElement* root = XmlDocument.FirstChildElement( "EdnLang" ); if (NULL == root) { EDN_ERROR( "can not load Hightlight XML: main node not find: \"EdnLang\""); return; } int32_t level1 = 0; int32_t level2 = 0; TiXmlNode * child = root->FirstChild(); while(NULL != child) { if (child->Type()==TiXmlNode::TINYXML_COMMENT) { // nothing to do ... } else if (!strcmp(child->Value(), "ext")) { const char *myData = child->ToElement()->GetText(); if (NULL != myData) { //EDN_INFO(PFX"(l %d) node fined : %s=\"%s\"", child->Row(), child->Value() , myData); Edn::String myEdnData = myData; m_listExtentions.push_back(myEdnData); } } else if (!strcmp(child->Value(), "pass1")) { // Get sub Nodes ... TiXmlNode *passChild = child->FirstChild(); while (NULL != passChild) { if (passChild->Type()==TiXmlNode::TINYXML_COMMENT) { // nothing to do ... } else if (!strcmp(passChild->Value(), "rule")) { ParseRules(passChild, m_listHighlightPass1, level1++); } else { EDN_ERROR("(l "<< passChild->Row() << ") node not suported : \""<< passChild->Value() << "\" must be [rule]" ); } // get the next node element : passChild = passChild->NextSibling(); } } else if (!strcmp(child->Value(), "pass2")) { // Get sub Nodes ... TiXmlNode *passChild = child->FirstChild(); while (NULL != passChild) { if (passChild->Type()==TiXmlNode::TINYXML_COMMENT) { // nothing to do ... } else if (!strcmp(passChild->Value(), "rule")) { ParseRules(passChild, m_listHighlightPass2, level2++); } else { EDN_ERROR("(l "<< passChild->Row() << ") node not suported : \""<< passChild->Value() << "\" must be [rule]" ); } // get the next node element : passChild = passChild->NextSibling(); } } else { EDN_ERROR("(l "<< child->Row() << ") node not suported : \""<< child->Value() << "\" must be [ext,pass1,pass2]" ); } // get the next node element : child = child->NextSibling(); } } Highlight::~Highlight(void) { uint32_t i; // clean all Element for (i=0; i< m_listHighlightPass1.size(); i++) { delete(m_listHighlightPass1[i]); } // clear the compleate list m_listHighlightPass1.clear(); } bool Highlight::HasExtention(Edn::String &ext) { uint32_t i; for (i=0; iGetName().c_str() ); //m_listHighlightPass1[i]->Display(); } // Display all elements for (i=0; i< m_listHighlightPass2.size(); i++) { EDN_INFO(" " << i << " Pass 2 : " << m_listHighlightPass2[i]->GetName().c_str() ); //m_listHighlightPass2[i]->Display(); } } void Highlight::Parse(int32_t start, int32_t stop, std::vector &metaData, int32_t &addingPos, EdnVectorBuf &buffer, int32_t elementID) { if (0 > addingPos) { addingPos = 0; } /*int32_t emptyId = -1; for (i=0; i< (int32_t)metaData.size(); i++) { }*/ //EDN_DEBUG("Parse element " << elementID << " / " << m_listHighlightPass1.size() << " ==> position search: (" << start << "," << stop << ")" ); if (elementID >= (int32_t)m_listHighlightPass1.size() ){ //EDN_DEBUG("Return at " << elementID << " / " << m_listHighlightPass1.size() ); return; } int32_t elementStart = start; int32_t elementStop = stop; resultFind_te ret = HLP_FIND_OK; colorInformation_ts resultat; while (HLP_FIND_ERROR != ret && elementStartFind(elementStart, elementStop, resultat, buffer); if (HLP_FIND_ERROR != ret) { //EDN_INFO("Find Pattern in the Buffer : (" << resultat.beginStart << "," << resultat.endStop << ")" ); // Add curent element in the list ... if (HLP_FIND_OK_NO_END == ret) { // find if we have a next element with th save Pointer and not higher the this one int32_t findNextElement = -1; int32_t i; int32_t curentLevel = ((HighlightPattern*)resultat.patern)->GetLevel(); for (i=addingPos; i< (int32_t)metaData.size(); i++) { if (curentLevel > ((HighlightPattern*)metaData[i].patern)->GetLevel() ) { //EDN_DEBUG(" -> Find upper element at "<< i ); break; } else if (curentLevel < ((HighlightPattern*)metaData[i].patern)->GetLevel() ) { findNextElement = i; //EDN_DEBUG(" -> Find under element at "<< i ); } if (metaData[i].patern == resultat.patern) { findNextElement = i; //EDN_DEBUG(" -> Find a same element at "<< i ); break; } } if (-1 != findNextElement) { // if not find a end, we need to search the end of this one and parse all data inside... int32_t newEnd = buffer.Size(); if (findNextElement >= (int32_t)metaData.size()-1) { // Remove old element : //EDN_DEBUG(" --> Remove : " << addingPos << "==>" << (int32_t)metaData.size() << " (end)" ); metaData.erase(metaData.begin()+addingPos,metaData.end()); } else { // Remove old element : //EDN_DEBUG(" --> Remove : " << addingPos << "==>" << findNextElement+1 ); metaData.erase(metaData.begin()+addingPos,metaData.begin()+findNextElement+1); newEnd = metaData[addingPos].beginStart-1; } // Regenerate a local parsing : in a higher range of text Parse(elementStart, edn_max(newEnd, stop), metaData, addingPos, buffer, elementID); // Break the curent process, beacause we reparse the data in all range... return; } else { //EDN_DEBUG(" --> No element removed " ); metaData.insert(metaData.begin() + addingPos, resultat); //EDN_DEBUG("INSERT at "<< addingPos << " S=" << resultat.beginStart << " E=" << resultat.endStop ); } } else { metaData.insert(metaData.begin() + addingPos, resultat); //EDN_DEBUG("INSERT at "<< addingPos << " S=" << resultat.beginStart << " E=" << resultat.endStop ); } // parse the under element : Parse(elementStart, resultat.beginStart-1, metaData, addingPos, buffer, elementID+1); addingPos++; elementStart = resultat.endStop; } } // parse the under element : Parse(elementStart, elementStop, metaData, addingPos, buffer, elementID+1); } /** * @brief second pass of the hightlight * */ void Highlight::Parse2(int32_t start, int32_t stop, std::vector &metaData, EdnVectorBuf &buffer, int32_t elementID) { if (elementID >= (int32_t)m_listHighlightPass2.size() ){ return; } int32_t elementStart = start; int32_t elementStop = stop; resultFind_te ret = HLP_FIND_OK; colorInformation_ts resultat; while (HLP_FIND_ERROR != ret && elementStartFind(elementStart, elementStop, resultat, buffer); } else { ret = HLP_FIND_ERROR; } if (HLP_FIND_ERROR != ret) { //EDN_INFO("Find Pattern in the Buffer : (" << resultat.beginStart << "," << resultat.endStop << ")" ); // parse the under element : Parse2(elementStart, resultat.beginStart, metaData, buffer, elementID+1); // Add curent element in the list ... metaData.push_back(resultat); elementStart = resultat.endStop; } } // parse the under element : Parse2(elementStart, elementStop, metaData, buffer, elementID+1); }