| author | blanchet | 
| Thu, 21 Feb 2013 12:22:26 +0100 | |
| changeset 51214 | 4fb12e2598dc | 
| parent 50843 | 1465521b92a1 | 
| child 56498 | 6437c989a744 | 
| permissions | -rw-r--r-- | 
| 40743 | 1 | (* Title: Pure/System/isabelle_system.ML | 
| 2 | Author: Makarius | |
| 3 | ||
| 4 | Isabelle system support. | |
| 5 | *) | |
| 6 | ||
| 7 | signature ISABELLE_SYSTEM = | |
| 8 | sig | |
| 9 | val isabelle_tool: string -> string -> int | |
| 10 | val mkdirs: Path.T -> unit | |
| 40745 | 11 | val mkdir: Path.T -> unit | 
| 40743 | 12 | val copy_dir: Path.T -> Path.T -> unit | 
| 42127 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 13 | val create_tmp_path: string -> string -> Path.T | 
| 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 14 | val with_tmp_file: string -> string -> (Path.T -> 'a) -> 'a | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 15 | val with_tmp_dir: string -> (Path.T -> 'a) -> 'a | 
| 43849 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 16 | val with_tmp_fifo: (Path.T -> 'a) -> 'a | 
| 43850 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 17 | val bash_output: string -> string * int | 
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 18 | val bash: string -> int | 
| 40743 | 19 | end; | 
| 20 | ||
| 21 | structure Isabelle_System: ISABELLE_SYSTEM = | |
| 22 | struct | |
| 23 | ||
| 43850 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 24 | (* bash *) | 
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 25 | |
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 26 | fun bash_output s = | 
| 47499 
4b0daca2bf88
redirect bash stderr to Isabelle warning as appropriate -- avoid raw process error output which may either get ignored or overload PIDE syslog in extreme cases;
 wenzelm parents: 
46502diff
changeset | 27 | let | 
| 
4b0daca2bf88
redirect bash stderr to Isabelle warning as appropriate -- avoid raw process error output which may either get ignored or overload PIDE syslog in extreme cases;
 wenzelm parents: 
46502diff
changeset | 28 |     val {out, err, rc, ...} = Bash.process s;
 | 
| 
4b0daca2bf88
redirect bash stderr to Isabelle warning as appropriate -- avoid raw process error output which may either get ignored or overload PIDE syslog in extreme cases;
 wenzelm parents: 
46502diff
changeset | 29 | val _ = warning (trim_line err); | 
| 
4b0daca2bf88
redirect bash stderr to Isabelle warning as appropriate -- avoid raw process error output which may either get ignored or overload PIDE syslog in extreme cases;
 wenzelm parents: 
46502diff
changeset | 30 | in (out, rc) end; | 
| 43850 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 31 | |
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 32 | fun bash s = | 
| 47499 
4b0daca2bf88
redirect bash stderr to Isabelle warning as appropriate -- avoid raw process error output which may either get ignored or overload PIDE syslog in extreme cases;
 wenzelm parents: 
46502diff
changeset | 33 | let | 
| 
4b0daca2bf88
redirect bash stderr to Isabelle warning as appropriate -- avoid raw process error output which may either get ignored or overload PIDE syslog in extreme cases;
 wenzelm parents: 
46502diff
changeset | 34 | val (out, rc) = bash_output s; | 
| 
4b0daca2bf88
redirect bash stderr to Isabelle warning as appropriate -- avoid raw process error output which may either get ignored or overload PIDE syslog in extreme cases;
 wenzelm parents: 
46502diff
changeset | 35 | val _ = writeln (trim_line out); | 
| 
4b0daca2bf88
redirect bash stderr to Isabelle warning as appropriate -- avoid raw process error output which may either get ignored or overload PIDE syslog in extreme cases;
 wenzelm parents: 
46502diff
changeset | 36 | in rc end; | 
| 43850 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 37 | |
| 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 38 | |
| 40743 | 39 | (* system commands *) | 
| 40 | ||
| 41 | fun isabelle_tool name args = | |
| 42 | (case space_explode ":" (getenv "ISABELLE_TOOLS") |> get_first (fn dir => | |
| 43606 | 43 | let val path = File.platform_path (Path.append (Path.explode dir) (Path.basic name)) in | 
| 40743 | 44 | if can OS.FileSys.modTime path andalso | 
| 45 | not (OS.FileSys.isDir path) andalso | |
| 46 | OS.FileSys.access (path, [OS.FileSys.A_READ, OS.FileSys.A_EXEC]) | |
| 47 | then SOME path | |
| 48 | else NONE | |
| 49 | end handle OS.SysErr _ => NONE) of | |
| 50 | SOME path => bash (File.shell_quote path ^ " " ^ args) | |
| 47499 
4b0daca2bf88
redirect bash stderr to Isabelle warning as appropriate -- avoid raw process error output which may either get ignored or overload PIDE syslog in extreme cases;
 wenzelm parents: 
46502diff
changeset | 51 |   | NONE => (warning ("Unknown Isabelle tool: " ^ name); 2));
 | 
| 40743 | 52 | |
| 53 | fun system_command cmd = | |
| 54 |   if bash cmd <> 0 then error ("System command failed: " ^ cmd)
 | |
| 55 | else (); | |
| 56 | ||
| 57 | ||
| 58 | (* directory operations *) | |
| 59 | ||
| 60 | fun mkdirs path = system_command ("mkdir -p " ^ File.shell_path path);
 | |
| 61 | ||
| 40785 | 62 | fun mkdir path = | 
| 63 | if File.is_dir path then () else OS.FileSys.mkDir (File.platform_path path); | |
| 40743 | 64 | |
| 65 | fun copy_dir src dst = | |
| 66 | if File.eq (src, dst) then () | |
| 46502 
3d43d4d4d071
more uniform / portable representation of the idea of "copy_dir" (NB: cp -f dereferences symlinks on GNU/Linux, but does not on old-school Unixen including BSD/Mac OS X);
 wenzelm parents: 
45199diff
changeset | 67 |   else (system_command ("cp -p -R -f " ^ File.shell_path src ^ "/. " ^ File.shell_path dst); ());
 | 
| 40743 | 68 | |
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 69 | |
| 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 70 | (* unique tmp files *) | 
| 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 71 | |
| 42127 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 72 | fun create_tmp_path name ext = | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 73 | let | 
| 42127 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 74 | val path = File.tmp_path (Path.basic (name ^ serial_string ()) |> Path.ext ext); | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 75 | val _ = File.exists path andalso | 
| 41944 
b97091ae583a
Path.print is the official way to show file-system paths to users -- note that Path.implode often indicates violation of the abstract datatype;
 wenzelm parents: 
41352diff
changeset | 76 |       raise Fail ("Temporary file already exists: " ^ Path.print path);
 | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 77 | in path end; | 
| 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 78 | |
| 42127 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 79 | fun with_tmp_file name ext f = | 
| 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 80 | let val path = create_tmp_path name ext | 
| 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 81 | in Exn.release (Exn.capture f path before ignore (try File.rm path)) end; | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 82 | |
| 42127 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 83 | fun rm_tree path = system_command ("rm -r -f " ^ File.shell_path path);
 | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 84 | |
| 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 85 | fun with_tmp_dir name f = | 
| 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 86 | let | 
| 42127 
8223e7f4b0da
Isabelle_System.create_tmp_path/with_tmp_file: optional extension;
 wenzelm parents: 
41944diff
changeset | 87 | val path = create_tmp_path name ""; | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 88 | val _ = mkdirs path; | 
| 41352 
87adb55fb0fb
make SML/NJ and Poly/ML agree on the type of "before";
 wenzelm parents: 
41307diff
changeset | 89 | in Exn.release (Exn.capture f path before ignore (try rm_tree path)) end; | 
| 41307 
bb8468ae414e
slightly more standard Isabelle_System.with_tmp_file/with_tmp_dir (cf. Scala version);
 wenzelm parents: 
40785diff
changeset | 90 | |
| 43850 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 91 | |
| 43851 | 92 | (* fifo *) | 
| 43850 
7f2cbc713344
moved bash operations to Isabelle_System (cf. Scala version);
 wenzelm parents: 
43849diff
changeset | 93 | |
| 43849 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 94 | fun with_tmp_fifo f = | 
| 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 95 | with_tmp_file "isabelle-fifo-" "" | 
| 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 96 | (fn path => | 
| 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 97 |       (case bash_output ("mkfifo -m 600 " ^ File.shell_path path) of
 | 
| 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 98 | (_, 0) => f path | 
| 47499 
4b0daca2bf88
redirect bash stderr to Isabelle warning as appropriate -- avoid raw process error output which may either get ignored or overload PIDE syslog in extreme cases;
 wenzelm parents: 
46502diff
changeset | 99 | | (out, _) => error (trim_line out))); | 
| 43849 
00f4b305687d
access to process output stream via auxiliary fifo;
 wenzelm parents: 
43606diff
changeset | 100 | |
| 40743 | 101 | end; | 
| 102 |