summaryrefslogblamecommitdiff
path: root/src/lintmanager.cpp
blob: 312ddd699221084f45c0d41732759dcf6b5e4dbd (plain) (tree)



















































































































































                                                                             
/*
 *  The ManaPlus Client
 *  Copyright (C) 2014  The ManaPlus Developers
 *
 *  This file is part of The ManaPlus Client.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "lintmanager.h"

#include "rulebase.h"

#include "rules/dump.h"

#include <dirent.h>
#include <fstream>
#include <regex>

#include <sys/stat.h>

#include "localconsts.h"

LintManager::LintManager(std::string path)
{
    registerRules();
    enumFiles(path);
}

void LintManager::registerRules()
{
    mRules.push_back(new Dump);
}

void LintManager::enumFiles(std::string path)
{
    path += "/";
    struct dirent *next_file = nullptr;
    DIR *const dir = opendir(path.c_str());
    struct stat s;
    std::vector<std::string> dirs;

    while ((next_file = readdir(dir)))
    {
        const std::string file = next_file->d_name;
        if (file != "." && file != "..")
        {
            char *realPath = realpath((path + file).c_str(), nullptr);
            stat(realPath, &s);
            if (S_ISDIR(s.st_mode))
                dirs.push_back(path + file);
            else
                processFile(realPath);
        }
    }
    if (dir)
        closedir(dir);

    FOR_EACH (std::vector<std::string>::const_iterator, it, dirs)
        enumFiles(*it);
}

void LintManager::processFile(std::string fileName)
{
//    printf("file: %s\n", fileName.c_str());
    mFileName = fileName;
    selectRulesForFile();
    if (!mSelectedRules.empty())
    {
        readFile();
        applyRulesToFile();
    }
}

void LintManager::applyRulesToFile()
{
    FOR_EACH (std::vector<RuleBase*>::iterator, it, mRules)
    {
        RuleBase *const rule = *it;
        int line = 0;
        FOR_EACH (std::vector<std::string>::const_iterator, itStr, mFileData)
        {
            const std::string &str = *itStr;
            rule->setLine(line);
            rule->parseLine(str);
            line ++;
        }
    }
}

void LintManager::readFile()
{
//    printf("readFile: %s\n", mFileName.c_str());
    std::ifstream file;
    char line[3001];

    mFileData.clear();

    file.open(mFileName.c_str(), std::ios::in);
    if (!file.is_open())
        return;

    while (file.getline(line, 3000))
        mFileData.push_back(line);

    if (file.is_open())
        file.close();
}

void LintManager::selectRulesForFile()
{
//    printf("selectRulesForFile: %s\n", mFileName.c_str());
    mSelectedRules.clear();
    FOR_EACH (std::vector<RuleBase*>::iterator, it, mRules)
    {
        RuleBase *const rule = *it;
        if (isMatchFile(rule))
        {
            rule->setFile(mFileName);
            rule->init();
            mSelectedRules.push_back(rule);
        }
    }
}

bool LintManager::isMatchFile(RuleBase *const rule)
{
//    printf("isMatchFile: %s\n", fileName.c_str());
    const std::set<std::string> &masks = rule->getMasks();
    FOR_EACH (std::set<std::string>::const_iterator, it, masks)
    {
        std::regex exp(*it);
        if (std::regex_match (mFileName, exp))
            return true;
    }
    return false;
}