diff options
Diffstat (limited to 'Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp')
-rw-r--r-- | Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp new file mode 100644 index 0000000..694c3bd --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp @@ -0,0 +1,165 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "Input.h" + +#include <cstdio> + +#include "compiler/debug.h" + +namespace pp +{ + +Input::Input(int count, const char* const string[], const int length[]) + : mCount(count), + mString(string), + mLength(length), + mIndex(-1), + mSize(0), + mError(kErrorNone), + mState(kStateInitial) +{ + ASSERT(mCount >= 0); + switchToNextString(); +} + +bool Input::eof() const +{ + ASSERT(mIndex <= mCount); + return mIndex == mCount; +} + +int Input::read(char* buf, int bufSize) +{ + int nread = 0; + int startIndex = mIndex; + // Keep reading until the buffer is full or the current string is exhausted. + while ((mIndex == startIndex) && (nread < bufSize)) + { + int c = getChar(); + if (c == EOF) + { + if (mState == kStateBlockComment) + mError = kErrorUnexpectedEOF; + break; + } + + switch (mState) + { + case kStateInitial: + if (c == '/') + { + // Potentially a comment. + switch (peekChar()) + { + case '/': + getChar(); // Eat '/'. + mState = kStateLineComment; + break; + case '*': + getChar(); // Eat '*'. + mState = kStateBlockComment; + break; + default: + // Not a comment. + buf[nread++] = c; + break; + } + } else + { + buf[nread++] = c; + } + break; + + case kStateLineComment: + if (c == '\n') + { + buf[nread++] = c; + mState = kStateInitial; + } + break; + + case kStateBlockComment: + if (c == '*' && (peekChar() == '/')) + { + getChar(); // Eat '/'. + buf[nread++] = ' '; // Replace comment with whitespace. + mState = kStateInitial; + } else if (c == '\n') + { + // Line breaks are never skipped. + buf[nread++] = c; + } + break; + + default: + ASSERT(false); + break; + } + } + + return nread; +} + +int Input::getChar() +{ + if (eof()) return EOF; + + const char* str = mString[mIndex]; + int c = str[mSize++]; + + // Switch to next string if the current one is fully read. + int length = stringLength(mIndex); + // We never read from empty string. + ASSERT(length != 0); + if (((length < 0) && (str[mSize] == '\0')) || + ((length > 0) && (mSize == length))) + switchToNextString(); + + return c; +} + +int Input::peekChar() +{ + // Save the current read position. + int index = mIndex; + int size = mSize; + int c = getChar(); + + // Restore read position. + mIndex = index; + mSize = size; + return c; +} + +void Input::switchToNextString() +{ + ASSERT(mIndex < mCount); + + mSize = 0; + do + { + ++mIndex; + } while (!eof() && isStringEmpty(mIndex)); +} + +bool Input::isStringEmpty(int index) +{ + ASSERT(index < mCount); + + const char* str = mString[mIndex]; + int length = stringLength(mIndex); + return (length == 0) || ((length < 0) && (str[0] == '\0')); +} + +int Input::stringLength(int index) +{ + ASSERT(index < mCount); + return mLength ? mLength[index] : -1; +} + +} // namespace pp + |