aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSébastien Dailly <sebastien@dailly.me>2025-01-22 13:43:50 +0100
committerSébastien Dailly <sebastien@dailly.me>2025-01-23 12:24:10 +0100
commit37556ab070abcbf87a1a822c95aeccf19dade687 (patch)
treef7d7b4a3ae4e689224de177c01f4f0ecc2fd1a7c
parent8e012f4804ecf1665819e761283120a3c0e73643 (diff)
Force the locale before printing a result
-rw-r--r--bin/importer.ml23
-rwxr-xr-xlib/configuration/dune1
-rw-r--r--lib/configuration/importConf.ml11
-rw-r--r--lib/configuration/locale.c12
-rw-r--r--lib/csv/dataType.ml6
-rw-r--r--lib/csv/dataType.mli3
-rw-r--r--lib/csv/format.c8
-rw-r--r--lib/errors/importErrors.ml2
-rw-r--r--tests/importCSV_test.ml16
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