1(* filename.mlp *)
2
3(* open CharVector; *)
4
5fun extract arg = Substring.string(Substring.extract arg)
6
7fun check_suffix name suff =
8  let val name_len = size name
9      val suff_len = size suff
10  in
11    name_len >= suff_len andalso
12    extract(name, name_len - suff_len, SOME suff_len) = suff
13  end;
14
15fun chop_suffix name suff =
16  extract(name, 0, SOME (size name - size suff))
17;
18
19#ifdef unix
20val current_dir_name = ".";
21
22fun concat dirname filename =
23  let val len = size dirname
24      val x   = if len = 0 then "/" else extract(dirname, len-1, SOME 1)
25  in
26    case x of
27        "/"   => dirname ^ filename
28      | _     => dirname ^ "/" ^ filename
29  end;
30
31fun is_absolute n =
32  let val len = size n in
33     (len >= 1 andalso extract(n, 0, SOME 1) = "/")    orelse
34     (len >= 2 andalso extract(n, 0, SOME 2) = "./")   orelse
35     (len >= 3 andalso extract(n, 0, SOME 3) = "../")
36  end;
37
38fun slash_pos s =
39  let fun pos i =
40    if i < 0 then NONE else
41    case extract(s, i, SOME 1) of
42        "/"  => SOME i
43      | _    => pos (i - 1)
44  in pos (size s - 1) end
45;
46
47fun basename name =
48  case slash_pos name of
49      SOME p =>
50        extract(name, p+1, NONE)
51    | NONE   => name
52;
53
54fun dirname name =
55  if name = "/" then name else
56  case slash_pos name of
57      SOME p  => extract(name, 0, SOME p)
58    | NONE    => "."
59;
60#endif
61
62#ifdef macintosh
63val current_dir_name = ":";
64
65fun is_absolute n =
66  let val len = size n
67      fun h i =
68        if i >= len then false
69        else if extract(n, i, SOME 1) = ":" then true
70        else h (i+1)
71  in h 0 end;
72
73fun concat dirname filename =
74  let val dirname1 =
75        if is_absolute dirname
76        then dirname
77        else ":" ^ dirname
78      val l = size dirname1 - 1
79      val dirname2 =
80        if l < 0 orelse extract(dirname1, l, SOME 1) = ":"
81        then dirname1
82        else dirname1 ^ ":"
83      val len = size filename
84      val filename2 =
85        if len > 0 andalso extract(filename, 0, SOME 1) = ":"
86        then extract(filename, 1, NONE)
87        else filename
88  in dirname2 ^ filename2 end
89;
90
91fun colon_pos s =
92  let fun pos i =
93    if i < 0 then NONE else
94    case extract(s, i, SOME 1) of
95        ":"  => SOME i
96      | _    => pos (i - 1)
97  in pos (size s - 1) end
98;
99
100fun basename name =
101  case colon_pos name of
102      SOME p =>
103        extract(name, p+1, NONE)
104    | NONE   => name
105;
106
107fun dirname name =
108  if name = ":" then name else
109  case colon_pos name of
110      SOME p  => extract(name, 0, SOME p)
111    | NONE    => ":"
112;
113#endif
114
115#if defined(msdos) || defined(win32)
116val current_dir_name = ".";
117
118fun concat dirname filename =
119  let val len = size dirname
120      val x   = if len = 0 then "\\" else extract(dirname, len-1, SOME 1)
121  in
122    case x of
123        "\\"  => dirname ^ filename
124      | ":"   => dirname ^ filename
125      | _     => dirname ^ "\\" ^ filename
126  end;
127
128fun is_absolute n =
129  let val len = size n in
130    (len >= 2 andalso extract(n, 1, SOME 1) = ":")     orelse
131    (len >= 1 andalso extract(n, 0, SOME 1) = "\\")    orelse
132    (len >= 2 andalso extract(n, 0, SOME 2) = ".\\")   orelse
133    (len >= 3 andalso extract(n, 0, SOME 3) = "..\\")
134  end;
135
136fun sep_pos s =
137  let fun pos i =
138    if i < 0 then NONE else
139    case extract(s, i, SOME 1) of
140        "/"  => SOME i
141      | "\\" => SOME i
142      | ":"  => SOME i
143      | _    => pos (i - 1)
144  in pos (size s - 1) end
145;
146
147fun basename name =
148  case sep_pos name of
149      SOME p =>
150        extract(name, p+1, NONE)
151    | NONE   => name
152;
153
154fun dirname name =
155  let val len = size name in
156    if len >= 2 andalso extract(name, 1, SOME 1) = ":" then
157      extract(name, 0, SOME 2) ^
158        dirname (extract(name, 2, NONE))
159    else if name = "/" orelse name = "\\" then
160      name
161    else
162      case sep_pos name of
163          SOME p => extract(name, 0, SOME p)
164        | NONE   => "."
165  end;
166
167#endif
168