let file_parse conf fn =
  let parse lineno line =
    let origin =
      Printf.sprintf
        "File \"%s\", line %d."
        fn lineno
    in
    match trim (trim_comment line) with
      | "" ->
          ()
      | str ->
          begin
            let name, value =
              try
                Scanf.sscanf str "%s = %S" (fun name value -> name, value)
              with Scanf.Scan_failure _ ->
                begin
                  try
                    Scanf.sscanf str "%s = %s" (fun name value -> name, value)
                  with Scanf.Scan_failure _ ->
                    failwithf "Unparseable line: %s\n%s" line origin
                end
            in
              set ~origin conf name value
          end
  in
  let chn = open_in fn in
  let lineno = ref 0 in
    try
      while true do
        let line = input_line chn in
          incr lineno;
          parse !lineno line
      done;
      ()
    with
      | End_of_file ->
          close_in chn
      | e ->
          close_in chn;
          raise e