X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=generator%2Fgenerator_utils.ml;h=4180c0d634a203dfa1e9f35239b220dbe55e0367;hb=319e946b92e175c05cdd1fdcb85c9b86f5631011;hp=cede5c67349f17410f8735383871d7cf57b80adf;hpb=04d8209077d2227eb1d42695ba71147f78987050;p=libguestfs.git diff --git a/generator/generator_utils.ml b/generator/generator_utils.ml index cede5c6..4180c0d 100644 --- a/generator/generator_utils.ml +++ b/generator/generator_utils.ml @@ -1,5 +1,5 @@ (* 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 @@ -28,18 +28,46 @@ open Printf open Generator_types -(* Generate a random UUID (used in tests). *) +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 + * generator_actions.ml file. + * + * Originally I thought uuidgen was using RFC 4122, but it doesn't + * appear to. + * + * Note that the format must be 01234567-0123-0123-0123-0123456789ab + *) let uuidgen () = - let chan = open_process_in "uuidgen" in - let uuid = input_line chan in - (match close_process_in chan with - | WEXITED 0 -> () - | WEXITED _ -> - failwith "uuidgen: process exited with non-zero status" - | WSIGNALED _ | WSTOPPED _ -> - failwith "uuidgen: process signalled or stopped by signal" - ); - uuid + 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 ^ "-" + ^ String.sub s 16 4 ^ "-" + ^ String.sub s 20 12 type rstructs_used_t = RStructOnly | RStructListOnly | RStructAndList @@ -78,8 +106,8 @@ let rstructs_used_by functions = in List.iter ( - fun (_, style, _, _, _, _, _) -> - match fst style with + fun (_, (ret, _, _), _, _, _, _, _) -> + match ret with | RStruct (_, structname) -> update structname RStructOnly | RStructList (_, structname) -> update structname RStructListOnly | _ -> () @@ -225,7 +253,7 @@ let map_chars f str = 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, _) @@ -234,18 +262,22 @@ let seq_of_test = function | TestOutputTrue s | TestOutputFalse s | TestOutputLength (s, _) | TestOutputBuffer (s, _) | TestOutputStruct (s, _) + | TestOutputFileMD5 (s, _) + | TestOutputDevice (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 @@ -264,22 +296,27 @@ let pod2text_memo_updated () = * 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 @@ -296,3 +333,14 @@ let pod2text ~width name longdesc = 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