@@ -35,8 +35,10 @@ use syntax::ptr::P;
3535use graphviz as dot;
3636
3737use std:: borrow:: { Cow , IntoCow } ;
38+ use std:: env;
3839use std:: old_io:: { self , BufReader } ;
3940use std:: option;
41+ use std:: os;
4042use std:: str:: FromStr ;
4143
4244#[ derive( Copy , PartialEq , Debug ) ]
@@ -67,9 +69,8 @@ pub enum PpMode {
6769 PpmFlowGraph ( PpFlowGraphMode ) ,
6870}
6971
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 > {
7374 let mut split = name. splitn ( 1 , '=' ) ;
7475 let first = split. next ( ) . unwrap ( ) ;
7576 let opt_second = split. next ( ) ;
@@ -84,23 +85,23 @@ pub fn parse_pretty(sess: &Session,
8485 ( "identified" , _) => PpmSource ( PpmIdentified ) ,
8586 ( "flowgraph" , true ) => PpmFlowGraph ( PpFlowGraphMode :: Default ) ,
8687 ( "flowgraph,unlabelled" , true ) => PpmFlowGraph ( PpFlowGraphMode :: UnlabelledEdges ) ,
87- _ => {
88+ _ => return Err ( {
8889 if extended {
89- sess . fatal ( & format ! (
90+ format ! (
9091 "argument to `xpretty` must be one of `normal`, \
9192 `expanded`, `flowgraph[,unlabelled]=<nodeid>`, `typed`, \
9293 `typed,unsuffixed_literals`, `identified`, \
93- `expanded,identified`, or `everybody_loops`; got {}", name) ) ;
94+ `expanded,identified`, or `everybody_loops`; got {}", name)
9495 } else {
95- sess . fatal ( & format ! (
96+ format ! (
9697 "argument to `pretty` must be one of `normal`, \
9798 `expanded`, `typed`, `identified`, \
98- or `expanded,identified`; got {}", name) ) ;
99+ or `expanded,identified`; got {}", name)
99100 }
100- }
101+ } )
101102 } ;
102103 let opt_second = opt_second. and_then ( |s| s. parse :: < UserIdentifiedItem > ( ) . ok ( ) ) ;
103- ( first, opt_second)
104+ Ok ( ( first, opt_second) )
104105}
105106
106107struct NoAnn ;
@@ -391,15 +392,46 @@ impl fold::Folder for ReplaceBodyWithLoop {
391392 }
392393}
393394
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+
398430 if ppm == PpmSource ( PpmEveryBodyLoops ) {
399431 control. every_body_loops = true ;
400432 }
401433
402- match ppm {
434+ let phase = match ppm {
403435 PpmSource ( PpmNormal ) |
404436 PpmSource ( PpmEveryBodyLoops ) |
405437 PpmSource ( PpmIdentified ) => {
@@ -421,14 +453,44 @@ pub fn printing_phase<'a, 'b>(control: &'a mut driver::CompileController<'b>,
421453 PpmFlowGraph ( _) => {
422454 & mut control. after_analysis
423455 }
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 ;
424486 }
425487}
426488
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 < ( ) > {
432494 let sess = state. session ;
433495 let krate = state. krate . or ( state. expanded_crate )
434496 . expect ( "--pretty=typed missing crate" ) ;
0 commit comments