Commit 3c80851b authored by Johannes Braun's avatar Johannes Braun

Add optional example executable and enable processed_file validity check.

parent 49cbe9c3
......@@ -5,7 +5,7 @@ list(APPEND INCLUDES ${PROJECT_SOURCE_DIR}/include)
if (MSVC)
list(APPEND LIBRARIES opengl32)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++latest")
#set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++latest")
elseif (UNIX)
list(APPEND LIBRARIES dl stdc++fs)
endif()
......@@ -18,4 +18,24 @@ target_include_directories(glsp PUBLIC ${INCLUDES})
set_property(TARGET glsp PROPERTY CXX_STANDARD 17)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/glsp DESTINATION include FILES_MATCHING PATTERN *.hpp)
install (TARGETS glsp ARCHIVE DESTINATION lib LIBRARY DESTINATION lib RUNTIME DESTINATION bin)
\ No newline at end of file
install (TARGETS glsp ARCHIVE DESTINATION lib LIBRARY DESTINATION lib RUNTIME DESTINATION bin)
option(GLSP_BUILD_EXECUTABLE OFF "Builds the example executable(s).")
if(GLSP_BUILD_EXECUTABLE)
file(GLOB children RELATIVE ${PROJECT_SOURCE_DIR}/examples ${PROJECT_SOURCE_DIR}/examples/*)
message("[GLSP] Enabled Executables. Adding...")
foreach(example ${children})
if(IS_DIRECTORY ${PROJECT_SOURCE_DIR}/examples/${example})
file(GLOB SOURCES ${PROJECT_SOURCE_DIR}/examples/${example}/*.cpp)
add_executable(${example} ${SOURCES})
target_link_libraries(${example} glsp)
if(MSVC)
target_link_libraries(${example} opengl32)
endif()
set_target_properties(${example} PROPERTIES LINKER_LANGUAGE CXX RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/examples/${example}" CXX_STANDARD 17)
target_include_directories(${example} PUBLIC ${INCLUDES})
target_include_directories(${example} PUBLIC ${PROJECT_SOURCE_DIR}/examples/${example})
endif()
endforeach()
endif()
\ No newline at end of file
{
// Informationen zu dieser Datei finden Sie unter https://go.microsoft.com//fwlink//?linkid=834763.
"configurations": [
{
"name": "[x64] Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
},
{
"name": "[x64] Release with Debug Info",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
},
{
"name": "[x64] Release",
"generator": "Ninja",
"configurationType": "Release",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
},
{
"name": "[exec, x64] Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "-DGLSP_BUILD_EXECUTABLE=ON",
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
},
{
"name": "[exec, x64] Release",
"generator": "Ninja",
"configurationType": "Release",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "-DGLSP_BUILD_EXECUTABLE=ON",
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
},
{
"name": "[exec, x64] Release with Debug Info",
"generator": "Ninja",
"configurationType": "Release",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "-DGLSP_BUILD_EXECUTABLE=ON",
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
}
]
}
\ No newline at end of file
*.exe
*.lib
*.dll
*.manifest
*.pdb
*.ilk
\ No newline at end of file
#pragma once
#include "enums.hpp"
#include <cinttypes>
#include <vector>
namespace gl
{
enum class native_handle : uint64_t { null = 0 };
class context
{
public:
template<typename T, typename = std::enable_if_t<sizeof(T) == sizeof(void*)>>
context(T hnd, std::vector<std::pair<context_attribs, int>> context_attributes, const context * const shared = nullptr)
: context((check_handle(reinterpret_cast<native_handle&>(hnd)), reinterpret_cast<native_handle&>(hnd)), std::move(context_attributes), shared)
{};
context(native_handle window, std::vector<std::pair<context_attribs, int>> context_attributes, const context * const shared = nullptr);
~context();
void set_pixel_format(std::vector<std::pair<pixel_format_attribs, int>> attributes);
void make_current() const noexcept;
void swap_buffers() const noexcept;
void set_swap_interval(int i) const noexcept;
private:
void check_handle(native_handle hnd) const;
int(*swapIntervalEXT)(int) = nullptr;
bool _is_window_owner;
native_handle _own_window;
native_handle _device_context;
native_handle _context;
};
}
\ No newline at end of file
#pragma once
#define BLUB 0;
\ No newline at end of file
#pragma once
enum context_profile_mask
{
GL_CONTEXT_CORE_PROFILE_BIT_ARB = 0x00000001,
GL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = 0x00000002
};
enum context_release_behavior
{
GL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB = 0,
GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB = 0x2098
};
enum context_flags
{
GL_CONTEXT_DEBUG_BIT_ARB = 0x00000001,
GL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB = 0x00000002,
GL_CONTEXT_ROBUST_ACCESS_BIT_ARB = 0x00000004,
GL_CONTEXT_RESET_ISOLATION_BIT_ARB = 0x00000008,
};
enum context_attribs
{
GL_CONTEXT_MAJOR_VERSION_ARB = 0x2091,
GL_CONTEXT_MINOR_VERSION_ARB = 0x2092,
GL_CONTEXT_FLAGS_ARB = 0x2094,
GL_CONTEXT_OPENGL_NO_ERROR_ARB = 0x31B3,
GL_CONTEXT_PROFILE_MASK_ARB = 0x9126,
GL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB = 0x8256,
GL_CONTEXT_RELEASE_BEHAVIOR_ARB = 0x2097,
};
enum pixel_format_attribs
{
GL_NUMBER_PIXEL_FORMATS_ARB = 0x2000,
GL_DRAW_TO_WINDOW_ARB = 0x2001,
GL_DRAW_TO_BITMAP_ARB = 0x2002,
GL_ACCELERATION_ARB = 0x2003,
GL_NEED_PALETTE_ARB = 0x2004,
GL_NEED_SYSTEM_PALETTE_ARB = 0x2005,
GL_SWAP_LAYER_BUFFERS_ARB = 0x2006,
GL_SWAP_METHOD_ARB = 0x2007,
GL_NUMBER_OVERLAYS_ARB = 0x2008,
GL_NUMBER_UNDERLAYS_ARB = 0x2009,
GL_TRANSPARENT_ARB = 0x200A,
GL_TRANSPARENT_RED_VALUE_ARB = 0x2037,
GL_TRANSPARENT_GREEN_VALUE_ARB = 0x2038,
GL_TRANSPARENT_BLUE_VALUE_ARB = 0x2039,
GL_TRANSPARENT_ALPHA_VALUE_ARB = 0x203A,
GL_TRANSPARENT_INDEX_VALUE_ARB = 0x203B,
GL_SHARE_DEPTH_ARB = 0x200C,
GL_SHARE_STENCIL_ARB = 0x200D,
GL_SHARE_ACCUM_ARB = 0x200E,
GL_SUPPORT_GDI_ARB = 0x200F,
GL_SUPPORT_OPENGL_ARB = 0x2010,
GL_DOUBLE_BUFFER_ARB = 0x2011,
GL_STEREO_ARB = 0x2012,
GL_PIXEL_TYPE_ARB = 0x2013,
GL_COLOR_BITS_ARB = 0x2014,
GL_RED_BITS_ARB = 0x2015,
GL_RED_SHIFT_ARB = 0x2016,
GL_GREEN_BITS_ARB = 0x2017,
GL_GREEN_SHIFT_ARB = 0x2018,
GL_BLUE_BITS_ARB = 0x2019,
GL_BLUE_SHIFT_ARB = 0x201A,
GL_ALPHA_BITS_ARB = 0x201B,
GL_ALPHA_SHIFT_ARB = 0x201C,
GL_ACCUM_BITS_ARB = 0x201D,
GL_ACCUM_RED_BITS_ARB = 0x201E,
GL_ACCUM_GREEN_BITS_ARB = 0x201F,
GL_ACCUM_BLUE_BITS_ARB = 0x2020,
GL_ACCUM_ALPHA_BITS_ARB = 0x2021,
GL_DEPTH_BITS_ARB = 0x2022,
GL_STENCIL_BITS_ARB = 0x2023,
GL_AUX_BUFFERS_ARB = 0x2024,
GL_SAMPLE_BUFFERS_ARB = 0x2041,
GL_SAMPLES_ARB = 0x2042,
};
enum acceleration
{
GL_NO_ACCELERATION_ARB = 0x2025,
GL_GENERIC_ACCELERATION_ARB = 0x2026,
GL_FULL_ACCELERATION_ARB = 0x2027
};
enum swap_method
{
GL_SWAP_EXCHANGE_ARB = 0x2028,
GL_SWAP_COPY_ARB = 0x2029,
GL_SWAP_UNDEFINED_ARB = 0x202A
};
enum pixel_type
{
GL_TYPE_RGBA_ARB = 0x202B,
GL_TYPE_COLORINDEX_ARB = 0x202C
};
\ No newline at end of file
#pragma once
#define MY_EXTERNAL_DEFINE gl_Position
#define MY_EXTERNAL_INCLUDE "dinc.glsl"
#error Expecto Errorum.
\ No newline at end of file
#include <iostream>
#include <context.hpp>
#include <glsp/preprocess.hpp>
int main()
{
gl::context context(gl::native_handle::null, {
{ GL_CONTEXT_MAJOR_VERSION_ARB, 4 },
{ GL_CONTEXT_MINOR_VERSION_ARB, 5 },
{ GL_CONTEXT_PROFILE_MASK_ARB, GL_CONTEXT_CORE_PROFILE_BIT_ARB },
{ GL_CONTEXT_FLAGS_ARB, GL_CONTEXT_DEBUG_BIT_ARB }
});
glsp::state process_state;
const glsp::processed_file file = process_state.preprocess_file("test.vert");
if(!file)
{
std::cout << "Failed to process file.\n";
}
std::cin.ignore();
return 0;
}
\ No newline at end of file
#version 450 core
#include "inc.glsl"
#include MY_EXTERNAL_INCLUDE
void main()
{
MY_EXTERNAL_DEFINE = vec4(BLUB, BLUB, BLUB, 1) * MY_EXTERNAL_DEFINE;
}
\ No newline at end of file
#include "context.hpp"
#if defined(WIN32)
#include <Windows.h>
#include <cassert>
namespace gl
{
HDC native_dc(native_handle h) { return reinterpret_cast<HDC>(h); }
native_handle native_dc(HDC h) { return reinterpret_cast<native_handle&>(h); }
void context::check_handle(native_handle hnd) const
{
assert(hnd == native_handle(0) || IsWindow(reinterpret_cast<HWND>(hnd)));
}
context::context(native_handle window, std::vector<std::pair<context_attribs, int>> context_attributes, const context * const shared)
{
check_handle(window);
PIXELFORMATDESCRIPTOR desc{
sizeof(PIXELFORMATDESCRIPTOR),
1,
DWORD((window==native_handle(0) ? PFD_DRAW_TO_WINDOW : 0) | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER),
PFD_TYPE_RGBA,
32,
0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0,
24,
8,
8,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
HWND win;
if (window==native_handle(0))
{
WNDCLASSW wnd{ 0 };
wnd.lpfnWndProc = [](HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) ->LRESULT {return DefWindowProcW(hWnd, msg, wParam, lParam); };
wnd.hInstance = GetModuleHandle(nullptr);
wnd.lpszClassName = L"temp_win_wgl";
//Register window class
RegisterClassW(&wnd);
win = CreateWindowExW(0, L"temp_win_wgl", L"", 0, 0, 0, 1, 1, nullptr, nullptr, GetModuleHandleW(nullptr), nullptr);
_own_window = reinterpret_cast<native_handle&>(win);
_is_window_owner = true;
}
else
{
_own_window = window;
_is_window_owner = false;
}
_device_context = native_dc(GetDC(reinterpret_cast<HWND>(_own_window)));
int pixel_format = ChoosePixelFormat(native_dc(_device_context), &desc);
SetPixelFormat(native_dc(_device_context), pixel_format, &desc);
HGLRC temp_context = wglCreateContext(native_dc(_device_context));
wglMakeCurrent(native_dc(_device_context), temp_context);
auto wglCreateContextAttribsARB = reinterpret_cast<HGLRC(*)(HDC, HGLRC, const int*)>(wglGetProcAddress("wglCreateContextAttribsARB"));
swapIntervalEXT = reinterpret_cast<int(*)(int)>(wglGetProcAddress("wglSwapIntervalEXT"));
context_attributes.emplace_back(context_attribs(0), 0);
int* attr = reinterpret_cast<int*>(&context_attributes[0].first);
_context = static_cast<native_handle>(reinterpret_cast<uint64_t>(wglCreateContextAttribsARB(native_dc(_device_context), reinterpret_cast<HGLRC>(shared ? shared->_context : native_handle::null), attr)));
set_pixel_format({});
make_current();
wglDeleteContext(temp_context);
}
void context::set_pixel_format(std::vector<std::pair<pixel_format_attribs, int>> attributes)
{
float pixel_attribs_f[] = { 0 };
std::vector<std::pair<pixel_format_attribs, int>> default_attributes
{
{ GL_DRAW_TO_WINDOW_ARB, true },
{ GL_SUPPORT_OPENGL_ARB, true },
{ GL_COLOR_BITS_ARB, 32 },
{ GL_RED_BITS_ARB, 8 },
{ GL_GREEN_BITS_ARB, 8 },
{ GL_BLUE_BITS_ARB, 8 },
{ GL_ALPHA_BITS_ARB, 8 },
{ GL_DEPTH_BITS_ARB, 24 },
{ GL_STENCIL_BITS_ARB, 8 },
{ GL_DOUBLE_BUFFER_ARB, true },
{ GL_PIXEL_TYPE_ARB, GL_TYPE_RGBA_ARB },
};
default_attributes.insert(default_attributes.end(), attributes.begin(), attributes.end());
default_attributes.emplace_back(pixel_format_attribs(0), 0);
int* attr = reinterpret_cast<int*>(&default_attributes[0].first);
auto wglChoosePixelFormatARB = reinterpret_cast<BOOL(*)(HDC, const int*, const float *, UINT, int *, UINT *)>(wglGetProcAddress("wglChoosePixelFormatARB"));
UINT format_count = 0;
int pixel_format;
wglChoosePixelFormatARB(native_dc(_device_context), attr, pixel_attribs_f, 1, &pixel_format, &format_count);
if (format_count == 0) throw std::runtime_error("Could not find suitable pixel formats.");
PIXELFORMATDESCRIPTOR pfd;
DescribePixelFormat(native_dc(_device_context), pixel_format, sizeof(pfd), &pfd);
SetPixelFormat(native_dc(_device_context), pixel_format, &pfd);
}
void context::set_swap_interval(int i) const noexcept
{
swapIntervalEXT(i);
}
context::~context()
{
if (_context != native_handle::null)
wglDeleteContext(reinterpret_cast<HGLRC>(_context));
if(_is_window_owner)
DestroyWindow(reinterpret_cast<HWND>(_own_window));
}
void context::make_current() const noexcept
{
wglMakeCurrent(native_dc(_device_context), reinterpret_cast<HGLRC>(_context));
}
void context::swap_buffers() const noexcept
{
SwapBuffers(native_dc(_device_context));
}
}
#endif //defined(WIN32)
\ No newline at end of file
......@@ -47,6 +47,10 @@ namespace glshader::process
std::map<std::string, ext_behavior> extensions; /* All explicitly enabled/required glsl extensions. */
std::map<std::string, definition_info> definitions; /* All definitions which have been defined in the shader without being undefined afterwards. */
std::string contents; /* The fully processed shader code string. */
int error_count = 0; /* The number of syntax errors that occurred while preprocessing. */
bool valid() const noexcept; /* Returns true when the file has been processed successfully, false when there were syntax errors. */
operator bool() const noexcept; /* Returns true when the file has been processed successfully, false when there were syntax errors. */
};
/* Loads and processes a shader file.
......@@ -59,7 +63,7 @@ namespace glshader::process
/* Customizable function which is called when a syntax error was detected.
You can redefine ERR_OUTPUT(str) in config.h. */
inline void syntax_error(const files::path& file, const int line, const std::string& reason)
inline void syntax_error_print(const files::path& file, const int line, const std::string& reason)
{
ERR_OUTPUT("Error in " + file.string() + ":" + std::to_string(line) + ": " + reason);
}
......
......@@ -5,7 +5,8 @@
#include "../opengl/loader.hpp"
#include "../strings.hpp"
#include <cassert>
#include <fstream>
#include <fstream>
#include <sstream>
namespace glshader::process
{
......@@ -79,7 +80,7 @@ namespace glshader::process
if (!(glCreateShaderProgramv && glGetProgramiv && glGetProgramInfoLog && glDeleteProgram && glGetProgramBinary))
{
result.success = false;
syntax_error("Function Loader", 0, strings::serr_loader_failed);
syntax_error_print("Function Loader", 0, strings::serr_loader_failed);
return result;
}
......@@ -98,7 +99,7 @@ namespace glshader::process
std::string log(log_length, ' ');
glGetProgramInfoLog(id, log_length, &log_length, log.data());
glDeleteProgram(id);
syntax_error("Linking", 0, log);
syntax_error_print("Linking", 0, log);
result.success = false;
return result;
}
......@@ -236,7 +237,7 @@ namespace glshader::process
result.format = internal_format;
} break;
case format::spirv:
syntax_error("Loader", 0, strfmt(strings::serr_unsupported, "SPIR-V"));
syntax_error_print("Loader", 0, strfmt(strings::serr_unsupported, "SPIR-V"));
default:
result.data.clear();
return result;
......
......@@ -57,8 +57,8 @@ namespace glshader::process::impl::operation
return std::strncmp(x, y, len) == 0;
}
int eval_operator(const char* begin, const eval_item& o, int len, const files::path& file, const int line);
int eval(const char* x, int len, const files::path& file, const int line)
int eval_operator(const char* begin, const eval_item& o, int len, const files::path& file, const int line, processed_file& processed);
int eval(const char* x, int len, const files::path& file, const int line, processed_file& processed)
{
enum state
{
......@@ -97,7 +97,8 @@ namespace glshader::process::impl::operation
++c;
if (c - begin > len)
{
syntax_error(file, line, strings::serr_eval_end_of_brackets);
++processed.error_count;
syntax_error_print(file, line, strings::serr_eval_end_of_brackets);
return 0;
}
if (*c == '(') ++stk;
......@@ -148,10 +149,10 @@ namespace glshader::process::impl::operation
if (limit == opstack.end())
limit = opstack.begin();
return eval_operator(begin, *limit, len, file, line);
return eval_operator(begin, *limit, len, file, line, processed);
}
int eval_operator(const char* begin, const eval_item& o, int len, const files::path& file, const int line)
int eval_operator(const char* begin, const eval_item& o, int len, const files::path& file, const int line, processed_file& processed)
{
const int num_begin = int(o.first_of_op - begin);
const int num_end = int(len - (o.first_after_op - begin));
......@@ -159,26 +160,26 @@ namespace glshader::process::impl::operation
/*** Curious switch :P ***/
switch (o.o)
{
case op_neg: return - eval(o.first_after_op, num_end, file, line);
case op_pos: return + eval(o.first_after_op, num_end, file, line);
case op_not: return ! eval(o.first_after_op, num_end, file, line);
case op_inv: return ~ eval(o.first_after_op, num_end, file, line);
case op_mul: return eval(begin, num_begin, file, line) * eval(o.first_after_op, num_end, file, line);
case op_div: return eval(begin, num_begin, file, line) / eval(o.first_after_op, num_end, file, line);
case op_mod: return eval(begin, num_begin, file, line) % eval(o.first_after_op, num_end, file, line);
case op_add: return eval(begin, num_begin, file, line) + eval(o.first_after_op, num_end, file, line);
case op_sub: return eval(begin, num_begin, file, line) - eval(o.first_after_op, num_end, file, line);
case op_lt: return eval(begin, num_begin, file, line) < eval(o.first_after_op, num_end, file, line);
case op_leq: return eval(begin, num_begin, file, line) <= eval(o.first_after_op, num_end, file, line);
case op_gt: return eval(begin, num_begin, file, line) > eval(o.first_after_op, num_end, file, line);
case op_geq: return eval(begin, num_begin, file, line) >= eval(o.first_after_op, num_end, file, line);
case op_eq: return eval(begin, num_begin, file, line) == eval(o.first_after_op, num_end, file, line);
case op_neq: return eval(begin, num_begin, file, line) != eval(o.first_after_op, num_end, file, line);
case op_and: return eval(begin, num_begin, file, line) & eval(o.first_after_op, num_end, file, line);
case op_xor: return eval(begin, num_begin, file, line) ^ eval(o.first_after_op, num_end, file, line);
case op_or: return eval(begin, num_begin, file, line) | eval(o.first_after_op, num_end, file, line);
case op_land: return eval(begin, num_begin, file, line) && eval(o.first_after_op, num_end, file, line);
case op_lor: return eval(begin, num_begin, file, line) || eval(o.first_after_op, num_end, file, line);
case op_neg: return - eval(o.first_after_op, num_end, file, line, processed);
case op_pos: return + eval(o.first_after_op, num_end, file, line, processed);
case op_not: return ! eval(o.first_after_op, num_end, file, line, processed);
case op_inv: return ~ eval(o.first_after_op, num_end, file, line, processed);
case op_mul: return eval(begin, num_begin, file, line, processed) * eval(o.first_after_op, num_end, file, line, processed);
case op_div: return eval(begin, num_begin, file, line, processed) / eval(o.first_after_op, num_end, file, line, processed);
case op_mod: return eval(begin, num_begin, file, line, processed) % eval(o.first_after_op, num_end, file, line, processed);
case op_add: return eval(begin, num_begin, file, line, processed) + eval(o.first_after_op, num_end, file, line, processed);
case op_sub: return eval(begin, num_begin, file, line, processed) - eval(o.first_after_op, num_end, file, line, processed);
case op_lt: return eval(begin, num_begin, file, line, processed) < eval(o.first_after_op, num_end, file, line, processed);
case op_leq: return eval(begin, num_begin, file, line, processed) <= eval(o.first_after_op, num_end, file, line, processed);
case op_gt: return eval(begin, num_begin, file, line, processed) > eval(o.first_after_op, num_end, file, line, processed);
case op_geq: return eval(begin, num_begin, file, line, processed) >= eval(o.first_after_op, num_end, file, line, processed);
case op_eq: return eval(begin, num_begin, file, line, processed) == eval(o.first_after_op, num_end, file, line, processed);
case op_neq: return eval(begin, num_begin, file, line, processed) != eval(o.first_after_op, num_end, file, line, processed);
case op_and: return eval(begin, num_begin, file, line, processed) & eval(o.first_after_op, num_end, file, line, processed);
case op_xor: return eval(begin, num_begin, file, line, processed) ^ eval(o.first_after_op, num_end, file, line, processed);
case op_or: return eval(begin, num_begin, file, line, processed) | eval(o.first_after_op, num_end, file, line, processed);
case op_land: return eval(begin, num_begin, file, line, processed) && eval(o.first_after_op, num_end, file, line, processed);
case op_lor: return eval(begin, num_begin, file, line, processed) || eval(o.first_after_op, num_end, file, line, processed);
default: return 0;
}
}
......
#pragma once
#include "files.hpp"
#include <glsp/preprocess.hpp>
namespace glshader::process::impl::operation
{
......@@ -8,5 +9,5 @@ namespace glshader::process::impl::operation
Takes a const char* substring with a given length and tries to evaluate it's value.
Evaluates arithmetical, logical and comparison operations on integral values.
***/
int eval(const char* x, int len, const files::path& current_file, const int current_line);
}
\ No newline at end of file
int eval(const char* x, int len, const files::path& current_file, const int current_line, processed_file& processed);
}
......@@ -60,7 +60,8 @@ namespace glshader::process::impl::macro
if (inputs.size() != info.parameters.size() || (info.parameters.size() >= inputs.size() - 1 && inputs.back() ==
"..."))
{
syntax_error(current_file, current_line, strfmt(strings::serr_non_matching_argc, name));
++processed.error_count;
syntax_error_print(current_file, current_line, strfmt(strings::serr_non_matching_argc, name));
return "";
}
......
......@@ -27,7 +27,7 @@ namespace glshader::process
namespace macro = impl::macro;
namespace ext = impl::ext;
namespace lgl = impl::loader;
void process_impl(const files::path& file_path, const std::vector<files::path>& include_directories,
processed_file& processed, std::set<files::path>& unique_includes,
std::stringstream& result)
......@@ -45,10 +45,6 @@ namespace glshader::process
int current_line = 1;
std::string curr = current_file.filename().string();
std::replace(curr.begin(), curr.end(), '\\', '/');
/* if (!processed.dependencies.empty())
{
result << "#line " << current_line - 1 << " \"" << curr << "\"\n\n";
}*/
// There is no way you could put a macro starting from the first character of the shader.
// Set to true if the current text_ptr may point to the start of a macro name.
......@@ -84,7 +80,7 @@ namespace glshader::process
(*(text_ptr + 1) - '0') * 10 +
(*(text_ptr + 2) - '0');
processed.definitions["__VERSION__"] = std::string{text_ptr, text_ptr + 3};
processed.definitions["__VERSION__"] = std::string{ text_ptr, text_ptr + 3 };
result << "#version " << *text_ptr << *(text_ptr + 1) << *(text_ptr + 2) << " ";
text_ptr = skip::to_next_token(text_ptr);
......@@ -106,7 +102,8 @@ namespace glshader::process
}
else
{
syntax_error(current_file, current_line, strfmt(strings::serr_unrecognized_profile, std::string(text_ptr, skip::to_endline(text_ptr))));
++processed.error_count;
syntax_error_print(current_file, current_line, strfmt(strings::serr_unrecognized_profile, std::string(text_ptr, skip::to_endline(text_ptr))));
processed.definitions["GL_core_profile"] = 1;
processed.profile = shader_profile::core;
}
......@@ -135,7 +132,10 @@ namespace glshader::process
else if (cls::is_token_equal(text_ptr, "disable", 6))
processed.extensions[extension] = ext_behavior::disable;
else
syntax_error(current_file, current_line, strfmt(strings::serr_extension_all_behavior, std::string(text_ptr, skip::to_endline(text_ptr))));
{
++processed.error_count;
syntax_error_print(current_file, current_line, strfmt(strings::serr_extension_all_behavior, std::string(text_ptr, skip::to_endline(text_ptr))));
}
}