yum-mirror/glslang
git clone https://git.yummers.dev/yum-mirror/glslang
23baa3f7
main
1// 2// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. 3// Copyright (C) 2017 Google, Inc. 4// 5// All rights reserved. 6// 7// Redistribution and use in source and binary forms, with or without 8// modification, are permitted provided that the following conditions 9// are met: 10// 11// Redistributions of source code must retain the above copyright 12// notice, this list of conditions and the following disclaimer. 13// 14// Redistributions in binary form must reproduce the above 15// copyright notice, this list of conditions and the following 16// disclaimer in the documentation and/or other materials provided 17// with the distribution. 18// 19// Neither the name of 3Dlabs Inc. Ltd. nor the names of its 20// contributors may be used to endorse or promote products derived 21// from this software without specific prior written permission. 22// 23// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34// POSSIBILITY OF SUCH DAMAGE. 35// 36 37#pragma once 38 39#include <vector> 40#include <string> 41#include <fstream> 42#include <algorithm> 43#include <filesystem> 44#include <set> 45 46#include "./../glslang/Public/ShaderLang.h" 47 48// Default include class for normal include convention of search backward 49// through the stack of active include paths (for nested includes). 50// Can be overridden to customize. 51class DirStackFileIncluder :public glslang ::TShader ::Includer { 52public : 53DirStackFileIncluder () { } 54 55virtual IncludeResult * includeLocal (const char * headerName , 56const char * includerName , 57size_t inclusionDepth )override 58 { 59recordLocalPath (includerName ,inclusionDepth ); 60return readLocalPath (headerName ); 61 } 62 63virtual IncludeResult * includeSystem (const char * headerName , 64const char * includerName , 65size_t inclusionDepth )override 66 { 67recordLocalPath (includerName ,inclusionDepth ); 68return readSystemPath (headerName ); 69 } 70 71// Externally set directories. E.g., from a command-line -I<dir>. 72// - Most-recently pushed are checked first. 73// - All these are checked after the parse-time stack of local directories 74// is checked. 75// - Makes its own copy of the path. 76// - Search paths are processed similar to GCC: "local" inclusions will 77// search in the current directory and external directories, while 78// <system> inclusions will search external directories only. 79virtual void pushExternalDirectory (const std ::string & dir ) 80 { 81externalDirectoryList .push_back (dir ); 82 } 83 84virtual void releaseInclude (IncludeResult * result )override 85 { 86if (result != nullptr ) { 87delete []static_cast < tUserDataElement *> (result -> userData ); 88delete result ; 89 } 90 } 91 92virtual std ::set < std ::string > getIncludedFiles () 93 { 94return includedFiles ; 95 } 96 97virtual ~DirStackFileIncluder ()override { } 98 99protected : 100typedef char tUserDataElement ; 101std ::vector < std ::string > localDirectoryStack ; 102std ::vector < std ::string > externalDirectoryList ; 103std ::set < std ::string > includedFiles ; 104 105// Record local path for future local inclusion. 106// Discard popped include directories, and 107// initialize when at parse-time first level. 108void recordLocalPath (const char * includerName ,size_t depth ) 109 { 110localDirectoryStack .resize (depth ); 111if (depth == 1 ) 112localDirectoryStack .back ()= getDirectory (includerName ); 113 } 114 115// Search for a valid "local" path based on combining the stack of include 116// directories and the nominal name of the header. 117virtual IncludeResult * readLocalPath (const char * headerName ) 118 { 119// Open absolute paths directly. 120if (std ::filesystem ::path (headerName ).is_absolute ()) { 121std ::ifstream file (headerName ,std ::ios_base ::binary |std ::ios_base ::ate ); 122 123if (file ) { 124includedFiles .insert (headerName ); 125return newIncludeResult (headerName ,file , (int )file .tellg ()); 126 } 127 128return nullptr ; 129 } 130 131// Find a directory that works, using a reverse search of the include stack. 132for (autoit = localDirectoryStack. rbegin (); it != localDirectoryStack. rend (); ++ it) { 133std :: string path = * it + '/' + headerName; 134std :: replace (path. begin (), path. end (), '\\' , '/' ); 135std :: ifstream file( path , std :: ios_base ::binary | std:: ios_base ::ate); 136if (file) { 137localDirectoryStack. push_back ( getDirectory (path)); 138includedFiles. insert (path); 139return newIncludeResult (path, file, ( int )file. tellg ()); 140} 141} 142 143return nullptr ; 144} 145 146// Search for a valid <system> path. 147virtual IncludeResult * readSystemPath ( const char * headerName) 148{ 149// Search for external directories only. 150for (auto it = externalDirectoryList. begin (); it != externalDirectoryList. end (); ++ it) { 151std :: string path = * it + '/' + headerName; 152std :: replace (path. begin (), path. end (), '\\' , '/' ); 153std :: ifstream file( path , std :: ios_base ::binary | std:: ios_base ::ate); 154if (file) { 155localDirectoryStack. push_back ( getDirectory (path)); 156includedFiles. insert (path); 157return newIncludeResult (path, file, ( int )file. tellg ()); 158} 159} 160return nullptr ; 161} 162 163// Do actual reading of the file, filling in a new include result. 164virtual IncludeResult * newIncludeResult ( const std ::string & path, std ::ifstream & file, int length) const 165{ 166char * content = new tUserDataElement [length]; 167file. seekg ( 0 , file. beg ); 168file. read (content, length); 169return new IncludeResult (path, content, length, content); 170} 171 172// If no path markers, return current working directory. 173// Otherwise, strip file name and return path leading up to it. 174virtual std::string getDirectory ( const std ::string path) const 175{ 176size_t last = path. find_last_of ( "/\\" ); 177return last == std::string::npos ? "." : path. substr ( 0 , last ); 178 } 179};