Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/common/lexers/stream.h
9913 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "../sys/platform.h"
7
#include "../sys/ref.h"
8
#include "../sys/filename.h"
9
#include "../sys/estring.h"
10
11
#include <vector>
12
#include <iostream>
13
#include <cstdio>
14
#include <string.h>
15
16
namespace embree
17
{
18
/*! stores the location of a stream element in the source */
19
class ParseLocation
20
{
21
public:
22
ParseLocation () : lineNumber(-1), colNumber(-1) {}
23
ParseLocation (std::shared_ptr<std::string> fileName, ssize_t lineNumber, ssize_t colNumber, ssize_t /*charNumber*/)
24
: fileName(fileName), lineNumber(lineNumber), colNumber(colNumber) {}
25
26
std::string str() const
27
{
28
std::string str = "unknown";
29
if (fileName) str = *fileName;
30
if (lineNumber >= 0) str += " line " + toString(lineNumber);
31
if (lineNumber >= 0 && colNumber >= 0) str += " character " + toString(colNumber);
32
return str;
33
}
34
35
private:
36
std::shared_ptr<std::string> fileName; /// name of the file (or stream) the token is from
37
ssize_t lineNumber; /// the line number the token is from
38
ssize_t colNumber; /// the character number in the current line
39
};
40
41
/*! a stream class templated over the stream elements */
42
template<typename T> class Stream : public RefCount
43
{
44
enum { BUF_SIZE = 1024 };
45
46
private:
47
virtual T next() = 0;
48
virtual ParseLocation location() = 0;
49
__forceinline std::pair<T,ParseLocation> nextHelper() {
50
ParseLocation l = location();
51
T v = next();
52
return std::pair<T,ParseLocation>(v,l);
53
}
54
__forceinline void push_back(const std::pair<T,ParseLocation>& v) {
55
if (past+future == BUF_SIZE) pop_front();
56
size_t end = (start+past+future++)%BUF_SIZE;
57
buffer[end] = v;
58
}
59
__forceinline void pop_front() {
60
if (past == 0) THROW_RUNTIME_ERROR("stream buffer empty");
61
start = (start+1)%BUF_SIZE; past--;
62
}
63
public:
64
Stream () : start(0), past(0), future(0), buffer(BUF_SIZE) {}
65
virtual ~Stream() {}
66
67
public:
68
69
const ParseLocation& loc() {
70
if (future == 0) push_back(nextHelper());
71
return buffer[(start+past)%BUF_SIZE].second;
72
}
73
T get() {
74
if (future == 0) push_back(nextHelper());
75
T t = buffer[(start+past)%BUF_SIZE].first;
76
past++; future--;
77
return t;
78
}
79
const T& peek() {
80
if (future == 0) push_back(nextHelper());
81
return buffer[(start+past)%BUF_SIZE].first;
82
}
83
const T& unget(size_t n = 1) {
84
if (past < n) THROW_RUNTIME_ERROR ("cannot unget that many items");
85
past -= n; future += n;
86
return peek();
87
}
88
void drop() {
89
if (future == 0) push_back(nextHelper());
90
past++; future--;
91
}
92
private:
93
size_t start,past,future;
94
std::vector<std::pair<T,ParseLocation> > buffer;
95
};
96
97
/*! warps an iostream stream */
98
class StdStream : public Stream<int>
99
{
100
public:
101
StdStream (std::istream& cin, const std::string& name = "std::stream")
102
: cin(cin), lineNumber(1), colNumber(0), charNumber(0), name(std::shared_ptr<std::string>(new std::string(name))) {}
103
~StdStream() {}
104
ParseLocation location() {
105
return ParseLocation(name,lineNumber,colNumber,charNumber);
106
}
107
int next() {
108
int c = cin.get();
109
if (c == '\n') { lineNumber++; colNumber = 0; } else if (c != '\r') colNumber++;
110
charNumber++;
111
return c;
112
}
113
private:
114
std::istream& cin;
115
ssize_t lineNumber; /// the line number the token is from
116
ssize_t colNumber; /// the character number in the current line
117
ssize_t charNumber; /// the character in the file
118
std::shared_ptr<std::string> name; /// name of buffer
119
};
120
121
/*! creates a stream from a file */
122
class FileStream : public Stream<int>
123
{
124
public:
125
FileStream (const FileName& fileName)
126
: lineNumber(1), colNumber(0), charNumber(0), name(std::shared_ptr<std::string>(new std::string(fileName.str())))
127
{
128
if (ifs) ifs.close();
129
ifs.open(fileName.str());
130
if (!ifs.is_open()) THROW_RUNTIME_ERROR("cannot open file " + fileName.str());
131
}
132
~FileStream() {
133
if (ifs) ifs.close();
134
}
135
136
public:
137
ParseLocation location() {
138
return ParseLocation(name,lineNumber,colNumber,charNumber);
139
}
140
141
int next() {
142
int c = ifs.get();
143
if (c == '\n') { lineNumber++; colNumber = 0; } else if (c != '\r') colNumber++;
144
charNumber++;
145
return c;
146
}
147
148
149
private:
150
std::ifstream ifs;
151
ssize_t lineNumber; /// the line number the token is from
152
ssize_t colNumber; /// the character number in the current line
153
ssize_t charNumber; /// the character in the file
154
std::shared_ptr<std::string> name; /// name of buffer
155
};
156
157
/*! creates a stream from a string */
158
class StrStream : public Stream<int>
159
{
160
public:
161
162
StrStream (const char* str)
163
: str(str), lineNumber(1), colNumber(0), charNumber(0) {}
164
165
public:
166
ParseLocation location() {
167
return ParseLocation(std::shared_ptr<std::string>(),lineNumber,colNumber,charNumber);
168
}
169
170
int next() {
171
int c = str[charNumber];
172
if (c == 0) return EOF;
173
if (c == '\n') { lineNumber++; colNumber = 0; } else if (c != '\r') colNumber++;
174
charNumber++;
175
return c;
176
}
177
178
private:
179
const char* str;
180
ssize_t lineNumber; /// the line number the token is from
181
ssize_t colNumber; /// the character number in the current line
182
ssize_t charNumber; /// the character in the file
183
};
184
185
/*! creates a character stream from a command line */
186
class CommandLineStream : public Stream<int>
187
{
188
public:
189
CommandLineStream (int argc, char** argv, const std::string& name = "command line")
190
: i(0), j(0), charNumber(0), name(std::shared_ptr<std::string>(new std::string(name)))
191
{
192
if (argc > 0) {
193
for (size_t i=0; argv[0][i] && i<1024; i++) charNumber++;
194
charNumber++;
195
}
196
for (ssize_t k=1; k<argc; k++) args.push_back(argv[k]);
197
}
198
~CommandLineStream() {}
199
public:
200
ParseLocation location() {
201
return ParseLocation(name,0,charNumber,charNumber);
202
}
203
int next() {
204
if (i == args.size()) return EOF;
205
if (j == args[i].size()) { i++; j=0; charNumber++; return ' '; }
206
charNumber++;
207
return args[i][j++];
208
}
209
private:
210
size_t i,j;
211
std::vector<std::string> args;
212
ssize_t charNumber; /// the character in the file
213
std::shared_ptr<std::string> name; /// name of buffer
214
};
215
}
216
217