src/Pure/General/file.scala
author wenzelm
Sun, 11 Oct 2020 14:01:32 +0200
changeset 72442 90868036d693
parent 72378 075f3cbc7546
child 72572 e7e93c0f6d96
permissions -rw-r--r--
clarified signature;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/General/file.scala
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
     3
64698
e022a69db531 tuned comments;
wenzelm
parents: 64668
diff changeset
     4
File-system operations.
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
     5
*/
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
     6
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
     7
package isabelle
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
     8
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
     9
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
    10
import java.io.{BufferedWriter, OutputStreamWriter, FileOutputStream, BufferedOutputStream,
51504
18095684c5a6 basic support for xz files;
wenzelm
parents: 51251
diff changeset
    11
  OutputStream, InputStream, FileInputStream, BufferedInputStream, BufferedReader,
18095684c5a6 basic support for xz files;
wenzelm
parents: 51251
diff changeset
    12
  InputStreamReader, File => JFile, IOException}
62703
01b71da798dd more operations;
wenzelm
parents: 62636
diff changeset
    13
import java.nio.file.{StandardOpenOption, StandardCopyOption, Path => JPath,
69402
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
    14
  Files, SimpleFileVisitor, FileVisitOption, FileVisitResult, FileSystemException}
62443
133f65ac17e5 just one File.find_files, based on Java 7 Files operations;
wenzelm
parents: 62294
diff changeset
    15
import java.nio.file.attribute.BasicFileAttributes
64775
dd3797f1e0d6 clarified file URIs;
wenzelm
parents: 64760
diff changeset
    16
import java.net.{URL, MalformedURLException}
50684
12b7e0b4a66e support File.read_gzip as well, in accordance to File.write_gzip;
wenzelm
parents: 50203
diff changeset
    17
import java.util.zip.{GZIPInputStream, GZIPOutputStream}
60992
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    18
import java.util.regex.Pattern
69293
72a9860f8602 clarified find_files: follow links by default, e.g. relevant for "~/cronjob/log";
wenzelm
parents: 66693
diff changeset
    19
import java.util.EnumSet
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
    20
64002
08f89f0e8a62 clarified modules;
wenzelm
parents: 64000
diff changeset
    21
import org.tukaani.xz.{XZInputStream, XZOutputStream}
08f89f0e8a62 clarified modules;
wenzelm
parents: 64000
diff changeset
    22
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
    23
import scala.collection.mutable
60992
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    24
import scala.util.matching.Regex
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
    25
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
    26
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
    27
object File
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
    28
{
60992
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    29
  /* standard path (Cygwin or Posix) */
60988
1d7a7e33fd67 tuned signature, according to ML version;
wenzelm
parents: 58610
diff changeset
    30
1d7a7e33fd67 tuned signature, according to ML version;
wenzelm
parents: 58610
diff changeset
    31
  def standard_path(path: Path): String = path.expand.implode
1d7a7e33fd67 tuned signature, according to ML version;
wenzelm
parents: 58610
diff changeset
    32
60992
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    33
  def standard_path(platform_path: String): String =
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    34
    if (Platform.is_windows) {
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    35
      val Platform_Root = new Regex("(?i)" +
61291
e00e1bf23d03 uniform treatment of bootstrap directories;
wenzelm
parents: 60992
diff changeset
    36
        Pattern.quote(Isabelle_System.cygwin_root()) + """(?:\\+|\z)(.*)""")
64775
dd3797f1e0d6 clarified file URIs;
wenzelm
parents: 64760
diff changeset
    37
      val Drive = new Regex("""([a-zA-Z]):\\*(.*)""")
60992
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    38
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    39
      platform_path.replace('/', '\\') match {
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    40
        case Platform_Root(rest) => "/" + rest.replace('\\', '/')
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    41
        case Drive(letter, rest) =>
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    42
          "/cygdrive/" + Word.lowercase(letter) +
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    43
            (if (rest == "") "" else "/" + rest.replace('\\', '/'))
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    44
        case path => path.replace('\\', '/')
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    45
      }
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    46
    }
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    47
    else platform_path
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    48
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    49
  def standard_path(file: JFile): String = standard_path(file.getPath)
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    50
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    51
  def standard_url(name: String): String =
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    52
    try {
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    53
      val url = new URL(name)
64775
dd3797f1e0d6 clarified file URIs;
wenzelm
parents: 64760
diff changeset
    54
      if (url.getProtocol == "file" && Url.is_wellformed_file(name))
dd3797f1e0d6 clarified file URIs;
wenzelm
parents: 64760
diff changeset
    55
        standard_path(Url.parse_file(name))
60992
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    56
      else name
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    57
    }
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    58
    catch { case _: MalformedURLException => standard_path(name) }
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    59
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    60
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    61
  /* platform path (Windows or Posix) */
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    62
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    63
  private val Cygdrive = new Regex("/cygdrive/([a-zA-Z])($|/.*)")
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    64
  private val Named_Root = new Regex("//+([^/]*)(.*)")
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    65
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    66
  def platform_path(standard_path: String): String =
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    67
    if (Platform.is_windows) {
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    68
      val result_path = new StringBuilder
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    69
      val rest =
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    70
        standard_path match {
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    71
          case Cygdrive(drive, rest) =>
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    72
            result_path ++= (Word.uppercase(drive) + ":" + JFile.separator)
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    73
            rest
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    74
          case Named_Root(root, rest) =>
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    75
            result_path ++= JFile.separator
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    76
            result_path ++= JFile.separator
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    77
            result_path ++= root
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    78
            rest
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    79
          case path if path.startsWith("/") =>
61291
e00e1bf23d03 uniform treatment of bootstrap directories;
wenzelm
parents: 60992
diff changeset
    80
            result_path ++= Isabelle_System.cygwin_root()
60992
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    81
            path
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    82
          case path => path
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    83
        }
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    84
      for (p <- space_explode('/', rest) if p != "") {
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    85
        val len = result_path.length
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    86
        if (len > 0 && result_path(len - 1) != JFile.separatorChar)
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    87
          result_path += JFile.separatorChar
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    88
        result_path ++= p
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    89
      }
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    90
      result_path.toString
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    91
    }
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    92
    else standard_path
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    93
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    94
  def platform_path(path: Path): String = platform_path(standard_path(path))
60988
1d7a7e33fd67 tuned signature, according to ML version;
wenzelm
parents: 58610
diff changeset
    95
  def platform_file(path: Path): JFile = new JFile(platform_path(path))
1d7a7e33fd67 tuned signature, according to ML version;
wenzelm
parents: 58610
diff changeset
    96
60992
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
    97
66232
be0ab4b94c62 clarified signature;
wenzelm
parents: 65589
diff changeset
    98
  /* platform files */
be0ab4b94c62 clarified signature;
wenzelm
parents: 65589
diff changeset
    99
be0ab4b94c62 clarified signature;
wenzelm
parents: 65589
diff changeset
   100
  def absolute(file: JFile): JFile = file.toPath.toAbsolutePath.normalize.toFile
66233
7188967253e5 more operations;
wenzelm
parents: 66232
diff changeset
   101
  def absolute_name(file: JFile): String = absolute(file).getPath
7188967253e5 more operations;
wenzelm
parents: 66232
diff changeset
   102
66232
be0ab4b94c62 clarified signature;
wenzelm
parents: 65589
diff changeset
   103
  def canonical(file: JFile): JFile = file.getCanonicalFile
66233
7188967253e5 more operations;
wenzelm
parents: 66232
diff changeset
   104
  def canonical_name(file: JFile): String = canonical(file).getPath
66232
be0ab4b94c62 clarified signature;
wenzelm
parents: 65589
diff changeset
   105
be0ab4b94c62 clarified signature;
wenzelm
parents: 65589
diff changeset
   106
  def path(file: JFile): Path = Path.explode(standard_path(file))
be0ab4b94c62 clarified signature;
wenzelm
parents: 65589
diff changeset
   107
  def pwd(): Path = path(Path.current.absolute_file)
be0ab4b94c62 clarified signature;
wenzelm
parents: 65589
diff changeset
   108
be0ab4b94c62 clarified signature;
wenzelm
parents: 65589
diff changeset
   109
66693
02588021b581 more operations;
wenzelm
parents: 66233
diff changeset
   110
  /* relative paths */
02588021b581 more operations;
wenzelm
parents: 66233
diff changeset
   111
02588021b581 more operations;
wenzelm
parents: 66233
diff changeset
   112
  def relative_path(base: Path, other: Path): Option[Path] =
02588021b581 more operations;
wenzelm
parents: 66233
diff changeset
   113
  {
02588021b581 more operations;
wenzelm
parents: 66233
diff changeset
   114
    val base_path = base.file.toPath
02588021b581 more operations;
wenzelm
parents: 66233
diff changeset
   115
    val other_path = other.file.toPath
02588021b581 more operations;
wenzelm
parents: 66233
diff changeset
   116
    if (other_path.startsWith(base_path))
02588021b581 more operations;
wenzelm
parents: 66233
diff changeset
   117
      Some(path(base_path.relativize(other_path).toFile))
02588021b581 more operations;
wenzelm
parents: 66233
diff changeset
   118
    else None
02588021b581 more operations;
wenzelm
parents: 66233
diff changeset
   119
  }
02588021b581 more operations;
wenzelm
parents: 66233
diff changeset
   120
02588021b581 more operations;
wenzelm
parents: 66233
diff changeset
   121
62545
8ebffdaf2ce2 Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
wenzelm
parents: 62544
diff changeset
   122
  /* bash path */
60992
89effcb342df clarified modules, like ML version;
wenzelm
parents: 60988
diff changeset
   123
64304
96bc94c87a81 clarified modules;
wenzelm
parents: 64220
diff changeset
   124
  def bash_path(path: Path): String = Bash.string(standard_path(path))
96bc94c87a81 clarified modules;
wenzelm
parents: 64220
diff changeset
   125
  def bash_path(file: JFile): String = Bash.string(standard_path(file))
60988
1d7a7e33fd67 tuned signature, according to ML version;
wenzelm
parents: 58610
diff changeset
   126
72036
e48a5b6b7554 clarified signature;
wenzelm
parents: 71601
diff changeset
   127
  def bash_platform_path(path: Path): String = Bash.string(platform_path(path))
e48a5b6b7554 clarified signature;
wenzelm
parents: 71601
diff changeset
   128
60988
1d7a7e33fd67 tuned signature, according to ML version;
wenzelm
parents: 58610
diff changeset
   129
62544
efa178abe023 manage the underlying ML process in Scala;
wenzelm
parents: 62444
diff changeset
   130
  /* directory entries */
efa178abe023 manage the underlying ML process in Scala;
wenzelm
parents: 62444
diff changeset
   131
efa178abe023 manage the underlying ML process in Scala;
wenzelm
parents: 62444
diff changeset
   132
  def check_dir(path: Path): Path =
efa178abe023 manage the underlying ML process in Scala;
wenzelm
parents: 62444
diff changeset
   133
    if (path.is_dir) path else error("No such directory: " + path)
efa178abe023 manage the underlying ML process in Scala;
wenzelm
parents: 62444
diff changeset
   134
efa178abe023 manage the underlying ML process in Scala;
wenzelm
parents: 62444
diff changeset
   135
  def check_file(path: Path): Path =
efa178abe023 manage the underlying ML process in Scala;
wenzelm
parents: 62444
diff changeset
   136
    if (path.is_file) path else error("No such file: " + path)
efa178abe023 manage the underlying ML process in Scala;
wenzelm
parents: 62444
diff changeset
   137
efa178abe023 manage the underlying ML process in Scala;
wenzelm
parents: 62444
diff changeset
   138
62829
4141c2a8458b clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
wenzelm
parents: 62704
diff changeset
   139
  /* directory content */
4141c2a8458b clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
wenzelm
parents: 62704
diff changeset
   140
4141c2a8458b clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
wenzelm
parents: 62704
diff changeset
   141
  def read_dir(dir: Path): List[String] =
4141c2a8458b clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
wenzelm
parents: 62704
diff changeset
   142
  {
69300
8b6ab9989bcd is_file/is_dir/read_dir: more uniform treatment of errors and boundary cases, notably for symlinks in ssh;
wenzelm
parents: 69299
diff changeset
   143
    if (!dir.is_dir) error("No such directory: " + dir.toString)
62829
4141c2a8458b clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
wenzelm
parents: 62704
diff changeset
   144
    val files = dir.file.listFiles
4141c2a8458b clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
wenzelm
parents: 62704
diff changeset
   145
    if (files == null) Nil
69427
ff2f39a221d4 clarified operations: uniform sorting of results;
wenzelm
parents: 69405
diff changeset
   146
    else files.toList.map(_.getName).sorted
62829
4141c2a8458b clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
wenzelm
parents: 62704
diff changeset
   147
  }
48613
232652ac346e clarified directory content operations (similar to ML version);
wenzelm
parents: 48550
diff changeset
   148
72442
90868036d693 clarified signature;
wenzelm
parents: 72378
diff changeset
   149
  def get_dir(dir: Path): String =
90868036d693 clarified signature;
wenzelm
parents: 72378
diff changeset
   150
    read_dir(dir).filter(name => (dir + Path.basic(name)).is_dir) match {
90868036d693 clarified signature;
wenzelm
parents: 72378
diff changeset
   151
      case List(entry) => entry
90868036d693 clarified signature;
wenzelm
parents: 72378
diff changeset
   152
      case dirs =>
90868036d693 clarified signature;
wenzelm
parents: 72378
diff changeset
   153
        error("Exactly one directory entry expected: " + commas_quote(dirs.sorted))
90868036d693 clarified signature;
wenzelm
parents: 72378
diff changeset
   154
    }
90868036d693 clarified signature;
wenzelm
parents: 72378
diff changeset
   155
64932
89c0896a19ad clarified operation: include dirs as well;
wenzelm
parents: 64775
diff changeset
   156
  def find_files(
89c0896a19ad clarified operation: include dirs as well;
wenzelm
parents: 64775
diff changeset
   157
    start: JFile,
89c0896a19ad clarified operation: include dirs as well;
wenzelm
parents: 64775
diff changeset
   158
    pred: JFile => Boolean = _ => true,
69293
72a9860f8602 clarified find_files: follow links by default, e.g. relevant for "~/cronjob/log";
wenzelm
parents: 66693
diff changeset
   159
    include_dirs: Boolean = false,
69299
2fd070377c99 clarified default (amending 72a9860f8602): avoid implicit change of File.find_files (it can have bad effects e.g. on "isabelle update_cartouches");
wenzelm
parents: 69293
diff changeset
   160
    follow_links: Boolean = false): List[JFile] =
48613
232652ac346e clarified directory content operations (similar to ML version);
wenzelm
parents: 48550
diff changeset
   161
  {
62443
133f65ac17e5 just one File.find_files, based on Java 7 Files operations;
wenzelm
parents: 62294
diff changeset
   162
    val result = new mutable.ListBuffer[JFile]
64932
89c0896a19ad clarified operation: include dirs as well;
wenzelm
parents: 64775
diff changeset
   163
    def check(file: JFile) { if (pred(file)) result += file }
62443
133f65ac17e5 just one File.find_files, based on Java 7 Files operations;
wenzelm
parents: 62294
diff changeset
   164
64932
89c0896a19ad clarified operation: include dirs as well;
wenzelm
parents: 64775
diff changeset
   165
    if (start.isFile) check(start)
62443
133f65ac17e5 just one File.find_files, based on Java 7 Files operations;
wenzelm
parents: 62294
diff changeset
   166
    else if (start.isDirectory) {
69293
72a9860f8602 clarified find_files: follow links by default, e.g. relevant for "~/cronjob/log";
wenzelm
parents: 66693
diff changeset
   167
      val options =
72a9860f8602 clarified find_files: follow links by default, e.g. relevant for "~/cronjob/log";
wenzelm
parents: 66693
diff changeset
   168
        if (follow_links) EnumSet.of(FileVisitOption.FOLLOW_LINKS)
72a9860f8602 clarified find_files: follow links by default, e.g. relevant for "~/cronjob/log";
wenzelm
parents: 66693
diff changeset
   169
        else EnumSet.noneOf(classOf[FileVisitOption])
72a9860f8602 clarified find_files: follow links by default, e.g. relevant for "~/cronjob/log";
wenzelm
parents: 66693
diff changeset
   170
      Files.walkFileTree(start.toPath, options, Integer.MAX_VALUE,
62443
133f65ac17e5 just one File.find_files, based on Java 7 Files operations;
wenzelm
parents: 62294
diff changeset
   171
        new SimpleFileVisitor[JPath] {
64932
89c0896a19ad clarified operation: include dirs as well;
wenzelm
parents: 64775
diff changeset
   172
          override def preVisitDirectory(path: JPath, attrs: BasicFileAttributes): FileVisitResult =
89c0896a19ad clarified operation: include dirs as well;
wenzelm
parents: 64775
diff changeset
   173
          {
89c0896a19ad clarified operation: include dirs as well;
wenzelm
parents: 64775
diff changeset
   174
            if (include_dirs) check(path.toFile)
89c0896a19ad clarified operation: include dirs as well;
wenzelm
parents: 64775
diff changeset
   175
            FileVisitResult.CONTINUE
89c0896a19ad clarified operation: include dirs as well;
wenzelm
parents: 64775
diff changeset
   176
          }
62443
133f65ac17e5 just one File.find_files, based on Java 7 Files operations;
wenzelm
parents: 62294
diff changeset
   177
          override def visitFile(path: JPath, attrs: BasicFileAttributes): FileVisitResult =
133f65ac17e5 just one File.find_files, based on Java 7 Files operations;
wenzelm
parents: 62294
diff changeset
   178
          {
69301
f6c17b9e1104 more uniform find_files, notably for symlinks;
wenzelm
parents: 69300
diff changeset
   179
            val file = path.toFile
f6c17b9e1104 more uniform find_files, notably for symlinks;
wenzelm
parents: 69300
diff changeset
   180
            if (include_dirs || !file.isDirectory) check(file)
62443
133f65ac17e5 just one File.find_files, based on Java 7 Files operations;
wenzelm
parents: 62294
diff changeset
   181
            FileVisitResult.CONTINUE
133f65ac17e5 just one File.find_files, based on Java 7 Files operations;
wenzelm
parents: 62294
diff changeset
   182
          }
133f65ac17e5 just one File.find_files, based on Java 7 Files operations;
wenzelm
parents: 62294
diff changeset
   183
        }
133f65ac17e5 just one File.find_files, based on Java 7 Files operations;
wenzelm
parents: 62294
diff changeset
   184
      )
133f65ac17e5 just one File.find_files, based on Java 7 Files operations;
wenzelm
parents: 62294
diff changeset
   185
    }
133f65ac17e5 just one File.find_files, based on Java 7 Files operations;
wenzelm
parents: 62294
diff changeset
   186
133f65ac17e5 just one File.find_files, based on Java 7 Files operations;
wenzelm
parents: 62294
diff changeset
   187
    result.toList
48613
232652ac346e clarified directory content operations (similar to ML version);
wenzelm
parents: 48550
diff changeset
   188
  }
232652ac346e clarified directory content operations (similar to ML version);
wenzelm
parents: 48550
diff changeset
   189
232652ac346e clarified directory content operations (similar to ML version);
wenzelm
parents: 48550
diff changeset
   190
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   191
  /* read */
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   192
65589
f70c617e9c26 more robust treatment of non-UTF8 text files (cf. 3ed43cfc8b14), notably old log files in ISO-8859-15;
wenzelm
parents: 64934
diff changeset
   193
  def read(file: JFile): String = Bytes.read(file).text
48913
f686cb016c0c more direct File.read_bytes -- avoid cumulative copying of StringBuilder;
wenzelm
parents: 48613
diff changeset
   194
  def read(path: Path): String = read(path.file)
f686cb016c0c more direct File.read_bytes -- avoid cumulative copying of StringBuilder;
wenzelm
parents: 48613
diff changeset
   195
50684
12b7e0b4a66e support File.read_gzip as well, in accordance to File.write_gzip;
wenzelm
parents: 50203
diff changeset
   196
12b7e0b4a66e support File.read_gzip as well, in accordance to File.write_gzip;
wenzelm
parents: 50203
diff changeset
   197
  def read_stream(reader: BufferedReader): String =
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   198
  {
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   199
    val output = new StringBuilder(100)
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   200
    var c = -1
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   201
    while ({ c = reader.read; c != -1 }) output += c.toChar
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   202
    reader.close
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   203
    output.toString
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   204
  }
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   205
50684
12b7e0b4a66e support File.read_gzip as well, in accordance to File.write_gzip;
wenzelm
parents: 50203
diff changeset
   206
  def read_stream(stream: InputStream): String =
64000
445b3deced8f clarified modules;
wenzelm
parents: 62854
diff changeset
   207
    read_stream(new BufferedReader(new InputStreamReader(stream, UTF8.charset)))
50684
12b7e0b4a66e support File.read_gzip as well, in accordance to File.write_gzip;
wenzelm
parents: 50203
diff changeset
   208
12b7e0b4a66e support File.read_gzip as well, in accordance to File.write_gzip;
wenzelm
parents: 50203
diff changeset
   209
  def read_gzip(file: JFile): String =
12b7e0b4a66e support File.read_gzip as well, in accordance to File.write_gzip;
wenzelm
parents: 50203
diff changeset
   210
    read_stream(new GZIPInputStream(new BufferedInputStream(new FileInputStream(file))))
64000
445b3deced8f clarified modules;
wenzelm
parents: 62854
diff changeset
   211
  def read_gzip(path: Path): String = read_gzip(path.file)
51504
18095684c5a6 basic support for xz files;
wenzelm
parents: 51251
diff changeset
   212
64002
08f89f0e8a62 clarified modules;
wenzelm
parents: 64000
diff changeset
   213
  def read_xz(file: JFile): String =
08f89f0e8a62 clarified modules;
wenzelm
parents: 64000
diff changeset
   214
    read_stream(new XZInputStream(new BufferedInputStream(new FileInputStream(file))))
64000
445b3deced8f clarified modules;
wenzelm
parents: 62854
diff changeset
   215
  def read_xz(path: Path): String = read_xz(path.file)
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   216
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   217
50845
477ca927676f immediate theory progress for build_dialog;
wenzelm
parents: 50684
diff changeset
   218
  /* read lines */
477ca927676f immediate theory progress for build_dialog;
wenzelm
parents: 50684
diff changeset
   219
69487
681760f50723 clarified signature;
wenzelm
parents: 69427
diff changeset
   220
  def read_line(reader: BufferedReader): Option[String] =
681760f50723 clarified signature;
wenzelm
parents: 69427
diff changeset
   221
  {
681760f50723 clarified signature;
wenzelm
parents: 69427
diff changeset
   222
    val line =
681760f50723 clarified signature;
wenzelm
parents: 69427
diff changeset
   223
      try { reader.readLine}
681760f50723 clarified signature;
wenzelm
parents: 69427
diff changeset
   224
      catch { case _: IOException => null }
71601
97ccf48c2f0c misc tuning based on hints by IntelliJ IDEA;
wenzelm
parents: 71534
diff changeset
   225
    Option(line)
69487
681760f50723 clarified signature;
wenzelm
parents: 69427
diff changeset
   226
  }
681760f50723 clarified signature;
wenzelm
parents: 69427
diff changeset
   227
50845
477ca927676f immediate theory progress for build_dialog;
wenzelm
parents: 50684
diff changeset
   228
  def read_lines(reader: BufferedReader, progress: String => Unit): List[String] =
477ca927676f immediate theory progress for build_dialog;
wenzelm
parents: 50684
diff changeset
   229
  {
477ca927676f immediate theory progress for build_dialog;
wenzelm
parents: 50684
diff changeset
   230
    val result = new mutable.ListBuffer[String]
69487
681760f50723 clarified signature;
wenzelm
parents: 69427
diff changeset
   231
    var line: Option[String] = None
681760f50723 clarified signature;
wenzelm
parents: 69427
diff changeset
   232
    while ({ line = read_line(reader); line.isDefined }) {
681760f50723 clarified signature;
wenzelm
parents: 69427
diff changeset
   233
      progress(line.get)
681760f50723 clarified signature;
wenzelm
parents: 69427
diff changeset
   234
      result += line.get
50845
477ca927676f immediate theory progress for build_dialog;
wenzelm
parents: 50684
diff changeset
   235
    }
477ca927676f immediate theory progress for build_dialog;
wenzelm
parents: 50684
diff changeset
   236
    reader.close
477ca927676f immediate theory progress for build_dialog;
wenzelm
parents: 50684
diff changeset
   237
    result.toList
477ca927676f immediate theory progress for build_dialog;
wenzelm
parents: 50684
diff changeset
   238
  }
477ca927676f immediate theory progress for build_dialog;
wenzelm
parents: 50684
diff changeset
   239
477ca927676f immediate theory progress for build_dialog;
wenzelm
parents: 50684
diff changeset
   240
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   241
  /* write */
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   242
71534
f10bffaa2bae more scalable output of YXML files;
wenzelm
parents: 71377
diff changeset
   243
  def writer(file: JFile): BufferedWriter =
f10bffaa2bae more scalable output of YXML files;
wenzelm
parents: 71377
diff changeset
   244
    new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), UTF8.charset))
f10bffaa2bae more scalable output of YXML files;
wenzelm
parents: 71377
diff changeset
   245
64002
08f89f0e8a62 clarified modules;
wenzelm
parents: 64000
diff changeset
   246
  def write_file(file: JFile, text: CharSequence, make_stream: OutputStream => OutputStream)
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   247
  {
51504
18095684c5a6 basic support for xz files;
wenzelm
parents: 51251
diff changeset
   248
    val stream = make_stream(new FileOutputStream(file))
69393
ed0824ef337e static type for Library.using: avoid Java 11 warnings on "Illegal reflective access";
wenzelm
parents: 69301
diff changeset
   249
    using(new BufferedWriter(new OutputStreamWriter(stream, UTF8.charset)))(_.append(text))
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   250
  }
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   251
64003
73af1d36aeff tuned signature;
wenzelm
parents: 64002
diff changeset
   252
  def write(file: JFile, text: CharSequence): Unit = write_file(file, text, s => s)
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   253
  def write(path: Path, text: CharSequence): Unit = write(path.file, text)
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   254
64002
08f89f0e8a62 clarified modules;
wenzelm
parents: 64000
diff changeset
   255
  def write_gzip(file: JFile, text: CharSequence): Unit =
51504
18095684c5a6 basic support for xz files;
wenzelm
parents: 51251
diff changeset
   256
    write_file(file, text, (s: OutputStream) => new GZIPOutputStream(new BufferedOutputStream(s)))
48494
00eb5be9e76b read/write dependency information;
wenzelm
parents: 48418
diff changeset
   257
  def write_gzip(path: Path, text: CharSequence): Unit = write_gzip(path.file, text)
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   258
64002
08f89f0e8a62 clarified modules;
wenzelm
parents: 64000
diff changeset
   259
  def write_xz(file: JFile, text: CharSequence, options: XZ.Options): Unit =
64003
73af1d36aeff tuned signature;
wenzelm
parents: 64002
diff changeset
   260
    File.write_file(file, text, s => new XZOutputStream(new BufferedOutputStream(s), options))
73af1d36aeff tuned signature;
wenzelm
parents: 64002
diff changeset
   261
  def write_xz(file: JFile, text: CharSequence): Unit = write_xz(file, text, XZ.options())
64002
08f89f0e8a62 clarified modules;
wenzelm
parents: 64000
diff changeset
   262
  def write_xz(path: Path, text: CharSequence, options: XZ.Options): Unit =
08f89f0e8a62 clarified modules;
wenzelm
parents: 64000
diff changeset
   263
    write_xz(path.file, text, options)
64003
73af1d36aeff tuned signature;
wenzelm
parents: 64002
diff changeset
   264
  def write_xz(path: Path, text: CharSequence): Unit = write_xz(path, text, XZ.options())
64000
445b3deced8f clarified modules;
wenzelm
parents: 62854
diff changeset
   265
53336
b3bf6d72fea5 more general backup files;
wenzelm
parents: 52671
diff changeset
   266
  def write_backup(path: Path, text: CharSequence)
b3bf6d72fea5 more general backup files;
wenzelm
parents: 52671
diff changeset
   267
  {
64482
43f6c28ff496 clarified File.move: target directory like File.copy;
wenzelm
parents: 64345
diff changeset
   268
    if (path.is_file) move(path, path.backup)
62444
wenzelm
parents: 62443
diff changeset
   269
    write(path, text)
53336
b3bf6d72fea5 more general backup files;
wenzelm
parents: 52671
diff changeset
   270
  }
b3bf6d72fea5 more general backup files;
wenzelm
parents: 52671
diff changeset
   271
58610
fffdbce036db added update_cartouches tool;
wenzelm
parents: 56783
diff changeset
   272
  def write_backup2(path: Path, text: CharSequence)
fffdbce036db added update_cartouches tool;
wenzelm
parents: 56783
diff changeset
   273
  {
64482
43f6c28ff496 clarified File.move: target directory like File.copy;
wenzelm
parents: 64345
diff changeset
   274
    if (path.is_file) move(path, path.backup2)
62444
wenzelm
parents: 62443
diff changeset
   275
    write(path, text)
58610
fffdbce036db added update_cartouches tool;
wenzelm
parents: 56783
diff changeset
   276
  }
fffdbce036db added update_cartouches tool;
wenzelm
parents: 56783
diff changeset
   277
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   278
72378
075f3cbc7546 clarified signature;
wenzelm
parents: 72036
diff changeset
   279
  /* change */
075f3cbc7546 clarified signature;
wenzelm
parents: 72036
diff changeset
   280
075f3cbc7546 clarified signature;
wenzelm
parents: 72036
diff changeset
   281
  def change(file: JFile, f: String => String): Unit = write(file, f(read(file)))
075f3cbc7546 clarified signature;
wenzelm
parents: 72036
diff changeset
   282
  def change(path: Path, f: String => String): Unit = write(path, f(read(path)))
075f3cbc7546 clarified signature;
wenzelm
parents: 72036
diff changeset
   283
075f3cbc7546 clarified signature;
wenzelm
parents: 72036
diff changeset
   284
62703
01b71da798dd more operations;
wenzelm
parents: 62636
diff changeset
   285
  /* append */
01b71da798dd more operations;
wenzelm
parents: 62636
diff changeset
   286
01b71da798dd more operations;
wenzelm
parents: 62636
diff changeset
   287
  def append(file: JFile, text: CharSequence): Unit =
01b71da798dd more operations;
wenzelm
parents: 62636
diff changeset
   288
    Files.write(file.toPath, UTF8.bytes(text.toString),
01b71da798dd more operations;
wenzelm
parents: 62636
diff changeset
   289
      StandardOpenOption.APPEND, StandardOpenOption.CREATE)
01b71da798dd more operations;
wenzelm
parents: 62636
diff changeset
   290
01b71da798dd more operations;
wenzelm
parents: 62636
diff changeset
   291
  def append(path: Path, text: CharSequence): Unit = append(path.file, text)
01b71da798dd more operations;
wenzelm
parents: 62636
diff changeset
   292
01b71da798dd more operations;
wenzelm
parents: 62636
diff changeset
   293
64213
b265dd04d57d clarified file operations;
wenzelm
parents: 64003
diff changeset
   294
  /* eq */
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   295
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   296
  def eq(file1: JFile, file2: JFile): Boolean =
49673
2a088cff1e7b more robust File.eq, and thus File.copy of "~~/lib/logo/isabelle.gif";
wenzelm
parents: 49610
diff changeset
   297
    try { java.nio.file.Files.isSameFile(file1.toPath, file2.toPath) }
2a088cff1e7b more robust File.eq, and thus File.copy of "~~/lib/logo/isabelle.gif";
wenzelm
parents: 49610
diff changeset
   298
    catch { case ERROR(_) => false }
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   299
64213
b265dd04d57d clarified file operations;
wenzelm
parents: 64003
diff changeset
   300
  def eq(path1: Path, path2: Path): Boolean = eq(path1.file, path2.file)
b265dd04d57d clarified file operations;
wenzelm
parents: 64003
diff changeset
   301
b265dd04d57d clarified file operations;
wenzelm
parents: 64003
diff changeset
   302
64934
795055a0be98 hardlink within JVM;
wenzelm
parents: 64932
diff changeset
   303
  /* eq_content */
795055a0be98 hardlink within JVM;
wenzelm
parents: 64932
diff changeset
   304
795055a0be98 hardlink within JVM;
wenzelm
parents: 64932
diff changeset
   305
  def eq_content(file1: JFile, file2: JFile): Boolean =
795055a0be98 hardlink within JVM;
wenzelm
parents: 64932
diff changeset
   306
    if (eq(file1, file2)) true
795055a0be98 hardlink within JVM;
wenzelm
parents: 64932
diff changeset
   307
    else if (file1.length != file2.length) false
795055a0be98 hardlink within JVM;
wenzelm
parents: 64932
diff changeset
   308
    else Bytes.read(file1) == Bytes.read(file2)
795055a0be98 hardlink within JVM;
wenzelm
parents: 64932
diff changeset
   309
795055a0be98 hardlink within JVM;
wenzelm
parents: 64932
diff changeset
   310
  def eq_content(path1: Path, path2: Path): Boolean = eq_content(path1.file, path2.file)
795055a0be98 hardlink within JVM;
wenzelm
parents: 64932
diff changeset
   311
795055a0be98 hardlink within JVM;
wenzelm
parents: 64932
diff changeset
   312
64213
b265dd04d57d clarified file operations;
wenzelm
parents: 64003
diff changeset
   313
  /* copy */
b265dd04d57d clarified file operations;
wenzelm
parents: 64003
diff changeset
   314
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   315
  def copy(src: JFile, dst: JFile)
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   316
  {
61371
17944b500166 clarified, according to Isabelle_System.copy_file in ML;
wenzelm
parents: 61291
diff changeset
   317
    val target = if (dst.isDirectory) new JFile(dst, src.getName) else dst
61373
16ed9b97c72d more accurate imitation of "cp -p -f";
wenzelm
parents: 61371
diff changeset
   318
    if (!eq(src, target))
16ed9b97c72d more accurate imitation of "cp -p -f";
wenzelm
parents: 61371
diff changeset
   319
      Files.copy(src.toPath, target.toPath,
16ed9b97c72d more accurate imitation of "cp -p -f";
wenzelm
parents: 61371
diff changeset
   320
        StandardCopyOption.COPY_ATTRIBUTES,
16ed9b97c72d more accurate imitation of "cp -p -f";
wenzelm
parents: 61371
diff changeset
   321
        StandardCopyOption.REPLACE_EXISTING)
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   322
  }
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   323
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   324
  def copy(path1: Path, path2: Path): Unit = copy(path1.file, path2.file)
64213
b265dd04d57d clarified file operations;
wenzelm
parents: 64003
diff changeset
   325
b265dd04d57d clarified file operations;
wenzelm
parents: 64003
diff changeset
   326
b265dd04d57d clarified file operations;
wenzelm
parents: 64003
diff changeset
   327
  /* move */
b265dd04d57d clarified file operations;
wenzelm
parents: 64003
diff changeset
   328
64482
43f6c28ff496 clarified File.move: target directory like File.copy;
wenzelm
parents: 64345
diff changeset
   329
  def move(src: JFile, dst: JFile)
43f6c28ff496 clarified File.move: target directory like File.copy;
wenzelm
parents: 64345
diff changeset
   330
  {
43f6c28ff496 clarified File.move: target directory like File.copy;
wenzelm
parents: 64345
diff changeset
   331
    val target = if (dst.isDirectory) new JFile(dst, src.getName) else dst
43f6c28ff496 clarified File.move: target directory like File.copy;
wenzelm
parents: 64345
diff changeset
   332
    if (!eq(src, target))
43f6c28ff496 clarified File.move: target directory like File.copy;
wenzelm
parents: 64345
diff changeset
   333
      Files.move(src.toPath, target.toPath, StandardCopyOption.REPLACE_EXISTING)
43f6c28ff496 clarified File.move: target directory like File.copy;
wenzelm
parents: 64345
diff changeset
   334
  }
64213
b265dd04d57d clarified file operations;
wenzelm
parents: 64003
diff changeset
   335
64482
43f6c28ff496 clarified File.move: target directory like File.copy;
wenzelm
parents: 64345
diff changeset
   336
  def move(path1: Path, path2: Path): Unit = move(path1.file, path2.file)
69402
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   337
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   338
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   339
  /* symbolic link */
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   340
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   341
  def link(src: Path, dst: Path, force: Boolean = false)
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   342
  {
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   343
    val src_file = src.file
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   344
    val dst_file = dst.file
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   345
    val target = if (dst_file.isDirectory) new JFile(dst_file, src_file.getName) else dst_file
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   346
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   347
    if (force) target.delete
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   348
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   349
    try { Files.createSymbolicLink(target.toPath, src_file.toPath) }
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   350
    catch {
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   351
      case _: UnsupportedOperationException if Platform.is_windows =>
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   352
        Cygwin.link(standard_path(src), target)
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   353
      case _: FileSystemException if Platform.is_windows =>
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   354
        Cygwin.link(standard_path(src), target)
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   355
    }
61f4c406d727 more direct File.link operation: avoid external process;
wenzelm
parents: 69393
diff changeset
   356
  }
69405
22428643351f more direct File.executable operation: avoid external process (on Unix);
wenzelm
parents: 69402
diff changeset
   357
22428643351f more direct File.executable operation: avoid external process (on Unix);
wenzelm
parents: 69402
diff changeset
   358
22428643351f more direct File.executable operation: avoid external process (on Unix);
wenzelm
parents: 69402
diff changeset
   359
  /* permissions */
22428643351f more direct File.executable operation: avoid external process (on Unix);
wenzelm
parents: 69402
diff changeset
   360
69788
c175499a7537 added executable flag for exports;
wenzelm
parents: 69487
diff changeset
   361
  def is_executable(path: Path): Boolean =
c175499a7537 added executable flag for exports;
wenzelm
parents: 69487
diff changeset
   362
  {
c175499a7537 added executable flag for exports;
wenzelm
parents: 69487
diff changeset
   363
    if (Platform.is_windows) Isabelle_System.bash("test -x " + bash_path(path)).check.ok
c175499a7537 added executable flag for exports;
wenzelm
parents: 69487
diff changeset
   364
    else path.file.canExecute
c175499a7537 added executable flag for exports;
wenzelm
parents: 69487
diff changeset
   365
  }
c175499a7537 added executable flag for exports;
wenzelm
parents: 69487
diff changeset
   366
69789
2c3e5e58d93f more thorough File.set_executable, notably for Windows;
wenzelm
parents: 69788
diff changeset
   367
  def set_executable(path: Path, flag: Boolean)
69405
22428643351f more direct File.executable operation: avoid external process (on Unix);
wenzelm
parents: 69402
diff changeset
   368
  {
71114
6cfec8029831 clarified signature;
wenzelm
parents: 69789
diff changeset
   369
    if (Platform.is_windows && flag) Isabelle_System.chmod("a+x", path)
6cfec8029831 clarified signature;
wenzelm
parents: 69789
diff changeset
   370
    else if (Platform.is_windows) Isabelle_System.chmod("a-x", path)
69789
2c3e5e58d93f more thorough File.set_executable, notably for Windows;
wenzelm
parents: 69788
diff changeset
   371
    else path.file.setExecutable(flag, false)
69405
22428643351f more direct File.executable operation: avoid external process (on Unix);
wenzelm
parents: 69402
diff changeset
   372
  }
48411
5b3440850d36 more abstract file system operations in Scala, corresponding to ML version;
wenzelm
parents:
diff changeset
   373
}