code:
#include "Log.h"

#include "CommandLineParams.h"
#include <streambuf>
#include <map>
#include "StringUtils.h"

namespace {
    class NoStream : public std::streambuf {
    public:
        int overflow(int c) { return c; }
    };

    NoStream noStream;
    std::ostream nothing (&noStream);
    std::map<LogType, Logger> loggerCache;

    std::ostream& log(LogType lt) {
        auto cacheEntry = loggerCache.find(lt);
        if (cacheEntry == loggerCache.end()) {
            auto& outStream = ((lt == LogType::ERROR) ? std::cerr : std::cout);
            auto newEntry = std::make_pair(lt, Logger(lt, outStream));
            loggerCache.insert(newEntry);
        }
        return loggerCache[lt]();
    }
}

Logger::Logger() :
    logType(LogType::DBUG),
    outStream(std::cout),
    shouldLog(true) {
}

Logger::Logger(LogType lt, std::ostream& out) :
    logType(lt),
    outStream(out),
    shouldLog(false) {
    std::string specifiedLog = toLowercase(getRelativeCLParam("-log", 1));
    LogType logLevel = LogType::ERROR;
    if (specifiedLog == "warning") {
        logLevel = LogType::WARNING;
    } else if (specifiedLog == "info") {
        logLevel = LogType::INFO;
    } else if (specifiedLog == "debug") {
        logLevel = LogType::DBUG;
    }

    if (lt <= logLevel) {
        shouldLog = true;
    }
}

std::ostream& Logger::operator()() {
    if (shouldLog) {
        return outStream;
    }
    return nothing;
}

std::ostream& logError() {
    return log(LogType::ERROR);
}

std::ostream& logWarning() {
    return log(LogType::WARNING);
}

std::ostream& logNotice() {
    return log(LogType::NOTICE);
}

std::ostream& logInfo() {
    return log(LogType::INFO);
}

std::ostream& logDebug() {
    return log(LogType::DBUG);
}


code:
#ifndef LOG_H
#define LOG_H

#include <iostream>

/*
  USAGE:
    The functions provided returns standard output/error streams depending
    on the log level specified at startup. Example usage:

    logWarning() << "WARNING WARNING" << std::endl;

    You can create custom logger objects if you want different output
    streams. You can then invoke these objects with function syntax:

    Logger loggg (LogLevel::INFO, std::cerr);
    loggg() << "HEY" << std::endl;

    Use the command line flag "-log <logtype>" to print logtypes higher
    than error. For example, if you specify "-log info", then the program
    will print out info, and all lower prioritized logtypes (warning+error).
 */
// I'd like logging macro(s) that auto include __FILE__ and __LINE__ for where the output is coming from (would be cool if we could include function/method name (and class if method)) - odilitime 17/08/02
enum class LogType {
    ERROR, // issue
    WARNING, // potential issue
    NOTICE, // basic user messages, Default include NOTICE, WARNING, ERROR
    INFO, // basic 10k ft overview of what's going on
    DBUG, // can't be DEBUG in clang
    CALLLIST // track each function call entrance and exit
};
// network logging should be separate

class Logger {
public:
    Logger();
    Logger(LogType lt, std::ostream& out);
    std::ostream& operator()();
private:
    LogType logType;
    std::ostream& outStream;
    bool shouldLog;
};

// can we have some sort of macro to make these noOPs if compile as such
// no need to compile in all the debug logging calls in release
std::ostream& logError();
std::ostream& logWarning();
std::ostream& logNotice();
std::ostream& logInfo();
std::ostream& logDebug();

#endif

repo_name: despair/netrunner

license: mit


code:
#include "Scheduler.h"
#include <GLFW/glfw3.h>
#include <iostream>
#include <algorithm>
#include <stdlib.h>

std::shared_ptr<timer_handle> Scheduler::setTimeout(std::function<void()> callback, unsigned long delay) {
    double now = glfwGetTime() * 1000;
    std::shared_ptr<timer_handle> handle = std::make_shared<timer_handle>();
    handle->callback = callback;
    handle->nextAt = now + delay;
    handle->interval = 0;
    //handle->timeout = true;
    this->timers.push_back(handle);
    return handle;
}

std::shared_ptr<timer_handle> Scheduler::setInterval(std::function<void()> callback, unsigned long delay) {
    double now = glfwGetTime() * 1000;
    //std::cout << "Scheduler::setInterval at " << (int)now << std::endl;
    std::shared_ptr<timer_handle> handle = std::make_shared<timer_handle>();
    handle->callback = callback;
    handle->nextAt = now + delay;
    handle->interval = delay;
    //handle->timeout = false;
    this->timers.push_back(handle);
    //std::cout << "scheduled at " << (int)handle->nextAt << std::endl;
    return handle;
}

unsigned long Scheduler::getNext() {
    unsigned long lowest = LONG_MAX;
    double now = glfwGetTime() * 1000; // it's number of ms since start up
    //std::cout << "there are " << this->timers.size() << std::endl;
    for(std::vector<std::shared_ptr<timer_handle>>::iterator it=this->timers.begin(); it!=this->timers.end(); ++it) {
        //std::cout << "nextAt " << (int)it->get()->nextAt << " long " << (int)(now - it->get()->nextAt) << std::endl;
        //std::cout << "now " << (int)now << " - nextAt: " << (int)it->get()->nextAt << std::endl;
        int diff = it->get()->nextAt - now;
        if (diff < 0) diff = 0;
        //std::cout << "timer fires in " << diff << std::endl;
        lowest = std::min(lowest, static_cast<unsigned long>(diff));
    }
    //std::cout << "returning " << lowest << std::endl;
    return lowest;
}

bool Scheduler::fireTimer(std::shared_ptr<timer_handle> timer, double now) {
    timer->callback();
    if (!timer->interval) {
        return true;
    }
    // schedule the next one
    //std::cout << "Scheduling next timer in " << timer->interval << "+" << now << "=" << (now + timer->interval) << std::endl;
    timer->nextAt = now + timer->interval;
    return false;
}

void Scheduler::fireTimers() {
    double now = glfwGetTime() * 1000;
    size_t unfired = 0;
    int next = INT_MAX;
    for(std::vector<std::shared_ptr<timer_handle>>::iterator it=this->timers.begin(); it!=this->timers.end(); ++it) {
        // if it's the timer time to fire
        int left = abs(static_cast<int>(it->get()->nextAt - now)); // maybe remove the ABS
        if (left <= 10 || it->get()->nextAt < now) {
            // fire it, do we need to clean it up
            if (this->fireTimer(*it, now)) {
                // clean up
                it = this->timers.erase(it);
                if (it == this->timers.end()) break;
            }
        } else {
            //std::cout << "left" << left << std::endl;
            next = std::min(left, next);
            unfired++;
        }
    }
    if (unfired) {
        if (next < 10) {
            std::cout << "There are " << unfired << "/" << this->timers.size() << " unfired timers left, next at " << next << std::endl;
            std::cout << "Scheduler::fireTimers - failed" << std::endl;
        }
    }
}

bool Scheduler::clearInterval(std::shared_ptr<timer_handle> timer) {
    // find and remove it
    //it2 = std::find(this->rootComponent->children.begin(), this->rootComponent->children.end(), it->get()->selectorBox);
    std::vector<std::shared_ptr<timer_handle>>::iterator it = std::find(this->timers.begin(), this->timers.end(), timer);
    if (it != this->timers.end()) {
        //std::cout << "Clearing Interval" << std::endl;
        this->timers.erase(it);
    } else {
        std::cout << "Couldnt find timer" << std::endl;
    }
    return true;
}


code:
#ifndef SCHEDULER_H
#define SCHEDULER_H

#include <memory>
#include <vector>
#include <functional>
#include <limits.h>

class timer_handle {
public:
    unsigned long interval; // in milliseconds
    double nextAt; // timestamp in milliseconds
    //bool timeout; // replaced by interval
    std::function<void()> callback;
};

class Scheduler {
public:
    std::shared_ptr<timer_handle> setTimeout(std::function<void()> callback, unsigned long delay);
    std::shared_ptr<timer_handle> setInterval(std::function<void()> callback, unsigned long delay);
    unsigned long getNext();
    bool fireTimer(std::shared_ptr<timer_handle> timer, double now);
    void fireTimers();
    bool clearInterval(std::shared_ptr<timer_handle> timer);
    std::vector<std::shared_ptr<timer_handle>> timers;
};

#endif


code:
#include "StringUtils.h"
#include <algorithm>
#include <iostream>
#include <iterator>

/**
 * get an extension from a filename
 * @param fileName a filename string
 * @return '' or a string with the found extension
 */
const std::string getFilenameExtension(std::string const& fileName) {
    auto dotPos = fileName.find_last_of('.');
    if (dotPos != std::string::npos && dotPos + 1 != std::string::npos) {
        //std::cout << "StringUtils::getFilenameExtension - " << fileName.substr(dotPos + 1) << std::endl;
        return fileName.substr(dotPos + 1);
    }
    return "";
}

/**
 * convert string to lowercase
 * @param str string
 * @return lowercased version of str
 */
const std::string toLowercase(const std::string &str) {
    std::string returnString = "";
    std::transform(str.begin(),
                   str.end(),
                   back_inserter(returnString),
                   tolower);
    return returnString;
/*
    std::string stringToLower(std::string s) {
    std::transform(s.begin(), s.end(), s.begin(),
            [](unsigned char c){ return std::tolower(c); });
    return s;
*/
}

std::vector<std::string> split(const std::string &text, char sep) {
    std::vector<std::string> tokens;
    std::size_t start = 0, end = 0;
    while ((end = text.find(sep, start)) != std::string::npos) {
        if (end != start) {
            tokens.push_back(text.substr(start, end - start));
        }
        start = end + 1;
    }
    if (end != start) {
        tokens.push_back(text.substr(start));
    }
    return tokens;
}

bool in_array(std::string needle, std::vector<std::string> haystack) {
    for(auto it : haystack) {
        if (it == needle) return true;
    }
    return false;
}

// FIXME: , in quotes or {} (JSON) <= top priority for 4chan
std::vector<std::string> parseSepButNotBetween(std::string string, std::string sep, std::vector<std::string> open, std::vector<std::string> close) {
    //std::cout << "looking at [" << string << "]" << std::endl;
    std::vector<std::string> arr;
    size_t state = 0;
    size_t last = 0;
    size_t cursor;
    size_t scopeLevel = 0;
    for (cursor = 0; cursor < string.length(); cursor++) {
        auto it = string[cursor];
        if (state == 0) {
            if (it == '{') {
                state = 1;
                scopeLevel++;
            } else if (it == '\'') {
                state = 4;
            } else if (it == '"') {
                state = 5;
            } else if (it == ',') {
                // flush buffer
                auto str3 = string.substr(last, last ? (cursor - last) : cursor);
                //std::cout << "from " << last << " to " << cursor << " pushing [" << str3 << "] it[" << it << "]" << std::endl;
                arr.push_back(str3);
                last = cursor + 1;
            }
        } else if (state == 1) {
            if (it == '{') {
                scopeLevel++;
            } else
            if (it == '}') {
                scopeLevel--;
                if (!scopeLevel) {
                    state = 0;
                }
            }
        } else if (state == 4) {
            if (it == '\'') {
                if (string[cursor - 1] != '\\') {
                    state = 0;
                }
            }
        } else if (state == 5) {
            if (it == '"') {
                if (string[cursor - 1] != '\\') {
                    state = 0;
                }
            }
        }
    }

    // flush last bit
    auto str3 = string.substr(last, last - string.size());
    //std::cout << "ending on " << state << " pushing [" << str3 << "]" << std::endl;
    arr.push_back(str3);
    return arr;
}

/*
std::vector<std::string> parseCommas(std::string string, std::string sep, std::vector<std::string> quotes) {
    std::vector<std::string> arr;
    if (!quotes.size()) {
        quotes.push_back("'");
        quotes.push_back("\"");
    }
    size_t mp = string.length();
    std::string str3 = "";
    for(int p = 0; p < mp; p++) {
        auto next = string.find(sep, p); // find next comma after p
        // if last string without a ,
        if (next == std::string::npos) {
            next = mp; // set to end
        }
        auto diff = next - p; // number of charaters to examine
        auto str2 = string.substr(p, diff); // get substring in this scan
        auto open = str2.substr(0, 1);
        str3 += str2;
        bool flush =  true;
        if (in_array(open, quotes)) {
            auto last = trim(str2).substr(-1, 1);
            if (last!=open) {
                str3 += ',';
                flush = false;
            }
        }
        if (flush) {
            arr.push_back(str3);
            str3 = "";
        }
        p += diff;
    }
    return arr;
}

size_t findMatching(std::string string, std::string opens, std::string closes, std::string escape="\\") {
    // find open
    auto opos = string.find(open);
    if (opos == std::string::npos) {
        return 0;
    }
    auto pos = opos;
    while(pos != std::string::npos) {
        auto cpos = string.find(close, pos+(open==close?1:0)); // don't want to end up with the opening marker as the start
        if (escape!="") {
            auto prevchar = string.substr(cpos - escape.length(), escape.length()); // get previous char before cpos
            if (prevchar != escape) {
                return cpos;
            }
        }
        pos = cpos;
    }
    return 0;
}
*/


code:
#ifndef STRINGUTILS_H
#define STRINGUTILS_H

#include <string>
#include <vector>

const std::string toLowercase(const std::string &str);

// should be moved to URL
const std::string getFilenameExtension(std::string const& fileName);
const std::string getDocumentFromURL(const std::string &url);
const std::string getHostFromURL(const std::string &url);
const std::string getSchemeFromURL(const std::string &url);
std::vector<std::string> split(const std::string &text, char sep);
std::vector<std::string> parseSepButNotBetween(std::string string, std::string sep, std::vector<std::string> open, std::vector<std::string> close);

bool in_array(std::string needle, std::vector<std::string> haystack);

// from https://stackoverflow.com/a/25385766/7697705

// trim from end of string (right)
inline std::string& rtrim(std::string& s, const char* t = " \t\n\r\f\v") {
    s.erase(s.find_last_not_of(t) + 1);
    return s;
}

// trim from beginning of string (left)
inline std::string& ltrim(std::string& s, const char* t = " \t\n\r\f\v") {
    s.erase(0, s.find_first_not_of(t));
    return s;
}

// trim from both ends of string (left & right)
inline std::string& trim(std::string& s, const char* t = " \t\n\r\f\v") {
    return ltrim(rtrim(s, t), t);
}

#endif


code:
#include "TextBlock.h"
#include <iostream>

void TextBlock::print() {
    std::cout << "TextBlock::print - " << this->lines.size() << std::endl;
    for(auto line: this->lines) {
        std::cout << "[" << line << "]" << std::endl;
    }
    std::cout << "TextBlock::print - trailingNewline " << this->trailingNewline << std::endl;
}

// only safe to one char rn
void TextBlock::insertAt(std::string str, size_t x, size_t y) {
    if (y > this->lines.size()) {
        std::cout << "TextArea::insertCharAt - y: " << y << " lines: " << this->lines.size() << std::endl;
        return;
    }
    if (!this->lines.size()) {
        this->lines.push_back(str);
        return;
    }
    if (x > this->lines[y].size()) {
        this->lines[y] += str;
        return;
    }
    // FIXME: search entire str for any \r
    if (str == "\r") {
        this->lines.push_back("");
        // does this mean we need to insert one
        // or that we have one?
        // what problem was it originally trying to solve?
        //this->trailingNewline = true;
        // not sure what up's with this shit but it breaks a lot...
        //this->setValue(this->getValue()); // in-efficient but should give a correctish algorithm
    } else {
        //std::cout << "TextBlock::insertAt - [" << this->lines[y].substr(0, x) << "]+[" << str << "]+[" << this->lines[y].substr(x) << "]" << std::endl;
        this->lines[y] = this->lines[y].substr(0, x) + str + this->lines[y].substr(x);
    }
    //std::cout << "TextBlock::insertAt - lines: " << this->lines.size() << std::endl;
}

// only tested to one char atm
void TextBlock::deleteAt(size_t x, size_t y, size_t count) {
    //std::cout << "TextBlock::deleteAt - start delete " << count << " chars @ " << x << "," << y << std::endl;
    if (y > this->lines.size()) {
        std::cout << "TextArea::deleteAt - y: " << y << " lines: " << this->lines.size() << std::endl;
        return;
    }
    // could we just remove the if?
    if (count) {
        if (x == 0) {
            if (y) {
                //std::cout << "TextArea::deleteAt - y!=0, lines: " << this->lines.size() << std::endl;
                if (y < this->lines.size()) {
                    //std::cout << "TextArea::deleteAt - nuked line [" << y << "] chars on line: " << this->lineLength(y) << std::endl;
                    if (this->lineLength(y)) {
                        this->trailingNewline = true;
                    }
                    this->lines.erase(this->lines.begin() + static_cast<int>(y));
                    return;
                } else {
                    if (y == this->lines.size()) {
                        // delete the last line
                        if (this->trailingNewline) {
                            this->trailingNewline = false;
                        } else {
                            std::cout << "TextArea::deleteAt - do nothing" << std::endl;
                        }
                        return;
                    }
                    std::cout << "TextArea::deleteAt - requesting deletion at " << x << "," << y << " but only " << this->lines.size() << std::endl;
                }
            } // else we're at 0,0 deleting a char
        }
        if (x >= this->lineLength(y)) {
            //std::cout << "TextArea::deleteAt - x == lineLength [" << this->lines[y].substr(0, x - 1) << "]" << std::endl;
            if (x) {
                this->lines[y] = this->lines[y].substr(0, x - 1);
            } else {
                this->trailingNewline = false;
            }
        } else {
            if (x) {
                if (x == this->lineLength(y) - 1) {
                    //std::cout << "TextArea::deleteAt - endOfLine [" << this->lines[y].substr(0, x) << "]+[" << this->lines[y].substr(x + count) << "]" << std::endl;
                    this->lines[y] = this->lines[y].substr(0, x) + this->lines[y].substr(x + count);
                } else {
                    //std::cout << "TextArea::deleteAt - x>0 [" << this->lines[y].substr(0, x) << "]+[" << this->lines[y].substr(x + count) << "]" << std::endl;
                    this->lines[y] = this->lines[y].substr(0, x) + this->lines[y].substr(x + count);
                }
            } else {
                //std::cout << "TextArea::deleteAt - x@0 [" << this->lines[y].substr(x + count) << "]" << std::endl;
                this->lines[y] = this->lines[y].substr(x + count);
            }
        }
    } else {
        this->lines[y] = this->lines[y].substr(0, x);
    }
}

size_t TextBlock::setValue(std::string value) {
    // split on \n
    std::string delimiter(1, '\r');
    this->lines.clear();

    size_t pos = 0;
    size_t lPos = 0;
    size_t tLines = 0; // start at 0 (should this start at 1?)
    this->trailingNewline = false;
    while ((pos = value.find(delimiter, lPos)) != std::string::npos) {
        //std::cout << "TextBlock::setValue pushing [" << value.substr(lPos, pos) << "]" << std::endl;
        std::string token = value.substr(lPos, pos);
        if (token[token.size() - 1] == '\r') {
            token.pop_back();
            //std::cout << "TextBlock::setValue adjusted [" << token << "]" << std::endl;
            //std::cout << "lPos: " << lPos << " pos: " << pos << " size: " << value.size() << std::endl;
            if (pos == value.size() - 1) {
                //std::cout << "TextBlock::setValue - enabling trailing line" << std::endl;
                this->trailingNewline = true;
            }
        }
        this->lines.push_back(token);
        //value.erase(0, pos + delimiter.length());
        lPos = pos + delimiter.length();
        tLines++;
    }
    //std::cout << "lPos: " << lPos << " pos: " << pos << " size: " << value.size() << " last: [" << value.substr(lPos) << "]" << std::endl;
    // if we're not at the end of the string, we don't end on a trailing slash
    // lPos == value.size()? true :
    if (value.substr(lPos) != "") {
        //std::cout << "Pushing back [" << value.substr(lPos) << "]" << std::endl;

        this->lines.push_back(value.substr(lPos));
    } else {
        if (lPos == 1) {
            this->trailingNewline = true;
        }
    }
    return tLines;
}

std::string TextBlock::getValue() {
    std::string value = "";
    for(auto s : this->lines) {
        value += s + '\r';
    }
    //std::cout << "TextBlock::getValue before strip[" << !this->trailingNewline << "] [" << value << "] lines[" << this->lines.size() << "]" << std::endl;
    if (!this->trailingNewline && this->lines.size()) {
        value.pop_back();
    }
    return value;
}

std::string TextBlock::getValueUpTo(size_t x, size_t y) {
    std::string value;
    if (y && this->lines.size()) {
        for(size_t cy = 0; cy < y; cy++) {
            value += this->lines[cy] + "\r";
        }
        // we don't want this because 1st char on the 2nd line breaks
        /*
        // if we're not at the start of a new line, remove the newline
        if (this->lineLength(y)) {
            std::cout << "TextBlock::getValueUpTo - removing added newline because this line has text" << std::endl;
            value.pop_back();
        }
        */
        //std::cout << "TextBlock::getValueUpTo y read[" << value << "]" << std::endl;
    }
    if (x) {
        //std::cout << "TextBlock::getValueUpTo value pre x [" << value << "]" << std::endl;
        value += this->lines[y].substr(0, x);
        //std::cout << "TextBlock::getValueUpTo x [" << value << "]" << std::endl;
    }
    //std::cout << "TextBlock::getValueUpTo trailingNewline: " << this->trailingNewline << std::endl;
    /*
    if (this->trailingNewline) {
        // and we're at the end of the last line
        //std::cout << "lines: " << this->lines.size() << " lineLength: " << this->lineLength(y) << std::endl;
        // x can't be at the start of the line
        //if (y == this->lines.size() - 1 && x == this->lineLength(y) && x) {
            //std::cout << "TextBlock::getValueUpTo adding a trailingNewline" << std::endl;
            //value += "\r";
        //}
    }
    */
    return value;
}

size_t TextBlock::lineLength(size_t y) {
    if (y >= this->lines.size()) {
        if (!this->trailingNewline) {
            std::cout << "TextArea::lengthLine - y: " << y << " lines: " << this->lines.size() << std::endl;
        }
        return 0;
    }
    return this->lines[y].size();
}


code:
#ifndef TEXTBLOCK_H
#define TEXTBLOCK_H

#include <string>
#include <vector>

class TextBlock {
public:
    // methods
    void print();
    void insertAt(std::string str, size_t x, size_t y);
    void deleteAt(size_t x, size_t y, size_t count);
    std::string getValue();
    std::string getValueUpTo(size_t x, size_t y);
    size_t setValue(std::string value);
    size_t lineLength(size_t y);
    // properties
    std::vector<std::string> lines;
    bool trailingNewline = false;
};

#endif


code:
#include "URL.h"

#include "StringUtils.h"

/*
 * From the following RFC: https://tools.ietf.org/html/rfc3986
 *
 * pct-encoded = "%" HEXDIG HEXDIG
 * reserved    = gen-delims / sub-delims
 * gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"
 * sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
 *                / "*" / "+" / "," / ";" / "="
 *
 */

enum URIParseState {
    SCHEME,
    FIRST_SLASH,
    SECOND_SLASH_OR_ELSE,
    AUTHORITY,
    AUTHORITY_USERINFO, /* The part before '@' */
    AUTHORITY_PASSWORD, /* RFC states that we should either reject or ignore it (We ignore it) */
    AUTHORITY_HOST,
    AUTHORITY_PORT,
    PATH,
    QUERY,
    FRAGMENT,
};

// TODO
bool isValidCharacter(char c);
bool isValidCharacter(char c) {
    return true;
}

// put inside URL(std::string) constructor?
std::tuple<std::unique_ptr<URL>,enum URIParseError> parseUri(std::string raw) {
    std::unique_ptr<URL> uri = std::make_unique<URL>();
    uri->path = "/";
    unsigned int cursor = 0;
    unsigned int last = 0;
    unsigned int lastSemicolon = 0;
    bool isPercentEncoded = true;
    enum URIParseState state = SCHEME;
    // TODO Validate at the end that every field were defined (ie: http:// is valid, but it's clearly not)
    // Remember file:// doesn't need a port (for end validation)

    if (raw[cursor] == '/') {
        // unless it's / for relative URLs
        // need this so we can merge URLs

        // make sure it's not // (relative scheme)
        if (raw.length() > 1) {
            if (raw[cursor + 1] == '/') {
                // there is a host
                uri->scheme = "relative";
                state = AUTHORITY;
                cursor += 2; // skip the //
                last = 2;
            } else {
                 // relative path
                uri->scheme = ""; // probably doesn't matter if it's "" or "relative"
                state = PATH;
            }
        }
    } else {
        // First character of scheme MUST be alphabetic
        if (!isalpha(raw[cursor])) {
            std::cerr << "invalid scheme: '" << raw.substr(last, cursor - last+1) << "'" << std::endl;
            return std::make_tuple(std::move(uri), URI_PARSE_ERROR_SCHEME);
        }
    }
    //std::cout << "URL::parseUri - starting at " << cursor << " [" << raw[cursor] << "]" << std::endl;
    for (; cursor < raw.length(); cursor++) {
        /* TODO
         * Allow scheme-less uri (and fallback to https/http) */
        if (state == SCHEME) {
            if (raw[cursor] == ':') {
                uri->scheme = toLowercase(raw.substr(0, cursor));
                uri->setPort();
                state = FIRST_SLASH;
            } else if (!isalpha(raw[cursor]) && !isdigit(raw[cursor]) && raw[cursor] != '+' &&
                       raw[cursor] != '-' && raw[cursor] != '.'  && raw[cursor] != '/') { // why this exception list?
                /* URI MUST have a scheme  */
                std::cerr << "invalid scheme: '" << raw.substr(last, cursor - last+1) << "' cursor: " << cursor << std::endl;
                return std::make_tuple(std::move(uri), URI_PARSE_ERROR_SCHEME);
            }
        } else if (state == FIRST_SLASH) {
            if (raw[cursor] == '/') {
                state = SECOND_SLASH_OR_ELSE;
            } else {
                std::cerr << "missing '/' after scheme" << std::endl;
                return std::make_tuple(std::move(uri), URI_PARSE_ERROR_SCHEME);
            }
        } else if (state == SECOND_SLASH_OR_ELSE) {
            if (raw[cursor] == '/') {
                last = cursor + 1;
                state = AUTHORITY;
                if (uri->scheme == "file") {
                    //std::cout << "URL:::parseUri file scheme, current path[" << uri->path << "]" << std::endl;
                    state = PATH;
                }
            } else {
                // TODO Handle this, URI may have only one slash
                std::cerr << "URI with only one '/' not currently supported" << std::endl;
                return std::make_tuple(std::move(uri), URI_PARSE_ERROR_SCHEME);
            }
        } else if (state == AUTHORITY) {
            /* At this point, this could either be the semi colon for
             * the password or for the port*/
            if (raw[cursor] == ':') {
                lastSemicolon = cursor;
            } else if (raw[cursor] == '@') {
                uri->userinfo = raw.substr(last, cursor - last);
                last = cursor + 1;
                state = AUTHORITY_HOST;
                // Authority is finished, everything should be considered as the host[port].
                //  TODO terminated by the next slash ("/"), question mark ("?"), or number sign ("#") character, or by the end of the URI.
                //  What to do when ? and # ?
            } else if (raw[cursor] == '/') { // end if we run into /
                if (lastSemicolon > 0) { // FIXME: it's a colon not semicolon
                    // TODO Validate port
                    if (cursor - lastSemicolon - 1 > 0) {
                        uri->port = std::stoi(raw.substr(lastSemicolon+1, cursor - lastSemicolon+1));
                    }
                    uri->host = raw.substr(last, lastSemicolon - last);
                } else {
                    uri->host = raw.substr(last, cursor - last);
                }
                last = cursor;
                cursor--;
                state = PATH;
            } else if (raw[cursor] == '?' || raw[cursor] == '#') {
                uri->host = raw.substr(last, cursor - last);
                last = cursor;
                if (raw[cursor] == '?') {
                    state = QUERY;
                } else {
                    state = FRAGMENT;
                }
            } else if (cursor + 1 == raw.length()) { // if at end of input
                uri->host = raw.substr(last, lastSemicolon - last);
                uri->path = "/";
                break;
            } else {
                if (isPercentEncoded && !isValidCharacter(raw[cursor])) {
                    isPercentEncoded = false;
                }
            }
        // TODO Accept Ipv weirdness (ipversion and literal)
        /* We are accepting pretty much anything here.. However not everything
         * is valid. Should we try to validate at this point ? */
        } else if (state == AUTHORITY_HOST) {
            if (raw[cursor] == ':') {
                uri->host = raw.substr(last, cursor - last);
                last = cursor + 1;
                state = AUTHORITY_PORT;
            } else if (raw[cursor] == '/') {
                uri->host = raw.substr(last, cursor - last);
                last = cursor;
                cursor--;
                state = PATH;
            } else {
                if (isPercentEncoded && !isValidCharacter(raw[cursor])) {
                    isPercentEncoded = false;
                }
            }
        } else if (state == AUTHORITY_PORT) {
            if (raw[cursor] == '/') {
                if (cursor - last > 0) {
                    /* RFC doesn't specify the max port number, so at this point
                     * just accept it. */
                    uri->port = std::stoi(raw.substr(last, cursor - last));
                }
                last = cursor;
                cursor--;
                state = PATH;
            } else if (!isdigit(raw[cursor])) {
                std::cerr << "invalid port: '" << raw.substr(last, cursor - last + 1) << "'" << std::endl;
                return std::make_tuple(std::move(uri), URI_PARSE_ERROR_PORT);
            }
        } else if (state == PATH) {
            //std::cout << "state == PATH char:" << raw[cursor] << std::endl;
            if (raw[cursor] == '?' || raw[cursor] == '#') {
                uri->path = raw.substr(last, cursor - last);
                last = cursor;
                if (raw[cursor] == '?') {
                    state = QUERY;
                } else {
                    state = FRAGMENT;
                }
            } else if (cursor + 1 == raw.length()) {
                uri->path = raw.substr(last, cursor + 1 - last);
                break;
            }
        } else if (state == QUERY) {
            //std::cout << "parsing query " << raw[cursor] << " @ " << (cursor + 1) << "/" << raw.length() << std::endl;
            if (raw[cursor] == '#') {
                uri->query = raw.substr(last + 1, cursor - last - 1);
                std::cout << "Parsed query " << uri->query << std::endl;
                last = cursor;
                state = FRAGMENT;
            } else if (cursor + 1 == raw.length()) {
                uri->query = raw.substr(last + 1, cursor + 1 - last);
                std::cout << "Parsed query " << uri->query << std::endl;
                break;
            }
        } else if (state == FRAGMENT) {
            if (cursor + 1 == raw.length()) {
                uri->fragment = raw.substr(last + 1, cursor + 1 - last);
                break;
            }
        }
    }
    /*
     * File scheme allows a host (ie: file://<host>/<path>)
     * If the host is empty then be default to localhost
     */
    if (uri->host.length() == 0 && uri->scheme == "file") {
        uri->host = "127.0.0.1";
    }
    return std::make_tuple(std::move(uri), URI_PARSE_ERROR_NONE);
}

// Why do we need this ? -tomleb
URL::URL() {
    scheme = "";
    userinfo = "";
    host = "";
    port = 0;
    path = "";
    query = "";
    fragment = "";
}

URL::URL(std::string const& url) {
    construct(url);
}

void URL::setPort() {
    /* TODO
     * Put default port now (Should use a table for that but
     * I don't know C++ enough) */
    if (this->scheme == "http") {
        this->port = 80;
    }
    if (this->scheme == "https") {
        this->port = 443;
    }
}

std::string URL::toString() const {
    //std::cout << "scheme[" << scheme << "] host[" << host << "] path [" << path << "] query[" << query << "]" << std::endl;
    if (isRelative()) {
        return path;
    }
    /* File is most likely gonna be localhost, we don't wanna print it .. */
    if (scheme == "file") {
        return scheme + "://" + path;
    } else {
        if (query != "") {
            return scheme + "://" + host + path + "?" + query;
        }
        return scheme + "://" + host + path;
    }
}

bool URL::isRelative() const {
    return scheme.size() == 0;
}

URL URL::merge(URL const& url) const {
    if (url.scheme == "relative") {
        URL returnURL = url.copy();
        returnURL.scheme = this->scheme;
        returnURL.setPort();
        return returnURL;
    }
    if (!url.isRelative()) {
        return url.copy();
    }

    URL returnURL = copy();
    //std::cout << "URL::merge - source " << url.toString() << std::endl;
    //std::cout << "URL::merge - copy " << returnURL.toString() << std::endl;

    // if path is //
    if (url.path[0] == '/' && url.path[1] == '/') {
        auto slashPos = url.path.find('/', 2);
        returnURL.host = url.path.substr(2, slashPos - 2);
        if (slashPos == std::string::npos) {
            returnURL.path = "/";
        } else {
            returnURL.path = url.path.substr(slashPos);
        }
    } else if (url.path[0] == '/') { // is absolute path
        returnURL.path = url.path;
        // FIXME: make smarter about merging query strings
        if (url.query !="") {
            returnURL.query += "&"+url.query;
        }
    } else {
        if (returnURL.path.back() != '/') { // if doesn't end at /
            // strip off up to last slash
            auto finalSlashPos = returnURL.path.find_last_of('/');
            returnURL.path.erase(finalSlashPos + 1);
        }
        returnURL.path += url.path;
    }

    /*
    auto hashPos = returnURL.document.find("#");
    if (hashPos != std::string::npos) {
        returnURL.document = returnURL.document.substr(0, hashPos);
    }
    */

    return returnURL;
}

void URL::construct(std::string const& url) {
    auto result = parseUri(url);
    if (std::get<1>(result) != URI_PARSE_ERROR_NONE) {
        // TODO We probably wanna handle this better..
        std::cerr << "error parsing uri" << std::endl;
        return;
    }
    std::unique_ptr<URL> uri = std::move(std::get<0>(result));
    scheme = uri->scheme;
    userinfo = uri->userinfo;
    host = uri->host;
    port = uri->port;
    path = uri->path;
    query = uri->query;
    fragment = uri->fragment;

    /*
    scheme = getSchemeFromURL(url);
    if (scheme.size() != 0) {
        host = getHostFromURL(url);
        path = getDocumentFromURL(url);
    } else {
        host = "";
        path = url;
    }

    if (path.size() == 0) {
        path = "/";
    }
    */
}

URL URL::copy() const {
    URL url;
    url.scheme = scheme;
    url.userinfo = userinfo;
    url.host = host;
    url.port = port;
    url.path = path;
    url.query = query;
    url.fragment = fragment;
    return url;
}

std::ostream& operator<<(std::ostream& out, URL const& url) {
    out << url.toString();
    return out;
}


code:
#ifndef URL_H
#define URL_H

#include <string>
#include <memory>
#include <iostream>

enum URIParseError {
    URI_PARSE_ERROR_SCHEME,
    URI_PARSE_ERROR_PORT,
    URI_PARSE_ERROR_NONE,
};

struct URL {
    URL();
    URL(std::string const& url);

    void setPort();
    std::string toString() const;
    bool isRelative() const;
    URL merge(URL const& url) const;

    // switching to the official RFC names
    std::string scheme; // was protocol
    //struct Authority authority; /* Can be empty */
    std::string userinfo;
    std::string host;
    int port;
    std::string path; // was document
    std::string query; // ?blablabla=asdfasf....
    std::string fragment; // #asfawefm

private:
    void construct(std::string const& url);
    URL copy() const;
};

std::tuple<std::unique_ptr<URL>,enum URIParseError> parseUri(std::string raw);
std::ostream& operator<<(std::ostream& out, URL const& url);

#endif


code:
#include "WebResource.h"

#include <fstream>
#include <map>
#include <algorithm>
#include "../networking/HTTPCommon.h"
#include "../networking/HTTPRequest.h"
#include "../networking/HTTPResponse.h"
#include "../networking/HTTPSRequest.h"
#include "StringUtils.h"
#include <iostream>
#include "Log.h"

namespace {

    // only used for local files atm
    std::map<std::string, ResourceType> strToRT = {
        {"html", ResourceType::HTML},
        {"txt", ResourceType::TXT},
        {"text", ResourceType::TXT},
        {"css", ResourceType::CSS}, //TXT?
        {"js", ResourceType::JS} //TXT?
    };

    bool isOnlineResource(URL const& url) {
        return url.scheme != "file";
    }

}

WebResource::WebResource() {
    resourceType = ResourceType::INVALID;
    raw = "";
}

WebResource::WebResource(ResourceType rtype, std::string const& rraw) {
    resourceType = rtype;
    raw = rraw;
}

WebResource getWebResource(URL const& url) {
    if (isOnlineResource(url)) {
        //std::cout << "WebReousrce::getWebResource - isOnline" << std::endl;
        return getOnlineWebResource(url, nullptr);
    }
    //std::cout << "WebReousrce::getWebResource - isOffline" << std::endl;
    return getLocalWebResource(url);
}

WebResource getLocalWebResource(URL const& url) {
    std::string fileExtension = getFilenameExtension(url.path);
    if (fileExtension.length() == 0) {
        return WebResource(ResourceType::INVALID,
                           "Could not find any file extension");
    }

    // Convert file extension to lowercase for table lookup.
    std::transform(fileExtension.begin(),
                   fileExtension.end(),
                   fileExtension.begin(),
                   tolower);

    if (strToRT.find(fileExtension) == strToRT.end()) {
        return WebResource(ResourceType::INVALID,
                           "Local file with extension " + fileExtension + " is not supported. Did you forget a http[s]://?");
    }

    std::ifstream in(url.path, std::ios::in | std::ios::binary);
    if (in) {
        // There exists more efficient ways of doing this, but it works for the
        // time being.
        std::string contents = std::string(std::istreambuf_iterator<char>(in),
                                           std::istreambuf_iterator<char>());

        return WebResource(strToRT[fileExtension], contents);
    }

    return WebResource(ResourceType::INVALID,
                       "Could not open file " + url.path);
}

WebResource getOnlineWebResource(URL const& url, std::unique_ptr<std::map<std::string, std::string>> formData) {
    std::shared_ptr<URL> uri=std::make_shared<URL>(url);

    std::unique_ptr<std::string> ptrPostBody = nullptr;
    if (formData) {
        std::string postBody = "";
        // iterator over formData
        for (auto &entry : *formData) {
            postBody += entry.first + "=" + entry.second + "&";
        }
        // strip last & off
        postBody = postBody.substr(0, postBody.size() - 1);
        std::cout << "postBody is " << postBody << std::endl;
        // add to string
        ptrPostBody = std::make_unique<std::string>(postBody);
    }

    WebResource returnRes;
    std::string redirectLocation = "";

    std::function<void(const HTTPResponse&)> responseCallback = [&](HTTPResponse const& response){
        logDebug() << "getOnlineWebResource responseCallback got " << response.statusCode << std::endl;
        if (response.statusCode == 301 || response.statusCode == 302 || response.statusCode == 303) {
            std::string location;
            if (response.properties.find("Location")==response.properties.end()) {
                if (response.properties.find("location")==response.properties.end()) {
                    logDebug() << "getOnlineWebResource responseCallback - got " << response.statusCode << " without a location" << std::endl;
                    for(auto const &row : response.properties) {
                        logDebug() << "getOnlineWebResource responseCallback - " << row.first << "=" << response.properties.at(row.first) << std::endl;
                    }
                    redirectLocation = "_";
                } else {
                    location = response.properties.at("location");
                }
            } else {
                location = response.properties.at("Location");
            }
            logDebug() << "Redirect To: " << location << std::endl;
            redirectLocation = location;

            // download redirect
            returnRes = getOnlineWebResource(redirectLocation, nullptr);

        } else if (response.statusCode != 200) {
            returnRes.resourceType = ResourceType::INVALID;
            returnRes.raw = "Unsupported status code: " + std::to_string(response.statusCode);
        } else {
            // TODO: Set resourceType based on Content-Type field.
            std::string contentType = "";
            if (response.properties.find("Content-type") != response.properties.end()) {
                contentType = response.properties.at("Content-type");
            }
            if (response.properties.find("Content-Type") != response.properties.end()) {
                contentType = response.properties.at("Content-Type");
            }
            std::cout << "Content-type: " << contentType << std::endl;
            if (contentType == "text/plain") {
                returnRes.resourceType = ResourceType::TXT;
            } else if (contentType == "application/json") {
                returnRes.resourceType = ResourceType::TXT;
            } else {
                returnRes.resourceType = ResourceType::HTML;
            }
            returnRes.raw = std::move(response.body);
        }
    };

    //logDebug() << "Scheme: " << uri->scheme << std::endl;
    if  (uri->scheme == "https") {
        HTTPSRequest secure(uri);
        if (formData) {
            secure.method = Method::POST;
        }
        //secure.version = Version::HTTP11;
        //logDebug() << "sending request over SSL" << std::endl;
        bool res = secure.sendRequest(responseCallback, std::move(ptrPostBody));
        //logDebug() << "SSL result: " << res << std::endl;
    } else {
        HTTPRequest request(uri);
        if (formData) {
            request.method = Method::POST;
        }
        request.sendRequest(responseCallback, std::move(ptrPostBody));
    }
    return returnRes;
}


code:
#ifndef WEBRESOURCE_H
#define WEBRESOURCE_H

#include <string>
#include <map>
#include "URL.h"
#include "../networking/HTTPResponse.h"
#include <functional>

enum class ResourceType {
    INVALID,
    HTML,
    CSS,
    JS,
    TXT
};

struct WebResource {
    WebResource();
    WebResource(ResourceType rtype, std::string const& rraw);

    ResourceType resourceType;
    std::string raw;
    static std::function<void(const HTTPResponse&)> responseCallback;
};

// Depending on the resourceName specified, this function will forward the call
// to either getLocalWebResource or getOnlineWebResource.
WebResource getWebResource(URL const& url);

// Loads a resource from the local file storage.
WebResource getLocalWebResource(URL const& url);

// Loads a resource from an internet address.
WebResource getOnlineWebResource(URL const& url, std::unique_ptr<std::map<std::string, std::string>> formData);

#endif


code:
/* libSoX minimal glob for MS-Windows: (c) 2009 SoX contributors
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or (at
 * your option) any later version.
 *
 * This library 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 Lesser
 * General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "win32-glob.h"
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>

typedef struct file_entry
{
    char name[MAX_PATH];
    struct file_entry *next;
} file_entry;

static int
insert(
    const char* path,
    const char* name,
    file_entry** phead)
{
    int len;
    file_entry* cur = malloc(sizeof(file_entry));
    if (!cur)
    {
        return ENOMEM;
    }

    len = _snprintf(cur->name, MAX_PATH, "%s%s", path, name);
    cur->name[MAX_PATH - 1] = 0;
    cur->next = *phead;
    *phead = cur;

    return len < 0 || len >= MAX_PATH ? ENAMETOOLONG : 0;
}

static int
entry_comparer(
    const void* pv1,
    const void* pv2)
{
	const file_entry* const * pe1 = pv1;
	const file_entry* const * pe2 = pv2;
    return _stricmp((*pe1)->name, (*pe2)->name);
}

int
glob(
    const char *pattern,
    int flags,
    void *unused,
    glob_t *pglob)
{
    char path[MAX_PATH];
    file_entry *head = NULL;
    int err = 0;
    size_t len;
    unsigned entries = 0;
    WIN32_FIND_DATAA finddata;
    HANDLE hfindfile = FindFirstFileA(pattern, &finddata);

    if (!pattern || flags != (flags & GLOB_FLAGS) || unused || !pglob)
    {
        errno = EINVAL;
        return EINVAL;
    }

    path[MAX_PATH - 1] = 0;
    strncpy(path, pattern, MAX_PATH);
    if (path[MAX_PATH - 1] != 0)
    {
        errno = ENAMETOOLONG;
        return ENAMETOOLONG;
    }

    len = strlen(path);
    while (len > 0 && path[len - 1] != '/' && path[len - 1] != '\\')
        len--;
    path[len] = 0;

    if (hfindfile == INVALID_HANDLE_VALUE)
    {
        if (flags & GLOB_NOCHECK)
        {
            err = insert("", pattern, &head);
            entries++;
        }
    }
    else
    {
        do
        {
            err = insert(path, finddata.cFileName, &head);
            entries++;
        } while (!err && FindNextFileA(hfindfile, &finddata));

        FindClose(hfindfile);
    }

    if (err == 0)
    {
        pglob->gl_pathv = malloc((entries + 1) * sizeof(char*));
        if (pglob->gl_pathv)
        {
            pglob->gl_pathc = entries;
            pglob->gl_pathv[entries] = NULL;
            for (; head; head = head->next, entries--)
                pglob->gl_pathv[entries - 1] = (char*)head;
            qsort(pglob->gl_pathv, pglob->gl_pathc, sizeof(char*), entry_comparer);
        }
        else
        {
            pglob->gl_pathc = 0;
            err = ENOMEM;
        }
    }
    else if (pglob)
    {
        pglob->gl_pathc = 0;
        pglob->gl_pathv = NULL;
    }

    if (err)
    {
        file_entry *cur;
        while (head)
        {
            cur = head;
            head = head->next;
            free(cur);
        }

        errno = err;
    }

    return err;
}

void
globfree(
    glob_t* pglob)
{
    if (pglob)
    {
        char** cur;
        for (cur = pglob->gl_pathv; *cur; cur++)
        {
            free(*cur);
        }

        pglob->gl_pathc = 0;
        pglob->gl_pathv = NULL;
    }
}


code:
/* libSoX minimal glob for MS-Windows: (c) 2009 SoX contributors
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or (at
 * your option) any later version.
 *
 * This library 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 Lesser
 * General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef GLOB_H
#define GLOB_H 1

#define GLOB_NOCHECK (16)
#define GLOB_FLAGS (GLOB_NOCHECK)

typedef struct glob_t
{
    unsigned gl_pathc;
    char **gl_pathv;
} glob_t;

#ifdef __cplusplus
extern "C" {
#endif

int
glob(
    const char *pattern,
    int flags,
    void *unused,
    glob_t *pglob);

void
globfree(
    glob_t* pglob);

#ifdef __cplusplus
}
#endif

#endif /* ifndef GLOB_H */


code:
#include <string>
#include <iostream>
#include "LRUCache.h"

using namespace std;

int main(int argc, char **argv) {
	LRUCache<string, int> lru(4);

	lru.insert("hello", new int(1));
	lru.insert("hi", 2);
	lru.insert("where", 3);
	lru.insert("are", 4);
	lru.insert("you", 5);
	lru.debug_cache();
	lru.find("where");
	std::cout << "------------" << std::endl;
	lru.debug_cache();
	return 0;
}


code:
#include "netrunner.h"
#include "CFGFileParser.h"
#ifdef _WIN32
extern "C"{void init_heap();}
#endif

int main(void){
    #ifdef _WIN32
    init_heap();
    #endif

    // test vectors
    // This is our reference, should always be valid.
    ntr::fast_string buf1 = "# This is a comment.\n.This is a formatting directive.\n# The following is a valid directive:\nHOMEPAGE:[http://motherfuckingwebsite.com]\n# Another comment.\nDIRECTIVE2:[sometext]\n\n";

    // Leading number.
    ntr::fast_string buf2 = "# This is a comment.\n.This is a formatting directive.\n# Not a valid directive:\n4chan:[sometext here]\n# Still another comment.";

    // Lowercase letters. Also a valid directive.
    ntr::fast_string buf3 = "# Comment.\n.h2 Perl formatting junk.\n# Another comment.\nbad_directive:[ssometext]\n# One more comment.";

    // Unescaped comment.
    ntr::fast_string buf4 = "# A comment.\nUnescaped comment!\n# A valid comment.\n\n# The following directive is untouched, since the parser SHOULD have quit earlier:\nBUGURL:[http://rvx86.net]\n# One final comment.";

    // Old-style Lynx directive. Invalid here.
    ntr::fast_string buf5 = "# This is a comment.\n.This is a formatting directive.\n# The following is a valid directive in Lynx, but not for NetRunner:\nHOMEPAGE:http://motherfuckingwebsite.com\n# Another comment.";

    // Invalid leading character.
    ntr::fast_string buf6 = "# Comment.\n.h2 Perl formatting junk.\n# Another comment.\n^bad_directive:[ssometext]\n# One more comment.";

    // Incomplete directive.
    ntr::fast_string buf7 = "# Comment.\n.h2 Perl formatting junk.\n# Another comment.\nbad_directive:[ssometext\n# One more comment.";

    // Incomplete directive.
    ntr::fast_string buf8 = "# Comment.\n.h2 Perl formatting junk.\n# Another comment.\nbad_directive:ssometext]\n# One more comment.";

    // Incomplete directive.
    ntr::fast_string buf9 = "# Comment.\n.h2 Perl formatting junk.\n# Another comment.\nbad_directive [ssometext]\n# One more comment.";

    // Must have a space
    ntr::fast_string buf10 = "# Comment.\n.h2 Perl formatting junk.\n# Another comment.\nbad_directive:[ ]\n# One more comment.";

    CFGFileParser test1(buf1);
    CFGFileParser test2(buf2);
    CFGFileParser test3(buf3);
    CFGFileParser test4(buf4);
    CFGFileParser test5(buf5);
    CFGFileParser test6(buf6);
    CFGFileParser test7(buf7);
    CFGFileParser test8(buf8);
    CFGFileParser test9(buf9);
    CFGFileParser test10(buf10);

    puts("CFG Parser Test for /ntr/\n<despair@netrunner.cc>\n");

    if (test1.ParseText()){
        puts("Test 1 passed. This is the reference string.\n");
    }
    else{
        puts("Test 1 FAILED!\n");
    }
    if (test2.ParseText()){
        puts("Test 2 passed.\n");
    }
    else{
        puts("Test 2 FAILED: Directives must not begin with a number.\n");
    }
    if (test3.ParseText()){
        puts("Test 3 passed. Mixed-case directives are valid.\n");
    }
    else{
        puts("Test 3 FAILED: see above\n");
    }
    if (test4.ParseText()){
        puts("Test 4 passed.\n");
    }
    else{
        puts("Test 4 FAILED: A stray comment.\n");
    }
    if (test5.ParseText()){
        puts("Test 5 passed.");
    }
    else{
        puts("Test 5 FAILED: Old-style Lynx CFG directive. No longer valid here.\n");
    }
    if (test6.ParseText()){
        puts("Test 6 passed.");
    }
    else{
        puts("Test 6 FAILED: Leading non-alpha symbol\n");
    }
    if (test7.ParseText()){
        puts("Test 7 passed.");
    }
    else{
        puts("Test 7 FAILED: Missing terminator\n");
    }
    if (test8.ParseText()){
        puts("Test 8 passed.");
    }
    else{
        puts("Test 8 FAILED: Missing separator\n");
    }
    if (test9.ParseText()){
        puts("Test 9 passed.");
    }
    else{
        puts("Test 9 FAILED: Missing colon separator\n");
    }
    if (test10.ParseText()){
        puts("Test 10 passed. Blank directives MUST have at least one space");
    }
    else{
        puts("Test 10 FAILED: Null directive\n");
    }
    return 0;
}


code:
#include <algorithm>
#include <iostream>
#include <memory>
#include <string>
#include "../../src/TextBlock.h"

int main(void) {
    TextBlock jenny;
    size_t lines;
    if (jenny.getValue() != "") {
        std::cout << "FAIL Start: " << jenny.getValue() << std::endl;
    }
    lines = jenny.setValue("Everybody mad at the rocks that I wear");
    if (jenny.getValue() != "Everybody mad at the rocks that I wear") {
        std::cout << "FAIL SetSingle: " << lines << " " << jenny.getValue() << std::endl;
    }
    jenny.deleteAt(0, 0, 1);
    if (jenny.getValue() != "verybody mad at the rocks that I wear") {
        std::cout << "FAIL DelFirst: " << lines << " " << jenny.getValue() << std::endl;
    }
    jenny.deleteAt(jenny.getValue().size() -1, 0, 1);
    if (jenny.getValue() != "verybody mad at the rocks that I wea") {
        std::cout << "FAIL DelLast: " << lines << " " << jenny.getValue() << std::endl;
    }
    lines = jenny.setValue("Men go working\rSome go stealing");
    if (jenny.getValue() != "Men go working\rSome go stealing") {
        std::cout << "FAIL SetMutli: " << lines << " " << jenny.getValue() << std::endl;
    }
    lines = jenny.setValue("Men go working\rSome go stealing\r");
    if (jenny.getValue() != "Men go working\rSome go stealing\r") {
        std::cout << "FAIL SetMutliTrailing: " << lines << " [" << jenny.getValue() << "]" << std::endl;
    }
    lines = jenny.setValue("");
    if (jenny.getValue() != "") {
        std::cout << "FAIL SetClear: " << lines << " [" << jenny.getValue() << "]" << std::endl;
    }
    jenny.insertAt("r", 0, 0);
    if (jenny.getValue() != "r") {
        std::cout << "FAIL InsertChar: " << lines << " " << jenny.getValue() << std::endl;
    }
    jenny.insertAt("cha", 0, 0);
    if (jenny.getValue() != "char") {
        std::cout << "FAIL InsertString: " << lines << " " << jenny.getValue() << std::endl;
    }
    jenny.insertAt("s", jenny.getValue().size(), 0);
    if (jenny.getValue() != "chars") {
        std::cout << "FAIL AppendChar: " << lines << " " << jenny.getValue() << std::endl;
    }
    jenny.insertAt("tring", jenny.getValue().size(), 0);
    if (jenny.getValue() != "charstring") {
        std::cout << "FAIL AppendString: " << lines << " " << jenny.getValue() << std::endl;
    }
    lines = jenny.setValue("135");
    if (jenny.getValue() != "135") {
        std::cout << "FAIL SetClear: " << lines << " [" << jenny.getValue() << "]" << std::endl;
    }
    jenny.insertAt("2", 1, 0);
    if (jenny.getValue() != "1235") {
        std::cout << "FAIL Insert2: " << lines << " " << jenny.getValue() << std::endl;
    }
    jenny.insertAt("4", 3, 0);
    if (jenny.getValue() != "12345") {
        std::cout << "FAIL Insert3: " << lines << " " << jenny.getValue() << std::endl;
    }
    jenny.deleteAt(3, 0, 1); // delete char we just added
    if (jenny.getValue() != "1235") {
        std::cout << "FAIL Delete3: " << lines << " " << jenny.getValue() << std::endl;
    }
    jenny.deleteAt(1, 0, 1); // delete char we just added
    if (jenny.getValue() != "135") {
        std::cout << "FAIL Delete1: " << lines << " " << jenny.getValue() << std::endl;
    }
    lines = jenny.setValue("asdf");
    if (jenny.getValue() != "asdf") {
        std::cout << "FAIL SetClear: " << lines << " [" << jenny.getValue() << "]" << std::endl;
    }
    jenny.deleteAt(2, 0, 1); // delete char we just added
    if (jenny.getValue() != "asf") {
        std::cout << "FAIL Delete2: " << lines << " " << jenny.getValue() << std::endl;
    }
    lines = jenny.setValue("\r");
    if (jenny.getValue() != "\r") {
        std::cout << "FAIL SetNewline: " << lines << " [" << jenny.getValue() << "]" << std::endl;
    }
    jenny.deleteAt(0, 0, 1); // delete char we just added
    if (jenny.getValue() != "") {
        std::cout << "FAIL DeleteLine: " << lines << " [" << jenny.getValue() << "]" << std::endl;
    }
    lines = jenny.setValue("zxcv\rzxcv\r");
    //jenny.print();
    if (jenny.getValue() != "zxcv\rzxcv\r") {
        std::cout << "FAIL Set2Newline: " << lines << " [" << jenny.getValue() << "]" << std::endl;
    }
    jenny.deleteAt(0, 2, 1); // delete char last trailing slash
    if (jenny.getValue() != "zxcv\rzxcv") {
        std::cout << "FAIL DeleteTrailingLine: " << lines << " [" << jenny.getValue() << "]" << std::endl;
    }
    jenny.deleteAt(3, 1, 1); // delete char last trailing slash
    if (jenny.getValue() != "zxcv\rzxc") {
        std::cout << "FAIL Delete3: " << lines << " [" << jenny.getValue() << "]" << std::endl;
    }
    jenny.deleteAt(2, 1, 1); // delete char last trailing slash
    if (jenny.getValue() != "zxcv\rzx") {
        std::cout << "FAIL Delete2: " << lines << " [" << jenny.getValue() << "]" << std::endl;
    }
    jenny.deleteAt(1, 1, 1); // delete char last trailing slash
    if (jenny.getValue() != "zxcv\rz") {
        std::cout << "FAIL Delete1: " << lines << " [" << jenny.getValue() << "]" << std::endl;
    }
    jenny.deleteAt(0, 1, 1); // delete char last trailing slash
    if (jenny.getValue() != "zxcv\r") {
        std::cout << "FAIL Delete0: " << lines << " [" << jenny.getValue() << "]" << std::endl;
    }
    return 0;
}


code:
#include <algorithm>
#include <iostream>
#include <memory>
#include <string>
#include "../../src/URL.h"

void test_parser(std::string url, std::string scheme, std::string userinfo,
                 std::string host, int port, std::string path, std::string query, std::string fragment) {
    //std::unique_ptr<URL>
    std::tuple<std::unique_ptr<URL>,enum URIParseError> result = parseUri(url);
    if (std::get<1>(result) != URI_PARSE_ERROR_NONE) {
        // TODO We probably wanna handle this better..
        std::cerr << "error parsing uri" << std::endl;
        return;
    }
    std::unique_ptr<URL> uri = std::move(std::get<0>(result));
    if (uri->scheme == scheme && uri->userinfo == userinfo &&
        uri->host == host && uri->port == port &&
        uri->path == path && uri->query == query && uri->fragment == fragment) {
        std::cout << "noice" << std::endl;
    } else {
        std::cout << "nope" << std::endl;
        std::cout << uri->scheme << " vs " << scheme << std::endl;
        std::cout << uri->userinfo << " vs " << userinfo << std::endl;
        std::cout << uri->host << " vs " << host << std::endl;
        std::cout << uri->port << " vs " << port << std::endl;
        std::cout << uri->path << " vs " << path << std::endl;
        std::cout << uri->query << " vs " << query << std::endl;
        std::cout << uri->fragment << " vs " << fragment << std::endl;
    }
}

int main(void) {
    test_parser("HTTP://username:password@www.example.org:8080/",                 "http", "username:password", "www.example.org", 8080, "/", "", "");
    test_parser("http://username:password@www.example.org:8080/",                 "http", "username:password", "www.example.org", 8080, "/", "", "");
    test_parser("http://www.example.org:8080/",                                   "http", "",                  "www.example.org", 8080, "/", "", "");
    test_parser("http://www.example.org/",                                        "http", "",                  "www.example.org", 80, "/", "", "");
    test_parser("http://www.example.org",                                         "http", "",                  "www.example.org", 80, "/", "", "");
    //test_parser("http://www.example.org//",                                       "http", "",                  "www.example.org", 80, "/", "", "");
    test_parser("http://www.example.org/this/path",                               "http", "",                  "www.example.org", 80, "/this/path", "", "");
    test_parser("http://www.example.org:/this/path",                              "http", "",                  "www.example.org", 80, "/this/path", "", "");
    test_parser("http://username:password@www.example.org:/this/path",            "http", "username:password", "www.example.org", 80, "/this/path", "", "");
    test_parser("http://username:password@www.example.org/",                      "http", "username:password",  "www.example.org", 80, "/", "", "");
    test_parser("http://username:passwor:d@www.example.org/",                     "http", "username:passwor:d", "www.example.org", 80, "/", "", "");
    test_parser("http://username:passwor:d@www.example.org:9090/",                "http", "username:passwor:d", "www.example.org", 9090, "/", "", "");
    test_parser("http://username:passwor:d@www.example.org:9090/this/path?query", "http", "username:passwor:d", "www.example.org", 9090, "/this/path", "query", "");
    test_parser("http://www.example.org:9090/this/path?query",                    "http", "", "www.example.org", 9090, "/this/path", "query", "");
    test_parser("http://www.example.org/this/path?query",                         "http", "", "www.example.org", 80, "/this/path", "query", "");
    test_parser("http://www.example.org?query",                                   "http", "", "www.example.org", 80, "/", "query", "");
    return 0;
}


code:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <VCProjectVersion>15.0</VCProjectVersion>
    <ProjectGuid>{0ECC8CA1-2094-4A51-BD89-8AEC9A6B6A43}</ProjectGuid>
    <Keyword>Win32Proj</Keyword>
    <RootNamespace>NetRunner</RootNamespace>
    <WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v141</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v141</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v141</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v141</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Label="Shared">
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <LinkIncremental>true</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <LinkIncremental>true</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <LinkIncremental>false</LinkIncremental>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <LinkIncremental>false</LinkIncremental>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <ClCompile>
      <PrecompiledHeader>
      </PrecompiledHeader>
      <WarningLevel>Level3</WarningLevel>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>C:\Users\user1\Source\Repos\netrunner\deps\vcpkg-master\vcpkg-master\installed\x86-windows\include;C:\Users\user1\Source\Repos\netrunner\deps\vcpkg-master\vcpkg-master\installed\x86-windows\include\harfbuzz;C:\Users\user1\Source\Repos\netrunner\deps\glew-2.0.0-win32\glew-2.0.0\include;C:\Users\user1\Source\Repos\netrunner\deps\glfw-3.2.1.bin.WIN32\glfw-3.2.1.bin.WIN32\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ClCompile>
    <Link>
      <SubSystem>Console</SubSystem>
      <AdditionalLibraryDirectories>C:\Users\user1\Source\Repos\netrunner\deps\vcpkg-master\vcpkg-master\installed\x86-windows\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
      <AdditionalDependencies>opengl32.lib;Ws2_32.lib;glew32.lib;glfw3dll.lib;harfbuzz.lib;freetype.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
    <PostBuildEvent>
      <Command>copy "$(SolutionDir)..\*.ttf" "$(OutDir)"
copy "$(SolutionDir)glfw3.dll" "$(OutDir)"
copy "$(SolutionDir)glew32d.dll" "$(OutDir)"
copy "$(SolutionDir)freetyped.dll" "$(OutDir)"
copy "$(SolutionDir)harfbuzz.dll" "$(OutDir)"</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <ClCompile>
      <PrecompiledHeader>
      </PrecompiledHeader>
      <WarningLevel>Level3</WarningLevel>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <PrecompiledHeader>
      </PrecompiledHeader>
      <Optimization>MaxSpeed</Optimization>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>C:\Users\user1\Source\Repos\netrunner\deps\vcpkg-master\vcpkg-master\installed\x86-windows\include;C:\Users\user1\Source\Repos\netrunner\deps\vcpkg-master\vcpkg-master\installed\x86-windows\include\harfbuzz;C:\Users\user1\Source\Repos\netrunner\deps\glew-2.0.0-win32\glew-2.0.0\include;C:\Users\user1\Source\Repos\netrunner\deps\glfw-3.2.1.bin.WIN32\glfw-3.2.1.bin.WIN32\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ClCompile>
    <Link>
      <SubSystem>Console</SubSystem>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
      <AdditionalLibraryDirectories>C:\Users\user1\Source\Repos\netrunner\deps\vcpkg-master\vcpkg-master\installed\x86-windows\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
      <AdditionalDependencies>opengl32.lib;Ws2_32.lib;glew32.lib;glfw3dll.lib;harfbuzz.lib;freetype.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
    <PostBuildEvent>
      <Command>copy "$(SolutionDir)..\*.ttf" "$(OutDir)"
copy "$(SolutionDir)glfw3.dll" "$(OutDir)"
copy "$(SolutionDir)glew32d.dll" "$(OutDir)"
copy "$(SolutionDir)freetyped.dll" "$(OutDir)"
copy "$(SolutionDir)harfbuzz.dll" "$(OutDir)"</Command>
    </PostBuildEvent>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <PrecompiledHeader>
      </PrecompiledHeader>
      <Optimization>MaxSpeed</Optimization>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
    <Link>
      <SubSystem>Windows</SubSystem>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClInclude Include="..\..\src\BrowsingHistory.h" />
    <ClInclude Include="..\..\src\CommandLineParams.h" />
    <ClInclude Include="..\..\src\graphics\components\AnimeComponent.h" />
    <ClInclude Include="..\..\src\graphics\components\BoxComponent.h" />
    <ClInclude Include="..\..\src\graphics\components\Component.h" />
    <ClInclude Include="..\..\src\graphics\components\ComponentBuilder.h" />
    <ClInclude Include="..\..\src\graphics\components\TextComponent.h" />
    <ClInclude Include="..\..\src\graphics\elements\AElement.h" />
    <ClInclude Include="..\..\src\graphics\elements\BLOCKQUOTEElement.h" />
    <ClInclude Include="..\..\src\graphics\elements\DIVElement.h" />
    <ClInclude Include="..\..\src\graphics\elements\Element.h" />
    <ClInclude Include="..\..\src\graphics\elements\H1Element.h" />
    <ClInclude Include="..\..\src\graphics\elements\H2Element.h" />
    <ClInclude Include="..\..\src\graphics\elements\H3Element.h" />
    <ClInclude Include="..\..\src\graphics\elements\LIElement.h" />
    <ClInclude Include="..\..\src\graphics\elements\PElement.h" />
    <ClInclude Include="..\..\src\graphics\elements\SPANElement.h" />
    <ClInclude Include="..\..\src\graphics\elements\STRONGElement.h" />
    <ClInclude Include="..\..\src\graphics\opengl\shaders\gen\FontShader.h" />
    <ClInclude Include="..\..\src\graphics\opengl\shaders\gen\TextureShader.h" />
    <ClInclude Include="..\..\src\graphics\opengl\Window.h" />
    <ClInclude Include="..\..\src\graphics\text\TextRasterizer.h" />
    <ClInclude Include="..\..\src\graphics\text\TextRasterizerCache.h" />
    <ClInclude Include="..\..\src\html\HTMLParser.h" />
    <ClInclude Include="..\..\src\html\Node.h" />
    <ClInclude Include="..\..\src\html\TagNode.h" />
    <ClInclude Include="..\..\src\html\TextNode.h" />
    <ClInclude Include="..\..\src\Log.h" />
    <ClInclude Include="..\..\src\networking\HTTPRequest.h" />
    <ClInclude Include="..\..\src\networking\HTTPResponse.h" />
    <ClInclude Include="..\..\src\StringUtils.h" />
    <ClInclude Include="..\..\src\URL.h" />
    <ClInclude Include="..\..\src\WebResource.h" />
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="..\..\src\BrowsingHistory.cpp" />
    <ClCompile Include="..\..\src\CommandLineParams.cpp" />
    <ClCompile Include="..\..\src\graphics\components\AnimeComponent.cpp" />
    <ClCompile Include="..\..\src\graphics\components\BoxComponent.cpp" />
    <ClCompile Include="..\..\src\graphics\components\Component.cpp" />
    <ClCompile Include="..\..\src\graphics\components\ComponentBuilder.cpp" />
    <ClCompile Include="..\..\src\graphics\components\TextComponent.cpp" />
    <ClCompile Include="..\..\src\graphics\elements\AElement.cpp" />
    <ClCompile Include="..\..\src\graphics\elements\BLOCKQUOTEElement.cpp" />
    <ClCompile Include="..\..\src\graphics\elements\DIVElement.cpp" />
    <ClCompile Include="..\..\src\graphics\elements\Element.cpp" />
    <ClCompile Include="..\..\src\graphics\elements\H1Element.cpp" />
    <ClCompile Include="..\..\src\graphics\elements\H2Element.cpp" />
    <ClCompile Include="..\..\src\graphics\elements\H3Element.cpp" />
    <ClCompile Include="..\..\src\graphics\elements\LIElement.cpp" />
    <ClCompile Include="..\..\src\graphics\elements\PElement.cpp" />
    <ClCompile Include="..\..\src\graphics\elements\SPANElement.cpp" />
    <ClCompile Include="..\..\src\graphics\elements\STRONGElement.cpp" />
    <ClCompile Include="..\..\src\graphics\opengl\Window.cpp" />
    <ClCompile Include="..\..\src\graphics\text\TextRasterizer.cpp" />
    <ClCompile Include="..\..\src\graphics\text\TextRasterizerCache.cpp" />
    <ClCompile Include="..\..\src\html\HTMLParser.cpp" />
    <ClCompile Include="..\..\src\html\Node.cpp" />
    <ClCompile Include="..\..\src\html\TagNode.cpp" />
    <ClCompile Include="..\..\src\html\TextNode.cpp" />
    <ClCompile Include="..\..\src\Log.cpp" />
    <ClCompile Include="..\..\src\main.cpp" />
    <ClCompile Include="..\..\src\networking\HTTPRequest.cpp" />
    <ClCompile Include="..\..\src\networking\HTTPResponse.cpp" />
    <ClCompile Include="..\..\src\StringUtils.cpp" />
    <ClCompile Include="..\..\src\URL.cpp" />
    <ClCompile Include="..\..\src\WebResource.cpp" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
</Project>


code:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Filter Include="Source Files">
      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
    </Filter>
    <Filter Include="Header Files">
      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
    </Filter>
    <Filter Include="Resource Files">
      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
    </Filter>
    <Filter Include="Source Files\networking">
      <UniqueIdentifier>{d3806624-b48c-45eb-a367-a6481b24d213}</UniqueIdentifier>
    </Filter>
    <Filter Include="Source Files\graphics">
      <UniqueIdentifier>{e3775856-f829-4d9b-b20a-6c3e6c156ab2}</UniqueIdentifier>
    </Filter>
    <Filter Include="Source Files\html">
      <UniqueIdentifier>{3573b3b1-5cfc-433f-bd1e-03ddc2811eb8}</UniqueIdentifier>
    </Filter>
    <Filter Include="Header Files\networking">
      <UniqueIdentifier>{2c052b20-bcae-4565-8594-1ab9e012a98f}</UniqueIdentifier>
    </Filter>
    <Filter Include="Header Files\html">
      <UniqueIdentifier>{38cd59ca-42a0-47a0-90e1-916c7ecd065b}</UniqueIdentifier>
    </Filter>
    <Filter Include="Header Files\graphics">
      <UniqueIdentifier>{948541f0-b0e8-4535-87b0-ad7fb0199ed0}</UniqueIdentifier>
    </Filter>
    <Filter Include="Source Files\graphics\components">
      <UniqueIdentifier>{56747018-d135-4bad-b0a2-bf9cf7438026}</UniqueIdentifier>
    </Filter>
    <Filter Include="Source Files\graphics\elements">
      <UniqueIdentifier>{e3b25b6b-3d95-4156-ad1d-b9a8a4d53947}</UniqueIdentifier>
    </Filter>
    <Filter Include="Source Files\graphics\text">
      <UniqueIdentifier>{2ef32f37-7c86-4cd9-bf85-f1af8e47315f}</UniqueIdentifier>
    </Filter>
    <Filter Include="Header Files\graphics\components">
      <UniqueIdentifier>{a5b3417d-3b6b-44cf-b498-117febf74dbe}</UniqueIdentifier>
    </Filter>
    <Filter Include="Header Files\graphics\elements">
      <UniqueIdentifier>{473cc93d-f674-4934-83c0-a8c06431bcac}</UniqueIdentifier>
    </Filter>
    <Filter Include="Header Files\graphics\opengl">
      <UniqueIdentifier>{da2eefb8-838f-4c69-b286-43b1d6d48eee}</UniqueIdentifier>
    </Filter>
    <Filter Include="Header Files\graphics\text">
      <UniqueIdentifier>{17b7d69a-f320-497f-8179-d5bc0a85b98b}</UniqueIdentifier>
    </Filter>
    <Filter Include="Source Files\graphics\opengl">
      <UniqueIdentifier>{595beb1e-4d80-4cfa-9a93-24f5e6d12c68}</UniqueIdentifier>
    </Filter>
    <Filter Include="Header Files\graphics\opengl\shaders">
      <UniqueIdentifier>{90c82a2c-6f33-4d6d-b333-e28496b75985}</UniqueIdentifier>
    </Filter>
    <Filter Include="Header Files\graphics\opengl\shaders\gen">
      <UniqueIdentifier>{46372e18-9e00-41d5-a8f6-d69fc0c0748b}</UniqueIdentifier>
    </Filter>
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="..\..\src\StringUtils.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\WebResource.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\html\HTMLParser.h">
      <Filter>Header Files\html</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\html\Node.h">
      <Filter>Header Files\html</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\html\TagNode.h">
      <Filter>Header Files\html</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\html\TextNode.h">
      <Filter>Header Files\html</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\networking\HTTPRequest.h">
      <Filter>Header Files\networking</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\networking\HTTPResponse.h">
      <Filter>Header Files\networking</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\components\AnimeComponent.h">
      <Filter>Header Files\graphics\components</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\components\BoxComponent.h">
      <Filter>Header Files\graphics\components</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\components\Component.h">
      <Filter>Header Files\graphics\components</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\components\ComponentBuilder.h">
      <Filter>Header Files\graphics\components</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\components\TextComponent.h">
      <Filter>Header Files\graphics\components</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\elements\AElement.h">
      <Filter>Header Files\graphics\elements</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\elements\BLOCKQUOTEElement.h">
      <Filter>Header Files\graphics\elements</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\elements\DIVElement.h">
      <Filter>Header Files\graphics\elements</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\elements\Element.h">
      <Filter>Header Files\graphics\elements</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\elements\H1Element.h">
      <Filter>Header Files\graphics\elements</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\elements\H2Element.h">
      <Filter>Header Files\graphics\elements</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\elements\H3Element.h">
      <Filter>Header Files\graphics\elements</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\elements\LIElement.h">
      <Filter>Header Files\graphics\elements</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\elements\PElement.h">
      <Filter>Header Files\graphics\elements</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\elements\SPANElement.h">
      <Filter>Header Files\graphics\elements</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\elements\STRONGElement.h">
      <Filter>Header Files\graphics\elements</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\opengl\Window.h">
      <Filter>Header Files\graphics\opengl</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\text\TextRasterizer.h">
      <Filter>Header Files\graphics\text</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\text\TextRasterizerCache.h">
      <Filter>Header Files\graphics\text</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\opengl\shaders\gen\TextureShader.h">
      <Filter>Header Files\graphics\opengl\shaders\gen</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\graphics\opengl\shaders\gen\FontShader.h">
      <Filter>Header Files\graphics\opengl\shaders\gen</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\CommandLineParams.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\BrowsingHistory.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\Log.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\URL.h">
      <Filter>Header Files</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="..\..\src\main.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\StringUtils.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\WebResource.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\html\HTMLParser.cpp">
      <Filter>Source Files\html</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\html\Node.cpp">
      <Filter>Source Files\html</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\html\TagNode.cpp">
      <Filter>Source Files\html</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\html\TextNode.cpp">
      <Filter>Source Files\html</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\networking\HTTPResponse.cpp">
      <Filter>Source Files\networking</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\networking\HTTPRequest.cpp">
      <Filter>Source Files\networking</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\components\AnimeComponent.cpp">
      <Filter>Source Files\graphics\components</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\components\BoxComponent.cpp">
      <Filter>Source Files\graphics\components</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\components\Component.cpp">
      <Filter>Source Files\graphics\components</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\components\ComponentBuilder.cpp">
      <Filter>Source Files\graphics\components</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\components\TextComponent.cpp">
      <Filter>Source Files\graphics\components</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\elements\AElement.cpp">
      <Filter>Source Files\graphics\elements</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\elements\BLOCKQUOTEElement.cpp">
      <Filter>Source Files\graphics\elements</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\elements\DIVElement.cpp">
      <Filter>Source Files\graphics\elements</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\elements\Element.cpp">
      <Filter>Source Files\graphics\elements</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\elements\H1Element.cpp">
      <Filter>Source Files\graphics\elements</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\elements\H2Element.cpp">
      <Filter>Source Files\graphics\elements</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\elements\H3Element.cpp">
      <Filter>Source Files\graphics\elements</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\elements\LIElement.cpp">
      <Filter>Source Files\graphics\elements</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\elements\PElement.cpp">
      <Filter>Source Files\graphics\elements</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\elements\SPANElement.cpp">
      <Filter>Source Files\graphics\elements</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\elements\STRONGElement.cpp">
      <Filter>Source Files\graphics\elements</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\opengl\Window.cpp">
      <Filter>Source Files\graphics\opengl</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\text\TextRasterizer.cpp">
      <Filter>Source Files\graphics\text</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\graphics\text\TextRasterizerCache.cpp">
      <Filter>Source Files\graphics\text</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\BrowsingHistory.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\CommandLineParams.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\Log.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\URL.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
</Project>


code:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <LocalDebuggerCommandArguments>http://motherfuckingwebsite.com/</LocalDebuggerCommandArguments>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
    <LocalDebuggerWorkingDirectory>$(ProjectDir)..\..\</LocalDebuggerWorkingDirectory>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <LocalDebuggerCommandArguments>http://motherfuckingwebsite.com/</LocalDebuggerCommandArguments>
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
    <LocalDebuggerWorkingDirectory>$(ProjectDir)..\..\</LocalDebuggerWorkingDirectory>
  </PropertyGroup>
</Project>


code:
#!/usr/bin/sh
if [ $MSYSTEM == "MINGW32" ]
then
	make -fNTMakeFile
else
	make -fNTMakefile AMD64=1
fi
strip -s netrunner.exe
[ -e 'bin' ] || mkdir bin
mv *.crt bin 2> /dev/null
if [ $MSYSTEM == "MINGW32" ]
then
    cp deps/lib/nt_i386/*.dll bin
    cp reltools/winnt/i386/libs*.dll bin
    cp reltools/winnt/i386/libgcc_s_sjlj-1.dll bin
    cp reltools/winnt/i386/libwinpthread-1.dll bin
else
    cp deps/lib/nt_amd64/*.dll bin
    cp reltools/winnt/amd64/libs*.dll bin
    cp reltools/winnt/amd64/libgcc_s_seh-1.dll bin
    cp reltools/winnt/amd64/libwinpthread-1.dll bin
fi
cp LICENSE bin
cp browser.ntrml bin
cp -r res bin
mv netrunner.exe bin