summaryrefslogtreecommitdiffstats
path: root/servers
diff options
context:
space:
mode:
authorbitsawer <sawerduster@gmail.com>2023-09-04 14:51:04 +0300
committerbitsawer <sawerduster@gmail.com>2023-09-06 16:57:40 +0300
commit3c042fb99f661d60e17e26d67f03cd796e1c4662 (patch)
tree25cc164ecdcf46dae4af96a538b9d4e575143da3 /servers
parent2282fc5de992a278e6a4e9c279f4bf8086203b48 (diff)
downloadredot-engine-3c042fb99f661d60e17e26d67f03cd796e1c4662.tar.gz
Fix shader language preprocessor include marker handling
Diffstat (limited to 'servers')
-rw-r--r--servers/rendering/shader_language.cpp40
-rw-r--r--servers/rendering/shader_language.h1
-rw-r--r--servers/rendering/shader_preprocessor.cpp2
3 files changed, 33 insertions, 10 deletions
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 1460a91826..d6d6cc7731 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -610,19 +610,39 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
incp.push_back(0); // Zero end it.
String include_path(incp.ptr());
include_positions.write[include_positions.size() - 1].line = tk_line;
- FilePosition fp;
- fp.file = include_path;
- fp.line = 0;
- tk_line = 0;
- include_positions.push_back(fp);
- } else if (GETCHAR(0) == '@' && GETCHAR(1) == '<') {
- if (include_positions.size() == 1) {
- return _make_token(TK_ERROR, "Invalid include exit hint @@< without matching enter hint.");
+ String marker = ">>" + include_path;
+ if (!include_markers_handled.has(marker)) {
+ include_markers_handled.insert(marker);
+
+ FilePosition fp;
+ fp.file = include_path;
+ fp.line = 0;
+ tk_line = 0;
+ include_positions.push_back(fp);
}
+
+ } else if (GETCHAR(0) == '@' && GETCHAR(1) == '<') {
char_idx += 2;
- include_positions.resize(include_positions.size() - 1); // Pop back.
+ LocalVector<char32_t> incp;
+ while (GETCHAR(0) != '\n') {
+ incp.push_back(GETCHAR(0));
+ char_idx++;
+ }
+ incp.push_back(0); // Zero end it.
+ String include_path(incp.ptr());
+
+ String marker = "<<" + include_path;
+ if (!include_markers_handled.has(marker)) {
+ include_markers_handled.insert(marker);
+
+ if (include_positions.size() == 1) {
+ return _make_token(TK_ERROR, "Invalid include exit hint @@< without matching enter hint.");
+ }
+ include_positions.resize(include_positions.size() - 1); // Pop back.
+ }
+
tk_line = include_positions[include_positions.size() - 1].line - 1; // Restore line.
} else {
@@ -1217,6 +1237,8 @@ void ShaderLanguage::clear() {
include_positions.clear();
include_positions.push_back(FilePosition());
+ include_markers_handled.clear();
+
#ifdef DEBUG_ENABLED
keyword_completion_context = CF_UNSPECIFIED;
used_constants.clear();
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index 0ddd27f028..90fde72152 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -910,6 +910,7 @@ private:
int error_line = 0;
Vector<FilePosition> include_positions;
+ HashSet<String> include_markers_handled;
#ifdef DEBUG_ENABLED
struct Usage {
diff --git a/servers/rendering/shader_preprocessor.cpp b/servers/rendering/shader_preprocessor.cpp
index 8d6ddf9121..dbd1374941 100644
--- a/servers/rendering/shader_preprocessor.cpp
+++ b/servers/rendering/shader_preprocessor.cpp
@@ -747,7 +747,7 @@ void ShaderPreprocessor::process_include(Tokenizer *p_tokenizer) {
processor.preprocess(state, included, result);
add_to_output("@@>" + real_path + "\n"); // Add token for enter include path
add_to_output(result);
- add_to_output("\n@@<\n"); // Add token for exit include path
+ add_to_output("\n@@<" + real_path + "\n"); // Add token for exit include path.
// Reset to last include if there are no errors. We want to use this as context.
if (state->error.is_empty()) {