@@ -25,44 +25,45 @@ fn expand_syntax_ext(&ext_ctxt cx,
25
25
option:: t[ str] body ) -> @ast:: expr {
26
26
27
27
if ( vec:: len[ @ast:: expr] ( args) == 0 u) {
28
- // FIXME: Handle error correctly.
29
- log_err "malformed #fmt call" ;
30
- fail;
28
+ cx. span_err ( sp, "#fmt requires a format string" ) ;
31
29
}
32
30
33
- auto fmt = expr_to_str ( args. ( 0 ) ) ;
31
+ auto fmt = expr_to_str ( cx , args. ( 0 ) ) ;
34
32
35
33
// log "Format string:";
36
34
// log fmt;
37
35
38
36
auto pieces = parse_fmt_string ( fmt) ;
39
37
auto args_len = vec:: len[ @ast:: expr] ( args) ;
40
38
auto fmt_args = vec:: slice[ @ast:: expr] ( args, 1 u, args_len - 1 u) ;
41
- ret pieces_to_expr ( p , pieces, args) ;
39
+ ret pieces_to_expr ( cx , p , sp , pieces, args) ;
42
40
}
43
41
44
- fn expr_to_str ( @ast:: expr expr) -> str {
42
+ fn expr_to_str ( & ext_ctxt cx, @ast:: expr expr) -> str {
43
+ auto err_msg = "first argument to #fmt must be a string literal" ;
45
44
alt ( expr. node ) {
46
45
case ( ast:: expr_lit ( ?l, _) ) {
47
46
alt ( l. node ) {
48
47
case ( ast:: lit_str ( ?s) ) {
49
48
ret s;
50
49
}
51
- case ( _) { /* fallthrough */ }
50
+ case ( _) {
51
+ cx. span_err ( l. span , err_msg) ;
52
+ }
52
53
}
53
54
}
54
- case ( _) { /* fallthrough */ }
55
+ case ( _) {
56
+ cx. span_err ( expr. span , err_msg) ;
57
+ }
55
58
}
56
- log_err "first argument to #fmt must be a string literal" ;
57
- fail;
58
59
}
59
60
60
61
// FIXME: A lot of these functions for producing expressions can probably
61
62
// be factored out in common with other code that builds expressions.
62
63
// FIXME: Probably should be using the parser's span functions
63
64
// FIXME: Cleanup the naming of these functions
64
- fn pieces_to_expr( parser p , vec [ piece ] pieces , vec [ @ast :: expr ] args )
65
- -> @ast:: expr {
65
+ fn pieces_to_expr( & ext_ctxt cx , parser p , common :: span sp ,
66
+ vec [ piece ] pieces , vec [ @ast :: expr ] args ) -> @ast:: expr {
66
67
67
68
fn make_new_lit ( parser p, common:: span sp, ast:: lit_ lit) -> @ast:: expr {
68
69
auto sp_lit = @rec ( node=lit, span=sp) ;
@@ -263,7 +264,8 @@ fn pieces_to_expr(parser p, vec[piece] pieces, vec[@ast::expr] args)
263
264
ret make_call( p, arg. span, path, args) ;
264
265
}
265
266
266
- fn make_new_conv( parser p, conv cnv, @ast:: expr arg) -> @ast:: expr {
267
+ fn make_new_conv( & ext_ctxt cx, parser p, common:: span sp,
268
+ conv cnv, @ast:: expr arg) -> @ast:: expr {
267
269
268
270
// FIXME: Extract all this validation into extfmt::ct
269
271
fn is_signed_type( conv cnv) -> bool {
@@ -301,15 +303,14 @@ fn pieces_to_expr(parser p, vec[piece] pieces, vec[@ast::expr] args)
301
303
}
302
304
case ( flag_sign_always) {
303
305
if ( !is_signed_type( cnv) ) {
304
- log_err "+ flag only valid in signed #fmt conversion" ;
305
- fail ;
306
+ cx . span_err ( sp , "+ flag only valid in "
307
+ + "signed #fmt conversion" ) ;
306
308
}
307
309
}
308
310
case ( flag_space_for_sign) {
309
311
if ( !is_signed_type( cnv) ) {
310
- log_err "space flag only valid in "
311
- + "signed #fmt conversions" ;
312
- fail;
312
+ cx. span_err( sp, "space flag only valid in "
313
+ + "signed #fmt conversions" ) ;
313
314
}
314
315
}
315
316
case ( flag_left_zero_pad) {
@@ -471,40 +472,41 @@ fn pieces_to_expr(parser p, vec[piece] pieces, vec[@ast::expr] args)
471
472
}
472
473
}
473
474
474
- auto sp = args. ( 0 ) . span;
475
+ auto fmt_sp = args. ( 0 ) . span;
475
476
auto n = 0 u;
476
477
auto tmp_expr = make_new_str( p, sp, "" ) ;
477
478
auto nargs = vec:: len[ @ast:: expr] ( args) ;
478
479
479
480
for ( piece pc in pieces) {
480
481
alt ( pc) {
481
482
case ( piece_string( ?s) ) {
482
- auto s_expr = make_new_str( p, sp , s) ;
483
- tmp_expr = make_add_expr( p, sp , tmp_expr, s_expr) ;
483
+ auto s_expr = make_new_str( p, fmt_sp , s) ;
484
+ tmp_expr = make_add_expr( p, fmt_sp , tmp_expr, s_expr) ;
484
485
}
485
486
case ( piece_conv( ?conv) ) {
487
+ n += 1 u;
488
+
486
489
if ( n >= nargs) {
487
- log_err "too many conversions in #fmt string" ;
488
- fail ;
490
+ cx . span_err ( sp , "not enough arguments to #fmt "
491
+ + "for the given format string" ) ;
489
492
}
490
493
491
494
// TODO: Remove debug logging
492
495
//log "Building conversion:";
493
496
//log_conv(conv);
494
497
495
- n += 1 u;
496
498
auto arg_expr = args. ( n) ;
497
- auto c_expr = make_new_conv( p , conv, arg_expr) ;
498
- tmp_expr = make_add_expr( p, sp , tmp_expr, c_expr) ;
499
+ auto c_expr = make_new_conv( cx , p , fmt_sp , conv, arg_expr) ;
500
+ tmp_expr = make_add_expr( p, fmt_sp , tmp_expr, c_expr) ;
499
501
}
500
502
}
501
503
}
502
504
503
505
auto expected_nargs = n + 1 u; // n conversions + the fmt string
504
506
if ( expected_nargs < nargs) {
505
- log_err #fmt ( "too many arguments to #fmt. found %u, expected %u" ,
506
- nargs , expected_nargs ) ;
507
- fail ;
507
+ cx . span_err ( sp ,
508
+ # fmt ( "too many arguments to #fmt. found %u, expected %u" ,
509
+ nargs , expected_nargs ) ) ;
508
510
}
509
511
510
512
// TODO: Remove this debug logging
0 commit comments