1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
// slang-include-system.cpp
#include "slang-include-system.h"
#include "../core/slang-io.h"
#include "../core/slang-string-util.h"
namespace Slang
{
SlangResult IncludeSystem::findFile(SlangPathType fromPathType, const String& fromPath, const String& path, PathInfo& outPathInfo)
{
// Get relative path
ComPtr<ISlangBlob> combinedPathBlob;
SLANG_RETURN_ON_FAIL(m_fileSystemExt->calcCombinedPath(fromPathType, fromPath.begin(), path.begin(), combinedPathBlob.writeRef()));
String combinedPath(StringUtil::getString(combinedPathBlob));
if (combinedPath.getLength() <= 0)
{
return SLANG_FAIL;
}
SlangPathType pathType;
SLANG_RETURN_ON_FAIL(m_fileSystemExt->getPathType(combinedPath.begin(), &pathType));
if (pathType != SLANG_PATH_TYPE_FILE)
{
return SLANG_E_NOT_FOUND;
}
// Get the uniqueIdentity
ComPtr<ISlangBlob> uniqueIdentityBlob;
SLANG_RETURN_ON_FAIL(m_fileSystemExt->getFileUniqueIdentity(combinedPath.begin(), uniqueIdentityBlob.writeRef()));
// If the rel path exists -> a uniqueIdentity MUST exists too
String uniqueIdentity(StringUtil::getString(uniqueIdentityBlob));
if (uniqueIdentity.getLength() <= 0)
{
// Unique identity can't be empty
return SLANG_FAIL;
}
outPathInfo = PathInfo::makeNormal(combinedPath, uniqueIdentity);
return SLANG_OK;
}
String IncludeSystem::simplifyPath(const String& path)
{
ComPtr<ISlangBlob> simplifiedPath;
if (SLANG_FAILED(m_fileSystemExt->getSimplifiedPath(path.getBuffer(), simplifiedPath.writeRef())))
{
return path;
}
return StringUtil::getString(simplifiedPath);
}
SlangResult IncludeSystem::findFile(String const& pathToInclude, String const& pathIncludedFrom, PathInfo& outPathInfo)
{
outPathInfo.type = PathInfo::Type::Unknown;
// Try just relative to current path
{
SlangResult res = findFile(SLANG_PATH_TYPE_FILE, pathIncludedFrom, pathToInclude, outPathInfo);
// It either succeeded or wasn't found, anything else is a failure passed back
if (SLANG_SUCCEEDED(res) || res != SLANG_E_NOT_FOUND)
{
return res;
}
}
// Search all the searchDirectories
for (auto sd = m_searchDirectories; sd; sd = sd->parent)
{
for (auto& dir : sd->searchDirectories)
{
SlangResult res = findFile(SLANG_PATH_TYPE_DIRECTORY, dir.path, pathToInclude, outPathInfo);
if (SLANG_SUCCEEDED(res) || res != SLANG_E_NOT_FOUND)
{
return res;
}
}
}
return SLANG_E_NOT_FOUND;
}
SlangResult IncludeSystem::loadFile(const PathInfo& pathInfo, ComPtr<ISlangBlob>& outBlob)
{
if (m_sourceManager)
{
// See if this an already loaded source file
SourceFile* sourceFile = m_sourceManager->findSourceFileRecursively(pathInfo.uniqueIdentity);
// If not create a new one, and add to the list of known source files
if (!sourceFile)
{
ComPtr<ISlangBlob> foundSourceBlob;
if (SLANG_FAILED(m_fileSystemExt->loadFile(pathInfo.foundPath.getBuffer(), foundSourceBlob.writeRef())))
{
return SLANG_E_CANNOT_OPEN;
}
sourceFile = m_sourceManager->createSourceFileWithBlob(pathInfo, foundSourceBlob);
m_sourceManager->addSourceFile(pathInfo.uniqueIdentity, sourceFile);
outBlob = foundSourceBlob;
return SLANG_OK;
}
else
{
if (sourceFile->getContentBlob())
{
outBlob = sourceFile->getContentBlob();
return SLANG_OK;
}
ComPtr<ISlangBlob> foundSourceBlob;
if (SLANG_FAILED(m_fileSystemExt->loadFile(pathInfo.foundPath.getBuffer(), foundSourceBlob.writeRef())))
{
return SLANG_E_CANNOT_OPEN;
}
sourceFile->setContents(foundSourceBlob);
outBlob = foundSourceBlob;
return SLANG_OK;
}
}
else
{
// If we don't have the source manager, just load
return m_fileSystemExt->loadFile(pathInfo.foundPath.getBuffer(), outBlob.writeRef());
}
}
SlangResult IncludeSystem::findAndLoadFile(const String& pathToInclude, const String& pathIncludedFrom, PathInfo& outPathInfo, ComPtr<ISlangBlob>& outBlob)
{
SLANG_RETURN_ON_FAIL(findFile(pathToInclude, pathIncludedFrom, outPathInfo));
SLANG_RETURN_ON_FAIL(loadFile(outPathInfo, outBlob));
return SLANG_OK;
}
} // namespace Slang
|