src/Pure/System/isabelle_system.scala
changeset 51820 142c69695785
parent 51615 072a7249e1ac
child 51962 016cb7d8f297
equal deleted inserted replaced
51818:517f232e867d 51820:142c69695785
    27     if (home.getName == "jre" && parent != null &&
    27     if (home.getName == "jre" && parent != null &&
    28         (new JFile(new JFile(parent, "bin"), "javac")).exists) parent
    28         (new JFile(new JFile(parent, "bin"), "javac")).exists) parent
    29     else java_home
    29     else java_home
    30   }
    30   }
    31 
    31 
    32   def cygwin_root(): String =
    32   private def find_cygwin_root(cygwin_root0: String = ""): String =
    33   {
    33   {
    34     require(Platform.is_windows)
    34     require(Platform.is_windows)
    35 
    35 
    36     val cygwin_root1 = System.getenv("CYGWIN_ROOT")
    36     val cygwin_root1 = System.getenv("CYGWIN_ROOT")
    37     val cygwin_root2 = System.getProperty("cygwin.root")
    37     val cygwin_root2 = System.getProperty("cygwin.root")
    38 
    38 
    39     if (cygwin_root1 != null && cygwin_root1 != "") cygwin_root1
    39     if (cygwin_root0 != null && cygwin_root0 != "") cygwin_root0
       
    40     else if (cygwin_root1 != null && cygwin_root1 != "") cygwin_root1
    40     else if (cygwin_root2 != null && cygwin_root2 != "") cygwin_root2
    41     else if (cygwin_root2 != null && cygwin_root2 != "") cygwin_root2
    41     else error("Cannot determine Cygwin root directory")
    42     else error("Cannot determine Cygwin root directory")
    42   }
    43   }
    43 
    44 
    44 
    45 
    52     if (_settings.isEmpty) init()  // unsynchronized check
    53     if (_settings.isEmpty) init()  // unsynchronized check
    53     _settings.get
    54     _settings.get
    54   }
    55   }
    55 
    56 
    56   /*
    57   /*
    57     isabelle_home precedence:
    58     Isabelle home precedence:
    58       (1) this_isabelle_home as explicit argument
    59       (1) isabelle_home as explicit argument
    59       (2) ISABELLE_HOME process environment variable (e.g. inherited from running isabelle tool)
    60       (2) ISABELLE_HOME process environment variable (e.g. inherited from running isabelle tool)
    60       (3) isabelle.home system property (e.g. via JVM application boot process)
    61       (3) isabelle.home system property (e.g. via JVM application boot process)
    61   */
    62   */
    62   def init(this_isabelle_home: String = null): Unit = synchronized {
    63   def init(isabelle_home: String = "", cygwin_root: String = ""): Unit = synchronized {
    63     if (_settings.isEmpty) {
    64     if (_settings.isEmpty) {
    64       import scala.collection.JavaConversions._
    65       import scala.collection.JavaConversions._
    65 
    66 
       
    67       def set_cygwin_root()
       
    68       {
       
    69         if (Platform.is_windows)
       
    70           _settings = Some(_settings.getOrElse(Map.empty) +
       
    71             ("CYGWIN_ROOT" -> find_cygwin_root(cygwin_root)))
       
    72       }
       
    73 
       
    74       set_cygwin_root()
       
    75       val env0 = sys.env + ("ISABELLE_JDK_HOME" -> posix_path(jdk_home()))
       
    76 
       
    77       val user_home = System.getProperty("user.home")
       
    78       val env =
       
    79         if (user_home == null || env0.isDefinedAt("HOME")) env0
       
    80         else env0 + ("HOME" -> user_home)
       
    81 
       
    82       val system_home =
       
    83         if (isabelle_home != null && isabelle_home != "") isabelle_home
       
    84         else
       
    85           env.get("ISABELLE_HOME") match {
       
    86             case None | Some("") =>
       
    87               val path = System.getProperty("isabelle.home")
       
    88               if (path == null || path == "") error("Unknown Isabelle home directory")
       
    89               else path
       
    90             case Some(path) => path
       
    91           }
       
    92 
    66       val settings =
    93       val settings =
    67       {
    94         File.with_tmp_file("settings") { dump =>
    68         val env0 = sys.env + ("ISABELLE_JDK_HOME" -> posix_path(jdk_home()))
    95           val shell_prefix =
    69 
    96             if (Platform.is_windows) List(find_cygwin_root(cygwin_root) + "\\bin\\bash", "-l")
    70         val user_home = System.getProperty("user.home")
    97             else Nil
    71         val env =
    98           val cmdline =
    72           if (user_home == null || env0.isDefinedAt("HOME")) env0
    99             shell_prefix ::: List(system_home + "/bin/isabelle", "getenv", "-d", dump.toString)
    73           else env0 + ("HOME" -> user_home)
   100           val (output, rc) = process_output(raw_execute(null, env, true, cmdline: _*))
    74 
   101           if (rc != 0) error(output)
    75         val isabelle_home =
   102   
    76           if (this_isabelle_home != null) this_isabelle_home
   103           val entries =
    77           else
   104             (for (entry <- File.read(dump) split "\0" if entry != "") yield {
    78             env.get("ISABELLE_HOME") match {
   105               val i = entry.indexOf('=')
    79               case None | Some("") =>
   106               if (i <= 0) (entry -> "")
    80                 val path = System.getProperty("isabelle.home")
   107               else (entry.substring(0, i) -> entry.substring(i + 1))
    81                 if (path == null || path == "") error("Unknown Isabelle home directory")
   108             }).toMap
    82                 else path
   109           entries + ("PATH" -> entries("PATH_JVM")) - "PATH_JVM"
    83               case Some(path) => path
   110         }
    84             }
       
    85 
       
    86           File.with_tmp_file("settings") { dump =>
       
    87               val shell_prefix =
       
    88                 if (Platform.is_windows) List(cygwin_root() + "\\bin\\bash", "-l")
       
    89                 else Nil
       
    90               val cmdline =
       
    91                 shell_prefix ::: List(isabelle_home + "/bin/isabelle", "getenv", "-d", dump.toString)
       
    92               val (output, rc) = process_output(raw_execute(null, env, true, cmdline: _*))
       
    93               if (rc != 0) error(output)
       
    94 
       
    95               val entries =
       
    96                 (for (entry <- File.read(dump) split "\0" if entry != "") yield {
       
    97                   val i = entry.indexOf('=')
       
    98                   if (i <= 0) (entry -> "")
       
    99                   else (entry.substring(0, i) -> entry.substring(i + 1))
       
   100                 }).toMap
       
   101               entries + ("PATH" -> entries("PATH_JVM")) - "PATH_JVM"
       
   102             }
       
   103           }
       
   104       _settings = Some(settings)
   111       _settings = Some(settings)
       
   112       set_cygwin_root()
   105     }
   113     }
   106   }
   114   }
   107 
   115 
   108 
   116 
   109   /* getenv */
   117   /* getenv */
   113   def getenv_strict(name: String): String =
   121   def getenv_strict(name: String): String =
   114   {
   122   {
   115     val value = getenv(name)
   123     val value = getenv(name)
   116     if (value != "") value else error("Undefined environment variable: " + name)
   124     if (value != "") value else error("Undefined environment variable: " + name)
   117   }
   125   }
       
   126 
       
   127   def get_cygwin_root(): String = getenv_strict("CYGWIN_ROOT")
   118 
   128 
   119 
   129 
   120   /** file-system operations **/
   130   /** file-system operations **/
   121 
   131 
   122   /* jvm_path */
   132   /* jvm_path */
   136             result_path ++= JFile.separator
   146             result_path ++= JFile.separator
   137             result_path ++= JFile.separator
   147             result_path ++= JFile.separator
   138             result_path ++= root
   148             result_path ++= root
   139             rest
   149             rest
   140           case path if path.startsWith("/") =>
   150           case path if path.startsWith("/") =>
   141             result_path ++= cygwin_root()
   151             result_path ++= get_cygwin_root()
   142             path
   152             path
   143           case path => path
   153           case path => path
   144         }
   154         }
   145       for (p <- space_explode('/', rest) if p != "") {
   155       for (p <- space_explode('/', rest) if p != "") {
   146         val len = result_path.length
   156         val len = result_path.length
   156   /* posix_path */
   166   /* posix_path */
   157 
   167 
   158   def posix_path(jvm_path: String): String =
   168   def posix_path(jvm_path: String): String =
   159     if (Platform.is_windows) {
   169     if (Platform.is_windows) {
   160       val Platform_Root = new Regex("(?i)" +
   170       val Platform_Root = new Regex("(?i)" +
   161         Pattern.quote(cygwin_root()) + """(?:\\+|\z)(.*)""")
   171         Pattern.quote(get_cygwin_root()) + """(?:\\+|\z)(.*)""")
   162       val Drive = new Regex("""([a-zA-Z]):\\*(.*)""")
   172       val Drive = new Regex("""([a-zA-Z]):\\*(.*)""")
   163 
   173 
   164       jvm_path.replace('/', '\\') match {
   174       jvm_path.replace('/', '\\') match {
   165         case Platform_Root(rest) => "/" + rest.replace('\\', '/')
   175         case Platform_Root(rest) => "/" + rest.replace('\\', '/')
   166         case Drive(letter, rest) =>
   176         case Drive(letter, rest) =>
   255   /* plain execute */
   265   /* plain execute */
   256 
   266 
   257   def execute_env(cwd: JFile, env: Map[String, String], redirect: Boolean, args: String*): Process =
   267   def execute_env(cwd: JFile, env: Map[String, String], redirect: Boolean, args: String*): Process =
   258   {
   268   {
   259     val cmdline =
   269     val cmdline =
   260       if (Platform.is_windows) List(cygwin_root() + "\\bin\\env.exe") ++ args
   270       if (Platform.is_windows) List(get_cygwin_root() + "\\bin\\env.exe") ++ args
   261       else args
   271       else args
   262     val env1 = if (env == null) settings else settings ++ env
   272     val env1 = if (env == null) settings else settings ++ env
   263     raw_execute(cwd, env1, redirect, cmdline: _*)
   273     raw_execute(cwd, env1, redirect, cmdline: _*)
   264   }
   274   }
   265 
   275