let read_all_lines file_name = let in_channel = open_in file_name in let rec read_recursive lines = try Scanf.fscanf in_channel "%[^\r\n]\n" (fun x -> read_recursive (x :: lines)) with End_of_file -> lines in let lines = read_recursive [] in let _ = close_in_noerr in_channel in List.rev (lines) type lineresult = Ok of (string * string * string) | No of string | Skip let read_line_content (lst: string list) : lineresult = match lst with | [] -> Skip | domain::ip::cidr::[] -> Ok (domain, ip, cidr) | _ -> No (String.concat " " lst) let parse_config_file (fname: string) : lineresult list = let content = read_all_lines fname in let remove_comments (str:string) : string = match String.index_opt str '#' with | None -> str | Some n -> String.sub str 0 n in let parse_line line = line |> remove_comments |> String.split_on_char ' ' |> List.filter (fun s -> not (List.mem s ["\t"; ""; "\n"])) |> (* strip spaces *) read_line_content in content |> List.map parse_line