Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
glslang
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
glslang
Commits
56368b68
Commit
56368b68
authored
Mar 21, 2016
by
John Kessenich
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #198 from AWoloszyn/update-includer
Updated the includer interface to allow relative includes.
parents
ddb65a46
a132af5b
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
220 additions
and
54 deletions
+220
-54
StandAlone.cpp
StandAlone/StandAlone.cpp
+2
-1
Scan.h
glslang/MachineIndependent/Scan.h
+46
-7
ShaderLang.cpp
glslang/MachineIndependent/ShaderLang.cpp
+10
-9
Pp.cpp
glslang/MachineIndependent/preprocessor/Pp.cpp
+15
-11
PpContext.cpp
glslang/MachineIndependent/preprocessor/PpContext.cpp
+4
-2
PpContext.h
glslang/MachineIndependent/preprocessor/PpContext.h
+71
-16
ShaderLang.h
glslang/Public/ShaderLang.h
+72
-8
No files found.
StandAlone/StandAlone.cpp
View file @
56368b68
...
...
@@ -699,8 +699,9 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
if
(
Options
&
EOptionOutputPreprocessed
)
{
std
::
string
str
;
glslang
::
TShader
::
ForbidInclude
includer
;
if
(
shader
->
preprocess
(
&
Resources
,
defaultVersion
,
ENoProfile
,
false
,
false
,
messages
,
&
str
,
glslang
::
TShader
::
ForbidInclude
()
))
{
messages
,
&
str
,
includer
))
{
PutsIfNonEmpty
(
str
.
c_str
());
}
else
{
CompileFailed
=
true
;
...
...
glslang/MachineIndependent/Scan.h
View file @
56368b68
...
...
@@ -51,10 +51,10 @@ const int EndOfInput = -1;
//
class
TInputScanner
{
public
:
TInputScanner
(
int
n
,
const
char
*
const
s
[],
size_t
L
[],
const
char
*
const
*
names
=
nullptr
,
int
b
=
0
,
int
f
=
0
)
:
TInputScanner
(
int
n
,
const
char
*
const
s
[],
size_t
L
[],
const
char
*
const
*
names
=
nullptr
,
int
b
=
0
,
int
f
=
0
,
bool
single
=
false
)
:
numSources
(
n
),
sources
(
reinterpret_cast
<
const
unsigned
char
*
const
*>
(
s
)),
// up to this point, common usage is "char*", but now we need positive 8-bit characters
lengths
(
L
),
currentSource
(
0
),
currentChar
(
0
),
stringBias
(
b
),
finale
(
f
)
lengths
(
L
),
currentSource
(
0
),
currentChar
(
0
),
stringBias
(
b
),
finale
(
f
)
,
singleLogical
(
single
)
{
loc
=
new
TSourceLoc
[
numSources
];
for
(
int
i
=
0
;
i
<
numSources
;
++
i
)
{
...
...
@@ -67,6 +67,10 @@ public:
loc
[
currentSource
].
string
=
-
stringBias
;
loc
[
currentSource
].
line
=
1
;
loc
[
currentSource
].
column
=
0
;
logicalSourceLoc
.
string
=
0
;
logicalSourceLoc
.
line
=
1
;
logicalSourceLoc
.
column
=
0
;
logicalSourceLoc
.
name
=
loc
[
0
].
name
;
}
virtual
~
TInputScanner
()
...
...
@@ -82,8 +86,11 @@ public:
int
ret
=
peek
();
++
loc
[
currentSource
].
column
;
++
logicalSourceLoc
.
column
;
if
(
ret
==
'\n'
)
{
++
loc
[
currentSource
].
line
;
++
logicalSourceLoc
.
line
;
logicalSourceLoc
.
column
=
0
;
loc
[
currentSource
].
column
=
0
;
}
advance
();
...
...
@@ -118,6 +125,7 @@ public:
if
(
currentChar
>
0
)
{
--
currentChar
;
--
loc
[
currentSource
].
column
;
--
logicalSourceLoc
.
column
;
if
(
loc
[
currentSource
].
column
<
0
)
{
// We've moved back past a new line. Find the
// previous newline (or start of the file) to compute
...
...
@@ -129,6 +137,7 @@ public:
}
--
chIndex
;
}
logicalSourceLoc
.
column
=
(
int
)(
currentChar
-
chIndex
);
loc
[
currentSource
].
column
=
(
int
)(
currentChar
-
chIndex
);
}
}
else
{
...
...
@@ -141,23 +150,49 @@ public:
}
else
currentChar
=
lengths
[
currentSource
]
-
1
;
}
if
(
peek
()
==
'\n'
)
if
(
peek
()
==
'\n'
)
{
--
loc
[
currentSource
].
line
;
--
logicalSourceLoc
.
line
;
}
}
// for #line override
void
setLine
(
int
newLine
)
{
loc
[
getLastValidSourceIndex
()].
line
=
newLine
;
}
void
setFile
(
const
char
*
filename
)
{
loc
[
getLastValidSourceIndex
()].
name
=
filename
;
}
void
setLine
(
int
newLine
)
{
logicalSourceLoc
.
line
=
newLine
;
loc
[
getLastValidSourceIndex
()].
line
=
newLine
;
}
// for #line override in filename based parsing
void
setFile
(
const
char
*
filename
)
{
logicalSourceLoc
.
name
=
filename
;
loc
[
getLastValidSourceIndex
()].
name
=
filename
;
}
void
setString
(
int
newString
)
{
logicalSourceLoc
.
string
=
newString
;
loc
[
getLastValidSourceIndex
()].
string
=
newString
;
logicalSourceLoc
.
name
=
nullptr
;
loc
[
getLastValidSourceIndex
()].
name
=
nullptr
;
}
// for #include content indentation
void
setColumn
(
int
col
)
{
loc
[
getLastValidSourceIndex
()].
column
=
col
;
}
void
setColumn
(
int
col
)
{
logicalSourceLoc
.
column
=
col
;
loc
[
getLastValidSourceIndex
()].
column
=
col
;
}
const
TSourceLoc
&
getSourceLoc
()
const
{
return
loc
[
std
::
max
(
0
,
std
::
min
(
currentSource
,
numSources
-
finale
-
1
))];
}
const
TSourceLoc
&
getSourceLoc
()
const
{
if
(
singleLogical
)
{
return
logicalSourceLoc
;
}
else
{
return
loc
[
std
::
max
(
0
,
std
::
min
(
currentSource
,
numSources
-
finale
-
1
))];
}
}
// Returns the index (starting from 0) of the most recent valid source string we are reading from.
int
getLastValidSourceIndex
()
const
{
return
std
::
min
(
currentSource
,
numSources
-
1
);
}
...
...
@@ -204,6 +239,10 @@ protected:
int
stringBias
;
// the first string that is the user's string number 0
int
finale
;
// number of internal strings after user's last string
TSourceLoc
logicalSourceLoc
;
bool
singleLogical
;
// treats the strings as a single logical string.
// locations will be reported from the first string.
};
}
// end namespace glslang
...
...
glslang/MachineIndependent/ShaderLang.cpp
View file @
56368b68
...
...
@@ -131,7 +131,8 @@ bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profil
TIntermediate
intermediate
(
language
,
version
,
profile
);
TParseContext
parseContext
(
symbolTable
,
intermediate
,
true
,
version
,
profile
,
spv
,
vulkan
,
language
,
infoSink
);
TPpContext
ppContext
(
parseContext
,
TShader
::
ForbidInclude
());
TShader
::
ForbidInclude
includer
;
TPpContext
ppContext
(
parseContext
,
""
,
includer
);
TScanContext
scanContext
(
parseContext
);
parseContext
.
setScanContext
(
&
scanContext
);
parseContext
.
setPpContext
(
&
ppContext
);
...
...
@@ -482,7 +483,7 @@ bool ProcessDeferred(
TIntermediate
&
intermediate
,
// returned tree, etc.
ProcessingContext
&
processingContext
,
bool
requireNonempty
,
const
TShader
::
Includer
&
includer
TShader
::
Includer
&
includer
)
{
if
(
!
InitThread
())
...
...
@@ -550,7 +551,6 @@ bool ProcessDeferred(
version
=
defaultVersion
;
profile
=
defaultProfile
;
}
int
spv
=
(
messages
&
EShMsgSpvRules
)
?
100
:
0
;
// TODO find path to get real version number here, for now non-0 is what matters
bool
goodVersion
=
DeduceVersionProfile
(
compiler
->
infoSink
,
compiler
->
getLanguage
(),
versionNotFirst
,
defaultVersion
,
version
,
profile
,
spv
);
bool
versionWillBeError
=
(
versionNotFound
||
(
profile
==
EEsProfile
&&
version
>=
300
&&
versionNotFirst
));
...
...
@@ -590,7 +590,7 @@ bool ProcessDeferred(
TParseContext
parseContext
(
symbolTable
,
intermediate
,
false
,
version
,
profile
,
spv
,
vulkan
,
compiler
->
getLanguage
(),
compiler
->
infoSink
,
forwardCompatible
,
messages
);
glslang
::
TScanContext
scanContext
(
parseContext
);
TPpContext
ppContext
(
parseContext
,
includer
);
TPpContext
ppContext
(
parseContext
,
names
[
numPre
]
?
names
[
numPre
]
:
""
,
includer
);
parseContext
.
setScanContext
(
&
scanContext
);
parseContext
.
setPpContext
(
&
ppContext
);
parseContext
.
setLimits
(
*
resources
);
...
...
@@ -863,7 +863,7 @@ bool PreprocessDeferred(
bool
forceDefaultVersionAndProfile
,
bool
forwardCompatible
,
// give errors for use of deprecated features
EShMessages
messages
,
// warnings/errors/AST; things to print out
const
TShader
::
Includer
&
includer
,
TShader
::
Includer
&
includer
,
TIntermediate
&
intermediate
,
// returned tree, etc.
std
::
string
*
outputString
)
{
...
...
@@ -902,7 +902,7 @@ bool CompileDeferred(
bool
forwardCompatible
,
// give errors for use of deprecated features
EShMessages
messages
,
// warnings/errors/AST; things to print out
TIntermediate
&
intermediate
,
// returned tree, etc.
const
TShader
::
Includer
&
includer
)
TShader
::
Includer
&
includer
)
{
DoFullParse
parser
;
return
ProcessDeferred
(
compiler
,
shaderStrings
,
numStrings
,
inputLengths
,
stringNames
,
...
...
@@ -1051,9 +1051,10 @@ int ShCompile(
compiler
->
infoSink
.
debug
.
erase
();
TIntermediate
intermediate
(
compiler
->
getLanguage
());
TShader
::
ForbidInclude
includer
;
bool
success
=
CompileDeferred
(
compiler
,
shaderStrings
,
numStrings
,
inputLengths
,
nullptr
,
""
,
optLevel
,
resources
,
defaultVersion
,
ENoProfile
,
false
,
forwardCompatible
,
messages
,
intermediate
,
TShader
::
ForbidInclude
()
);
forwardCompatible
,
messages
,
intermediate
,
includer
);
//
// Call the machine dependent compiler
...
...
@@ -1361,7 +1362,7 @@ void TShader::setStringsWithLengthsAndNames(
// Returns true for success.
//
bool
TShader
::
parse
(
const
TBuiltInResource
*
builtInResources
,
int
defaultVersion
,
EProfile
defaultProfile
,
bool
forceDefaultVersionAndProfile
,
bool
forwardCompatible
,
EShMessages
messages
,
const
Includer
&
includer
)
bool
forwardCompatible
,
EShMessages
messages
,
Includer
&
includer
)
{
if
(
!
InitThread
())
return
false
;
...
...
@@ -1389,7 +1390,7 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources,
bool
forceDefaultVersionAndProfile
,
bool
forwardCompatible
,
EShMessages
message
,
std
::
string
*
output_string
,
const
TShader
::
Includer
&
includer
)
Includer
&
includer
)
{
if
(
!
InitThread
())
return
false
;
...
...
glslang/MachineIndependent/preprocessor/Pp.cpp
View file @
56368b68
...
...
@@ -611,24 +611,28 @@ int TPpContext::CPPinclude(TPpToken* ppToken)
if
(
token
!=
'\n'
&&
token
!=
EndOfInput
)
{
parseContext
.
ppError
(
ppToken
->
loc
,
"extra content after file designation"
,
"#include"
,
""
);
}
else
{
auto
include
=
includer
.
include
(
filename
.
c_str
());
std
::
string
sourceName
=
include
.
first
;
std
::
string
replacement
=
include
.
second
;
if
(
!
sourceName
.
empty
())
{
if
(
!
replacement
.
empty
())
{
TShader
::
Includer
::
IncludeResult
*
res
=
includer
.
include
(
filename
.
c_str
(),
TShader
::
Includer
::
EIncludeRelative
,
currentSourceFile
.
c_str
(),
includeStack
.
size
()
+
1
);
if
(
res
&&
!
res
->
file_name
.
empty
())
{
if
(
res
->
file_data
&&
res
->
file_length
)
{
const
bool
forNextLine
=
parseContext
.
lineDirectiveShouldSetNextLine
();
std
::
ostringstream
content
;
content
<<
"#line "
<<
forNextLine
<<
" "
<<
"
\"
"
<<
sourceName
<<
"
\"\n
"
;
content
<<
replacement
<<
(
replacement
.
back
()
==
'\n'
?
""
:
"
\n
"
)
;
content
<<
"#line "
<<
directiveLoc
.
line
+
forNextLine
<<
" "
<<
directiveLoc
.
getStringNameOrNum
()
<<
"
\n
"
;
pushInput
(
new
Tokenizable
String
(
directiveLoc
,
content
.
str
(),
this
));
std
::
ostringstream
prologue
;
std
::
ostringstream
epilogue
;
prologue
<<
"#line "
<<
forNextLine
<<
" "
<<
"
\"
"
<<
res
->
file_name
<<
"
\"\n
"
;
epilogue
<<
(
res
->
file_data
[
res
->
file_length
-
1
]
==
'\n'
?
""
:
"
\n
"
)
<<
"#line "
<<
directiveLoc
.
line
+
forNextLine
<<
" "
<<
directiveLoc
.
getStringNameOrNum
()
<<
"
\n
"
;
pushInput
(
new
Tokenizable
IncludeFile
(
directiveLoc
,
prologue
.
str
(),
res
,
epilogue
.
str
(),
this
));
}
// At EOF, there's no "current" location anymore.
if
(
token
!=
EndOfInput
)
parseContext
.
setCurrentColumn
(
0
);
// Don't accidentally return EndOfInput, which will end all preprocessing.
return
'\n'
;
}
else
{
parseContext
.
ppError
(
directiveLoc
,
replacement
.
c_str
(),
"#include"
,
""
);
std
::
string
message
=
res
?
std
::
string
(
res
->
file_data
,
res
->
file_length
)
:
std
::
string
(
"Could not process include directive"
);
parseContext
.
ppError
(
directiveLoc
,
message
.
c_str
(),
"#include"
,
""
);
if
(
res
)
{
includer
.
releaseInclude
(
res
);
}
}
}
}
...
...
glslang/MachineIndependent/preprocessor/PpContext.cpp
View file @
56368b68
...
...
@@ -83,8 +83,10 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace
glslang
{
TPpContext
::
TPpContext
(
TParseContext
&
pc
,
const
TShader
::
Includer
&
inclr
)
:
preamble
(
0
),
strings
(
0
),
parseContext
(
pc
),
includer
(
inclr
),
inComment
(
false
)
TPpContext
::
TPpContext
(
TParseContext
&
pc
,
const
std
::
string
&
rootFileName
,
TShader
::
Includer
&
inclr
)
:
preamble
(
0
),
strings
(
0
),
parseContext
(
pc
),
includer
(
inclr
),
inComment
(
false
),
rootFileName
(
rootFileName
),
currentSourceFile
(
rootFileName
)
{
InitAtomTable
();
InitScanner
();
...
...
glslang/MachineIndependent/preprocessor/PpContext.h
View file @
56368b68
...
...
@@ -78,6 +78,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef PPCONTEXT_H
#define PPCONTEXT_H
#include <stack>
#include <unordered_map>
#include "../ParseHelper.h"
...
...
@@ -121,7 +122,7 @@ class TInputScanner;
// Don't expect too much in terms of OO design.
class
TPpContext
{
public
:
TPpContext
(
TParseContext
&
,
const
TShader
::
Includer
&
);
TPpContext
(
TParseContext
&
,
const
std
::
string
&
rootFileName
,
TShader
::
Includer
&
);
virtual
~
TPpContext
();
void
setPreamble
(
const
char
*
preamble
,
size_t
length
);
...
...
@@ -290,7 +291,7 @@ protected:
//
// Used to obtain #include content.
const
TShader
::
Includer
&
includer
;
TShader
::
Includer
&
includer
;
int
InitCPP
();
int
CPPdefine
(
TPpToken
*
ppToken
);
...
...
@@ -430,16 +431,30 @@ protected:
TInputScanner
*
input
;
};
// Holds a string that can be tokenized via the tInput interface.
class
TokenizableString
:
public
tInput
{
// Holds a reference to included file data, as well as a
// prologue and an epilogue string. This can be scanned using the tInput
// interface and acts as a single source string.
class
TokenizableIncludeFile
:
public
tInput
{
public
:
// Copies str, which must be non-empty.
TokenizableString
(
const
TSourceLoc
&
startLoc
,
const
std
::
string
&
str
,
TPpContext
*
pp
)
// Copies prologue and epilogue. The includedFile must remain valid
// until this TokenizableIncludeFile is no longer used.
TokenizableIncludeFile
(
const
TSourceLoc
&
startLoc
,
const
std
::
string
&
prologue
,
TShader
::
Includer
::
IncludeResult
*
includedFile
,
const
std
::
string
&
epilogue
,
TPpContext
*
pp
)
:
tInput
(
pp
),
str_
(
str
),
strings
(
str_
.
data
()),
length
(
str_
.
size
()),
scanner
(
1
,
&
strings
,
&
length
),
prologue_
(
prologue
),
includedFile_
(
includedFile
),
epilogue_
(
epilogue
),
strings
({
prologue_
.
data
(),
includedFile_
->
file_data
,
epilogue_
.
data
()}),
lengths
({
prologue_
.
size
(),
includedFile_
->
file_length
,
epilogue_
.
size
()}),
names
({
includedFile_
->
file_name
.
c_str
(),
includedFile_
->
file_name
.
c_str
(),
includedFile_
->
file_name
.
c_str
()
}),
scanner
(
3
,
strings
,
lengths
,
names
,
0
,
0
,
true
),
prevScanner
(
nullptr
),
stringInput
(
pp
,
scanner
)
{
scanner
.
setLine
(
startLoc
.
line
);
...
...
@@ -456,16 +471,34 @@ protected:
{
prevScanner
=
pp
->
parseContext
.
getScanner
();
pp
->
parseContext
.
setScanner
(
&
scanner
);
pp
->
push_include
(
includedFile_
);
}
void
notifyDeleted
()
override
{
pp
->
parseContext
.
setScanner
(
prevScanner
);
pp
->
pop_include
();
}
void
notifyDeleted
()
override
{
pp
->
parseContext
.
setScanner
(
prevScanner
);
}
private
:
// Stores the titular string.
const
std
::
string
str_
;
// Will point to str_[0] and be passed to scanner constructor.
const
char
*
const
strings
;
// Stores the prologue for this string.
const
std
::
string
prologue_
;
// Stores the epilogue for this string.
const
std
::
string
epilogue_
;
// Points to the IncludeResult that this TokenizableIncludeFile represents.
TShader
::
Includer
::
IncludeResult
*
includedFile_
;
// Will point to prologue_, includedFile_->file_data and epilogue_
// This is passed to scanner constructor.
// These do not own the storage and it must remain valid until this
// object has been destroyed.
const
char
*
strings
[
3
];
// Length of str_, passed to scanner constructor.
size_t
length
;
size_t
lengths
[
3
];
// String names
const
char
*
names
[
3
];
// Scans over str_.
TInputScanner
scanner
;
// The previous effective scanner before the scanner in this instance
...
...
@@ -480,6 +513,24 @@ protected:
void
missingEndifCheck
();
int
lFloatConst
(
int
len
,
int
ch
,
TPpToken
*
ppToken
);
void
push_include
(
TShader
::
Includer
::
IncludeResult
*
result
)
{
currentSourceFile
=
result
->
file_name
;
includeStack
.
push
(
result
);
}
void
pop_include
()
{
TShader
::
Includer
::
IncludeResult
*
include
=
includeStack
.
top
();
includeStack
.
pop
();
includer
.
releaseInclude
(
include
);
if
(
includeStack
.
empty
())
{
currentSourceFile
=
rootFileName
;
}
else
{
currentSourceFile
=
includeStack
.
top
()
->
file_name
;
}
}
bool
inComment
;
//
...
...
@@ -487,8 +538,12 @@ protected:
//
typedef
TUnorderedMap
<
TString
,
int
>
TAtomMap
;
typedef
TVector
<
const
TString
*>
TStringMap
;
TAtomMap
atomMap
;
TStringMap
stringMap
;
std
::
stack
<
TShader
::
Includer
::
IncludeResult
*>
includeStack
;
std
::
string
currentSourceFile
;
std
::
string
rootFileName
;
int
nextAtom
;
void
InitAtomTable
();
void
AddAtomFixed
(
const
char
*
s
,
int
atom
);
...
...
glslang/Public/ShaderLang.h
View file @
56368b68
...
...
@@ -292,25 +292,89 @@ public:
void
setPreamble
(
const
char
*
s
)
{
preamble
=
s
;
}
// Interface to #include handlers.
//
// To support #include, a client of Glslang does the following:
// 1. Call setStringsWithNames to set the source strings and associated
// names. For example, the names could be the names of the files
// containing the shader sources.
// 2. Call parse with an Includer.
//
// When the Glslang parser encounters an #include directive, it calls
// the Includer's include method with the the requested include name
// together with the current string name. The returned IncludeResult
// contains the fully resolved name of the included source, together
// with the source text that should replace the #include directive
// in the source stream. After parsing that source, Glslang will
// release the IncludeResult object.
class
Includer
{
public
:
// On success, returns the full path and content of the file with the given
// filename that replaces "#include filename". On failure, returns an empty
// string and an error message.
virtual
std
::
pair
<
std
::
string
,
std
::
string
>
include
(
const
char
*
filename
)
const
=
0
;
typedef
enum
{
EIncludeRelative
,
// For #include "something"
EIncludeStandard
// Reserved. For #include <something>
}
IncludeType
;
// An IncludeResult contains the resolved name and content of a source
// inclusion.
struct
IncludeResult
{
// For a successful inclusion, the fully resolved name of the requested
// include. For example, in a filesystem-based includer, full resolution
// should convert a relative path name into an absolute path name.
// For a failed inclusion, this is an empty string.
std
::
string
file_name
;
// The content and byte length of the requested inclusion. The
// Includer producing this IncludeResult retains ownership of the
// storage.
// For a failed inclusion, the file_data
// field points to a string containing error details.
const
char
*
file_data
;
const
size_t
file_length
;
// Include resolver's context.
void
*
user_data
;
};
// Resolves an inclusion request by name, type, current source name,
// and include depth.
// On success, returns an IncludeResult containing the resolved name
// and content of the include. On failure, returns an IncludeResult
// with an empty string for the file_name and error details in the
// file_data field. The Includer retains ownership of the contents
// of the returned IncludeResult value, and those contents must
// remain valid until the releaseInclude method is called on that
// IncludeResult object.
virtual
IncludeResult
*
include
(
const
char
*
requested_source
,
IncludeType
type
,
const
char
*
requesting_source
,
size_t
inclusion_depth
)
=
0
;
// Signals that the parser will no longer use the contents of the
// specified IncludeResult.
virtual
void
releaseInclude
(
IncludeResult
*
result
)
=
0
;
};
// Returns an error message for any #include directive.
class
ForbidInclude
:
public
Includer
{
public
:
std
::
pair
<
std
::
string
,
std
::
string
>
include
(
const
char
*
/*filename*/
)
const
override
IncludeResult
*
include
(
const
char
*
,
IncludeType
,
const
char
*
,
size_t
)
override
{
return
std
::
make_pair
<
std
::
string
,
std
::
string
>
(
""
,
"unexpected include directive"
);
static
const
char
unexpected_include
[]
=
"unexpected include directive"
;
return
new
IncludeResult
(
{
""
,
unexpected_include
,
sizeof
(
unexpected_include
)
-
1
,
nullptr
});
}
virtual
void
releaseInclude
(
IncludeResult
*
result
)
override
{
delete
result
;
}
};
bool
parse
(
const
TBuiltInResource
*
res
,
int
defaultVersion
,
EProfile
defaultProfile
,
bool
forceDefaultVersionAndProfile
,
bool
forwardCompatible
,
EShMessages
messages
)
{
TShader
::
ForbidInclude
includer
;
return
parse
(
res
,
defaultVersion
,
defaultProfile
,
forceDefaultVersionAndProfile
,
forwardCompatible
,
messages
,
includer
);
}
bool
parse
(
const
TBuiltInResource
*
,
int
defaultVersion
,
EProfile
defaultProfile
,
bool
forceDefaultVersionAndProfile
,
bool
forwardCompatible
,
EShMessages
,
const
Includer
&
=
ForbidInclude
()
);
bool
forwardCompatible
,
EShMessages
,
Includer
&
);
// Equivalent to parse() without a default profile and without forcing defaults.
// Provided for backwards compatibility.
...
...
@@ -318,7 +382,7 @@ public:
bool
preprocess
(
const
TBuiltInResource
*
builtInResources
,
int
defaultVersion
,
EProfile
defaultProfile
,
bool
forceDefaultVersionAndProfile
,
bool
forwardCompatible
,
EShMessages
message
,
std
::
string
*
outputString
,
const
TShader
::
Includer
&
includer
);
Includer
&
includer
);
const
char
*
getInfoLog
();
const
char
*
getInfoDebugLog
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment