1
1
module C = Configurator. V1
2
2
3
+ type conf = { os_type : string ; major : int ; minor : int }
4
+
3
5
type op = Le | Ge
4
6
7
+ type condition =
8
+ | Version of op * int * int
9
+ | Os_type of string
10
+
5
11
type line =
6
- | If of op * int * int
7
- | Elseif of op * int * int
12
+ | If of condition
13
+ | Elseif of condition
8
14
| Else
9
15
| Endif
10
16
| Raw of string
@@ -26,12 +32,15 @@ let prefix ~pre s =
26
32
check 0
27
33
)
28
34
29
- let eval ~major ~minor op i j =
30
- match op with
31
- | Le -> (major, minor) < = (i, j)
32
- | Ge -> (major, minor) > = (i, j)
35
+ let eval ~conf = function
36
+ | Os_type ty -> conf.os_type = ty
37
+ | Version (op , i , j ) ->
38
+ match op with
39
+ | Le -> (conf.major, conf.minor) < = (i, j)
40
+ | Ge -> (conf.major, conf.minor) > = (i, j)
41
+
33
42
34
- let preproc_lines ~file ~major ~ minor (ic : in_channel ) : unit =
43
+ let preproc_lines ~file ~conf (ic : in_channel ) : unit =
35
44
let pos = ref 0 in
36
45
let fail msg =
37
46
failwith (Printf. sprintf " at line %d in '%s': %s" ! pos file msg)
@@ -46,13 +55,19 @@ let preproc_lines ~file ~major ~minor (ic : in_channel) : unit =
46
55
incr pos;
47
56
if line' <> " " && line'.[0 ] = '[' then
48
57
if prefix line' ~pre: " [@@@ifle" then
49
- Scanf. sscanf line' " [@@@ifle %d.%d]" (fun x y -> If (Le , x, y))
58
+ Scanf. sscanf line' " [@@@ifle %d.%d]" (fun x y -> If (Version ( Le , x, y) ))
50
59
else if prefix line' ~pre: " [@@@ifge" then
51
- Scanf. sscanf line' " [@@@ifge %d.%d]" (fun x y -> If (Ge , x, y))
60
+ Scanf. sscanf line' " [@@@ifge %d.%d]" (fun x y -> If (Version ( Ge , x, y) ))
52
61
else if prefix line' ~pre: " [@@@elifle" then
53
- Scanf. sscanf line' " [@@@elifle %d.%d]" (fun x y -> Elseif (Le , x, y))
62
+ Scanf. sscanf line' " [@@@elifle %d.%d]" (fun x y -> Elseif (Version ( Le , x, y) ))
54
63
else if prefix line' ~pre: " [@@@elifge" then
55
- Scanf. sscanf line' " [@@@elifge %d.%d]" (fun x y -> Elseif (Ge , x, y))
64
+ Scanf. sscanf line' " [@@@elifge %d.%d]" (fun x y -> Elseif (Version (Ge , x, y)))
65
+ else if prefix line' ~pre: " [@@@ifos" then
66
+ Scanf. sscanf line' " [@@@ifos %s]" (fun os_type ->
67
+ If (Os_type (String. lowercase_ascii os_type)))
68
+ else if prefix line' ~pre: " [@@@elifos" then
69
+ Scanf. sscanf line' " [@@@elifos %s]" (fun os_type ->
70
+ Elseif (Os_type (String. lowercase_ascii os_type)))
56
71
else if line' = " [@@@else_]" then
57
72
Else
58
73
else if line' = " [@@@endif]" then
@@ -67,8 +82,8 @@ let preproc_lines ~file ~major ~minor (ic : in_channel) : unit =
67
82
let rec top () =
68
83
match parse_line () with
69
84
| Eof -> ()
70
- | If ( op , i , j ) ->
71
- if eval ~major ~minor op i j then (
85
+ | If condition ->
86
+ if eval ~conf condition then (
72
87
pp_pos () ;
73
88
cat_block ()
74
89
) else
@@ -99,8 +114,8 @@ let preproc_lines ~file ~major ~minor (ic : in_channel) : unit =
99
114
| Endif ->
100
115
pp_pos () ;
101
116
top ()
102
- | Elseif ( op , i , j ) ->
103
- if elseok && eval ~major ~minor op i j then (
117
+ | Elseif condition ->
118
+ if elseok && eval ~conf condition then (
104
119
pp_pos () ;
105
120
cat_block ()
106
121
) else
@@ -120,9 +135,10 @@ let () =
120
135
let c = C. create " main" in
121
136
let version = C. ocaml_config_var_exn c " version" in
122
137
let major, minor = Scanf. sscanf version " %u.%u" (fun maj min -> maj, min) in
138
+ let os_type = String. lowercase_ascii (C. ocaml_config_var_exn c " os_type" ) in
123
139
124
140
let ic = open_in file in
125
- preproc_lines ~file ~major ~ minor ic;
141
+ preproc_lines ~file ~conf: {os_type; major; minor} ic;
126
142
127
143
Printf. printf " (* file preprocessed in %.3fs *)\n " (Unix. gettimeofday () -. t0);
128
144
()
0 commit comments