aboutsummaryrefslogtreecommitdiff
path: root/bin/main.ml
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-21 12:09:35 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-21 12:09:35 +0200
commitaaf3dc5ba55d46b6b318bb761305013f4c533b26 (patch)
tree7b60e382a93a496330c8c925494a261ec42591d1 /bin/main.ml
parent83cc11e31c08d14fd3449f95872f346a4daaf2b8 (diff)
downloadcolitur-aaf3dc5ba55d46b6b318bb761305013f4c533b26.tar.gz
colitur-aaf3dc5ba55d46b6b318bb761305013f4c533b26.zip
fix(cli): diagnose an INI overlay passed to --overlay
The INI overlay form is a SOURCE format that 'colitur convert' turns into the S-expression one. Handing the INI to --overlay instead failed deep in the sexp reader with 'more than one S-expression in file', which names neither the cause nor the cure -- and the shipped examples under data/ef/examples/ are exactly the files someone would try that with. The detector reads past the comment header to the first real line and looks for a [section]. Its first version capped that scan at 40 lines and poland.ini's own header is 43, so it silently never fired on the very file it was written for; the cap now bounds only how much of a binary gets read, and is not a guess at header length.
Diffstat (limited to 'bin/main.ml')
-rw-r--r--bin/main.ml34
1 files changed, 34 insertions, 0 deletions
diff --git a/bin/main.ml b/bin/main.ml
index 51c4989..c915255 100644
--- a/bin/main.ml
+++ b/bin/main.ml
@@ -169,8 +169,42 @@ let load_ef_layer ?(user_overlays = []) () =
let dir = data_dir () in
let sanctoral_path = Filename.concat dir "sanctoral.sexp" in
let adjustments_path = Filename.concat dir "adjustments.sexp" in
+ (* An overlay handed to --overlay must be the S-expression form. The INI
+ form is real but is a SOURCE format: `colitur convert` turns it into one.
+ Feeding the INI here otherwise fails deep inside the sexp reader with
+ "more than one S-expression in file", which names neither the cause nor
+ the cure. Detect it and say both. *)
+ let looks_like_ini path =
+ match open_in path with
+ | exception _ -> false
+ | ic ->
+ (* Skip the comment header and stop at the first real line. The cap
+ only bounds how much of a binary file gets read; it is NOT a guess
+ at how long a header may be. The first version capped at 40 and
+ poland.ini's own header is 43 lines, so the detection silently
+ never fired on the very file it was written for. *)
+ let rec scan n =
+ if n > 2000 then false
+ else
+ match input_line ic with
+ | exception End_of_file -> false
+ | line ->
+ let l = String.trim line in
+ if l = "" || l.[0] = ';' || l.[0] = '#' then scan (n + 1)
+ else String.length l > 1 && l.[0] = '[' && l.[String.length l - 1] = ']'
+ in
+ let r = scan 0 in
+ close_in_noerr ic;
+ r
+ in
let load_overlay path =
match Colitur_kernel.Overlay.load Rite_ef.Vocab_ef.rank_of_sexp path with
+ | Error _ when looks_like_ini path ->
+ Error
+ (Printf.sprintf
+ "%s looks like an INI overlay, not an S-expression one.\n\
+ colitur: convert it first: colitur convert %s > overlay.sexp"
+ path path)
| Error e -> Error (Printf.sprintf "failed to load %s: %s" path e)
| Ok o -> Ok o
in