221 lines
7.1 KiB
OCaml
Executable File
221 lines
7.1 KiB
OCaml
Executable File
#!/usr/bin/ocamlrun /usr/bin/ocaml
|
|
|
|
(* Command line arguments parsing *)
|
|
let basedir = ref "debian/arch"
|
|
let sourcedir = ref "."
|
|
let arch = ref ""
|
|
let subarch = ref ""
|
|
let flavour = ref ""
|
|
let config_name = ref ""
|
|
let verbose = ref false
|
|
let archindir = ref false
|
|
|
|
type action = Single | Create | Check
|
|
let action = ref Create
|
|
|
|
let set_action a () = action := a
|
|
|
|
let spec = [
|
|
"-b", Arg.Set_string basedir, "base dir of the arch configurations [default: debian/arch]";
|
|
"-bs", Arg.Set_string sourcedir, "base source dir containing the patched debian linux source tree [default: .]";
|
|
"-ba", Arg.Set archindir, "basedir includes arch";
|
|
"-a", Arg.Set_string arch, "arch";
|
|
"-s", Arg.Set_string subarch, "subarch";
|
|
"-f", Arg.Set_string flavour, "flavour";
|
|
"-v", Arg.Set verbose, "verbose";
|
|
"-c", Arg.Unit (set_action Check), "check";
|
|
]
|
|
let usage =
|
|
"Check single config file : ./kconfig.ml config_file\n" ^
|
|
"Create config file : ./kconfig.ml [ -ba ] [ -b basedir ] -a arch [ -s subarch ] -f flavour" ^ "\n" ^
|
|
"Check all config files : ./kconfig.ml -c [ -ba ] [ -b basedir ] [ -bs sourcedir ] [ -a arch ] [ -s subarch ] [ -f flavour ]" ^ "\n"
|
|
|
|
let () = Arg.parse
|
|
spec
|
|
(function s -> config_name := s; action := Single)
|
|
usage
|
|
|
|
let usage () = Arg.usage spec usage
|
|
|
|
(* Config file parsing *)
|
|
type options =
|
|
| Config_Yes of string
|
|
| Config_No of string
|
|
| Config_Module of string
|
|
| Config_Value of string * string
|
|
| Config_Comment of string
|
|
| Config_Empty
|
|
|
|
let print_option = function
|
|
| Config_Yes s -> Printf.printf "CONFIG_%s=y\n" s
|
|
| Config_No s -> Printf.printf "# CONFIG_%s is not set\n" s
|
|
| Config_Module s -> Printf.printf "CONFIG_%s=m\n" s
|
|
| Config_Value (s,v) -> Printf.printf "CONFIG_%s=%s\n" s v
|
|
| Config_Comment s -> Printf.printf "#%s\n" s
|
|
| Config_Empty -> Printf.printf "\n"
|
|
|
|
exception Comment
|
|
exception Error
|
|
|
|
let parse_config_line fd =
|
|
let line = input_line fd in
|
|
let len = String.length line in
|
|
if len = 0 then Config_Empty else
|
|
try
|
|
if len <= 9 then raise Comment else
|
|
match line.[0], line.[1], line.[2], line.[3], line.[4], line.[5], line.[6], line.[7], line.[8] with
|
|
| '#', ' ', 'C', 'O', 'N', 'F', 'I', 'G', '_' ->
|
|
begin
|
|
try
|
|
let space = String.index_from line 8 ' ' in
|
|
if String.sub line (space + 1) 10 = "is not set" then
|
|
let o = String.sub line 9 (space - 9) in
|
|
Config_No o
|
|
else raise Comment
|
|
with Not_found | Invalid_argument "String.sub" -> raise Comment
|
|
end
|
|
| '#', _, _, _, _, _, _, _, _ -> raise Comment
|
|
| 'C', 'O', 'N', 'F', 'I', 'G', _, _, _ ->
|
|
begin
|
|
try
|
|
let equal = String.index_from line 6 '=' in
|
|
let o = String.sub line 7 (equal - 7) in
|
|
let v = String.sub line (equal + 1) (len - equal - 1) in
|
|
match v with
|
|
| "y" -> Config_Yes o
|
|
| "m" -> Config_Module o
|
|
| _ -> Config_Value (o,v)
|
|
with Not_found | Invalid_argument "String.sub" -> raise Comment
|
|
end
|
|
| _ -> raise Comment
|
|
with Comment -> Config_Comment (String.sub line 1 (len - 1))
|
|
|
|
module C = Map.Make (String)
|
|
|
|
(* Map.add behavior ensures the latest entry is the one staying *)
|
|
let rec parse_config fd m =
|
|
try
|
|
let line = parse_config_line fd in
|
|
match line with
|
|
| Config_Comment _ | Config_Empty -> parse_config fd m
|
|
| Config_Yes s | Config_No s | Config_Module s | Config_Value (s,_) ->
|
|
parse_config fd (C.add s line m)
|
|
with End_of_file -> m
|
|
|
|
let print_config m = C.iter (function _ -> print_option) m
|
|
|
|
let parse_config_file name m force =
|
|
try
|
|
let config = open_in name in
|
|
let m = parse_config config m in
|
|
close_in config;
|
|
m
|
|
with Sys_error s ->
|
|
if force then raise (Sys_error s) else m
|
|
|
|
(* Defines parsing *)
|
|
type define =
|
|
| Defines_Base of string
|
|
| Defines_Field of string * string
|
|
| Defines_List of string
|
|
| Defines_Comment of string
|
|
| Defines_Error of string
|
|
| Defines_Empty
|
|
|
|
let print_define = function
|
|
| Defines_Base s -> Printf.printf "[%s]\n" s
|
|
| Defines_Field (n, v) -> Printf.printf "%s:%s\n" n v
|
|
| Defines_List s -> Printf.printf " %s\n" s
|
|
| Defines_Comment s -> Printf.printf "#%s\n" s
|
|
| Defines_Error s -> Printf.printf "*** ERROR *** %s\n" s
|
|
| Defines_Empty -> Printf.printf "\n"
|
|
|
|
let parse_define_line fd =
|
|
let line = input_line fd in
|
|
let len = String.length line in
|
|
if len = 0 then begin Defines_Empty end else
|
|
try
|
|
match line.[0] with
|
|
| '#' -> Defines_Comment (String.sub line 1 (len - 1))
|
|
| '[' -> begin
|
|
try
|
|
let c = String.index_from line 1 ']' in
|
|
Defines_Base (String.sub line 1 (c - 1))
|
|
with Not_found | Invalid_argument "String.sub" -> raise Error
|
|
end
|
|
| ' ' -> Defines_List (String.sub line 1 (len - 1))
|
|
| _ -> begin
|
|
try
|
|
let c = String.index_from line 1 ':' in
|
|
Defines_Field (String.sub line 0 c, String.sub line (c + 1) (len - c - 1))
|
|
with Not_found | Invalid_argument "String.sub" -> raise Error
|
|
end
|
|
with Error -> Defines_Error line
|
|
|
|
let rec parse_defines fd m l =
|
|
try
|
|
let line = parse_define_line fd in
|
|
match line with
|
|
| Defines_Comment _ | Defines_Empty -> parse_defines fd (line::m) (l+1)
|
|
| Defines_Error error ->
|
|
Printf.eprintf "*** Error at line %d : %s\n" l error;
|
|
parse_defines fd m (l+1)
|
|
| Defines_Base _ | Defines_Field _ | Defines_List _ -> parse_defines fd (line::m) (l+1)
|
|
with End_of_file -> List.rev m
|
|
|
|
let parse_defines_file name m force =
|
|
try
|
|
let defines = open_in name in
|
|
let m = parse_defines defines m 0 in
|
|
close_in defines;
|
|
m
|
|
with Sys_error s ->
|
|
if force then raise (Sys_error s) else m
|
|
|
|
let print_defines m = List.iter print_define m
|
|
|
|
(* Main functionality *)
|
|
let get_archdir () = if !archindir then Filename.dirname !basedir else !basedir
|
|
|
|
let do_single () =
|
|
try
|
|
begin if !verbose then Printf.eprintf "Reading config file %s" !config_name end;
|
|
let config = open_in !config_name in
|
|
let m = parse_config config C.empty in
|
|
print_config m;
|
|
close_in config
|
|
with Sys_error s -> Printf.eprintf "Error: %s\n" s
|
|
|
|
let do_create () =
|
|
if !arch <> "" && !flavour <> "" then begin
|
|
if !verbose then
|
|
Printf.eprintf "Creating config file for arch %s, subarch %s, flavour %s (basedir is %s)\n" !arch !subarch !flavour !basedir;
|
|
let dir = get_archdir () in
|
|
let m = parse_config_file (dir ^ "/config") C.empty false in
|
|
let archdir = dir ^ "/" ^ !arch in
|
|
let m = parse_config_file (archdir ^ "/config") m false in
|
|
let m, archdir =
|
|
if !subarch <> "" && !subarch <> "none" then
|
|
let archdir = archdir ^ "/" ^ !subarch in
|
|
parse_config_file (archdir ^ "/config") m false, archdir
|
|
else m, archdir
|
|
in
|
|
let m = parse_config_file (archdir ^ "/config." ^ !flavour) m true in
|
|
print_config m
|
|
end
|
|
else
|
|
usage ()
|
|
|
|
let do_check () =
|
|
let dir = get_archdir () in
|
|
begin if !verbose then Printf.eprintf "Checking config files in %s\n" dir end;
|
|
let m = parse_defines_file (dir ^ "/defines") [] true in
|
|
print_defines m
|
|
|
|
let () = try
|
|
match !action with
|
|
| Single -> do_single ()
|
|
| Create -> do_create ()
|
|
| Check -> do_check ()
|
|
with Sys_error s -> Printf.eprintf "Error: %s\n" s; usage ()
|