Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/compiler/preprocessor/Input.cpp
1693 views
1
//
2
// Copyright 2011 The ANGLE Project Authors. All rights reserved.
3
// Use of this source code is governed by a BSD-style license that can be
4
// found in the LICENSE file.
5
//
6
7
#include "compiler/preprocessor/Input.h"
8
9
#include <algorithm>
10
#include <cstring>
11
12
#include "common/debug.h"
13
14
namespace angle
15
{
16
17
namespace pp
18
{
19
20
Input::Input() : mCount(0), mString(0) {}
21
22
Input::~Input() {}
23
24
Input::Input(size_t count, const char *const string[], const int length[])
25
: mCount(count), mString(string)
26
{
27
mLength.reserve(mCount);
28
for (size_t i = 0; i < mCount; ++i)
29
{
30
int len = length ? length[i] : -1;
31
mLength.push_back(len < 0 ? std::strlen(mString[i]) : len);
32
}
33
}
34
35
const char *Input::skipChar()
36
{
37
// This function should only be called when there is a character to skip.
38
ASSERT(mReadLoc.cIndex < mLength[mReadLoc.sIndex]);
39
++mReadLoc.cIndex;
40
if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])
41
{
42
++mReadLoc.sIndex;
43
mReadLoc.cIndex = 0;
44
}
45
if (mReadLoc.sIndex >= mCount)
46
{
47
return nullptr;
48
}
49
return mString[mReadLoc.sIndex] + mReadLoc.cIndex;
50
}
51
52
size_t Input::read(char *buf, size_t maxSize, int *lineNo)
53
{
54
size_t nRead = 0;
55
// The previous call to read might have stopped copying the string when encountering a line
56
// continuation. Check for this possibility first.
57
if (mReadLoc.sIndex < mCount && maxSize > 0)
58
{
59
const char *c = mString[mReadLoc.sIndex] + mReadLoc.cIndex;
60
if ((*c) == '\\')
61
{
62
c = skipChar();
63
if (c != nullptr && (*c) == '\n')
64
{
65
// Line continuation of backslash + newline.
66
skipChar();
67
// Fake an EOF if the line number would overflow.
68
if (*lineNo == INT_MAX)
69
{
70
return 0;
71
}
72
++(*lineNo);
73
}
74
else if (c != nullptr && (*c) == '\r')
75
{
76
// Line continuation. Could be backslash + '\r\n' or just backslash + '\r'.
77
c = skipChar();
78
if (c != nullptr && (*c) == '\n')
79
{
80
skipChar();
81
}
82
// Fake an EOF if the line number would overflow.
83
if (*lineNo == INT_MAX)
84
{
85
return 0;
86
}
87
++(*lineNo);
88
}
89
else
90
{
91
// Not line continuation, so write the skipped backslash to buf.
92
*buf = '\\';
93
++nRead;
94
}
95
}
96
}
97
98
size_t maxRead = maxSize;
99
while ((nRead < maxRead) && (mReadLoc.sIndex < mCount))
100
{
101
size_t size = mLength[mReadLoc.sIndex] - mReadLoc.cIndex;
102
size = std::min(size, maxSize);
103
for (size_t i = 0; i < size; ++i)
104
{
105
// Stop if a possible line continuation is encountered.
106
// It will be processed on the next call on input, which skips it
107
// and increments line number if necessary.
108
if (*(mString[mReadLoc.sIndex] + mReadLoc.cIndex + i) == '\\')
109
{
110
size = i;
111
maxRead = nRead + size; // Stop reading right before the backslash.
112
}
113
}
114
std::memcpy(buf + nRead, mString[mReadLoc.sIndex] + mReadLoc.cIndex, size);
115
nRead += size;
116
mReadLoc.cIndex += size;
117
118
// Advance string if we reached the end of current string.
119
if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])
120
{
121
++mReadLoc.sIndex;
122
mReadLoc.cIndex = 0;
123
}
124
}
125
return nRead;
126
}
127
128
} // namespace pp
129
130
} // namespace angle
131
132