@@ -562,74 +562,72 @@ let emitDoc
562562 loopCont 0 d (fun x -> () )
563563
564564
565- (* Print a document on a channel *)
566- let fprint (chn : out_channel ) ~(width : int ) doc =
567- let doc = if ! flattenBeforePrint then flatten Nil doc else doc in
565+ let print_with_state ~width f =
568566 (* Save some parameters, to allow for nested calls of these routines. *)
569567 let old_maxCol = ! maxCol in
570568 maxCol := width;
571569 let old_breaks = ! breaks in
572570 breaks := [] ;
573- let old_alignDepth = ! alignDepth in
574- alignDepth := 0 ;
575571 let old_activeMarkups = ! activeMarkups in
576572 activeMarkups := [] ;
573+ let old_alignDepth = ! alignDepth in
574+ alignDepth := 0 ;
577575 let old_aligns = ! aligns in
578576 aligns := [{ gainBreak = 0 ; isTaken = ref false ; deltaFromPrev = ref 0 ; deltaToNext = ref 0 ; }];
579577 let old_topAlignAbsCol = ! topAlignAbsCol in
580578 topAlignAbsCol := 0 ;
581579 let old_breakAllMode = ! breakAllMode in
582580 breakAllMode := false ;
583- ignore (scan 0 doc);
584- breaks := List. rev ! breaks;
585- ignore (emitDoc
586- (fun s nrcopies ->
587- for _ = 1 to nrcopies do
588- output_string chn s
589- done ) doc);
590- breakAllMode := old_breakAllMode;
591- topAlignAbsCol := old_topAlignAbsCol;
592- aligns := old_aligns;
593- activeMarkups := old_activeMarkups;
594- alignDepth := old_alignDepth;
595- breaks := old_breaks; (* We must do this especially if we don't do emit
596- (which consumes breaks) because otherwise we waste
597- memory *)
598- maxCol := old_maxCol
581+
582+ let finally () =
583+ maxCol := old_maxCol;
584+ (* We must do this especially if we don't do emit
585+ (which consumes breaks) because otherwise we waste
586+ memory *)
587+ breaks := old_breaks;
588+ activeMarkups := old_activeMarkups;
589+ alignDepth := old_alignDepth;
590+ aligns := old_aligns;
591+ topAlignAbsCol := old_topAlignAbsCol;
592+ breakAllMode := old_breakAllMode
593+ in
594+
595+ match f () with
596+ | r ->
597+ finally () ;
598+ r
599+ | exception e ->
600+ let bt = Printexc. get_raw_backtrace () in
601+ finally () ;
602+ Printexc. raise_with_backtrace e bt
603+
604+ (* Print a document on a channel *)
605+ let fprint (chn : out_channel ) ~(width : int ) doc =
606+ let doc = if ! flattenBeforePrint then flatten Nil doc else doc in
607+ print_with_state ~width (fun () ->
608+ ignore (scan 0 doc);
609+ breaks := List. rev ! breaks;
610+ emitDoc (fun s nrcopies ->
611+ for _ = 1 to nrcopies do
612+ output_string chn s
613+ done
614+ ) doc
615+ )
599616
600617(* Print the document to a string *)
601618let sprint ~(width : int ) doc : string =
602619 let doc = if ! flattenBeforePrint then flatten Nil doc else doc in
603- let old_maxCol = ! maxCol in
604- maxCol := width;
605- let old_breaks = ! breaks in
606- breaks := [] ;
607- let old_activeMarkups = ! activeMarkups in
608- activeMarkups := [] ;
609- let old_alignDepth = ! alignDepth in
610- alignDepth := 0 ;
611- let old_aligns = ! aligns in
612- aligns := [{ gainBreak = 0 ; isTaken = ref false ; deltaFromPrev = ref 0 ; deltaToNext = ref 0 ; }];
613- let old_topAlignAbsCol = ! topAlignAbsCol in
614- topAlignAbsCol := 0 ;
615- let old_breakAllMode = ! breakAllMode in
616- breakAllMode := false ;
617- ignore (scan 0 doc);
618- breaks := List. rev ! breaks;
619- let buf = Buffer. create 1024 in
620- let rec add_n_strings str num =
621- if num < = 0 then ()
622- else begin Buffer. add_string buf str; add_n_strings str (num - 1 ) end
623- in
624- emitDoc add_n_strings doc;
625- breakAllMode := old_breakAllMode;
626- topAlignAbsCol := old_topAlignAbsCol;
627- aligns := old_aligns;
628- breaks := old_breaks;
629- activeMarkups := old_activeMarkups;
630- alignDepth := old_alignDepth;
631- maxCol := old_maxCol;
632- Buffer. contents buf
620+ print_with_state ~width (fun () ->
621+ ignore (scan 0 doc);
622+ breaks := List. rev ! breaks;
623+ let buf = Buffer. create 1024 in
624+ let rec add_n_strings str num =
625+ if num < = 0 then ()
626+ else begin Buffer. add_string buf str; add_n_strings str (num - 1 ) end
627+ in
628+ emitDoc add_n_strings doc;
629+ Buffer. contents buf
630+ )
633631
634632
635633 (* The rest is based on printf.ml *)
0 commit comments