4ec6f55cc42b3618865500871407b1676c784875
[hcoop/domtool2.git] / src / domain.sml
1 (* HCoop Domtool (http://hcoop.sourceforge.net/)
2 * Copyright (c) 2006, Adam Chlipala
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *)
18
19 (* Domain-related primitive actions *)
20
21 structure Domain :> DOMAIN = struct
22
23 fun isIdent ch = Char.isLower ch orelse Char.isDigit ch
24
25 fun validHost s =
26 size s > 0 andalso size s < 20
27 andalso CharVector.all (fn ch => isIdent ch orelse ch = #"-") s
28
29 fun validDomain s =
30 size s > 0 andalso size s < 100
31 andalso List.all validHost (String.fields (fn ch => ch = #".") s)
32
33 val _ = Env.type_one "host"
34 Env.string
35 validHost
36
37 val _ = Env.type_one "domain"
38 Env.string
39 validDomain
40
41 open Ast
42
43 val befores = ref (fn (_ : string) => ())
44 val afters = ref (fn (_ : string) => ())
45
46 fun registerBefore f =
47 let
48 val old = !befores
49 in
50 befores := (fn x => (old x; f x))
51 end
52
53 fun registerAfter f =
54 let
55 val old = !afters
56 in
57 afters := (fn x => (old x; f x))
58 end
59
60 val current = ref ""
61 val currentPath = ref ""
62
63 fun currentDomain () = !current
64
65 fun domainFile name = TextIO.openOut (!currentPath ^ name)
66
67 fun getPath domain =
68 let
69 val toks = String.fields (fn ch => ch = #".") domain
70
71 val elems = foldr (fn (piece, elems) =>
72 let
73 val elems = piece :: elems
74 val path = String.concatWith "/" (Config.resultRoot :: rev elems)
75 in
76 (if Posix.FileSys.ST.isDir
77 (Posix.FileSys.stat path) then
78 ()
79 else
80 (OS.FileSys.remove path;
81 OS.FileSys.mkDir path))
82 handle OS.SysErr _ => OS.FileSys.mkDir path;
83 elems
84 end) [] toks
85 in
86 String.concatWith "/" (Config.resultRoot :: rev ("" :: elems))
87 end
88
89 val _ = Env.container_one "domain"
90 ("domain", Env.string)
91 (fn dom => (current := dom;
92 currentPath := getPath dom;
93 !befores dom),
94 fn () => !afters (!current))
95
96 end