Improve ResourceLimits interface to be more forward compatible
[platform/upstream/glslang.git] / StandAlone / DirStackFileIncluder.h
index 8f06f9e..5a33c78 100644 (file)
@@ -40,6 +40,7 @@
 #include <string>
 #include <fstream>
 #include <algorithm>
+#include <set>
 
 #include "./../glslang/Public/ShaderLang.h"
 
 // Can be overridden to customize.
 class DirStackFileIncluder : public glslang::TShader::Includer {
 public:
+    DirStackFileIncluder() : externalLocalDirectoryCount(0) { }
+
     virtual IncludeResult* includeLocal(const char* headerName,
                                         const char* includerName,
                                         size_t inclusionDepth) override
     {
-        return readLocalPath(headerName, includerName, inclusionDepth);
+        return readLocalPath(headerName, includerName, (int)inclusionDepth);
     }
 
     virtual IncludeResult* includeSystem(const char* headerName,
@@ -62,6 +65,18 @@ public:
         return readSystemPath(headerName);
     }
 
+    // Externally set directories. E.g., from a command-line -I<dir>.
+    //  - Most-recently pushed are checked first.
+    //  - All these are checked after the parse-time stack of local directories
+    //    is checked.
+    //  - This only applies to the "local" form of #include.
+    //  - Makes its own copy of the path.
+    virtual void pushExternalLocalDirectory(const std::string& dir)
+    {
+        directoryStack.push_back(dir);
+        externalLocalDirectoryCount = (int)directoryStack.size();
+    }
+
     virtual void releaseInclude(IncludeResult* result) override
     {
         if (result != nullptr) {
@@ -70,28 +85,37 @@ public:
         }
     }
 
+    virtual std::set<std::string> getIncludedFiles()
+    {
+        return includedFiles;
+    }
+
     virtual ~DirStackFileIncluder() override { }
 
 protected:
     typedef char tUserDataElement;
     std::vector<std::string> directoryStack;
+    int externalLocalDirectoryCount;
+    std::set<std::string> includedFiles;
 
     // Search for a valid "local" path based on combining the stack of include
     // directories and the nominal name of the header.
     virtual IncludeResult* readLocalPath(const char* headerName, const char* includerName, int depth)
     {
-        // Discard popped include directories, and if first level, initialize.
-        directoryStack.resize(depth);
+        // Discard popped include directories, and
+        // initialize when at parse-time first level.
+        directoryStack.resize(depth + externalLocalDirectoryCount);
         if (depth == 1)
-            directoryStack.front() = getDirectory(includerName);
+            directoryStack.back() = getDirectory(includerName);
 
-        // find a directory that works, reverse search of include stack
+        // Find a directory that works, using a reverse search of the include stack.
         for (auto it = directoryStack.rbegin(); it != directoryStack.rend(); ++it) {
             std::string path = *it + '/' + headerName;
             std::replace(path.begin(), path.end(), '\\', '/');
             std::ifstream file(path, std::ios_base::binary | std::ios_base::ate);
             if (file) {
                 directoryStack.push_back(getDirectory(path));
+                includedFiles.insert(path);
                 return newIncludeResult(path, file, (int)file.tellg());
             }
         }