summaryrefslogtreecommitdiff
path: root/source/slang/slang-include-system.cpp
blob: 66aeb3f6738d770f0f9dca59d24557e265a335a4 (plain)
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