home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Moscow ML 1.42 / e_SML / copyrelease.sml < prev    next >
Encoding:
Text File  |  1996-07-23  |  7.4 KB  |  267 lines  |  [TEXT/Moml]

  1. (* copyrelease.sml *)
  2. (* 23Jul96 ----- e *)
  3.  
  4. load "Nonstdio"; load "FileSys"; load "Path"; load "Binaryset";
  5.  
  6. open FileSys;
  7.  
  8. exception Diff of string;
  9.  
  10. val buf_limit = 32768;
  11.  
  12. local
  13.   prim_eqtype buffer_
  14.   prim_val buffer_    : int -> buffer_ = 1 "create_string";
  15.   prim_val magic      : 'a -> 'b = 1 "identity";
  16.   prim_val fromCA     : CharArray.array -> buffer_ ref = 1 "identity";
  17.   prim_val sub_       : buffer_ -> int -> char         = 2 "get_nth_char";
  18.  
  19.   fun make_buffer__ len = ref (buffer_ len)
  20. in
  21.  
  22. val make_buffer : int -> CharArray.array =  magic make_buffer__
  23.  
  24. (* compare files *)
  25.  
  26. fun compare_file_guts s1 s2 =
  27.    let val z1 = Nonstdio.in_stream_length s1
  28.        val z2 = Nonstdio.in_stream_length s2
  29.    in if z1 <> z2 then raise Diff "size" else
  30.      let
  31.        val b1 = make_buffer (if z1 > buf_limit then buf_limit else z1)
  32.        val b2 = make_buffer (if z2 > buf_limit then buf_limit else z2)
  33.        val ref b1' = fromCA b1
  34.        val ref b2' = fromCA b2
  35.        fun comp_bufs n =
  36.          if n < 0 then ()
  37.          else if (sub_ b1' n) = (sub_ b2' n)
  38.               then comp_bufs (n-1)
  39.               else raise Diff "diff"
  40.        fun comp_chunk x =
  41.          let val nxx = x + buf_limit
  42.              val nxc = if nxx > z1 then z1 else nxx
  43.              val csz = nxc - x
  44.          in if csz <= 0 then ()
  45.             else ( Nonstdio.buff_input s1 b1 0 csz;
  46.                    Nonstdio.buff_input s2 b2 0 csz;
  47.                    comp_bufs (csz-1);
  48.                    comp_chunk nxc )
  49.          end
  50.      in comp_chunk 0
  51.      end
  52.    end
  53.  
  54. end
  55. ;
  56.  
  57. fun compare_files src tgt =
  58.    let val is = BasicIO.open_in_bin src
  59.    in let val os = BasicIO.open_in_bin tgt
  60.       in
  61.          (if modTime src <> modTime tgt 
  62.           then raise Diff "time"
  63.           else ();
  64.           compare_file_guts is os;
  65.           BasicIO.close_in is;
  66.           BasicIO.close_in os)
  67.          handle x => (BasicIO.close_in os; raise x)
  68.       end
  69.       handle x => (BasicIO.close_in is; raise x)
  70.    end
  71. ;
  72.  
  73. (* copy files *)
  74.  
  75. fun copy_file_guts is os =
  76.    let val sz = Nonstdio.in_stream_length is
  77.        val bf = make_buffer (if sz > buf_limit then buf_limit else sz)
  78.        fun copy_chunk x =
  79.          let val nxx = x + buf_limit
  80.              val nxc = if nxx > sz then sz else nxx
  81.              val csz = nxc - x
  82.          in if csz <= 0 then ()
  83.             else ( Nonstdio.buff_input  is bf 0 csz;
  84.                    Nonstdio.buff_output os bf 0 csz;
  85.                    copy_chunk nxc )
  86.          end
  87.    in copy_chunk 0
  88.    end
  89. ;
  90.  
  91. fun copy_bin_file src tgt =
  92.    let val is = BasicIO.open_in_bin src
  93.    in let val os = BasicIO.open_out_bin tgt
  94.       in
  95.          (copy_file_guts is os;
  96.           BasicIO.close_in is;
  97.           BasicIO.close_out os;
  98.           setTime (tgt, SOME (modTime src)))
  99.          handle x => (BasicIO.close_out os; remove tgt; raise x)
  100.       end
  101.       handle x => (BasicIO.close_in is; raise x)
  102.    end
  103. ;
  104.  
  105. fun copy_txt_file src tgt =
  106.    let val is = BasicIO.open_in src
  107.    in let val os = BasicIO.open_out tgt
  108.       in
  109.          (copy_file_guts is os;
  110.           BasicIO.close_in is;
  111.           BasicIO.close_out os;
  112.           setTime (tgt, SOME (modTime src)))
  113.          handle x => (BasicIO.close_out os; remove tgt; raise x)
  114.       end
  115.       handle x => (BasicIO.close_in is; raise x)
  116.    end
  117. ;
  118.  
  119. local
  120. fun option_compare (NONE  ,  NONE)  = EQUAL
  121.   | option_compare (NONE  ,     _)  = LESS
  122.   | option_compare (     _,  NONE)  = GREATER
  123.   | option_compare (SOME a,SOME b)  = String.compare (a,b)
  124. in
  125. val bins = Binaryset.addList
  126.            ((Binaryset.empty option_compare),
  127.            [      SOME "ui", SOME "uo" ])
  128. val objs = Binaryset.addList
  129.            ((Binaryset.empty option_compare),
  130.            [NONE, SOME "ui", SOME "uo", SOME "sig"])
  131. val txts = Binaryset.addList
  132.            ((Binaryset.empty option_compare),
  133.            [SOME "sml", SOME "sig", SOME "mlp", SOME "fke",
  134.             SOME "grm", SOME "lex", SOME "txt"])
  135. end;
  136.  
  137. fun copy_file_for_ext ext =
  138.    if Binaryset.member (txts,ext)
  139.    then copy_txt_file
  140.    else copy_bin_file
  141. ;
  142.  
  143. fun ensure_dir tgt =
  144.   if access (tgt,[])
  145.   then raise Fail ("Target directory: '" ^ tgt ^ "' already exists!")
  146.   else mkDir tgt
  147. ;
  148.  
  149. fun copy_dir_filtered ffun src tgt =
  150.   let val _ = ensure_dir tgt
  151.       val dir = openDir src
  152.       val _   =   chDir src
  153.       fun copy_file fname =
  154.         let val {base, ext} = Path.splitBaseExt fname
  155.             val tname = Path.joinDirFile {dir = tgt, file = fname }
  156.         in if isDir fname
  157.            then () (* do nested dirs? *)
  158.            else if ffun base ext
  159.            then copy_file_for_ext ext fname tname
  160.            else ()
  161.         end
  162.       fun copy "" = ()
  163.         | copy f  = ( copy_file f ; copy (readDir dir) )
  164.   in
  165.      let val _ = copy (readDir dir)
  166.      in closeDir dir
  167.      end
  168.      handle exn as OS.SysErr (msg, _) => (closeDir dir; raise exn)
  169.   end
  170. ;
  171.  
  172. fun compare_dirs_filtered ffun src tgt =
  173.   let val dir = openDir src
  174.       val _   =   chDir src
  175.       val result = ref true
  176.       fun comp_file fname =
  177.         let val {base, ext} = Path.splitBaseExt fname
  178.             val tname = Path.joinDirFile {dir = tgt, file = fname }
  179.         in if isDir fname
  180.            then () (* do nested dirs? *)
  181.            else if ffun base ext
  182.            then compare_files fname tname
  183.            else ()
  184.         end
  185.         handle e as Diff s =>
  186.           ( if !moolevel > 1
  187.             then (print s; print " "; print fname; print "\n")
  188.             else ();
  189.             result := false )
  190.       fun comp "" = ()
  191.         | comp f  = ( comp_file f ; comp (readDir dir) )
  192.   in
  193.      let val _ = comp (readDir dir)
  194.      in closeDir dir; !result
  195.      end
  196.      handle exn as OS.SysErr (msg, _) => (closeDir dir; raise exn)
  197.   end
  198. ;
  199.  
  200. (* deleting a file in the current dir screws readDir (it skips names)
  201. fun clean_dir_filtered ffun tgt =
  202.   let val dir = openDir tgt
  203.       val _   =   chDir tgt
  204.       fun delf_file fname =
  205.         let val {base, ext} = Path.splitBaseExt fname
  206.         in if isDir fname
  207.            then () (* do nested dirs? *)
  208.            else if ffun base ext
  209.            then remove fname
  210.            else ()
  211.         end
  212.       fun delf "" = ()
  213.         | delf f  = ( delf_file f ; delf (readDir dir) )
  214.   in
  215.      let val _ = delf (readDir dir)
  216.      in closeDir dir
  217.      end
  218.      handle exn as OS.SysErr (msg, _) => (closeDir dir; raise exn)
  219.   end
  220. ;
  221. *)
  222. fun clean_dir_filtered ffun tgt =
  223.   let val dir = openDir tgt
  224.       val _   =   chDir tgt
  225.       val nms = ref []
  226.       fun delf_file fname =
  227.         let val {base, ext} = Path.splitBaseExt fname
  228.         in if isDir fname
  229.            then () (* do nested dirs? *)
  230.            else if ffun base ext
  231.            then nms := fname :: (!nms)
  232.            else ()
  233.         end
  234.       fun delf "" = ()
  235.         | delf f  = ( delf_file f ; delf (readDir dir) )
  236.   in
  237.      let val _ = delf (readDir dir)
  238.      in List.app remove (!nms); closeDir dir
  239.      end
  240.      handle exn as OS.SysErr (msg, _) => (closeDir dir; raise exn)
  241.   end
  242. ;
  243.  
  244. fun no_filt _ _ = true;
  245.  
  246. fun lib_filt _ ext = Binaryset.member(objs,ext);
  247.  
  248. fun bin_filt _ ext = Binaryset.member(bins,ext);
  249.  
  250. val clean_dir_bin = clean_dir_filtered bin_filt;
  251.  
  252. val copy_dir = copy_dir_filtered no_filt;
  253.  
  254. val copy_dir_obj = copy_dir_filtered lib_filt;
  255.  
  256. val compare_dirs = compare_dirs_filtered no_filt;
  257.  
  258. val compare_dirs_obj = compare_dirs_filtered lib_filt;
  259.  
  260. (* 
  261. clean_dir_bin (home ^ "src:mosmllib:");
  262. clean_dir_bin (home ^ "src:compiler:");
  263. clean_dir_bin (home ^ "src:lex:");
  264. clean_dir_bin (home ^ "src:toolssrc:");
  265. copy_dir_obj (home ^ "src:mosmllib:") (home ^ "lib2:");
  266. compare_dirs_obj (home ^ "src:mosmllib:") (home ^ "lib2:");
  267. *)