diff options
author | Sébastien Dailly <sebastien@dailly.me> | 2025-01-22 13:43:50 +0100 |
---|---|---|
committer | Sébastien Dailly <sebastien@dailly.me> | 2025-01-23 12:24:10 +0100 |
commit | 37556ab070abcbf87a1a822c95aeccf19dade687 (patch) | |
tree | f7d7b4a3ae4e689224de177c01f4f0ecc2fd1a7c | |
parent | 8e012f4804ecf1665819e761283120a3c0e73643 (diff) |
Force the locale before printing a result
-rw-r--r-- | bin/importer.ml | 23 | ||||
-rwxr-xr-x | lib/configuration/dune | 1 | ||||
-rw-r--r-- | lib/configuration/importConf.ml | 11 | ||||
-rw-r--r-- | lib/configuration/locale.c | 12 | ||||
-rw-r--r-- | lib/csv/dataType.ml | 6 | ||||
-rw-r--r-- | lib/csv/dataType.mli | 3 | ||||
-rw-r--r-- | lib/csv/format.c | 8 | ||||
-rw-r--r-- | lib/errors/importErrors.ml | 2 | ||||
-rw-r--r-- | tests/importCSV_test.ml | 16 |
9 files changed, 42 insertions, 40 deletions
diff --git a/bin/importer.ml b/bin/importer.ml index c710aed..8549643 100644 --- a/bin/importer.ml +++ b/bin/importer.ml @@ -100,10 +100,12 @@ end Each value is given with the associated expression in the configuration, the function is expected to convert the result into string in order to include the content in the output CSV. *) -let printer : Path.t ImportExpression.T.t * ImportCSV.DataType.t -> string = - fun (column, value) -> +let printer : + string -> Path.t ImportExpression.T.t * ImportCSV.DataType.t -> string = + fun locale (column, value) -> ignore column; - ImportCSV.DataType.to_string value + (* Set the output locale accoording the configuration file *) + ImportCSV.DataType.to_string locale value let bom = "\xEF\xBB\xBF" @@ -119,6 +121,7 @@ let process_table : let source = Analyse.table mapping in (* Load all the element in the database *) let file = Filename.concat dirname source.file in + let locale = Option.value ~default:"" conf.configuration.locale in let file_date = creation_date file in let recent = @@ -134,7 +137,8 @@ let process_table : table. *) match ImportSQL.Db.query_headers db source with | Ok v -> - let text_headers = Array.map v ~f:ImportCSV.DataType.to_string in + let f = ImportCSV.DataType.to_string locale in + let text_headers = Array.map v ~f in Headers.SheeetMap.add source text_headers map | Error _ -> map) | _ -> @@ -159,7 +163,8 @@ let process_table : match headers_opt with | None -> map | Some v -> - let text_headers = Array.map v ~f:ImportCSV.DataType.to_string in + let f = ImportCSV.DataType.to_string locale in + let text_headers = Array.map v ~f in Headers.SheeetMap.add source text_headers map in headers @@ -197,7 +202,7 @@ let check_deps : exn = Failure (Printf.sprintf "Key '%s' not found" - (CSV.DataType.to_string value)); + (CSV.DataType.to_string "C" value)); } in @@ -289,9 +294,13 @@ let () = (* Run the query *) ignore @@ Db.create_view db conf.configuration; Printf.printf "Extracting results %!"; + + let locale = Option.value ~default:"" conf.configuration.locale in match Db.query db conf.configuration ~f:(fun v -> - let arr = Array.to_seq v |> Seq.map printer |> List.of_seq in + let arr = + Array.to_seq v |> Seq.map (printer locale) |> List.of_seq + in Helpers.Console.update_cursor (); Csv.output_record out_csv arr) diff --git a/lib/configuration/dune b/lib/configuration/dune index 74ace87..6a0bc61 100755 --- a/lib/configuration/dune +++ b/lib/configuration/dune @@ -16,7 +16,6 @@ ppx_deriving.show
ppx_deriving.eq
))
- (foreign_stubs (language c) (names locale))
)
(rule
diff --git a/lib/configuration/importConf.ml b/lib/configuration/importConf.ml index 2f56bd6..ebbcb7c 100644 --- a/lib/configuration/importConf.ml +++ b/lib/configuration/importConf.ml @@ -5,8 +5,6 @@ module Path = ImportDataTypes.Path module T = Read_conf module Expression = ImportExpression.T -external set_locale : string -> unit = "set_locale" - let latest_version = 1 module TomlReader = Read_conf.Make (Helpers.Toml.Decode) @@ -19,14 +17,7 @@ let t_of_toml : Otoml.t -> (Syntax.t, string) result = [ "version" ] in match version with - | n when n = latest_version -> - let conf = TomlReader.read toml in - let () = - Result.iter - (fun conf -> set_locale (Option.value ~default:"" conf.Syntax.locale)) - conf - in - conf + | n when n = latest_version -> TomlReader.read toml | _ -> Printf.eprintf "Unsuported version : %d\n" version; exit 1 diff --git a/lib/configuration/locale.c b/lib/configuration/locale.c deleted file mode 100644 index eeafd26..0000000 --- a/lib/configuration/locale.c +++ /dev/null @@ -1,12 +0,0 @@ -#include <stdio.h> -#include <locale.h> -#include <caml/memory.h> -#include <caml/alloc.h> - -CAMLprim value set_locale( value param ) -{ - const char *s; - s = String_val(param); - setlocale(LC_NUMERIC, s); - return Val_unit; -} diff --git a/lib/csv/dataType.ml b/lib/csv/dataType.ml index 1d2c7f9..6bf85ae 100644 --- a/lib/csv/dataType.ml +++ b/lib/csv/dataType.ml @@ -1,4 +1,4 @@ -external show_float : float -> string = "show_float" +external show_float : string -> float -> string = "show_float" let match_date = Re.Str.regexp {|[0-9]+/[0-9]+/[0-9]+|} @@ -9,11 +9,11 @@ type t = | Integer of int | Float of float -let to_string = function +let to_string locale = function | Null -> "" | Error s -> s | Integer i -> string_of_int i - | Float f -> show_float f + | Float f -> show_float locale f | Content c -> ( match String.starts_with ~prefix:"0" c with | false -> c diff --git a/lib/csv/dataType.mli b/lib/csv/dataType.mli index ebb8bc7..df5edf1 100644 --- a/lib/csv/dataType.mli +++ b/lib/csv/dataType.mli @@ -5,4 +5,5 @@ type t = | Integer of int | Float of float -val to_string : t -> string +val to_string : string -> t -> string +(** [to_string locale value] Format the text using the given locale *) diff --git a/lib/csv/format.c b/lib/csv/format.c index 31e4bbe..1394dc7 100644 --- a/lib/csv/format.c +++ b/lib/csv/format.c @@ -36,13 +36,17 @@ int asprintf(char *strp[], const char *fmt, ...) { return r;} #endif // asprintf -CAMLprim value show_float( value float_param ) +CAMLprim value show_float(value locale_param, value float_param ) { - CAMLparam1( float_param ); + CAMLparam2(locale_param, float_param ); CAMLlocal1( ml_data ); double f = Double_val(float_param); char* raw_data; + const char *s; + s = String_val(locale_param); + const char *saved_locale = setlocale(LC_NUMERIC, s); int data_len = asprintf(&raw_data, "%f", f); + setlocale(LC_NUMERIC, saved_locale); ml_data = caml_copy_string( raw_data ); free(raw_data); CAMLreturn( ml_data ); diff --git a/lib/errors/importErrors.ml b/lib/errors/importErrors.ml index f888725..7433e9b 100644 --- a/lib/errors/importErrors.ml +++ b/lib/errors/importErrors.ml @@ -74,7 +74,7 @@ let output_error : t -> xlsError -> unit = string_of_int error.sheet; string_of_int error.row; target; - CSV.DataType.to_string error.value; + CSV.DataType.to_string "C" error.value; repr_error error.exn; ] diff --git a/tests/importCSV_test.ml b/tests/importCSV_test.ml index fc6d545..8d83688 100644 --- a/tests/importCSV_test.ml +++ b/tests/importCSV_test.ml @@ -3,11 +3,20 @@ open Test_migration let assert_equal = Alcotest.(check int "") +let float_repr = + "float_repr" >:: fun () -> + let () = + Alcotest.(check string) + "Float repr" "3873921.620000" + ImportCSV.DataType.(to_string "C" (Float 3873921.62)) + in + () + let test_suit = [ - ("Column A" >:: fun _ -> assert_equal 1 (Csv.column_of_string "A")); - ("Column a" >:: fun _ -> assert_equal 1 (Csv.column_of_string "a")); - ( "Column name" >:: fun _ -> + ("Column A" >:: fun () -> assert_equal 1 (Csv.column_of_string "A")); + ("Column a" >:: fun () -> assert_equal 1 (Csv.column_of_string "a")); + ( "Column name" >:: fun () -> let () = for i = 1 to 1_000 do let column_name = Csv.column_to_string i in @@ -17,6 +26,7 @@ let test_suit = done in () ); + float_repr; ] let tests = "importCSV_test" >::: test_suit |