#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; }