2 //Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
3 //Copyright (C) 2013 LunarG, Inc.
7 //Redistribution and use in source and binary forms, with or without
8 //modification, are permitted provided that the following conditions
11 // Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
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.
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.
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.
36 #ifndef _GLSLANG_SCAN_INCLUDED_
37 #define _GLSLANG_SCAN_INCLUDED_
44 // A character scanner that seamlessly, on read-only strings, reads across an
45 // array of strings without assuming null termination.
49 TInputScanner(int n, const char* const s[], size_t L[], int b = 0, int f = 0) :
50 numSources(n), sources(s), lengths(L), currentSource(0), currentChar(0), stringBias(b), finale(f)
52 loc = new TSourceLoc[numSources];
53 loc[currentSource].string = -stringBias;
54 loc[currentSource].line = 1;
55 loc[currentSource].column = 0;
58 virtual ~TInputScanner()
63 // return of -1 means end of strings,
64 // anything else is the next character
66 // retrieve the next character and advance one character
69 if (currentSource >= numSources)
72 int ret = sources[currentSource][currentChar];
73 ++loc[currentSource].column;
75 ++loc[currentSource].line;
76 loc[currentSource].column = 0;
83 // retrieve the next character, no advance
86 if (currentSource >= numSources)
89 return sources[currentSource][currentChar];
92 // go back one character
95 if (currentChar > 0) {
97 --loc[currentSource].column;
98 if (loc[currentSource].column < 0) {
99 // We've moved back past a new line. Find the
100 // previous newline (or start of the file) to compute
101 // the column count on the now current line.
102 size_t ch = currentChar;
104 if (sources[currentSource][ch] == '\n') {
109 loc[currentSource].column = (int)(currentChar - ch);
114 } while (currentSource > 0 && lengths[currentSource] == 0);
115 if (lengths[currentSource] == 0) {
116 // set to 0 if we've backed up to the start of an empty string
119 currentChar = lengths[currentSource] - 1;
122 --loc[currentSource].line;
125 // for #line override
126 void setLine(int newLine) { loc[currentSource].line = newLine; }
127 void setString(int newString) { loc[currentSource].string = newString; }
129 const TSourceLoc& getSourceLoc() const { return loc[std::max(0, std::min(currentSource, numSources - finale - 1))]; }
131 void consumeWhiteSpace(bool& foundNonSpaceTab);
132 bool consumeComment();
133 void consumeWhitespaceComment(bool& foundNonSpaceTab);
134 bool scanVersion(int& version, EProfile& profile, bool& notFirstToken);
138 // advance one character
142 if (currentChar >= static_cast<int>(lengths[currentSource])) {
144 if (currentSource < numSources) {
145 loc[currentSource].string = loc[currentSource - 1].string + 1;
146 loc[currentSource].line = 1;
147 loc[currentSource].column = 0;
149 while (currentSource < numSources && lengths[currentSource] == 0) {
151 if (currentSource < numSources) {
152 loc[currentSource].string = loc[currentSource - 1].string + 1;
153 loc[currentSource].line = 1;
154 loc[currentSource].column = 0;
161 int numSources; // number of strings in source
162 const char* const *sources; // array of strings
163 const size_t *lengths; // length of each string
167 // This is for reporting what string/line an error occurred on, and can be overridden by #line.
168 // It remembers the last state of each source string as it is left for the next one, so unget()
169 // can restore that state.
170 TSourceLoc* loc; // an array
172 int stringBias; // the first string that is the user's string number 0
173 int finale; // number of internal strings after user's last string
176 } // end namespace glslang
178 #endif // _GLSLANG_SCAN_INCLUDED_