src/Pure/Thy/path.ML
changeset 4113 f7130dcacefa
child 4114 8d80c1a3b546
equal deleted inserted replaced
4112:98c8f40f7bbe 4113:f7130dcacefa
       
     1 (*  Title:      Pure/Thy/path.ML
       
     2     ID:         $Id$
       
     3     Author:     Markus Wenzel, TU Muenchen
       
     4 
       
     5 Abstract algebra of file paths.  External representation Unix-style.
       
     6 
       
     7 TODO:
       
     8   - support variables and  eval:(string->T)->T->T (!?)
       
     9 *)
       
    10 
       
    11 signature PATH =
       
    12 sig
       
    13   type T
       
    14   val pack: T -> string
       
    15   val unpack: string -> T
       
    16   val current: T
       
    17   val parent: T
       
    18   val root: T
       
    19   val absolute: T -> bool
       
    20   val append: T -> T -> T
       
    21 end;
       
    22 
       
    23 structure Path: PATH =
       
    24 struct
       
    25 
       
    26 (* type path *)
       
    27 
       
    28 datatype T = Path of string list;
       
    29 
       
    30 val current = Path [];
       
    31 val parent = Path [".."];
       
    32 val root = Path [""];
       
    33 
       
    34 fun absolute (Path ("" :: _)) = true
       
    35   | absolute _ = false;
       
    36 
       
    37 
       
    38 (* append and norm *)
       
    39 
       
    40 (*append non-normal path (2n arg) to reversed normal one, result is normal*)
       
    41 fun rev_app xs [] = rev xs
       
    42   | rev_app _ ("" :: ys) = rev_app [""] ys
       
    43   | rev_app xs ("." :: ys) = rev_app xs ys
       
    44   | rev_app [] (".." :: ys) = rev_app [".."] ys
       
    45   | rev_app (xs as ".." :: _) (".." :: ys) = rev_app (".." :: xs) ys
       
    46   | rev_app (xs as "" :: _) (".." :: ys) = rev_app xs ys
       
    47   | rev_app (_ :: xs) (".." :: ys) = rev_app xs ys
       
    48   | rev_app xs (y :: ys) = rev_app (y :: xs) ys;
       
    49 
       
    50 fun norm path = rev_app [] path;
       
    51 fun append (Path xs) (Path ys) = Path (rev_app (rev xs) ys);
       
    52 
       
    53 
       
    54 (* pack and unpack *)
       
    55 
       
    56 fun pack (Path []) = "."
       
    57   | pack (path as Path xs) =
       
    58       (if absolute path then "/" else "") ^ space_implode "/" xs;
       
    59 
       
    60 fun unpack str =
       
    61   Path (norm
       
    62     (case space_explode "/" str of
       
    63       [""] => []
       
    64     | "" :: xs => "" :: filter (not_equal "") xs
       
    65     | xs => filter (not_equal "") xs));
       
    66 
       
    67 
       
    68 end;