@@ -7,8 +7,70 @@ static const std::vector<Value> EMPTY_VECTOR;
7
7
static const std::map<std::string, Value> EMPTY_MAP;
8
8
9
9
static std::string escape (const std::string &str) {
10
- // TODO: escape
11
- return " " ;
10
+ std::string result = " '" ;
11
+
12
+ if (!str.empty ()) {
13
+ result.reserve (2 + str.length ());
14
+
15
+ size_t pos = 0 ;
16
+ size_t nextUnprocessed = 0 ;
17
+
18
+ while (true ) {
19
+ pos = str.find_first_of (" \"\'\b\f\n\r\t\\ " , pos);
20
+ if (pos == std::string::npos) {
21
+ break ;
22
+ }
23
+
24
+ if (pos != nextUnprocessed) {
25
+ result += str.substr (nextUnprocessed, pos - nextUnprocessed);
26
+ }
27
+
28
+ switch (str[pos]) {
29
+ case ' "' : {
30
+ result += " \\\" " ;
31
+ break ;
32
+ }
33
+ case ' \' ' : {
34
+ result += " \\ '" ;
35
+ break ;
36
+ }
37
+ case ' \b ' : {
38
+ result += " \\ b" ;
39
+ break ;
40
+ }
41
+ case ' \f ' : {
42
+ result += " \\ f" ;
43
+ break ;
44
+ }
45
+ case ' \n ' : {
46
+ result += " \\ n" ;
47
+ break ;
48
+ }
49
+ case ' \r ' : {
50
+ result += " \\ r" ;
51
+ break ;
52
+ }
53
+ case ' \t ' : {
54
+ result += " \\ t" ;
55
+ break ;
56
+ }
57
+ case ' \\ ' : {
58
+ result += " \\\\ " ;
59
+ break ;
60
+ }
61
+ }
62
+
63
+ ++pos;
64
+ nextUnprocessed = pos;
65
+ }
66
+
67
+ if (nextUnprocessed != str.length ()) {
68
+ result += str.substr (nextUnprocessed);
69
+ }
70
+ }
71
+
72
+ result += " '" ;
73
+ return result;
12
74
}
13
75
14
76
static std::string escapeKey (const std::string &str) {
@@ -767,6 +829,7 @@ class Parser {
767
829
auto isMultiline = false ;
768
830
long lastCodeUnit = -1 ;
769
831
auto lastCodeUnitLocation = Location::unknown ();
832
+ auto newLine = false ;
770
833
771
834
auto c = lookaheadChar ();
772
835
if (c == startChar) {
@@ -834,6 +897,14 @@ class Parser {
834
897
text += ' \' ' ;
835
898
break ;
836
899
}
900
+ case ' b' : {
901
+ text += ' \b ' ;
902
+ break ;
903
+ }
904
+ case ' f' : {
905
+ text += ' \f ' ;
906
+ break ;
907
+ }
837
908
case ' n' : {
838
909
text += ' \n ' ;
839
910
break ;
@@ -908,11 +979,14 @@ class Parser {
908
979
Location (escapeLine, escapeColumn));
909
980
}
910
981
}
911
- } else {
982
+ } else if (! isspace (c) || !newLine) {
912
983
text += c;
913
984
}
985
+
986
+ newLine = (newLine && (c == ' ' || c == ' \t ' )) || c == ' \n ' ;
914
987
}
915
988
989
+ text.shrink_to_fit ();
916
990
return Token (TokenKind::String, combine (startLocation, endLine, endColumn),
917
991
text);
918
992
}
@@ -929,6 +1003,7 @@ class Parser {
929
1003
Location location (startLocation.getStartLine (),
930
1004
startLocation.getStartColumn (), endLine, endColumn);
931
1005
1006
+ text.shrink_to_fit ();
932
1007
if (text == " true" ) {
933
1008
return Token (TokenKind::True, location);
934
1009
} else if (text == " false" ) {
@@ -1111,7 +1186,7 @@ class Parser {
1111
1186
if (path != " ." ) {
1112
1187
itemPath += " ." ;
1113
1188
}
1114
- itemPath += itemKey;
1189
+ itemPath += escapeKey ( itemKey) ;
1115
1190
1116
1191
expect (TokenKind::Colon);
1117
1192
0 commit comments