-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathreadline.cpp
More file actions
121 lines (92 loc) · 1.95 KB
/
readline.cpp
File metadata and controls
121 lines (92 loc) · 1.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "readline.h"
#include <vector>
namespace SDR
{
namespace etc
{
enum tokens
{
T_q,
T_d,
T_b,
T_v,
T_error,
T_num
};
enum states
{
S_s,
S_uq,
S_uqo,
S_qf,
S_qfo,
S_wait,
S_num
};
static int trans_table[S_num][T_num] =
{
//start
{S_qf, S_s, S_s, S_uq, S_s},
//unquoted field
{S_uqo, S_s, S_uq, S_uq, S_s},
//unquoted field odd
//{S_qf, S_s, S_s, S_uq, S_s},
{S_uq, S_uqo, S_uqo, S_uqo, S_s},
//quoted field
{S_wait, S_qf, S_qf, S_qf, S_s},
//qouted field odd
{S_qf, S_qfo, S_qfo, S_qfo, S_s},
//wait
{S_qf, S_s, S_wait, S_qfo, S_s},
};
inline bool q(char c) { return c == '\"'; }
inline bool d(char c, char delim) { return c == delim; }
inline bool b(char c) { return c == ' ' || c == '\t'; }
inline bool v(char c, char delim) { return !(q(c) || d(c, delim) || b(c) || c == '\0' || c == '\r' || c == '\f'); }
inline tokens token(char c, char delim)
{
if (q(c)) return T_q;
else if (d(c, delim)) return T_d;
else if (b(c)) return T_b;
else if (v(c, delim)) return T_v;
else return T_error;
}
extern const char FS;
bool readline(std::string& S, std::istream& is)
{
char c;
states cur = S_s;
char delim = ',';
bool more = is.get(c) != 0;
int could_be_endq = 0;
bool mapped = 0; //debug purposes; now testing
if (more)
{
is.putback(c);
std::vector<char> V; // guaranteed linear-time push_back() [AUS99]
while (is.get(c) && c != '\r' && c != '\n')
{
if (c == 0x1C)
delim = 0x1C;
tokens tok = token(c, delim);
if (q(c))
{
if (!(cur == S_s || cur == S_qf))
c = '\'';
if (cur == S_qf) // remember the last quoted
could_be_endq = V.size();
}
if (cur == S_wait && v(c, delim)) // moving to qfo from wait; map the last seen " to '
V[could_be_endq] = '\'';
cur = (states) trans_table[cur][tok];
V.push_back(c);
}
if (c == '\r' && (c = is.get()) != '\n')
is.putback(c);
S.resize(V.size());
std::copy(V.begin(), V.end(), S.begin());
}
return more;
}
}
}