Add the "pr_wrap_cstr" function, for wrapping C string literals. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2172516 Signed-off-by: Laszlo Ersek <ler...@redhat.com> --- generator/utils.mli | 1 + generator/utils.ml | 54 ++++++++++++++++++++ 2 files changed, 55 insertions(+)
diff --git a/generator/utils.mli b/generator/utils.mli index 5bbb188fe934..9d6640c87842 100644 --- a/generator/utils.mli +++ b/generator/utils.mli @@ -53,6 +53,7 @@ val val output_to : string -> (unit -> 'a) -> unit val pr : ('a, unit, string, unit) format4 -> 'a val pr_wrap : ?maxcol:int -> char -> (unit -> 'a) -> unit +val pr_wrap_cstr : ?maxcol:int -> (unit -> 'a) -> unit val output_lineno : unit -> int val output_column : unit -> int diff --git a/generator/utils.ml b/generator/utils.ml index 919572b73557..ff1e8a72f7aa 100644 --- a/generator/utils.ml +++ b/generator/utils.ml @@ -213,6 +213,60 @@ let *) pr "%s" (String.concat "\n" rest) +(* Wrap the C string literal output at ‘maxcol’, breaking up lines when a space + * character occurs. For example: + * foobar = "a b c d e f g h i j k" + * └── pr_wrap_cstr ───┘ + * becomes: + * foobar = "a b c d " + * "e f g h " + * "i j k" + * + * Note that: + * - ‘code’ MUST NOT produce the surrounding quotes, + * - ‘code’ MUST NOT produce multiple lines, + * - ‘code’ MUST do its own quoting, + * - space characters produced by ‘code’ cannot be escaped from wrapping. + *) +let pr_wrap_cstr ?(maxcol = 76) code = + (* Just before entering ‘pr_wrap_cstr’, a leading quote must have been + * produced. + *) + let wrapping_col = !col - 1 in + assert (wrapping_col >= 0); + + let b = pr_buf code in + let lines = nsplit "\n" (Buffer.contents b) in + match lines with + | [] -> () + | line :: [] -> + let fields = nsplit " " line in + let nfields = List.length fields in + let indent = spaces wrapping_col in + List.iteri + (fun i field -> + (* Append a space character to each field except the last. *) + let f = if i < nfields - 1 then field ^ " " else field in + + (* Terminate the string literal, insert a line break, and start a + * properly indented new string literal, before printing the field, if + * (a) the field is not the first one in this string literal, and (b) + * printing the field plus a literal-terminating quote would not fit + * in ‘maxcol’. + * + * Note that this way, the literal-terminating quote will always fit + * in ‘maxcol’, except when the *sole* field in the literal is too + * long. + *) + if !col > wrapping_col + 1 && + !col + (String.length f) + 1 > maxcol then + pr "\"\n%s\"" indent; + + (* Print the field. *) + pr "%s" f + ) fields + | _ -> assert false + let output_lineno () = !lineno let output_column () = !col _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://listman.redhat.com/mailman/listinfo/libguestfs