yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// slang-include-system.cpp 2#include "slang-include-system.h" 3 4#include "../core/slang-file-system.h" 5#include "../core/slang-io.h" 6#include "../core/slang-string-util.h" 7#include "slang-artifact-impl.h" 8#include "slang-artifact-representation-impl.h" 9#include "slang-slice-allocator.h" 10 11namespace Slang 12{ 13 14IncludeSystem ::IncludeSystem ( 15SearchDirectoryList * searchDirectories , 16ISlangFileSystemExt * fileSystemExt , 17SourceManager * sourceManager ) 18 :m_searchDirectories (searchDirectories ) 19 ,m_fileSystemExt (fileSystemExt ) 20 ,m_sourceManager (sourceManager ) 21{ 22} 23 24SlangResult IncludeSystem ::findFile ( 25SlangPathType fromPathType , 26const String & fromPath , 27const String & path , 28PathInfo & outPathInfo ) 29{ 30String combinedPath ; 31 32if (fromPath .getLength ()== 0 || Path ::isAbsolute (path )) 33 { 34// If the path is absolute or the fromPath is empty, the combined path is just the path 35combinedPath = path ; 36 } 37else 38 { 39// Get relative path 40ComPtr < ISlangBlob > combinedPathBlob ; 41SLANG_RETURN_ON_FAIL (m_fileSystemExt -> calcCombinedPath ( 42fromPathType , 43fromPath .begin (), 44path .begin (), 45combinedPathBlob .writeRef ())); 46combinedPath = StringUtil ::getString (combinedPathBlob ); 47if (combinedPath .getLength () <=0 ) 48 { 49return SLANG_FAIL ; 50 } 51 } 52 53// This checks the path exists 54SlangPathType pathType ; 55SLANG_RETURN_ON_FAIL (m_fileSystemExt -> getPathType (combinedPath .begin (),& pathType )); 56if (pathType != SLANG_PATH_TYPE_FILE ) 57 { 58return SLANG_E_NOT_FOUND ; 59 } 60 61// Get the uniqueIdentity 62ComPtr < ISlangBlob > uniqueIdentityBlob ; 63SLANG_RETURN_ON_FAIL (m_fileSystemExt -> getFileUniqueIdentity ( 64combinedPath .begin (), 65uniqueIdentityBlob .writeRef ())); 66 67// If the rel path exists -> a uniqueIdentity MUST exists too 68String uniqueIdentity (StringUtil ::getString (uniqueIdentityBlob )); 69if (uniqueIdentity .getLength () <=0 ) 70 { 71// Unique identity can't be empty 72return SLANG_FAIL ; 73 } 74 75outPathInfo = PathInfo ::makeNormal (combinedPath ,uniqueIdentity ); 76return SLANG_OK ; 77} 78 79String IncludeSystem ::simplifyPath (const String & path ) 80{ 81ComPtr < ISlangBlob > simplifiedPath ; 82if (SLANG_FAILED (m_fileSystemExt -> getPath ( 83PathKind ::Simplified , 84path .getBuffer (), 85simplifiedPath .writeRef ()))) 86 { 87return path ; 88 } 89return StringUtil ::getString (simplifiedPath ); 90} 91 92SlangResult IncludeSystem ::findFile ( 93String const & pathToInclude , 94String const & pathIncludedFrom , 95PathInfo & outPathInfo ) 96{ 97outPathInfo .type = PathInfo ::Type ::Unknown ; 98 99// If it's absolute we only have to try and find if it's there - no need to look at search paths 100if (Path ::isAbsolute (pathToInclude )) 101 { 102// We pass in "" as the from path, so ensure no from path is taken into account 103// and to allow easy identification that this is in effect absolute 104return findFile ( 105SLANG_PATH_TYPE_DIRECTORY , 106UnownedStringSlice ::fromLiteral ("" ), 107pathToInclude , 108outPathInfo ); 109 } 110 111// Try just relative to current path 112 { 113SlangResult res = 114findFile (SLANG_PATH_TYPE_FILE ,pathIncludedFrom ,pathToInclude ,outPathInfo ); 115// It either succeeded or wasn't found, anything else is a failure passed back 116if (SLANG_SUCCEEDED (res )|| res != SLANG_E_NOT_FOUND ) 117 { 118return res ; 119 } 120 } 121 122// Search all the searchDirectories 123for (auto sd = m_searchDirectories ;sd ;sd = sd -> parent ) 124 { 125for (auto & dir :sd -> searchDirectories ) 126 { 127SlangResult res = 128findFile (SLANG_PATH_TYPE_DIRECTORY ,dir .path ,pathToInclude ,outPathInfo ); 129if (SLANG_SUCCEEDED (res )|| res != SLANG_E_NOT_FOUND ) 130 { 131return res ; 132 } 133 } 134 } 135 136return SLANG_E_NOT_FOUND ; 137} 138 139SlangResult IncludeSystem ::loadFile ( 140const PathInfo & pathInfo , 141ComPtr < ISlangBlob >& outBlob , 142SourceFile *& outSourceFile ) 143{ 144if (m_sourceManager ) 145 { 146// See if this an already loaded source file 147outSourceFile = m_sourceManager -> findSourceFileRecursively (pathInfo .uniqueIdentity ); 148 149// If not create a new one, and add to the list of known source files 150if (!outSourceFile ) 151 { 152ComPtr < ISlangBlob > foundSourceBlob ; 153if (SLANG_FAILED (m_fileSystemExt -> loadFile ( 154pathInfo .foundPath .getBuffer (), 155foundSourceBlob .writeRef ()))) 156 { 157return SLANG_E_CANNOT_OPEN ; 158 } 159 160outSourceFile = m_sourceManager -> createSourceFileWithBlob (pathInfo ,foundSourceBlob ); 161m_sourceManager -> addSourceFile (pathInfo .uniqueIdentity ,outSourceFile ); 162 163outBlob = foundSourceBlob ; 164return SLANG_OK ; 165 } 166else 167 { 168if (outSourceFile -> getContentBlob ()) 169 { 170outBlob = outSourceFile -> getContentBlob (); 171return SLANG_OK ; 172 } 173 174ComPtr < ISlangBlob > foundSourceBlob ; 175if (SLANG_FAILED (m_fileSystemExt -> loadFile ( 176pathInfo .foundPath .getBuffer (), 177foundSourceBlob .writeRef ()))) 178 { 179return SLANG_E_CANNOT_OPEN ; 180 } 181 182outSourceFile -> setContents (foundSourceBlob ); 183 184outBlob = foundSourceBlob ; 185return SLANG_OK ; 186 } 187 } 188else 189 { 190// If we don't have the source manager, just load 191outSourceFile = nullptr ; 192return m_fileSystemExt -> loadFile (pathInfo .foundPath .getBuffer (),outBlob .writeRef ()); 193 } 194} 195 196SlangResult IncludeSystem ::findAndLoadFile ( 197const String & pathToInclude , 198const String & pathIncludedFrom , 199PathInfo & outPathInfo , 200ComPtr < ISlangBlob >& outBlob ) 201{ 202SLANG_RETURN_ON_FAIL (findFile (pathToInclude ,pathIncludedFrom ,outPathInfo )); 203SLANG_RETURN_ON_FAIL (loadFile (outPathInfo ,outBlob )); 204return SLANG_OK ; 205} 206 207}// namespace Slang