let () = State.close ();; let dump = ref None let src = ref [] let args = ref [] let specs = [ "-dump", Arg.String (fun s -> dump := Some s), " specify filename for persistency"; "-quiet", Arg.Set Cduce.quiet, "suppress normal output (typing, results)"; "-v", Arg.Unit (fun () -> Printf.eprintf "CDuce, version %s\n" Cduce.version; exit 0), " print CDuce version"; "--", Arg.Rest (fun s -> args := s :: !args), " the following argument are passed to the CDuce program (in argv)"; ] let () = Arg.parse specs (fun s -> src := s :: !src) "cduce [options] [script]\n\nOptions:" let ppf = if !Cduce.quiet then Format.formatter_of_buffer (Buffer.create 1023) else Format.std_formatter let ppf_err = Format.err_formatter let do_file s = let (src, chan) = if s = "" then (`Stream, stdin) else (`File s, open_in s) in Location.push_source src; let input = Stream.of_channel chan in if Stream.peek input = Some '#' then ( let rec count n = match Stream.next input with | '\n' -> n | _ -> count (n + 1) in Wlexer.set_delta_loc (count 1) ); let ok = Cduce.run ppf ppf_err input in if s <> "" then close_in chan; if not ok then (Format.fprintf ppf_err "@."; exit 1) let main () = (match !dump with | Some f -> (try Format.fprintf ppf "Restoring state: "; let chan = open_in_bin f in let s = Marshal.from_channel chan in close_in chan; State.set s; Format.fprintf ppf "done ...@." with Sys_error _ -> Format.fprintf ppf "failed ...@.") | None -> let l = List.rev_map Value.string_latin1 !args in let l = Value.sequence l in let t = Sequence.star Sequence.string in Cduce.enter_global_value "argv" l t ); (match !src with | [] -> Format.fprintf ppf "CDuce %s\nNo script specified; using stdin ...@." Cduce.version; do_file "" | l -> List.iter do_file l); (match !dump with | Some f -> Format.fprintf ppf "Saving state ...@\n"; let s = State.get () in let chan = open_out_bin f in Marshal.to_channel chan s [ Marshal.Closures ]; close_out chan | None -> ()) let () = main ()