Commit 989b1acf authored by Johannes Braun's avatar Johannes Braun

Enable preprocessing from named source string.

parent 3c80851b
......@@ -18,6 +18,15 @@ int main()
std::cout << "Failed to process file.\n";
}
constexpr const char* source = R"(
#include "inc.glsl"
void main()
{}
)";
const glsp::processed_file src = process_state.preprocess_source(source, "Shader");
std::cin.ignore();
return 0;
}
\ No newline at end of file
......@@ -12,6 +12,8 @@
#include <experimental/filesystem>
#include <map>
#include <set>
#include <string>
#include <vector>
#ifndef ERR_OUTPUT
#include <iostream>
......@@ -42,7 +44,7 @@ namespace glshader::process
{
uint32_t version{ 0 }; /* GLSL Shader version in integral form (e.g. 450) or 0 if no version tag is found. */
shader_profile profile{ shader_profile::core }; /* GLSL Shader profile (core or compatibility) or core if none specified. */
files::path file_path; /* The original path of the loaded file. */
files::path file_path; /* The original path of the loaded file or the "name" parameter if processed with preprocess_source(...). */
std::set<files::path> dependencies; /* All files included while loading the shader. */
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. */
......@@ -59,7 +61,16 @@ namespace glshader::process
file_path -- The source file to load.
include_directories -- A list of include directories to search in when parsing includes.
definitions -- A list of predefined definitions. */
processed_file preprocess_file(const files::path& file_path, const std::vector<files::path>& include_directories, const std::vector<definition>& definitions);
processed_file preprocess_file(const files::path& file_path, const std::vector<files::path>& include_directories ={}, const std::vector<definition>& definitions ={});
/* Processes the given shader source and treats it as if it were a file with the given name.
If being called while having a valid OpenGL context, all available extension names will be loaded and checked against when compiling.
Otherwise, extension related #if statements will always be evaluated as false.
source -- The shader source.
name -- The name of the source which will be shown when printing errors.
include_directories -- A list of include directories to search in when parsing includes.
definitions -- A list of predefined definitions. */
processed_file preprocess_source(const std::string& source, const std::string& name, const std::vector<files::path>& include_directories ={}, const std::vector<definition>& definitions ={});
/* Customizable function which is called when a syntax error was detected.
You can redefine ERR_OUTPUT(str) in config.h. */
......@@ -85,7 +96,11 @@ namespace glshader::process
/* Stacks all persistent include directories and definitions onto the ones passed as parameters (Therefore the need to copy),
and calls the global glsp::preprocess_file function. */
processed_file preprocess_file(const files::path& file_path, std::vector<files::path> include_directories ={}, std::vector<definition> definitions ={});
processed_file preprocess_file(const files::path& file_path, std::vector<files::path> include_directories ={}, std::vector<definition> definitions ={});
/* Stacks all persistent include directories and definitions onto the ones passed as parameters (Therefore the need to copy),
and calls the global glsp::preprocess_source function. */
processed_file preprocess_source(const std::string& source, const std::string& name, std::vector<files::path> include_directories ={}, std::vector<definition> definitions ={});
protected:
std::vector<files::path> _include_directories;
......
......@@ -28,16 +28,13 @@ namespace glshader::process
namespace ext = impl::ext;
namespace lgl = impl::loader;
void process_impl(const files::path& file_path, const std::vector<files::path>& include_directories,
void process_impl(const files::path& file_path, const std::string& contents, const std::vector<files::path>& include_directories,
processed_file& processed, std::set<files::path>& unique_includes,
std::stringstream& result)
{
int defines_nesting = 0;
std::stack<bool> accept_else_directive;
std::ifstream root_file(file_path, std::ios::in);
std::string contents(std::istreambuf_iterator<char>{root_file}, std::istreambuf_iterator<char>{});
const char* text_ptr = contents.data();
files::path current_file = file_path;
......@@ -505,7 +502,10 @@ namespace glshader::process
result << ctrl::line_directive(current_file, current_line);
result << ctrl::line_directive(file, 1);
processed.dependencies.emplace(file);
process_impl(file, include_directories, processed, unique_includes, result);
std::ifstream root_file(file, std::ios::in);
std::string contents(std::istreambuf_iterator<char>{root_file}, std::istreambuf_iterator<char>{});
process_impl(file, contents, include_directories, processed, unique_includes, result);
}
text_ptr = skip::to_endline(include_begin);
......@@ -536,6 +536,14 @@ namespace glshader::process
processed_file preprocess_file(const files::path& file_path, const std::vector<files::path>& include_directories,
const std::vector<definition>& definitions)
{
std::ifstream root_file(file_path, std::ios::in);
std::string contents(std::istreambuf_iterator<char>{root_file}, std::istreambuf_iterator<char>{});
return preprocess_source(contents, file_path.string(), include_directories, definitions);
}
processed_file preprocess_source(const std::string& source, const std::string& name,
const std::vector<files::path>& include_directories, const std::vector<definition>& definitions)
{
constexpr uint32_t NUM_EXTENSIONS = 0x821D;
constexpr uint32_t EXTENSIONS = 0x1F03;
......@@ -560,15 +568,15 @@ namespace glshader::process
processed_file processed;
processed.version = -1;
processed.file_path = file_path;
processed.file_path = name;
for (auto&& definition : definitions)
processed.definitions[definition.name] = definition.info;
std::stringstream result;
std::set<files::path> unique_includes;
unique_includes.emplace(file_path);
process_impl(file_path, include_directories, processed, unique_includes, result);
unique_includes.emplace(name);
process_impl(name, source, include_directories, processed, unique_includes, result);
processed.contents = result.str();
return processed;
......@@ -601,6 +609,13 @@ namespace glshader::process
include_directories.insert(include_directories.begin(), _include_directories.begin(), _include_directories.end());
definitions.insert(definitions.begin(), _definitions.begin(), _definitions.end());
return glsp::preprocess_file(file_path, include_directories, definitions);
}
processed_file state::preprocess_source(const std::string& source, const std::string& name, std::vector<files::path> include_directories, std::vector<definition> definitions)
{
include_directories.insert(include_directories.begin(), _include_directories.begin(), _include_directories.end());
definitions.insert(definitions.begin(), _definitions.begin(), _definitions.end());
return glsp::preprocess_source(source, name, include_directories, definitions);
}
bool processed_file::valid() const noexcept
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment