13 import java.nio.file.{Path => JPath} |
13 import java.nio.file.{Path => JPath} |
14 |
14 |
15 import scala.util.matching.Regex |
15 import scala.util.matching.Regex |
16 |
16 |
17 |
17 |
18 object Path |
18 object Path { |
19 { |
|
20 /* path elements */ |
19 /* path elements */ |
21 |
20 |
22 sealed abstract class Elem |
21 sealed abstract class Elem |
23 private case class Root(name: String) extends Elem |
22 private case class Root(name: String) extends Elem |
24 private case class Basic(name: String) extends Elem |
23 private case class Basic(name: String) extends Elem |
93 val ISABELLE_HOME: Path = variable("ISABELLE_HOME") |
92 val ISABELLE_HOME: Path = variable("ISABELLE_HOME") |
94 |
93 |
95 |
94 |
96 /* explode */ |
95 /* explode */ |
97 |
96 |
98 def explode(str: String): Path = |
97 def explode(str: String): Path = { |
99 { |
|
100 def explode_elem(s: String): Elem = |
98 def explode_elem(s: String): Elem = |
101 try { |
99 try { |
102 if (s == "..") Parent |
100 if (s == "..") Parent |
103 else if (s == "~") Variable("USER_HOME") |
101 else if (s == "~") Variable("USER_HOME") |
104 else if (s == "~~") Variable("ISABELLE_HOME") |
102 else if (s == "~~") Variable("ISABELLE_HOME") |
146 Long_Name.explode(name).exists(a => reserved_windows.contains(Word.uppercase(a))) |
144 Long_Name.explode(name).exists(a => reserved_windows.contains(Word.uppercase(a))) |
147 |
145 |
148 |
146 |
149 /* case-insensitive names */ |
147 /* case-insensitive names */ |
150 |
148 |
151 def check_case_insensitive(paths: List[Path]): Unit = |
149 def check_case_insensitive(paths: List[Path]): Unit = { |
152 { |
|
153 val table = |
150 val table = |
154 paths.foldLeft(Multi_Map.empty[String, String]) { case (tab, path) => |
151 paths.foldLeft(Multi_Map.empty[String, String]) { case (tab, path) => |
155 val name = path.expand.implode |
152 val name = path.expand.implode |
156 tab.insert(Word.lowercase(name), name) |
153 tab.insert(Word.lowercase(name), name) |
157 } |
154 } |
235 def log: Path = ext("log") |
233 def log: Path = ext("log") |
236 def orig: Path = ext("orig") |
234 def orig: Path = ext("orig") |
237 def patch: Path = ext("patch") |
235 def patch: Path = ext("patch") |
238 def shasum: Path = ext("shasum") |
236 def shasum: Path = ext("shasum") |
239 |
237 |
240 def backup: Path = |
238 def backup: Path = { |
241 { |
|
242 val (prfx, s) = split_path |
239 val (prfx, s) = split_path |
243 prfx + Path.basic(s + "~") |
240 prfx + Path.basic(s + "~") |
244 } |
241 } |
245 |
242 |
246 def backup2: Path = |
243 def backup2: Path = { |
247 { |
|
248 val (prfx, s) = split_path |
244 val (prfx, s) = split_path |
249 prfx + Path.basic(s + "~~") |
245 prfx + Path.basic(s + "~~") |
250 } |
246 } |
251 |
247 |
252 def exe: Path = ext("exe") |
248 def exe: Path = ext("exe") |
253 def platform_exe: Path = if (Platform.is_windows) exe else this |
249 def platform_exe: Path = if (Platform.is_windows) exe else this |
254 |
250 |
255 private val Ext = new Regex("(.*)\\.([^.]*)") |
251 private val Ext = new Regex("(.*)\\.([^.]*)") |
256 |
252 |
257 def split_ext: (Path, String) = |
253 def split_ext: (Path, String) = { |
258 { |
|
259 val (prefix, base) = split_path |
254 val (prefix, base) = split_path |
260 base match { |
255 base match { |
261 case Ext(b, e) => (prefix + Path.basic(b), e) |
256 case Ext(b, e) => (prefix + Path.basic(b), e) |
262 case _ => (prefix + Path.basic(base), "") |
257 case _ => (prefix + Path.basic(base), "") |
263 } |
258 } |
269 def squash: Path = new Path(elems.map(elem => Path.Basic(Path.squash_elem(elem)))) |
264 def squash: Path = new Path(elems.map(elem => Path.Basic(Path.squash_elem(elem)))) |
270 |
265 |
271 |
266 |
272 /* expand */ |
267 /* expand */ |
273 |
268 |
274 def expand_env(env: JMap[String, String]): Path = |
269 def expand_env(env: JMap[String, String]): Path = { |
275 { |
|
276 def eval(elem: Path.Elem): List[Path.Elem] = |
270 def eval(elem: Path.Elem): List[Path.Elem] = |
277 elem match { |
271 elem match { |
278 case Path.Variable(s) => |
272 case Path.Variable(s) => |
279 val path = Path.explode(Isabelle_System.getenv_strict(s, env)) |
273 val path = Path.explode(Isabelle_System.getenv_strict(s, env)) |
280 if (path.elems.exists(_.isInstanceOf[Path.Variable])) |
274 if (path.elems.exists(_.isInstanceOf[Path.Variable])) |
291 def file_name: String = expand.base.implode |
285 def file_name: String = expand.base.implode |
292 |
286 |
293 |
287 |
294 /* implode wrt. given directories */ |
288 /* implode wrt. given directories */ |
295 |
289 |
296 def implode_symbolic: String = |
290 def implode_symbolic: String = { |
297 { |
|
298 val directories = |
291 val directories = |
299 Library.space_explode(':', Isabelle_System.getenv("ISABELLE_DIRECTORIES")).reverse |
292 Library.space_explode(':', Isabelle_System.getenv("ISABELLE_DIRECTORIES")).reverse |
300 val full_name = expand.implode |
293 val full_name = expand.implode |
301 directories.view.flatMap(a => |
294 directories.view.flatMap(a => |
302 try { |
295 try { |