generator: Properly lay out and indent multi-line C function decls.
authorRichard W.M. Jones <rjones@redhat.com>
Wed, 3 Nov 2010 19:26:10 +0000 (19:26 +0000)
committerRichard W.M. Jones <rjones@redhat.com>
Wed, 3 Nov 2010 19:26:10 +0000 (19:26 +0000)
generator/generator_c.ml
generator/generator_utils.ml
generator/generator_utils.mli

index c1b2e63..ca14d14 100644 (file)
@@ -35,27 +35,41 @@ type optarg_proto = Dots | VA | Argv
 (* Generate a C function prototype. *)
 let rec generate_prototype ?(extern = true) ?(static = false)
     ?(semicolon = true)
-    ?(single_line = false) ?(newline = false) ?(in_daemon = false)
+    ?(single_line = false) ?(indent = "") ?(newline = false)
+    ?(in_daemon = false)
     ?(prefix = "") ?(suffix = "")
     ?handle
     ?(optarg_proto = Dots)
     name (ret, args, optargs) =
+  pr "%s" indent;
   if extern then pr "extern ";
   if static then pr "static ";
   (match ret with
-   | RErr -> pr "int "
-   | RInt _ -> pr "int "
-   | RInt64 _ -> pr "int64_t "
-   | RBool _ -> pr "int "
-   | RConstString _ | RConstOptString _ -> pr "const char *"
-   | RString _ | RBufferOut _ -> pr "char *"
-   | RStringList _ | RHashtable _ -> pr "char **"
+   | RErr
+   | RInt _
+   | RBool _ ->
+       pr "int";
+       if single_line then pr " " else pr "\n%s" indent
+   | RInt64 _ ->
+       pr "int64_t";
+       if single_line then pr " " else pr "\n%s" indent
+   | RConstString _ | RConstOptString _ ->
+       pr "const char *";
+       if not single_line then pr "\n%s" indent
+   | RString _ | RBufferOut _ ->
+       pr "char *";
+       if not single_line then pr "\n%s" indent
+   | RStringList _ | RHashtable _ ->
+       pr "char **";
+       if not single_line then pr "\n%s" indent
    | RStruct (_, typ) ->
        if not in_daemon then pr "struct guestfs_%s *" typ
-       else pr "guestfs_int_%s *" typ
+       else pr "guestfs_int_%s *" typ;
+       if not single_line then pr "\n%s" indent
    | RStructList (_, typ) ->
        if not in_daemon then pr "struct guestfs_%s_list *" typ
-       else pr "guestfs_int_%s_list *" typ
+       else pr "guestfs_int_%s_list *" typ;
+       if not single_line then pr "\n%s" indent
   );
   let is_RBufferOut = match ret with RBufferOut _ -> true | _ -> false in
   pr "%s%s%s (" prefix name suffix;
@@ -69,7 +83,10 @@ let rec generate_prototype ?(extern = true) ?(static = false)
     );
     let next () =
       if !comma then (
-        if single_line then pr ", " else pr ",\n\t\t"
+        if single_line then pr ", "
+        else
+          pr ",\n%s%s"
+            indent (spaces (String.length prefix + String.length name + 2))
       );
       comma := true
     in
@@ -152,8 +169,7 @@ and generate_actions_pod () =
       if not (List.mem NotInDocs flags) then (
         let name = "guestfs_" ^ shortname in
         pr "=head2 %s\n\n" name;
-        pr " ";
-        generate_prototype ~extern:false ~handle:"g" name style;
+        generate_prototype ~extern:false ~indent:" " ~handle:"g" name style;
         pr "\n\n";
 
         let uc_shortname = String.uppercase shortname in
index 8511227..425a579 100644 (file)
@@ -305,3 +305,12 @@ let pod2text ~width name longdesc =
 
 (* 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
index f43a276..bbdab79 100644 (file)
@@ -99,3 +99,9 @@ val pod2text : width:int -> string -> string -> string list
 
 val action_compare : Generator_types.action -> Generator_types.action -> int
 (** Compare the names of two actions, for sorting. *)
+
+val chars : char -> int -> string
+(** [chars c n] creates a string containing character c repeated n times. *)
+
+val spaces : int -> string
+(** [spaces n] creates a string of n spaces. *)