1(*---------------------------------------------------------------------------
2     Tools for detecting and eliminating the CR character from files.
3 ---------------------------------------------------------------------------*)
4
5app load ["BinIO", "FileSys", "Int"];
6exception CANT_OPEN;
7
8fun unCRfile file1 file2 = 
9 let open BinIO
10     val (istrm,ostrm) = (openIn file1, openOut file2)
11     fun loop() =
12       case input1 istrm
13        of SOME ch => (if ch = 0wxD then () else output1(ostrm,ch) ; loop())
14         | NONE    => (closeIn istrm; flushOut ostrm; closeOut ostrm)
15  in loop()
16  end;
17
18fun variant str =  (* get an unused file name in the current directory *)
19 if FileSys.access(str,[]) then 
20 let fun vary i = let val s = str^Int.toString i
21      in if FileSys.access(s,[]) then vary (i+1) else s 
22      end
23 in vary 0
24 end
25 else str;
26
27fun unCR file = 
28 let val file' = variant file
29 in unCRfile file file'
30  ; FileSys.remove file
31  ; FileSys.rename{old=file', new=file}
32 end  ;
33
34fun ignoring file =
35 case Path.ext file
36  of SOME "exe" => true
37   | SOME "ui"  => true
38   | SOME "uo"  => true
39   | SOME "so"  => true
40   | other      => false;
41
42fun hasCR file acc = 
43 if ignoring file then (print ("ignoring "^file^"\n"); acc)
44 else
45 let open BinIO
46     val istrm = openIn file handle _ => 
47                 (print ("Unable to open "^file^"\n"); raise CANT_OPEN);
48     fun loop() =
49       case input1 istrm
50        of SOME ch => if ch = 0wxD then (closeIn istrm; file::acc) else loop()
51         | NONE    => (closeIn istrm ; acc)
52  in loop()
53  end
54
55(*---------------------------------------------------------------------------
56     fold a function over the files in a directory 
57 ---------------------------------------------------------------------------*)
58
59fun itDir f dir = 
60  let val dstrm = FileSys.openDir dir
61      fun loop acc =
62        case FileSys.readDir dstrm
63         of NONE => (FileSys.closeDir dstrm; acc)
64          | SOME file => loop (f (dir,file) acc)
65  in loop
66  end
67
68fun checkCR () = 
69  itDir (fn (_,f) => fn l => (hasCR f l handle CANT_OPEN => l))
70        (FileSys.getDir()) [];
71
72
73(*---------------------------------------------------------------------------
74   Typical usage: 
75
76       run checkCR() in a directory, then map unCR over the result.
77 ---------------------------------------------------------------------------*)
78