<commit_before>#include "command.hpp"
#include "api.hpp"
#include <cstring>
#include <cstdlib>
#include <sstream>

#include <boost/regex.hpp>

/*
 * {
 *  (
 *    ([0-9]+)
 *    (
 *      /([%/]?)([^/]+)/(.+)
 *    )?
 *  )?
 * }
 */
#define PLACEHOLDER_REGEX         "" \
    "[{]" \
        "(" \
            "([0-9]+)" \
            "(" \
                "/([%/]?)([^/]*)/([^/}]*)" \
            ")?" \
        ")?" \
    "[}]"
#define REG_IDX_GROUP_NUMBER      2
#define REG_IDX_GROUP_REPLACE     3
#define REG_IDX_GROUP_REP_TYP     4
#define REG_IDX_GROUP_REP_OLD     5
#define REG_IDX_GROUP_REP_NEW     6



using namespace std;

namespace worker {

    namespace exception {

        invalid_argument_count::invalid_argument_count(uint expected, uint received) {
            stringstream s;
            if (received > expected) {
                s << "received too many arguments: ";
            } else {
                s << "received not enough arguments: ";
            }
            s << received << " instead of the expected " << expected;

            const string st = s.str();
            str = new char[st.length() + 1];
            memcpy(str, st.c_str(), st.length());
            str[st.length()] = '\0';
        }

        negative_index::negative_index(int index) {
            string s = "negative index not allowed: ";
            s += itoa(index);

            str = new char[s.length() + 1];
            memcpy(str, s.c_str(), s.length());
            str[s.length()] = '\0';
        }

        invalid_placeholder::invalid_placeholder(int index) {
            string s = "invalid placeholder index: ";
            s += itoa(index);

            str = new char[s.length() + 1];
            memcpy(str, s.c_str(), s.length());
            str[s.length()] = '\0';
        }

    }

    namespace impl {

        Replacement::Replacement(char typeIdentifier, const std::string &from, const std::string &to)
            : super_t((typeIdentifier == '%') ? REPLACE_END :
                    ((typeIdentifier == '/') ? REPLACE_ALL : REPLACE_FIRST),
                    from, to)
        {}

        string &Replacement::apply(string &str) const {
            switch(getType()) {
            case REPLACE_FIRST: {
                size_t idx = str.find(getOriginal());
                if (idx == string::npos) return str;
                size_t len = getOriginal().length();

                str.replace(idx, len, getReplacement());
                return str;
            }
            case REPLACE_ALL: {
                size_t offset = 0;
                string copy = str;
                while (true) {
                    size_t idx = copy.find(getOriginal());
                    if (idx == string::npos) return str;
                    size_t len = getOriginal().length();

                    str.replace(offset + idx, len, getReplacement());

                    offset += idx + len;
                    copy = str.c_str() + offset;
                }
            }
            case REPLACE_END: {
                size_t offset = str.length() - getOriginal().length();

                if (strcmp(str.c_str() + offset, getOriginal().c_str()) != 0) {
                    return str;
                }

                str.replace(offset, getOriginal().length(), getReplacement());
                return str;
            }
            default:
                return str;
            }
        }

        Placeholder::Placeholder(size_t offset, uint idx, size_t length, Replacement *replacement)
            : super_t(offset, idx, length, replacement)
        {}
    }

    typedef boost::regex regex_t;
    typedef boost::cmatch regmatch_t;

    static regex_t placeholderRegex(PLACEHOLDER_REGEX);

    uint getNbPlaceholders(const Command::indices_t &indices) {
        int result = -1;

        for (Command::indices_t::const_iterator current = indices.begin(), end = indices.end(); current != end; current++) {
            result = max(result, static_cast<int>(current->getIndex()));
        }

        return uint(result + 1);
    }

    Command::indices_t getPlaceholders(const string &str) {
        Command::indices_t result;

        uint currentRef;
        size_t stringOffset = 0;
        const char * const strStart = str.c_str();
        const char * strCurrent = strStart;

        regmatch_t match;

        Debug("Locating placeholders in string \"%s\"", strStart);

        while (true) {
            if (!boost::regex_search(strCurrent, match, placeholderRegex))
                return result;
<commit_msg>forgot to initialize currentRef<commit_after>#include "command.hpp"
#include "api.hpp"
#include <cstring>
#include <cstdlib>
#include <sstream>

#include <boost/regex.hpp>

/*
 * {
 *  (
 *    ([0-9]+)
 *    (
 *      /([%/]?)([^/]+)/(.+)
 *    )?
 *  )?
 * }
 */
#define PLACEHOLDER_REGEX         "" \
    "[{]" \
        "(" \
            "([0-9]+)" \
            "(" \
                "/([%/]?)([^/]*)/([^/}]*)" \
            ")?" \
        ")?" \
    "[}]"
#define REG_IDX_GROUP_NUMBER      2
#define REG_IDX_GROUP_REPLACE     3
#define REG_IDX_GROUP_REP_TYP     4
#define REG_IDX_GROUP_REP_OLD     5
#define REG_IDX_GROUP_REP_NEW     6



using namespace std;

namespace worker {

    namespace exception {

        invalid_argument_count::invalid_argument_count(uint expected, uint received) {
            stringstream s;
            if (received > expected) {
                s << "received too many arguments: ";
            } else {
                s << "received not enough arguments: ";
            }
            s << received << " instead of the expected " << expected;

            const string st = s.str();
            str = new char[st.length() + 1];
            memcpy(str, st.c_str(), st.length());
            str[st.length()] = '\0';
        }

        negative_index::negative_index(int index) {
            string s = "negative index not allowed: ";
            s += itoa(index);

            str = new char[s.length() + 1];
            memcpy(str, s.c_str(), s.length());
            str[s.length()] = '\0';
        }

        invalid_placeholder::invalid_placeholder(int index) {
            string s = "invalid placeholder index: ";
            s += itoa(index);

            str = new char[s.length() + 1];
            memcpy(str, s.c_str(), s.length());
            str[s.length()] = '\0';
        }

    }

    namespace impl {

        Replacement::Replacement(char typeIdentifier, const std::string &from, const std::string &to)
            : super_t((typeIdentifier == '%') ? REPLACE_END :
                    ((typeIdentifier == '/') ? REPLACE_ALL : REPLACE_FIRST),
                    from, to)
        {}

        string &Replacement::apply(string &str) const {
            switch(getType()) {
            case REPLACE_FIRST: {
                size_t idx = str.find(getOriginal());
                if (idx == string::npos) return str;
                size_t len = getOriginal().length();

                str.replace(idx, len, getReplacement());
                return str;
            }
            case REPLACE_ALL: {
                size_t offset = 0;
                string copy = str;
                while (true) {
                    size_t idx = copy.find(getOriginal());
                    if (idx == string::npos) return str;
                    size_t len = getOriginal().length();

                    str.replace(offset + idx, len, getReplacement());

                    offset += idx + len;
                    copy = str.c_str() + offset;
                }
            }
            case REPLACE_END: {
                size_t offset = str.length() - getOriginal().length();

                if (strcmp(str.c_str() + offset, getOriginal().c_str()) != 0) {
                    return str;
                }

                str.replace(offset, getOriginal().length(), getReplacement());
                return str;
            }
            default:
                return str;
            }
        }

        Placeholder::Placeholder(size_t offset, uint idx, size_t length, Replacement *replacement)
            : super_t(offset, idx, length, replacement)
        {}
    }

    typedef boost::regex regex_t;
    typedef boost::cmatch regmatch_t;

    static regex_t placeholderRegex(PLACEHOLDER_REGEX);

    uint getNbPlaceholders(const Command::indices_t &indices) {
        int result = -1;

        for (Command::indices_t::const_iterator current = indices.begin(), end = indices.end(); current != end; current++) {
            result = max(result, static_cast<int>(current->getIndex()));
        }

        return uint(result + 1);
    }

    Command::indices_t getPlaceholders(const string &str) {
        Command::indices_t result;

        uint currentRef = 0;
        size_t stringOffset = 0;
        const char * const strStart = str.c_str();
        const char * strCurrent = strStart;

        regmatch_t match;

        Debug("Locating placeholders in string \"%s\"", strStart);

        while (true) {
            if (!boost::regex_search(strCurrent, match, placeholderRegex))
                return result;

{'fraction_non_alphanumeric': 0.13560622670467004, 'fraction_numerical': 0.0044946283709712785, 'mean_word_length': 1.6306228373702423, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4374251', 'n_tokens_mistral': 2707, 'n_tokens_neox': 2557, 'n_words': 576}