diff --git a/doc/index.mld b/doc/index.mld index 7dd3b4f..b369d5a 100644 --- a/doc/index.mld +++ b/doc/index.mld @@ -8,6 +8,7 @@ {!modules: Scfg.Parse Scfg.Pp +Scfg.Query Scfg.Types } diff --git a/src/dune b/src/dune index 1ec348c..5bb9026 100644 --- a/src/dune +++ b/src/dune @@ -1,6 +1,6 @@ (library (public_name scfg) - (modules lexer menhir_parser parse pp types) + (modules lexer menhir_parser parse pp query types) (private_modules lexer menhir_parser) (preprocess (pps sedlex.ppx)) diff --git a/src/query.ml b/src/query.ml new file mode 100644 index 0000000..08d4b19 --- /dev/null +++ b/src/query.ml @@ -0,0 +1,31 @@ +(** Module providing functions to search inside a config. *) + +open Types + +(** Returns a list of directives with the provided name from a list of + directives. *) +let get_dirs name directives = + List.filter (fun directive -> directive.name = name) directives + +(** Returns the first directive with the provided name from a list of directive. *) +let get_dir name directives = + List.find_opt (fun directive -> directive.name = name) directives + +(** Extract a given number of parameters from a directive. *) +let get_params n directive = + let len = List.length directive.params in + if len < n then + Error + (Format.asprintf "directive %a: want %d params, got only %d" Pp.param + directive.name n len ) + else Ok (List.filteri (fun i _param -> i < n) directive.params) + +(** Extract a parameter at a given index from a directive. *) +let get_param n directive = + let params = directive.params in + match List.nth_opt params n with + | None -> + Error + (Format.asprintf "directive %a: want param at index %d, got only %d" + Pp.param directive.name n (List.length params) ) + | Some param -> Ok param diff --git a/test/dune b/test/dune index 863abe8..dc8d46b 100644 --- a/test/dune +++ b/test/dune @@ -5,6 +5,7 @@ (deps lex_error.scfg (glob_files parse_error*.scfg) + query.scfg test.scfg test.expected test_chan.scfg)) diff --git a/test/main.ml b/test/main.ml index 7e1fd74..8b9f566 100644 --- a/test/main.ml +++ b/test/main.ml @@ -1,5 +1,6 @@ open Scfg +(** Testing parsing and printing. *) let () = (* Parsing and printing the test *) let config = @@ -39,12 +40,14 @@ let () = assert (s = s_expected) +(** Testing lexing errors. *) let () = match Parse.from_file "lex_error.scfg" with | Error "lexer error" -> () | Error _e -> assert false | Ok _config -> assert false +(** Testing parsing errors. *) let () = for i = 1 to 4 do let file_name = Format.sprintf "parse_error%d.scfg" i in @@ -54,6 +57,7 @@ let () = | Ok _config -> assert false done +(** Testing other functions in Parse module. *) let () = let chan = open_in "test_chan.scfg" in match Parse.from_channel chan with @@ -62,3 +66,42 @@ let () = let expected = "a b c" in let s = Format.asprintf "%a" Pp.config config in assert (s = expected) + +(** Testing queries. *) +let () = + let config = + match Parse.from_file "query.scfg" with + | Error _e -> assert false + | Ok config -> config + in + assert (List.length config = 5); + let n1 = Query.get_dirs "n1" config in + assert (List.length n1 = 2); + let n11 = Query.get_dir "n1" n1 in + let n11 = match n11 with None -> assert false | Some n11 -> n11 in + let n12 = + match Query.get_dir "n1.2" n11.children with + | None -> assert false + | Some n12 -> n12 + in + let pn12 = + match Query.get_params 2 n12 with + | Error _e -> assert false + | Ok pn12 -> pn12 + in + assert (pn12 = [ "p1"; "p2" ]); + begin + match Query.get_params 3 n12 with + | Error "directive n1.2: want 3 params, got only 2" -> () + | Error _ | Ok _ -> assert false + end; + begin + match Query.get_param 0 n12 with + | Error _ -> assert false + | Ok p -> assert (p = "p1") + end; + match Query.get_param 5 n12 with + | Error "directive n1.2: want param at index 5, got only 2" -> () + | Error _ | Ok _ -> assert false + +let () = Format.printf "all tests OK! 🐱" diff --git a/test/query.scfg b/test/query.scfg new file mode 100644 index 0000000..8701c7b --- /dev/null +++ b/test/query.scfg @@ -0,0 +1,11 @@ +n1 p1 p2 { + n1.2 p1 p2 + n1.3 p1 p2 +} +n1 p3 p4 { + n1.2 p3 p4 + n1.3 p3 p4 +} +a b c +a c d +gggggggggggggggg g g g