[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/x29a/simplecpp/master/simplecpp.cpp [Back]  [Original]

/*
 * simplecpp - A simple and high-fidelity C/C++ preprocessor library
 * Copyright (C) 2016 Daniel Marjamki.
 *
 * 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 3 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, see .
 */

#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
#define NOMINMAX
#endif
#include "simplecpp.h"

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
#include 
#undef ERROR
#undef TRUE
#define SIMPLECPP_WINDOWS
#endif

static bool isHex(const std::string &s)
{
    return s.size()>2 && (s.compare(0,2,"0x")==0 || s.compare(0,2,"0X")==0);
}


static const simplecpp::TokenString DEFINE("define");
static const simplecpp::TokenString UNDEF("undef");

static const simplecpp::TokenString INCLUDE("include");

static const simplecpp::TokenString ERROR("error");
static const simplecpp::TokenString WARNING("warning");

static const simplecpp::TokenString IF("if");
static const simplecpp::TokenString IFDEF("ifdef");
static const simplecpp::TokenString IFNDEF("ifndef");
static const simplecpp::TokenString DEFINED("defined");
static const simplecpp::TokenString ELSE("else");
static const simplecpp::TokenString ELIF("elif");
static const simplecpp::TokenString ENDIF("endif");

static const simplecpp::TokenString PRAGMA("pragma");
static const simplecpp::TokenString ONCE("once");

template static std::string toString(T t)
{
    std::ostringstream ostr;
    ostr > std::hex;
    istr >> ret;
    return ret;
}

static unsigned long long stringToULL(const std::string &s)
{
    unsigned long long ret;
    const bool hex = isHex(s);
    std::istringstream istr(hex ? s.substr(2) : s);
    if (hex)
        istr >> std::hex;
    istr >> ret;
    return ret;
}

static bool startsWith(const std::string &str, const std::string &s)
{
    return (str.size() >= s.size() && str.compare(0, s.size(), s) == 0);
}

static bool endsWith(const std::string &s, const std::string &e)
{
    return (s.size() >= e.size() && s.compare(s.size() - e.size(), e.size(), e) == 0);
}

static bool sameline(const simplecpp::Token *tok1, const simplecpp::Token *tok2)
{
    return tok1 && tok2 && tok1->location.sameline(tok2->location);
}

static bool isAlternativeBinaryOp(const simplecpp::Token *tok, const std::string &alt)
{
    return (tok->name &&
            tok->str == alt &&
            tok->previous &&
            tok->next &&
            (tok->previous->number || tok->previous->name || tok->previous->op == ')') &&
            (tok->next->number || tok->next->name || tok->next->op == '('));
}

static bool isAlternativeUnaryOp(const simplecpp::Token *tok, const std::string &alt)
{
    return ((tok->name && tok->str == alt) &&
            (!tok->previous || tok->previous->op == '(') &&
            (tok->next && (tok->next->name || tok->next->number)));
}

void simplecpp::Location::adjust(const std::string &str)
{
    if (str.find_first_of("\r\n") == std::string::npos) {
        col += str.size();
        return;
    }

    for (std::size_t i = 0U; i < str.size(); ++i) {
        col++;
        if (str[i] == '\n' || str[i] == '\r') {
            col = 1;
            line++;
            if (str[i] == '\r' && (i+1)previous)
        tok = tok->previous;
    for (; tok; tok = tok->next) {
        if (tok->previous) {
            std::cout previous) ? ' ' : '\n');
        }
        std::cout str;
    }
    std::cout next) {
        if (tok != this) {
            std::cout previous) ? ' ' : '\n');
        }
        std::cout str;
    }
    std::cout next)
        push_back(new Token(*tok));
    sizeOfType = other.sizeOfType;
}

void simplecpp::TokenList::clear()
{
    backToken = NULL;
    while (frontToken) {
        Token *next = frontToken->next;
        delete frontToken;
        frontToken = next;
    }
    sizeOfType.clear();
}

void simplecpp::TokenList::push_back(Token *tok)
{
    if (!frontToken)
        frontToken = tok;
    else
        backToken->next = tok;
    tok->previous = backToken;
    backToken = tok;
}

void simplecpp::TokenList::dump() const
{
    std::cout location.line < loc.line || tok->location.fileIndex != loc.fileIndex) {
            ret location;
        }

        while (tok->location.line > loc.line) {
            ret previous, tok))
            ret str);
    }

    return ret.str();
}

static unsigned char readChar(std::istream &istr, unsigned int bom)
{
    unsigned char ch = (unsigned char)istr.get();

    // For UTF-16 encoded files the BOM is 0xfeff/0xfffe. If the
    // character is non-ASCII character then replace it with 0xff
    if (bom == 0xfeff || bom == 0xfffe) {
        const unsigned char ch2 = (unsigned char)istr.get();
        const int ch16 = (bom == 0xfeff) ? (chop == 'R') {
                std::string delim;
                ch = readChar(istr,bom);
                while (istr.good() && ch != '(' && ch != '\n') {
                    delim += ch;
                    ch = readChar(istr,bom);
                }
                if (!istr.good() || ch == '\n')
                    // TODO report
                    return;
                currentToken = '\"';
                const std::string endOfRawString(')' + delim + '\"');
                while (istr.good() && !endsWith(currentToken, endOfRawString))
                    currentToken += readChar(istr,bom);
                if (!endsWith(currentToken, endOfRawString))
                    // TODO report
                    return;
                currentToken.erase(currentToken.size() - endOfRawString.size(), endOfRawString.size() - 1U);
                back()->setstr(escapeString(currentToken));
                location.adjust(currentToken);
                if (currentToken.find_first_of("\r\n") == std::string::npos)
                    location.col += 2 + 2 * delim.size();
                else
                    location.col += 1 + delim.size();
                continue;
            }

            currentToken = readUntil(istr,location,ch,ch,outputList);
            if (currentToken.size() < 2U)
                // TODO report
                return;

            std::string s = currentToken;
            std::string::size_type pos;
            while ((pos = s.find_first_of("\r\n")) != std::string::npos) {
                s.erase(pos,1);
            }

            push_back(new Token(s, location)); // push string without newlines

            location.adjust(currentToken);

            continue;
        }

        else {
            currentToken += ch;
        }

        if (currentToken == "")
            result = (stringToLL(tok->previous->str) > stringToLL(tok->next->str));
        else if (tok->str == ">=")
            result = (stringToLL(tok->previous->str) >= stringToLL(tok->next->str));
        else if (tok->str == "

Web Proxy Viewer  |  New URL  |  Original Page