(* libguestfs
- * Copyright (C) 2009-2010 Red Hat Inc.
+ * Copyright (C) 2009-2011 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
open Generator_types
+let errcode_of_ret = function
+ | RConstOptString _ ->
+ `CannotReturnError
+ | RErr | RInt _ | RBool _ | RInt64 _ ->
+ `ErrorIsMinusOne
+ | RConstString _
+ | RString _ | RBufferOut _
+ | RStringList _ | RHashtable _
+ | RStruct _ | RStructList _ ->
+ `ErrorIsNULL
+
+let string_of_errcode = function
+ | `ErrorIsMinusOne -> "-1"
+ | `ErrorIsNULL -> "NULL"
+
(* Generate a uuidgen-compatible UUID (used in tests). However to
* avoid having the UUID change every time we rebuild the tests,
* generate it as a function of the contents of the
*)
let uuidgen () =
let s = Digest.to_hex (Digest.file "generator/generator_actions.ml") in
+
+ (* In util-linux <= 2.19, mkswap -U cannot handle the first byte of
+ * the UUID being zero, so we artificially rewrite such UUIDs.
+ * http://article.gmane.org/gmane.linux.utilities.util-linux-ng/4273
+ *)
+ if s.[0] = '0' && s.[1] = '0' then
+ s.[0] <- '1';
+
String.sub s 0 8 ^ "-"
^ String.sub s 8 4 ^ "-"
^ String.sub s 12 4 ^ "-"
in
List.iter (
- fun (_, style, _, _, _, _, _) ->
- match fst style with
+ fun (_, (ret, _, _), _, _, _, _, _) ->
+ match ret with
| RStruct (_, structname) -> update structname RStructOnly
| RStructList (_, structname) -> update structname RStructListOnly
| _ -> ()
let name_of_argt = function
| Pathname n | Device n | Dev_or_Path n | String n | OptString n
| StringList n | DeviceList n | Bool n | Int n | Int64 n
- | FileIn n | FileOut n | BufferIn n | Key n -> n
+ | FileIn n | FileOut n | BufferIn n | Key n | Pointer (_, n) -> n
let seq_of_test = function
| TestRun s | TestOutput (s, _) | TestOutputList (s, _)
| TestLastFail s -> s
let c_quote str =
+ let str = replace_str str "\\" "\\\\" in
let str = replace_str str "\r" "\\r" in
let str = replace_str str "\n" "\\n" in
let str = replace_str str "\t" "\\t" in
let str = replace_str str "\000" "\\0" in
+ let str = replace_str str "\"" "\\\"" in
str
(* Used to memoize the result of pod2text. *)
-let pod2text_memo_filename = "generator/.pod2text.data"
-let pod2text_memo : ((int * string * string), string list) Hashtbl.t =
+let pod2text_memo_filename = "generator/.pod2text.data.version.2"
+let pod2text_memo : ((int option * bool * bool * string * string), string list) Hashtbl.t =
try
let chan = open_in pod2text_memo_filename in
let v = input_value chan in
* Because this is very slow (the slowest part of autogeneration),
* we memoize the results.
*)
-let pod2text ~width name longdesc =
- let key = width, name, longdesc in
+let pod2text ?width ?(trim = true) ?(discard = true) name longdesc =
+ let key = width, trim, discard, name, longdesc in
try Hashtbl.find pod2text_memo key
with Not_found ->
let filename, chan = Filename.open_temp_file "gen" ".tmp" in
fprintf chan "=head1 %s\n\n%s\n" name longdesc;
close_out chan;
- let cmd = sprintf "pod2text -w %d %s" width (Filename.quote filename) in
+ let cmd =
+ match width with
+ | Some width ->
+ sprintf "pod2text -w %d %s" width (Filename.quote filename)
+ | None ->
+ sprintf "pod2text %s" (Filename.quote filename) in
let chan = open_process_in cmd in
let lines = ref [] in
let rec loop i =
let line = input_line chan in
- if i = 1 then (* discard the first line of output *)
+ if i = 1 && discard then (* discard the first line of output *)
loop (i+1)
else (
- let line = triml line in
+ let line = if trim then triml line else line in
lines := line :: !lines;
loop (i+1)
) in
pod2text_memo_updated ();
lines
+(* Compare two actions (for sorting). *)
+let action_compare (n1,_,_,_,_,_,_) (n2,_,_,_,_,_,_) = compare n1 n2
+
+let chars c n =
+ let str = String.create n in
+ for i = 0 to n-1 do
+ String.unsafe_set str i c
+ done;
+ str
+
+let spaces n = chars ' ' n