[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/chrchr-github/simplecpp/master/test.cpp [Back]  [Original]

/*
 * simplecpp - A simple and high-fidelity C/C++ preprocessor library
 * Copyright (C) 2016-2023 simplecpp team
 */

#include "simplecpp.h"

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

#ifndef SIMPLECPP_TEST_SOURCE_DIR
#error "SIMPLECPP_TEST_SOURCE_DIR is not defined."
#endif

#define STRINGIZE_(x) #x
#define STRINGIZE(x) STRINGIZE_(x)

static const std::string testSourceDir = SIMPLECPP_TEST_SOURCE_DIR;
static int numberOfFailedAssertions = 0;

#define ASSERT_EQUALS(expected, actual)  (assertEquals((expected), (actual), __LINE__))
#define ASSERT_THROW_EQUALS(stmt, e, expected) do { try { stmt; assertThrowFailed(__LINE__); } catch (const e& ex) { assertEquals((expected), (ex.what()), __LINE__); } } while (false)

static std::string pprint(const std::string &in)
{
    std::string ret;
    for (std::string::size_type i = 0; i < in.size(); ++i) {
        if (in[i] == '\n')
            ret += "\\n";
        ret += in[i];
    }
    return ret;
}

static int assertEquals(const std::string &expected, const std::string &actual, int line)
{
    if (expected != actual) {
        numberOfFailedAssertions++;
        std::cerr type);
    ASSERT_EQUALS("bad macro syntax. macroname=\" value=1", outputList.cbegin()->msg);
}

static void ifCond()
{
    {
        const char code[] = "int i;";
        std::list ifCond;
        ASSERT_EQUALS("int i ;", preprocess(code, &ifCond));
        ASSERT_EQUALS(0, ifCond.size());
    }
    {
        const char code[] = "#if 0\n"
                            "# elif __GNUC__ == 1\n"
                            "#  elif defined(__APPLE__)\n"
                            "#endif\n";
        std::list ifCond;
        ASSERT_EQUALS("", preprocess(code, &ifCond));
        ASSERT_EQUALS(3, ifCond.size());
        auto it = ifCond.cbegin();
        ASSERT_EQUALS(0, it->location.fileIndex);
        ASSERT_EQUALS(1, it->location.line);
        ASSERT_EQUALS(2, it->location.col);
        ASSERT_EQUALS("0", it->E);
        ASSERT_EQUALS(0, it->result);
        ++it;
        ASSERT_EQUALS(0, it->location.fileIndex);
        ASSERT_EQUALS(2, it->location.line);
        ASSERT_EQUALS(3, it->location.col);
        ASSERT_EQUALS("__GNUC__ == 1", it->E);
        ASSERT_EQUALS(0, it->result);
        ++it;
        ASSERT_EQUALS(0, it->location.fileIndex);
        ASSERT_EQUALS(3, it->location.line);
        ASSERT_EQUALS(4, it->location.col);
        ASSERT_EQUALS("0", it->E);
        ASSERT_EQUALS(0, it->result);
    }
}

static void macroUsage()
{
    {
        const char code[] = "int i;";
        std::list macroUsage;
        ASSERT_EQUALS("int i ;", preprocess(code, ¯oUsage));
        ASSERT_EQUALS(0, macroUsage.size());
    }
    {
        const char code[] = "#define DEF_1\n"
                            "#ifdef DEF_1\n"
                            "#endif\n";
        std::list macroUsage;
        ASSERT_EQUALS("", preprocess(code, ¯oUsage));
        ASSERT_EQUALS(1, macroUsage.size());
        auto it = macroUsage.cbegin();
        ASSERT_EQUALS("DEF_1", it->macroName);
        ASSERT_EQUALS(0, it->macroLocation.fileIndex);
        ASSERT_EQUALS(1, it->macroLocation.line);
        ASSERT_EQUALS(9, it->macroLocation.col);
        ASSERT_EQUALS(true, it->macroValueKnown);
        ASSERT_EQUALS(0, it->useLocation.fileIndex);
        ASSERT_EQUALS(2, it->useLocation.line);
        ASSERT_EQUALS(8, it->useLocation.col);
    }
}

static void isAbsolutePath() {
#ifdef _WIN32
    ASSERT_EQUALS(true, simplecpp::isAbsolutePath("C:\\foo\\bar"));
    ASSERT_EQUALS(true, simplecpp::isAbsolutePath("C:/foo/bar"));
    ASSERT_EQUALS(true, simplecpp::isAbsolutePath("\\\\foo\\bar"));

    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo\\bar"));
    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo/bar"));
    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo.cpp"));
    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:foo.cpp"));
    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:foo\\bar.cpp"));
    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("bar.cpp"));
    //ASSERT_EQUALS(true, simplecpp::isAbsolutePath("\\")); // TODO
    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("0:\\foo\\bar"));
    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("0:/foo/bar"));
    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("\\foo\\bar"));
    //ASSERT_EQUALS(false, simplecpp::isAbsolutePath("\\\\")); // TODO
    //ASSERT_EQUALS(false, simplecpp::isAbsolutePath("//")); // TODO
    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("/foo/bar"));
    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("/"));
#else
    ASSERT_EQUALS(true, simplecpp::isAbsolutePath("/foo/bar"));
    ASSERT_EQUALS(true, simplecpp::isAbsolutePath("/"));
    ASSERT_EQUALS(true, simplecpp::isAbsolutePath("//host/foo/bar"));

    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo/bar"));
    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("foo.cpp"));
    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:\\foo\\bar"));
    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("C:/foo/bar"));
    ASSERT_EQUALS(false, simplecpp::isAbsolutePath("\\\\foo\\bar"));
#endif
}

// crashes detected by fuzzer
static void fuzz_crash()
{
    {
        const char code[] = "#define n __VA_OPT__(u\n"
                            "n\n";
        (void)preprocess(code, simplecpp::DUI()); // do not crash
    }
    { // #346
        const char code[] = "#define foo(intp)f##oo(intp\n"
                            "foo(f##oo(intp))\n";
        (void)preprocess(code, simplecpp::DUI()); // do not crash
    }
    { // #546
        const char code[] = "#if __has_include 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}

Web Proxy Viewer  |  New URL  |  Original Page