Path: blob/main_old/src/compiler/preprocessor/Input.cpp
1693 views
//1// Copyright 2011 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56#include "compiler/preprocessor/Input.h"78#include <algorithm>9#include <cstring>1011#include "common/debug.h"1213namespace angle14{1516namespace pp17{1819Input::Input() : mCount(0), mString(0) {}2021Input::~Input() {}2223Input::Input(size_t count, const char *const string[], const int length[])24: mCount(count), mString(string)25{26mLength.reserve(mCount);27for (size_t i = 0; i < mCount; ++i)28{29int len = length ? length[i] : -1;30mLength.push_back(len < 0 ? std::strlen(mString[i]) : len);31}32}3334const char *Input::skipChar()35{36// This function should only be called when there is a character to skip.37ASSERT(mReadLoc.cIndex < mLength[mReadLoc.sIndex]);38++mReadLoc.cIndex;39if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])40{41++mReadLoc.sIndex;42mReadLoc.cIndex = 0;43}44if (mReadLoc.sIndex >= mCount)45{46return nullptr;47}48return mString[mReadLoc.sIndex] + mReadLoc.cIndex;49}5051size_t Input::read(char *buf, size_t maxSize, int *lineNo)52{53size_t nRead = 0;54// The previous call to read might have stopped copying the string when encountering a line55// continuation. Check for this possibility first.56if (mReadLoc.sIndex < mCount && maxSize > 0)57{58const char *c = mString[mReadLoc.sIndex] + mReadLoc.cIndex;59if ((*c) == '\\')60{61c = skipChar();62if (c != nullptr && (*c) == '\n')63{64// Line continuation of backslash + newline.65skipChar();66// Fake an EOF if the line number would overflow.67if (*lineNo == INT_MAX)68{69return 0;70}71++(*lineNo);72}73else if (c != nullptr && (*c) == '\r')74{75// Line continuation. Could be backslash + '\r\n' or just backslash + '\r'.76c = skipChar();77if (c != nullptr && (*c) == '\n')78{79skipChar();80}81// Fake an EOF if the line number would overflow.82if (*lineNo == INT_MAX)83{84return 0;85}86++(*lineNo);87}88else89{90// Not line continuation, so write the skipped backslash to buf.91*buf = '\\';92++nRead;93}94}95}9697size_t maxRead = maxSize;98while ((nRead < maxRead) && (mReadLoc.sIndex < mCount))99{100size_t size = mLength[mReadLoc.sIndex] - mReadLoc.cIndex;101size = std::min(size, maxSize);102for (size_t i = 0; i < size; ++i)103{104// Stop if a possible line continuation is encountered.105// It will be processed on the next call on input, which skips it106// and increments line number if necessary.107if (*(mString[mReadLoc.sIndex] + mReadLoc.cIndex + i) == '\\')108{109size = i;110maxRead = nRead + size; // Stop reading right before the backslash.111}112}113std::memcpy(buf + nRead, mString[mReadLoc.sIndex] + mReadLoc.cIndex, size);114nRead += size;115mReadLoc.cIndex += size;116117// Advance string if we reached the end of current string.118if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])119{120++mReadLoc.sIndex;121mReadLoc.cIndex = 0;122}123}124return nRead;125}126127} // namespace pp128129} // namespace angle130131132