summaryrefslogtreecommitdiffstats
path: root/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp')
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp165
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
+