@@ -35,8 +35,10 @@ use syntax::ptr::P;
35
35
use graphviz as dot;
36
36
37
37
use std:: borrow:: { Cow , IntoCow } ;
38
+ use std:: env;
38
39
use std:: old_io:: { self , BufReader } ;
39
40
use std:: option;
41
+ use std:: os;
40
42
use std:: str:: FromStr ;
41
43
42
44
#[ derive( Copy , PartialEq , Debug ) ]
@@ -67,9 +69,8 @@ pub enum PpMode {
67
69
PpmFlowGraph ( PpFlowGraphMode ) ,
68
70
}
69
71
70
- pub fn parse_pretty ( sess : & Session ,
71
- name : & str ,
72
- extended : bool ) -> ( PpMode , Option < UserIdentifiedItem > ) {
72
+ pub fn parse_pretty ( name : & str , extended : bool )
73
+ -> Result < ( PpMode , Option < UserIdentifiedItem > ) , String > {
73
74
let mut split = name. splitn ( 1 , '=' ) ;
74
75
let first = split. next ( ) . unwrap ( ) ;
75
76
let opt_second = split. next ( ) ;
@@ -84,23 +85,23 @@ pub fn parse_pretty(sess: &Session,
84
85
( "identified" , _) => PpmSource ( PpmIdentified ) ,
85
86
( "flowgraph" , true ) => PpmFlowGraph ( PpFlowGraphMode :: Default ) ,
86
87
( "flowgraph,unlabelled" , true ) => PpmFlowGraph ( PpFlowGraphMode :: UnlabelledEdges ) ,
87
- _ => {
88
+ _ => return Err ( {
88
89
if extended {
89
- sess . fatal ( & format ! (
90
+ format ! (
90
91
"argument to `xpretty` must be one of `normal`, \
91
92
`expanded`, `flowgraph[,unlabelled]=<nodeid>`, `typed`, \
92
93
`typed,unsuffixed_literals`, `identified`, \
93
- `expanded,identified`, or `everybody_loops`; got {}", name) ) ;
94
+ `expanded,identified`, or `everybody_loops`; got {}", name)
94
95
} else {
95
- sess . fatal ( & format ! (
96
+ format ! (
96
97
"argument to `pretty` must be one of `normal`, \
97
98
`expanded`, `typed`, `identified`, \
98
- or `expanded,identified`; got {}", name) ) ;
99
+ or `expanded,identified`; got {}", name)
99
100
}
100
- }
101
+ } )
101
102
} ;
102
103
let opt_second = opt_second. and_then ( |s| s. parse :: < UserIdentifiedItem > ( ) . ok ( ) ) ;
103
- ( first, opt_second)
104
+ Ok ( ( first, opt_second) )
104
105
}
105
106
106
107
struct NoAnn ;
@@ -391,15 +392,46 @@ impl fold::Folder for ReplaceBodyWithLoop {
391
392
}
392
393
}
393
394
394
- pub fn printing_phase < ' a , ' b > ( control : & ' a mut driver:: CompileController < ' b > ,
395
- ppm : PpMode ,
396
- opt_uii : Option < & UserIdentifiedItem > )
397
- -> & ' a mut driver:: PhaseController < ' b > {
395
+ pub fn setup_controller ( control : & mut driver:: CompileController ,
396
+ ppm_and_uui : Option < ( PpMode , Option < UserIdentifiedItem > ) > ,
397
+ dump_dir : Option < & str > ,
398
+ keep_going : bool ) {
399
+
400
+ fn mk_absolute ( path : & str ) -> Path {
401
+ let path = os:: getcwd ( ) . unwrap ( ) . join ( path) ;
402
+ assert ! ( path. is_absolute( ) ) ;
403
+ path
404
+ }
405
+
406
+ let ( ppm, opt_uii, dump_dir, keep_going) = match ppm_and_uui {
407
+ Some ( ( ppm, opt_uii) ) => {
408
+ ( ppm, opt_uii, dump_dir. map ( mk_absolute) , keep_going)
409
+ }
410
+ None => {
411
+ let decoded = env:: var ( "RUSTC_PRETTY_DUMP" ) . ok ( ) . and_then ( |s| {
412
+ let mut s = s. split ( ":" ) ;
413
+
414
+ s. next ( ) . and_then ( |mode| {
415
+ parse_pretty ( mode, true ) . ok ( )
416
+ } ) . and_then ( |( ppm, opt_uii) | {
417
+ s. next ( ) . map ( |dump_dir| {
418
+ ( ppm, opt_uii, Some ( mk_absolute ( dump_dir) ) , true )
419
+ } )
420
+ } )
421
+ } ) ;
422
+ if let Some ( parts) = decoded {
423
+ parts
424
+ } else {
425
+ return ;
426
+ }
427
+ }
428
+ } ;
429
+
398
430
if ppm == PpmSource ( PpmEveryBodyLoops ) {
399
431
control. every_body_loops = true ;
400
432
}
401
433
402
- match ppm {
434
+ let phase = match ppm {
403
435
PpmSource ( PpmNormal ) |
404
436
PpmSource ( PpmEveryBodyLoops ) |
405
437
PpmSource ( PpmIdentified ) => {
@@ -421,14 +453,44 @@ pub fn printing_phase<'a, 'b>(control: &'a mut driver::CompileController<'b>,
421
453
PpmFlowGraph ( _) => {
422
454
& mut control. after_analysis
423
455
}
456
+ } ;
457
+
458
+ phase. callback = box move |state| {
459
+ let pretty_output_path;
460
+ let output = if let Some ( ref dir) = dump_dir {
461
+ let file_path = if let Some ( outputs) = state. output_filenames {
462
+ outputs. with_extension ( "rs" )
463
+ } else {
464
+ state. session . fatal (
465
+ "-Z pretty-dump-dir cannot be used with --pretty \
466
+ options that print before expansion") ;
467
+ } ;
468
+ let file_path = os:: getcwd ( ) . unwrap ( ) . join ( & file_path) ;
469
+ assert ! ( file_path. is_absolute( ) ) ;
470
+
471
+ // Cheap isomorphism: /foo/bar--bar/baz <-> foo--bar----bar--baz.
472
+ let components: Vec < _ > = file_path. components ( ) . map ( |bytes| {
473
+ String :: from_utf8_lossy ( bytes) . replace ( "--" , "----" )
474
+ } ) . collect ( ) ;
475
+
476
+ pretty_output_path = dir. join ( components. connect ( "--" ) ) ;
477
+ Some ( & pretty_output_path)
478
+ } else {
479
+ state. output
480
+ } ;
481
+ print_from_phase ( state, ppm, opt_uii. as_ref ( ) , output) . unwrap ( ) ;
482
+ } ;
483
+
484
+ if !keep_going {
485
+ phase. stop = :: Compilation :: Stop ;
424
486
}
425
487
}
426
488
427
- pub fn print_from_phase ( state : driver:: CompileState ,
428
- ppm : PpMode ,
429
- opt_uii : Option < & UserIdentifiedItem > ,
430
- output : Option < & Path > )
431
- -> old_io:: IoResult < ( ) > {
489
+ fn print_from_phase ( state : driver:: CompileState ,
490
+ ppm : PpMode ,
491
+ opt_uii : Option < & UserIdentifiedItem > ,
492
+ output : Option < & Path > )
493
+ -> old_io:: IoResult < ( ) > {
432
494
let sess = state. session ;
433
495
let krate = state. krate . or ( state. expanded_crate )
434
496
. expect ( "--pretty=typed missing crate" ) ;
0 commit comments