#include "housestyle.h" #include "readfile.h" HouseStyle::HouseStyle ( const std::string& bufferParameter, const std::string& ruleDirectoryParameter, const std::string& ruleFileParameter, const std::string& filterDirectoryParameter, const std::string& filterFileParameter, const std::string& pathSeparatorParameter, int contextRangeParameter ) : buffer ( bufferParameter ), ruleDirectory ( ruleDirectoryParameter ), ruleFile ( ruleFileParameter ), filterDirectory ( filterDirectoryParameter ), filterFile ( filterFileParameter ), pathSeparator ( pathSeparatorParameter ), contextRange ( contextRangeParameter ), ruleVector ( new std::vector > ), dictionary ( new StringSet ), passiveDictionary ( new StringSet ) {} HouseStyle::~HouseStyle() {} void HouseStyle::collectFilter ( std::string& fileName, std::set& excludeSet, int *filterCount ) { if ( fileName == "(No filter)" ) return; string filePath, buffer; filePath = filterDirectory + pathSeparator + fileName; if ( !ReadFile::run ( filePath, buffer ) ) return; XmlFilterReader xfr; if ( !xfr.parse ( buffer ) ) { std::string report = xfr.getLastError(); throw runtime_error ( report.c_str() ); } std::map > > temporaryMap; std::map > >::iterator temporaryMapIterator; xfr.getFilterMap ( temporaryMap ); for ( temporaryMapIterator = temporaryMap.begin(); temporaryMapIterator != temporaryMap.end(); ++temporaryMapIterator ) { filterMap.insert ( *temporaryMapIterator ); ( *filterCount ) ++; } // add current file to exclude set excludeSet.insert ( fileName ); // fetch exclude vector std::vector localExcludeVector; std::vector::iterator excludeIterator; xfr.getExcludeVector ( localExcludeVector ); for ( excludeIterator = localExcludeVector.begin(); excludeIterator != localExcludeVector.end(); excludeIterator++ ) excludeSet.insert ( *excludeIterator ); // fetch include vector std::vector includeVector; std::vector::iterator includeIterator; xfr.getIncludeVector ( includeVector ); if ( includeVector.empty() ) return; for ( includeIterator = includeVector.begin(); includeIterator != includeVector.end(); includeIterator++ ) { if ( !excludeSet.count ( *includeIterator ) ) collectFilter ( *includeIterator, excludeSet, filterCount ); } } void HouseStyle::collectRules ( string& fileName, boost::shared_ptr > > ruleVector, std::set& excludeSet, int *ruleCount ) { std::string filePath, buffer; filePath = ruleDirectory + pathSeparator + fileName; if ( !ReadFile::run ( filePath, buffer ) ) return; std::auto_ptr xrr ( new XmlRuleReader ( dictionary, passiveDictionary, ruleVector ) ); if ( !xrr->parse ( buffer ) ) { std::string report = xrr->getIncorrectPatternReport(); if ( report != "" ) throw runtime_error ( report.c_str() ); else throw runtime_error ( xrr->getLastError().c_str() ); } // add current file to exclude set excludeSet.insert ( fileName ); // fetch exclude vector std::vector localExcludeVector; std::vector::iterator excludeIterator; xrr->getExcludeVector ( localExcludeVector ); for ( excludeIterator = localExcludeVector.begin(); excludeIterator != localExcludeVector.end(); excludeIterator++ ) excludeSet.insert ( *excludeIterator ); * ( ruleCount ) += xrr->getRuleCount(); // fetch include vector std::vector includeVector; xrr->getIncludeVector ( includeVector ); std::vector::iterator includeIterator; for ( includeIterator = includeVector.begin(); includeIterator != includeVector.end(); includeIterator++ ) { if ( !excludeSet.count ( *includeIterator ) ) collectRules ( *includeIterator, ruleVector, excludeSet, ruleCount ); } } bool HouseStyle::createReport() { if ( !updateRules() ) { error = "no rules found"; return false; } updateFilter(); auto_ptr xtr ( new HouseStyleReader ( filterMap ) ); if ( !xtr->parse ( buffer ) ) { error = "file is not well-formed"; return false; } std::vector > nodeVector; xtr->getNodeVector ( nodeVector ); int ruleVectorsize, nodeVectorSize; /* boost::shared_ptr rule(new Rule( "_", false)); */ std::vector contextVector; std::vector::iterator matchIterator; ruleVectorsize = ruleVector->size(); nodeVectorSize = nodeVector.size(); Spellcheck spellcheck ( dictionary, passiveDictionary ); std::string nodeBuffer; unsigned elementCount; for ( int j = 0; j < nodeVectorSize; ++j ) { nodeBuffer = nodeVector.at ( j ).first; elementCount = nodeVector.at ( j ).second; if ( !nodeBuffer.size() ) continue; for ( int i = 0; i < ruleVectorsize; i++ ) { //rule = ruleVector->at(i); boost::shared_ptr rule ( ruleVector->at ( i ) ); if ( rule->matchPatternGlobal ( nodeBuffer, contextVector, elementCount, contextRange ) ) { std::string report = rule->getReport(); for ( matchIterator = contextVector.begin(); matchIterator != contextVector.end(); matchIterator++ ) { if ( rule->getAdjustCaseAttribute() ) CaseHandler::adjustCase ( matchIterator->replace, matchIterator->match ); // tentative? matchIterator->tentative = ( rule->getTentativeAttribute() ) ? true : false; matchIterator->report = report; matchVector.push_back ( *matchIterator ); } contextVector.clear(); } } // check spelling if ( !dictionary->empty() ) { spellcheck.checkString ( nodeBuffer, contextVector, contextRange ); for ( matchIterator = contextVector.begin(); matchIterator != contextVector.end(); matchIterator++ ) { matchIterator->report = "Not in dictionary"; matchIterator->elementCount = elementCount; matchVector.push_back ( *matchIterator ); } contextVector.clear(); } } return true; } std::string HouseStyle::getLastError() { return error; } std::vector HouseStyle::getMatchVector() { return matchVector; } int HouseStyle::updateRules() { ruleVector->clear(); dictionary->clear(); passiveDictionary->clear(); int ruleCount = 0; set excludeSet; collectRules ( ruleFile, ruleVector, excludeSet, &ruleCount ); return ruleCount; } int HouseStyle::updateFilter() { filterMap.clear(); int filterCount = 0; set excludeSet; collectFilter ( filterFile, excludeSet, &filterCount ); return filterCount; }