90 lines
2.1 KiB
OCaml
90 lines
2.1 KiB
OCaml
|
type t = int
|
||
|
|
||
|
let _o = 1
|
||
|
let _a = 2
|
||
|
let _w = 4
|
||
|
let _i = 8
|
||
|
let _r = 16
|
||
|
let _O = 32
|
||
|
let _s = 64
|
||
|
|
||
|
let all ts = List.fold_left (lor) 0 ts
|
||
|
let filter t u = t land u
|
||
|
|
||
|
let of_bitmask_string ?(allowed = 12) s =
|
||
|
(* This parameter is a bitmask, with only 2 bits having any signification: if the bit 2
|
||
|
is set, the user mode 'w' will be set and if the bit 3 is set, the user mode 'i' will
|
||
|
be set. *)
|
||
|
try filter (int_of_string s) allowed
|
||
|
with Failure _ -> 0
|
||
|
|
||
|
let of_char = function
|
||
|
| 'o' -> _o
|
||
|
| 'a' -> _a
|
||
|
| 'w' -> _w
|
||
|
| 'i' -> _i
|
||
|
| 'r' -> _r
|
||
|
| 'O' -> _O
|
||
|
| 's' -> _s
|
||
|
| _ -> 0
|
||
|
|
||
|
let pp ppf t =
|
||
|
let f ch =
|
||
|
if t land (of_char ch) <> 0 then
|
||
|
Format.pp_print_char ppf ch
|
||
|
in
|
||
|
String.iter f "aiwroOs"
|
||
|
|
||
|
let rec of_string_rec s acc i =
|
||
|
if i >= String.length s then
|
||
|
acc
|
||
|
else
|
||
|
of_string_rec s (acc lor of_char s.[i]) (i + 1)
|
||
|
|
||
|
let of_string s =
|
||
|
of_string_rec s 0 0
|
||
|
|
||
|
type diff = int
|
||
|
|
||
|
let pp_diff ppf d =
|
||
|
if d < 0 then
|
||
|
(Format.pp_print_string ppf "-"; pp ppf (-d))
|
||
|
else
|
||
|
(Format.pp_print_string ppf "+"; pp ppf d)
|
||
|
|
||
|
let ( ~+ ) m = Int.abs m
|
||
|
let ( ~- ) m = Int.neg (~+ m)
|
||
|
|
||
|
let ( ^ ) t d =
|
||
|
if d < 0 then
|
||
|
Int.logand (Int.neg d |> Int.lognot) t
|
||
|
else
|
||
|
Int.logor d t
|
||
|
|
||
|
let diff_of_string s =
|
||
|
if String.starts_with s ~prefix:"-" then
|
||
|
- of_string_rec s 0 1
|
||
|
else
|
||
|
+ of_string s
|
||
|
|
||
|
;;
|
||
|
|
||
|
let%expect_test _ =
|
||
|
let print_mode_nl m =
|
||
|
Format.kasprintf print_string "%a\n" pp m
|
||
|
in
|
||
|
|
||
|
print_mode_nl (_O); [%expect {| O |}];
|
||
|
print_mode_nl (all [_o; _a]); [%expect {| ao |}];
|
||
|
print_mode_nl (all [_i; _w; _i]); [%expect {| iw |}];
|
||
|
print_mode_nl (all [_o; _a]); [%expect {| ao |}];
|
||
|
print_mode_nl (all [_o; _a] ^ +_w); [%expect {| awo |}];
|
||
|
print_mode_nl (all [_o; _a; _i] ^ -_o); [%expect {| ai |}];
|
||
|
|
||
|
print_mode_nl (of_string "awrO"); [%expect {| awrO |}];
|
||
|
print_mode_nl (of_string "is"); [%expect {| is |}];
|
||
|
print_mode_nl (of_bitmask_string "0"); [%expect {| |}];
|
||
|
print_mode_nl (of_bitmask_string "4"); [%expect {| w |}];
|
||
|
print_mode_nl (of_bitmask_string "8"); [%expect {| i |}];
|
||
|
print_mode_nl (of_bitmask_string "12"); [%expect {| iw |}];
|