]> git.tdb.fi Git - libs/gl.git/commitdiff
Track source names in SL::Module
authorMikko Rasa <tdb@tdb.fi>
Sat, 20 Feb 2021 12:42:19 +0000 (14:42 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sat, 20 Feb 2021 16:38:51 +0000 (18:38 +0200)
Error translation has also been moved to a separate class.  This will
allow moving the creation of shaders to Program.

source/glsl/compiler.cpp
source/glsl/parser.cpp
source/glsl/parser.h
source/glsl/sourcemap.cpp [new file with mode: 0644]
source/glsl/sourcemap.h [new file with mode: 0644]
source/glsl/syntax.h

index 0579bb017267c08dfab0af9f177a8077e048244d..347e16ad301dba1881b604713a68476095ccf0f2 100644 (file)
@@ -1,8 +1,6 @@
 #include <msp/core/algorithm.h>
 #include <msp/gl/extensions/ext_gpu_shader4.h>
 #include <msp/strings/format.h>
-#include <msp/strings/regex.h>
-#include <msp/strings/utils.h>
 #include "compatibility.h"
 #include "compiler.h"
 #include "error.h"
@@ -34,6 +32,7 @@ void Compiler::clear()
        delete module;
        module = new Module();
        imported_names.clear();
+       module->source_map.set_name(0, "<generated>");
 }
 
 void Compiler::set_source(const string &source, const string &src_name)
@@ -104,44 +103,14 @@ void Compiler::add_shaders(Program &program)
        }
        catch(const compile_error &e)
        {
-               static const Regex r_message("^(([0-9]+)\\(([0-9]+)\\) :|ERROR: ([0-9]+):([0-9]+):) (.*)$");
-               vector<string> lines = split(e.what(), '\n');
-               string translated;
-               for(vector<string>::const_iterator i=lines.begin(); i!=lines.end(); ++i)
-               {
-                       RegMatch m = r_message.match(*i);
-                       if(m)
-                       {
-                               unsigned index = 0;
-                               unsigned line = 0;
-                               if(m[2])
-                               {
-                                       index = lexical_cast<unsigned>(m[2].str);
-                                       line = lexical_cast<unsigned>(m[3].str);
-                               }
-                               else if(m[4])
-                               {
-                                       index = lexical_cast<unsigned>(m[4].str);
-                                       line = lexical_cast<unsigned>(m[5].str);
-                               }
-                               const char *src = "<unknown>";
-                               if(index==0)
-                                       src = "<generated>";
-                               else if(index-1<imported_names.size())
-                                       src = imported_names[index-1].c_str();
-                               translated += format("%s:%d: %s", src, line, m[6].str);
-                       }
-                       else
-                               translated += *i;
-                       translated += '\n';
-               }
-
-               throw compile_error(translated);
+               throw compile_error(module->source_map.translate_errors(e.what()));
        }
 }
 
 void Compiler::append_module(Module &mod, DataFile::Collection *res)
 {
+       module->source_map.merge_from(mod.source_map);
+
        vector<Import *> imports = NodeGatherer<Import>().apply(mod.shared);
        for(vector<Import *>::iterator i=imports.begin(); i!=imports.end(); ++i)
                import(res, (*i)->module);
@@ -192,7 +161,7 @@ void Compiler::import(DataFile::Collection *resources, const string &name)
        if(!io)
                throw runtime_error(format("module %s not found", name));
        Parser import_parser;
-       append_module(import_parser.parse(*io, fn, imported_names.size()), resources);
+       append_module(import_parser.parse(*io, fn, module->source_map.get_count()), resources);
 }
 
 void Compiler::generate(Stage &stage)
index 60cc3516b0750db9f131e8a665b135c89d7dab7b..eee6212930f5dccabdac77b4a32467f91fb89727 100644 (file)
@@ -28,30 +28,30 @@ Parser::~Parser()
 Module &Parser::parse(const string &s, const string &n, unsigned i)
 {
        source = s;
-       source_index = i;
-       parse_source(n);
+       parse_source(n, i);
        return *module;
 }
 
 Module &Parser::parse(IO::Base &io, const string &n, unsigned i)
 {
        source = string();
-       source_index = i;
        while(!io.eof())
        {
                char buffer[4096];
                unsigned len = io.read(buffer, sizeof(buffer));
                source.append(buffer, len);
        }
-       parse_source(n);
+       parse_source(n, i);
        return *module;
 }
 
-void Parser::parse_source(const string &name)
+void Parser::parse_source(const string &name, unsigned index)
 {
        delete module;
        module = new Module;
        cur_stage = &module->shared;
+       source_index = index;
+       module->source_map.set_name(source_index, name);
        tokenizer.begin(name, source);
        while(RefPtr<Statement> statement = parse_global_declaration())
                cur_stage->content.body.push_back(statement);
index b6c8369debb91d379e66d8f1a2afda5f2e53bea9..58b14b502f5bf550e1285098a651662fcf653bbe 100644 (file)
@@ -16,7 +16,6 @@ class Parser
 {
 private:
        std::string source;
-       std::string source_name;
        unsigned source_index;
        Tokenizer tokenizer;
        Preprocessor preprocessor;
@@ -33,7 +32,7 @@ public:
        Module &parse(IO::Base &, const std::string &, unsigned = 0);
 
 private:
-       void parse_source(const std::string &);
+       void parse_source(const std::string &, unsigned);
        void set_required_version(const Version &);
        void stage_change(Stage::Type);
 
diff --git a/source/glsl/sourcemap.cpp b/source/glsl/sourcemap.cpp
new file mode 100644 (file)
index 0000000..e74f1b6
--- /dev/null
@@ -0,0 +1,84 @@
+#include <msp/strings/format.h>
+#include <msp/strings/regex.h>
+#include <msp/strings/utils.h>
+#include "sourcemap.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+namespace SL {
+
+SourceMap::SourceMap():
+       base_index(0)
+{ }
+
+void SourceMap::set_name(unsigned i, const std::string &n)
+{
+       if(source_names.empty())
+               base_index = i;
+       else if(i<base_index)
+       {
+               source_names.insert(source_names.begin(), base_index-i, string());
+               base_index = i;
+       }
+       i -= base_index;
+
+       if(source_names.size()<=i)
+               source_names.resize(i+1);
+       source_names[i] = n;
+}
+
+void SourceMap::merge_from(const SourceMap &other)
+{
+       if(other.base_index<base_index)
+       {
+               source_names.insert(source_names.begin(), base_index-other.base_index, string());
+               base_index = other.base_index;
+       }
+       if(get_count()<other.get_count())
+               source_names.resize(other.get_count()-base_index);
+
+       for(unsigned i=0; i<other.source_names.size(); ++i)
+               if(!other.source_names[i].empty())
+                       source_names[i+other.base_index-base_index] = other.source_names[i];
+}
+
+string SourceMap::translate_errors(const string &errors) const
+{
+       static const Regex r_message("^(([0-9]+)\\(([0-9]+)\\) :|ERROR: ([0-9]+):([0-9]+):) (.*)$");
+       vector<string> lines = split(errors, '\n');
+       string translated;
+       for(vector<string>::const_iterator i=lines.begin(); i!=lines.end(); ++i)
+       {
+               RegMatch m = r_message.match(*i);
+               if(m)
+               {
+                       unsigned index = 0;
+                       unsigned line = 0;
+                       if(m[2])
+                       {
+                               index = lexical_cast<unsigned>(m[2].str);
+                               line = lexical_cast<unsigned>(m[3].str);
+                       }
+                       else if(m[4])
+                       {
+                               index = lexical_cast<unsigned>(m[4].str);
+                               line = lexical_cast<unsigned>(m[5].str);
+                       }
+                       const char *src = "<unknown>";
+                       if(index<source_names.size() && !source_names[index].empty())
+                               src = source_names[index].c_str();
+                       translated += format("%s:%d: %s", src, line, m[6].str);
+               }
+               else
+                       translated += *i;
+               translated += '\n';
+       }
+
+       return translated;
+}
+
+} // namespace SL
+} // namespace GL
+} // namespace Msp
diff --git a/source/glsl/sourcemap.h b/source/glsl/sourcemap.h
new file mode 100644 (file)
index 0000000..6df6418
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef MSP_GL_SL_SOURCEMAP_H_
+#define MSP_GL_SL_SOURCEMAP_H_
+
+#include <string>
+#include <vector>
+
+namespace Msp {
+namespace GL {
+namespace SL {
+
+class SourceMap
+{
+private:
+       unsigned base_index;
+       std::vector<std::string> source_names;
+
+public:
+       SourceMap();
+
+       void set_name(unsigned, const std::string &);
+       unsigned get_count() const { return base_index+source_names.size(); }
+       void merge_from(const SourceMap &);
+       std::string translate_errors(const std::string &) const;
+};
+
+} // namespace SL
+} // namespace GL
+} // namespace Msp
+
+#endif
index ac67a3fb9474dcd202682dd9795f939299750b31..7764712498bb3106666f3e8bee98de72881516df 100644 (file)
@@ -7,6 +7,7 @@
 #include <vector>
 #include <msp/core/refptr.h>
 #include "extension.h"
+#include "sourcemap.h"
 #include "uniform.h"
 
 #pragma push_macro("interface")
@@ -386,6 +387,7 @@ struct Stage
 
 struct Module
 {
+       SourceMap source_map;
        Stage shared;
        std::list<Stage> stages;