@@ -131,7 +131,10 @@ impl<'text> Parser<'text> {
131
131
self . skip_spaces ( ) ;
132
132
self . scanner . expect ( '=' ) ?;
133
133
self . skip_spaces ( ) ;
134
- self . read_eval ( )
134
+ let result = self . read_eval ( & [ ] ) ;
135
+ self . scanner . skip ( '\r' ) ;
136
+ self . scanner . expect ( '\n' ) ?;
137
+ result
135
138
}
136
139
137
140
/// Read a collection of ` foo = bar` variables, with leading indent.
@@ -195,57 +198,85 @@ impl<'text> Parser<'text> {
195
198
Ok ( ( ) )
196
199
}
197
200
201
+ fn read_unevaluated_paths_to (
202
+ & mut self ,
203
+ v : & mut Vec < EvalString < & ' text str > > ,
204
+ ) -> ParseResult < ( ) > {
205
+ self . skip_spaces ( ) ;
206
+ while self . scanner . peek ( ) != ':'
207
+ && self . scanner . peek ( ) != '|'
208
+ && !self . scanner . peek_newline ( )
209
+ {
210
+ v. push ( self . read_eval ( & [ ':' , '|' , ' ' ] ) ?) ;
211
+ self . skip_spaces ( ) ;
212
+ }
213
+ Ok ( ( ) )
214
+ }
215
+
198
216
fn read_build < L : Loader > ( & mut self , loader : & mut L ) -> ParseResult < Build < ' text , L :: Path > > {
199
217
let line = self . scanner . line ;
200
- let mut outs = Vec :: new ( ) ;
201
- self . read_paths_to ( loader , & mut outs ) ?;
202
- let explicit_outs = outs . len ( ) ;
218
+ let mut unevaluated_outs = Vec :: new ( ) ;
219
+ self . read_unevaluated_paths_to ( & mut unevaluated_outs ) ?;
220
+ let explicit_outs = unevaluated_outs . len ( ) ;
203
221
204
222
if self . scanner . peek ( ) == '|' {
205
223
self . scanner . next ( ) ;
206
- self . read_paths_to ( loader , & mut outs ) ?;
224
+ self . read_unevaluated_paths_to ( & mut unevaluated_outs ) ?;
207
225
}
208
226
209
227
self . scanner . expect ( ':' ) ?;
210
228
self . skip_spaces ( ) ;
211
229
let rule = self . read_ident ( ) ?;
212
230
213
- let mut ins = Vec :: new ( ) ;
214
- self . read_paths_to ( loader , & mut ins ) ?;
215
- let explicit_ins = ins . len ( ) ;
231
+ let mut unevaluated_ins = Vec :: new ( ) ;
232
+ self . read_unevaluated_paths_to ( & mut unevaluated_ins ) ?;
233
+ let explicit_ins = unevaluated_ins . len ( ) ;
216
234
217
235
if self . scanner . peek ( ) == '|' {
218
236
self . scanner . next ( ) ;
219
237
let peek = self . scanner . peek ( ) ;
220
238
if peek == '|' || peek == '@' {
221
239
self . scanner . back ( ) ;
222
240
} else {
223
- self . read_paths_to ( loader , & mut ins ) ?;
241
+ self . read_unevaluated_paths_to ( & mut unevaluated_ins ) ?;
224
242
}
225
243
}
226
- let implicit_ins = ins . len ( ) - explicit_ins;
244
+ let implicit_ins = unevaluated_ins . len ( ) - explicit_ins;
227
245
228
246
if self . scanner . peek ( ) == '|' {
229
247
self . scanner . next ( ) ;
230
248
if self . scanner . peek ( ) == '@' {
231
249
self . scanner . back ( ) ;
232
250
} else {
233
251
self . scanner . expect ( '|' ) ?;
234
- self . read_paths_to ( loader , & mut ins ) ?;
252
+ self . read_unevaluated_paths_to ( & mut unevaluated_ins ) ?;
235
253
}
236
254
}
237
- let order_only_ins = ins . len ( ) - implicit_ins - explicit_ins;
255
+ let order_only_ins = unevaluated_ins . len ( ) - implicit_ins - explicit_ins;
238
256
239
257
if self . scanner . peek ( ) == '|' {
240
258
self . scanner . next ( ) ;
241
259
self . scanner . expect ( '@' ) ?;
242
- self . read_paths_to ( loader , & mut ins ) ?;
260
+ self . read_unevaluated_paths_to ( & mut unevaluated_ins ) ?;
243
261
}
244
- let validation_ins = ins . len ( ) - order_only_ins - implicit_ins - explicit_ins;
262
+ let validation_ins = unevaluated_ins . len ( ) - order_only_ins - implicit_ins - explicit_ins;
245
263
246
264
self . scanner . skip ( '\r' ) ;
247
265
self . scanner . expect ( '\n' ) ?;
248
266
let vars = self . read_scoped_vars ( ) ?;
267
+
268
+ let env: & [ & dyn crate :: eval:: Env ] = & [ & vars, & self . vars ] ;
269
+
270
+ let mut outs = Vec :: new ( ) ;
271
+ for unevaluated_out in unevaluated_outs {
272
+ outs. push ( loader. path ( & mut unevaluated_out. evaluate ( env) ) ) ;
273
+ }
274
+
275
+ let mut ins = Vec :: new ( ) ;
276
+ for unevaluated_in in unevaluated_ins {
277
+ ins. push ( loader. path ( & mut unevaluated_in. evaluate ( env) ) ) ;
278
+ }
279
+
249
280
Ok ( Build {
250
281
rule,
251
282
line,
@@ -299,17 +330,26 @@ impl<'text> Parser<'text> {
299
330
Ok ( self . scanner . slice ( start, end) )
300
331
}
301
332
302
- fn read_eval ( & mut self ) -> ParseResult < EvalString < & ' text str > > {
333
+ /// Reads an EvalString. Stops at either a newline, or any of the characters
334
+ /// in stop_at, without consuming the character that caused it to stop.
335
+ fn read_eval ( & mut self , stop_at : & [ char ] ) -> ParseResult < EvalString < & ' text str > > {
303
336
// Guaranteed at least one part.
304
337
let mut parts = Vec :: with_capacity ( 1 ) ;
305
338
let mut ofs = self . scanner . ofs ;
306
339
let end = loop {
307
340
match self . scanner . read ( ) {
308
341
'\0' => return self . scanner . parse_error ( "unexpected EOF" ) ,
309
- '\n' => break self . scanner . ofs - 1 ,
342
+ x if stop_at. contains ( & x) => {
343
+ self . scanner . back ( ) ;
344
+ break self . scanner . ofs ;
345
+ }
346
+ '\n' => {
347
+ self . scanner . back ( ) ;
348
+ break self . scanner . ofs ;
349
+ }
310
350
'\r' if self . scanner . peek ( ) == '\n' => {
311
- self . scanner . next ( ) ;
312
- break self . scanner . ofs - 2 ;
351
+ self . scanner . back ( ) ;
352
+ break self . scanner . ofs ;
313
353
}
314
354
'$' => {
315
355
let end = self . scanner . ofs - 1 ;
0 commit comments