aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.extr5
-rw-r--r--driver/Configuration.ml125
-rw-r--r--driver/Driver.ml88
3 files changed, 122 insertions, 96 deletions
diff --git a/Makefile.extr b/Makefile.extr
index 35ae5f7b..5c9cc8dd 100644
--- a/Makefile.extr
+++ b/Makefile.extr
@@ -75,9 +75,10 @@ OCAMLLEX=ocamllex -q
MODORDER=tools/modorder .depend.extr
PARSERS=backend/CMparser.mly cparser/pre_parser.mly
-LEXERS=backend/CMlexer.mll cparser/Lexer.mll lib/Tokenize.mll
+LEXERS=backend/CMlexer.mll cparser/Lexer.mll \
+ lib/Tokenize.mll lib/Readconfig.mll
-LIBS=str.cmxa
+LIBS=str.cmxa unix.cmxa
EXECUTABLES=ccomp ccomp.byte cchecklink cchecklink.byte clightgen clightgen.byte
GENERATED=$(PARSERS:.mly=.mli) $(PARSERS:.mly=.ml) $(LEXERS:.mll=.ml)
diff --git a/driver/Configuration.ml b/driver/Configuration.ml
index e73125f7..0012dc0c 100644
--- a/driver/Configuration.ml
+++ b/driver/Configuration.ml
@@ -10,86 +10,87 @@
(* *)
(* *********************************************************************)
+open Printf
-let config_vars: (string, string) Hashtbl.t = Hashtbl.create 10
+(* Locate the .ini file, which is either in the same directory as
+ the executable or in the directory ../share *)
+let ini_file_name =
+ try
+ Sys.getenv "COMPCERT_CONFIG"
+ with Not_found ->
+ let exe_dir = Filename.dirname Sys.executable_name in
+ let exe_ini = Filename.concat exe_dir "compcert.ini" in
+ let share_dir =
+ Filename.concat (Filename.concat exe_dir Filename.parent_dir_name)
+ "share" in
+ let share_ini = Filename.concat share_dir "compcert.ini" in
+ if Sys.file_exists exe_ini then exe_ini
+ else if Sys.file_exists share_ini then share_ini
+ else begin
+ eprintf "Cannot find compcert.ini configuration file.\n";
+ exit 2
+ end
+
+(* Read in the .ini file *)
-(* Read in the .ini file, which is either in the same directory or in the directory ../share *)
let _ =
try
- let file =
- try
- let env_file = Sys.getenv "COMPCERT_CONFIG" in
- open_in env_file
- with Not_found ->
- let dir = Sys.getcwd ()
- and name = Sys.executable_name in
- let dirname = if Filename.is_relative name then
- Filename.dirname (Filename.concat dir name)
- else
- Filename.dirname name
- in
- let share_dir = Filename.concat (Filename.concat dirname Filename.parent_dir_name) "share" in
- try
- open_in (Filename.concat dirname "compcert.ini")
- with Sys_error _ ->
- open_in (Filename.concat share_dir "compcert.ini")
- in
- (try
- let ini_line = Str.regexp "\\([^=]+\\)=\\(.+\\)" in
- while true do
- let line = input_line file in
- if Str.string_match ini_line line 0 then
- let key = Str.matched_group 1 line
- and value = Str.matched_group 2 line in
- Hashtbl.add config_vars key value
- else
- Printf.eprintf "Wrong value %s in .ini file.\n" line
- done
- with End_of_file -> close_in file)
- with Sys_error msg -> Printf.eprintf "Unable to open .ini file\n"
+ Readconfig.read_config_file ini_file_name
+ with
+ | Readconfig.Error(file, lineno, msg) ->
+ eprintf "Error reading configuration file %s.\n" ini_file_name;
+ eprintf "%s:%d:%s\n" file lineno msg;
+ exit 2
+ | Sys_error msg ->
+ eprintf "Error reading configuration file %s.\n" ini_file_name;
+ eprintf "%s\n" msg;
+ exit 2
let get_config key =
- try
- Hashtbl.find config_vars key
- with Not_found ->
- Printf.eprintf "Configuration option `%s' is not set\n" key; exit 2
+ match Readconfig.key_val key with
+ | Some v -> v
+ | None -> eprintf "Configuration option `%s' is not set\n" key; exit 2
-let bad_config key v =
- Printf.eprintf "Invalid value `%s' for configuation option `%s'\n" v key; exit 2
+let bad_config key vl =
+ eprintf "Invalid value `%s' for configuration option `%s'\n"
+ (String.concat " " vl) key;
+ exit 2
-let prepro = get_config "prepro"
-let asm = get_config "asm"
-let linker = get_config "linker"
-let arch =
- let v = get_config "arch" in
- (match v with
- | "powerpc"
- | "arm"
- | "ia32" -> ()
- | _ -> bad_config "arch" v);
- v
+let get_config_string key =
+ match get_config key with
+ | [v] -> v
+ | vl -> bad_config key vl
-let model = get_config "model"
-let abi = get_config "abi"
-let system = get_config "system"
+let get_config_list key =
+ match get_config key with
+ | [] -> bad_config key []
+ | vl -> vl
+
+let prepro = get_config_list "prepro"
+let asm = get_config_list "asm"
+let linker = get_config_list "linker"
+let arch =
+ match get_config_string "arch" with
+ | "powerpc"|"arm"|"ia32" as a -> a
+ | v -> bad_config "arch" [v]
+let model = get_config_string "model"
+let abi = get_config_string "abi"
+let system = get_config_string "system"
let has_runtime_lib =
- match get_config "has_runtime_lib" with
+ match get_config_string "has_runtime_lib" with
| "true" -> true
| "false" -> false
- | v -> bad_config "has_runtime_lib" v
-
-
+ | v -> bad_config "has_runtime_lib" [v]
let stdlib_path =
if has_runtime_lib then
- get_config "stdlib_path"
+ get_config_string "stdlib_path"
else
""
-
let asm_supports_cfi =
- match get_config "asm_supports_cfi" with
+ match get_config_string "asm_supports_cfi" with
| "true" -> true
| "false" -> false
- | v -> bad_config "asm_supports_cfi" v
+ | v -> bad_config "asm_supports_cfi" [v]
-let version = get_config "version"
+let version = get_config_string "version"
diff --git a/driver/Driver.ml b/driver/Driver.ml
index fec87420..14ce11f4 100644
--- a/driver/Driver.ml
+++ b/driver/Driver.ml
@@ -20,17 +20,38 @@ open Timing
let stdlib_path = ref Configuration.stdlib_path
-let command cmd =
+(* Invocation of external tools *)
+
+let command ?stdout args =
if !option_v then begin
- prerr_string "+ "; prerr_string cmd; prerr_endline ""
+ eprintf "+ %s" (String.concat " " args);
+ begin match stdout with
+ | None -> ()
+ | Some f -> eprintf " > %s" f
+ end;
+ prerr_endline ""
end;
- Sys.command cmd
-
-let quote_options opts =
- String.concat " " (List.rev_map Filename.quote opts)
-
-let quote_arguments args =
- String.concat " " (List.map Filename.quote args)
+ let argv = Array.of_list args in
+ assert (Array.length argv > 0);
+ try
+ let fd_out =
+ match stdout with
+ | None -> Unix.stdout
+ | Some f ->
+ Unix.openfile f [Unix.O_WRONLY; Unix.O_CREAT; Unix.O_TRUNC] 0o666 in
+ let pid =
+ Unix.create_process argv.(0) argv Unix.stdin fd_out Unix.stderr in
+ let (_, status) =
+ Unix.waitpid [] pid in
+ if stdout <> None then Unix.close fd_out;
+ match status with
+ | Unix.WEXITED rc -> rc
+ | Unix.WSIGNALED n | Unix.WSTOPPED n ->
+ eprintf "Command '%s' killed on a signal.\n" argv.(0); -1
+ with Unix.Unix_error(err, fn, param) ->
+ eprintf "Error executing '%s': %s: %s %s\n"
+ argv.(0) fn (Unix.error_message err) param;
+ -1
let safe_remove file =
try Sys.remove file with Sys_error _ -> ()
@@ -68,16 +89,17 @@ let output_filename_default default_file =
let preprocess ifile ofile =
let output =
- if ofile = "-" then "" else sprintf "> %s" ofile in
- let cmd =
- sprintf "%s -D__COMPCERT__ %s %s %s %s"
- Configuration.prepro
- (if Configuration.has_runtime_lib
- then sprintf "-I%s" !stdlib_path
- else "")
- (quote_options !prepro_options)
- ifile output in
- if command cmd <> 0 then begin
+ if ofile = "-" then None else Some ofile in
+ let cmd = List.concat [
+ Configuration.prepro;
+ ["-D__COMPCERT__"];
+ (if Configuration.has_runtime_lib
+ then ["-I" ^ !stdlib_path]
+ else []);
+ List.rev !prepro_options;
+ [ifile]
+ ] in
+ if command ?stdout:output cmd <> 0 then begin
if ofile <> "-" then safe_remove ofile;
eprintf "Error during preprocessing.\n";
exit 2
@@ -208,11 +230,13 @@ let compile_cminor_file ifile ofile =
(* From asm to object file *)
let assemble ifile ofile =
- let cmd =
- sprintf "%s -o %s %s %s"
- Configuration.asm ofile (quote_options !assembler_options) ifile in
- let retcode = command cmd in
- if retcode <> 0 then begin
+ let cmd = List.concat [
+ Configuration.asm;
+ ["-o"; ofile];
+ List.rev !assembler_options;
+ [ifile]
+ ] in
+ if command cmd <> 0 then begin
safe_remove ofile;
eprintf "Error during assembling.\n";
exit 2
@@ -221,14 +245,14 @@ let assemble ifile ofile =
(* Linking *)
let linker exe_name files =
- let cmd =
- sprintf "%s -o %s %s %s"
- Configuration.linker
- (Filename.quote exe_name)
- (quote_arguments files)
- (if Configuration.has_runtime_lib
- then sprintf "-L%s -lcompcert" !stdlib_path
- else "") in
+ let cmd = List.concat [
+ Configuration.linker;
+ ["-o"; exe_name];
+ files;
+ (if Configuration.has_runtime_lib
+ then ["-L" ^ !stdlib_path; "-lcompcert"]
+ else [])
+ ] in
if command cmd <> 0 then exit 2
(* Processing of a .c file *)