Skip to content

Commit 76269be

Browse files
author
Ildus
committed
Support $^ escape sequence for newlines.
1 parent 896f6bf commit 76269be

File tree

4 files changed

+105
-91
lines changed

4 files changed

+105
-91
lines changed

doc/manual.asciidoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,8 @@ paths, where a space would otherwise separate filenames. See below.)
917917
`$:` :: a colon. (This is only necessary in `build` lines, where a colon
918918
would otherwise terminate the list of outputs.)
919919

920+
`$^` :: a newline. Inserts '\n' into the resulting string.
921+
920922
`$$`:: a literal `$`.
921923

922924
A `build` or `default` statement is first parsed as a space-separated

src/depfile_parser.cc

Lines changed: 76 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -105,55 +105,55 @@ bool DepfileParser::Parse(string* content, string* err) {
105105
};
106106
yych = *in;
107107
if (yybm[0+yych] & 128) {
108-
goto yy5;
108+
goto yy9;
109109
}
110110
if (yych <= '\r') {
111111
if (yych <= '\t') {
112-
if (yych >= 0x01) goto yy1;
112+
if (yych >= 0x01) goto yy4;
113113
} else {
114-
if (yych <= '\n') goto yy3;
115-
if (yych <= '\f') goto yy1;
116-
goto yy4;
114+
if (yych <= '\n') goto yy6;
115+
if (yych <= '\f') goto yy4;
116+
goto yy8;
117117
}
118118
} else {
119119
if (yych <= '$') {
120-
if (yych <= '#') goto yy1;
121-
goto yy7;
120+
if (yych <= '#') goto yy4;
121+
goto yy12;
122122
} else {
123-
if (yych <= '>') goto yy1;
124-
if (yych <= '\\') goto yy8;
125-
goto yy1;
123+
if (yych <= '>') goto yy4;
124+
if (yych <= '\\') goto yy13;
125+
goto yy4;
126126
}
127127
}
128128
++in;
129129
{
130130
break;
131131
}
132-
yy1:
132+
yy4:
133133
++in;
134-
yy2:
134+
yy5:
135135
{
136136
// For any other character (e.g. whitespace), swallow it here,
137137
// allowing the outer logic to loop around again.
138138
break;
139139
}
140-
yy3:
140+
yy6:
141141
++in;
142142
{
143143
// A newline ends the current file name and the current rule.
144144
have_newline = true;
145145
break;
146146
}
147-
yy4:
147+
yy8:
148148
yych = *++in;
149-
if (yych == '\n') goto yy3;
150-
goto yy2;
151-
yy5:
149+
if (yych == '\n') goto yy6;
150+
goto yy5;
151+
yy9:
152152
yych = *++in;
153153
if (yybm[0+yych] & 128) {
154-
goto yy5;
154+
goto yy9;
155155
}
156-
yy6:
156+
yy11:
157157
{
158158
// Got a span of plain text.
159159
int len = (int)(in - start);
@@ -163,54 +163,54 @@ bool DepfileParser::Parse(string* content, string* err) {
163163
out += len;
164164
continue;
165165
}
166-
yy7:
166+
yy12:
167167
yych = *++in;
168-
if (yych == '$') goto yy9;
169-
goto yy2;
170-
yy8:
168+
if (yych == '$') goto yy14;
169+
goto yy5;
170+
yy13:
171171
yych = *(yymarker = ++in);
172172
if (yych <= ' ') {
173173
if (yych <= '\n') {
174-
if (yych <= 0x00) goto yy2;
175-
if (yych <= '\t') goto yy10;
176-
goto yy11;
174+
if (yych <= 0x00) goto yy5;
175+
if (yych <= '\t') goto yy16;
176+
goto yy17;
177177
} else {
178-
if (yych == '\r') goto yy12;
179-
if (yych <= 0x1F) goto yy10;
180-
goto yy13;
178+
if (yych == '\r') goto yy19;
179+
if (yych <= 0x1F) goto yy16;
180+
goto yy21;
181181
}
182182
} else {
183183
if (yych <= '9') {
184-
if (yych == '#') goto yy14;
185-
goto yy10;
184+
if (yych == '#') goto yy23;
185+
goto yy16;
186186
} else {
187-
if (yych <= ':') goto yy15;
188-
if (yych == '\\') goto yy17;
189-
goto yy10;
187+
if (yych <= ':') goto yy25;
188+
if (yych == '\\') goto yy27;
189+
goto yy16;
190190
}
191191
}
192-
yy9:
192+
yy14:
193193
++in;
194194
{
195195
// De-escape dollar character.
196196
*out++ = '$';
197197
continue;
198198
}
199-
yy10:
199+
yy16:
200200
++in;
201-
goto yy6;
202-
yy11:
201+
goto yy11;
202+
yy17:
203203
++in;
204204
{
205205
// A line continuation ends the current file name.
206206
break;
207207
}
208-
yy12:
208+
yy19:
209209
yych = *++in;
210-
if (yych == '\n') goto yy11;
210+
if (yych == '\n') goto yy17;
211211
in = yymarker;
212-
goto yy2;
213-
yy13:
212+
goto yy5;
213+
yy21:
214214
++in;
215215
{
216216
// 2N+1 backslashes plus space -> N backslashes plus space.
@@ -222,7 +222,7 @@ bool DepfileParser::Parse(string* content, string* err) {
222222
*out++ = ' ';
223223
continue;
224224
}
225-
yy14:
225+
yy23:
226226
++in;
227227
{
228228
// De-escape hash sign, but preserve other leading backslashes.
@@ -233,17 +233,17 @@ bool DepfileParser::Parse(string* content, string* err) {
233233
*out++ = '#';
234234
continue;
235235
}
236-
yy15:
236+
yy25:
237237
yych = *++in;
238238
if (yych <= '\f') {
239-
if (yych <= 0x00) goto yy18;
240-
if (yych <= 0x08) goto yy16;
241-
if (yych <= '\n') goto yy18;
239+
if (yych <= 0x00) goto yy28;
240+
if (yych <= 0x08) goto yy26;
241+
if (yych <= '\n') goto yy28;
242242
} else {
243-
if (yych <= '\r') goto yy18;
244-
if (yych == ' ') goto yy18;
243+
if (yych <= '\r') goto yy28;
244+
if (yych == ' ') goto yy28;
245245
}
246-
yy16:
246+
yy26:
247247
{
248248
// De-escape colon sign, but preserve other leading backslashes.
249249
// Regular expression uses lookahead to make sure that no whitespace
@@ -255,29 +255,29 @@ bool DepfileParser::Parse(string* content, string* err) {
255255
*out++ = ':';
256256
continue;
257257
}
258-
yy17:
258+
yy27:
259259
yych = *++in;
260260
if (yych <= ' ') {
261261
if (yych <= '\n') {
262-
if (yych <= 0x00) goto yy6;
263-
if (yych <= '\t') goto yy10;
264-
goto yy6;
262+
if (yych <= 0x00) goto yy11;
263+
if (yych <= '\t') goto yy16;
264+
goto yy11;
265265
} else {
266-
if (yych == '\r') goto yy6;
267-
if (yych <= 0x1F) goto yy10;
268-
goto yy19;
266+
if (yych == '\r') goto yy11;
267+
if (yych <= 0x1F) goto yy16;
268+
goto yy30;
269269
}
270270
} else {
271271
if (yych <= '9') {
272-
if (yych == '#') goto yy14;
273-
goto yy10;
272+
if (yych == '#') goto yy23;
273+
goto yy16;
274274
} else {
275-
if (yych <= ':') goto yy15;
276-
if (yych == '\\') goto yy20;
277-
goto yy10;
275+
if (yych <= ':') goto yy25;
276+
if (yych == '\\') goto yy32;
277+
goto yy16;
278278
}
279279
}
280-
yy18:
280+
yy28:
281281
++in;
282282
{
283283
// Backslash followed by : and whitespace.
@@ -291,7 +291,7 @@ bool DepfileParser::Parse(string* content, string* err) {
291291
have_newline = true;
292292
break;
293293
}
294-
yy19:
294+
yy30:
295295
++in;
296296
{
297297
// 2N backslashes plus space -> 2N backslashes, end of filename.
@@ -301,26 +301,26 @@ bool DepfileParser::Parse(string* content, string* err) {
301301
out += len - 1;
302302
break;
303303
}
304-
yy20:
304+
yy32:
305305
yych = *++in;
306306
if (yych <= ' ') {
307307
if (yych <= '\n') {
308-
if (yych <= 0x00) goto yy6;
309-
if (yych <= '\t') goto yy10;
310-
goto yy6;
308+
if (yych <= 0x00) goto yy11;
309+
if (yych <= '\t') goto yy16;
310+
goto yy11;
311311
} else {
312-
if (yych == '\r') goto yy6;
313-
if (yych <= 0x1F) goto yy10;
314-
goto yy13;
312+
if (yych == '\r') goto yy11;
313+
if (yych <= 0x1F) goto yy16;
314+
goto yy21;
315315
}
316316
} else {
317317
if (yych <= '9') {
318-
if (yych == '#') goto yy14;
319-
goto yy10;
318+
if (yych == '#') goto yy23;
319+
goto yy16;
320320
} else {
321-
if (yych <= ':') goto yy15;
322-
if (yych == '\\') goto yy17;
323-
goto yy10;
321+
if (yych <= ':') goto yy25;
322+
if (yych == '\\') goto yy27;
323+
goto yy16;
324324
}
325325
}
326326
}

src/lexer.cc

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -716,23 +716,25 @@ bool Lexer::ReadEvalString(EvalString* eval, bool path, string* err) {
716716
if (yybm[0+yych] & 64) {
717717
goto yy122;
718718
}
719-
if (yych <= ' ') {
719+
if (yych <= '#') {
720720
if (yych <= '\f') {
721721
if (yych == '\n') goto yy114;
722722
goto yy112;
723723
} else {
724724
if (yych <= '\r') goto yy117;
725-
if (yych <= 0x1F) goto yy112;
726-
goto yy118;
725+
if (yych == ' ') goto yy118;
726+
goto yy112;
727727
}
728728
} else {
729-
if (yych <= '/') {
730-
if (yych == '$') goto yy120;
729+
if (yych <= ']') {
730+
if (yych <= '$') goto yy120;
731+
if (yych <= '/') goto yy112;
732+
if (yych <= ':') goto yy125;
731733
goto yy112;
732734
} else {
733-
if (yych <= ':') goto yy125;
735+
if (yych <= '^') goto yy127;
734736
if (yych <= '`') goto yy112;
735-
if (yych <= '{') goto yy127;
737+
if (yych <= '{') goto yy129;
736738
goto yy112;
737739
}
738740
}
@@ -760,7 +762,7 @@ bool Lexer::ReadEvalString(EvalString* eval, bool path, string* err) {
760762
}
761763
yy117:
762764
yych = *++p;
763-
if (yych == '\n') goto yy128;
765+
if (yych == '\n') goto yy130;
764766
goto yy113;
765767
yy118:
766768
++p;
@@ -790,26 +792,32 @@ bool Lexer::ReadEvalString(EvalString* eval, bool path, string* err) {
790792
continue;
791793
}
792794
yy127:
795+
++p;
796+
{
797+
eval->AddText(StringPiece("\n", 1));
798+
continue;
799+
}
800+
yy129:
793801
yych = *(q = ++p);
794802
if (yybm[0+yych] & 128) {
795-
goto yy131;
803+
goto yy133;
796804
}
797805
goto yy113;
798-
yy128:
806+
yy130:
799807
yych = *++p;
800-
if (yych == ' ') goto yy128;
808+
if (yych == ' ') goto yy130;
801809
{
802810
continue;
803811
}
804-
yy131:
812+
yy133:
805813
yych = *++p;
806814
if (yybm[0+yych] & 128) {
807-
goto yy131;
815+
goto yy133;
808816
}
809-
if (yych == '}') goto yy134;
817+
if (yych == '}') goto yy136;
810818
p = q;
811819
goto yy113;
812-
yy134:
820+
yy136:
813821
++p;
814822
{
815823
eval->AddSpecial(StringPiece(start + 2, p - start - 3));

src/lexer.in.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,10 @@ bool Lexer::ReadEvalString(EvalString* eval, bool path, string* err) {
259259
eval->AddText(StringPiece(":", 1));
260260
continue;
261261
}
262+
"$^" {
263+
eval->AddText(StringPiece("\n", 1));
264+
continue;
265+
}
262266
"$". {
263267
last_token_ = start;
264268
return Error("bad $-escape (literal $ must be written as $$)", err);

0 commit comments

Comments
 (0)