Richard W.M. Jones
2021-Dec-03 19:02 UTC
[Libguestfs] [PATCH libnbd 0/3] generator: Reset line directive after included code in lib/states.c
This restores the #line directives (probably?) The output looks right, but I didn't test it beyond opening it in the editor. Do #line directives have a way to indicate "current file"? Rich.
Richard W.M. Jones
2021-Dec-03 19:02 UTC
[Libguestfs] [PATCH libnbd 1/3] generator: Move location code from State_machine to Utils
Move the type [location] and the values [noloc], [string_of_location] and [line_directive_of_location] to [Utils]. Straightforward code motion, no change in functionality. --- generator/state_machine.ml | 12 +++--------- generator/state_machine.mli | 7 +------ generator/utils.ml | 7 +++++++ generator/utils.mli | 6 ++++++ 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/generator/state_machine.ml b/generator/state_machine.ml index d3edef4c9..3bc77f242 100644 --- a/generator/state_machine.ml +++ b/generator/state_machine.ml @@ -48,9 +48,6 @@ let string_of_external_event = function | CmdConnectSocket -> "CmdConnectSocket" | CmdIssue -> "CmdIssue" -type location = string * int -let noloc = ("", 0) - type state = { name : string; comment : string; @@ -61,7 +58,7 @@ and parsed_state = { prefix : string list; display_name : string; state_enum : string; - loc : location; + loc : Utils.location; code : string; internal_transitions : state list; events : (external_event * state) list; @@ -69,7 +66,8 @@ and parsed_state = { let default_state = { name = ""; comment = ""; external_events = []; parsed = { prefix = []; display_name = ""; - state_enum = ""; loc = noloc; code = ""; + state_enum = ""; loc = Utils.noloc; + code = ""; internal_transitions = []; events = [] } } type state_machine = state_group list @@ -878,7 +876,3 @@ and structured_reply_state_machine = [ external_events = []; }; ] - -let string_of_location (file, lineno) = sprintf "%s:%d" file lineno -let line_directive_of_location (file, lineno) - sprintf "#line %d \"%s\"" lineno file diff --git a/generator/state_machine.mli b/generator/state_machine.mli index 4e387e3ea..020225f84 100644 --- a/generator/state_machine.mli +++ b/generator/state_machine.mli @@ -80,11 +80,6 @@ type external_event val all_external_events : external_event list val string_of_external_event : external_event -> string -type location = string * int (** source location: file, line number *) -val noloc : location -val string_of_location : location -> string -val line_directive_of_location : location -> string - type state = { (** The state name (without prefix). If this has the special name "START" then it is the start state of the current group. Each @@ -117,7 +112,7 @@ and parsed_state = { state_enum : string; (** The C code implementing this state. *) - loc : location; + loc : Utils.location; code : string; (** Internal transitions, parsed out of the C code. *) diff --git a/generator/utils.ml b/generator/utils.ml index c326c0364..b8f394ce2 100644 --- a/generator/utils.ml +++ b/generator/utils.ml @@ -20,6 +20,9 @@ open Printf open Unix +type location = string * int +let noloc = ("", 0) + let failwithf fs = ksprintf failwith fs let rec filter_map f = function @@ -190,6 +193,10 @@ let pr_wrap ?(maxcol = 76) c code *) pr "%s" (String.concat "\n" rest) +let string_of_location (file, lineno) = sprintf "%s:%d" file lineno +let line_directive_of_location (file, lineno) + sprintf "#line %d \"%s\"" lineno file + type comment_style | CStyle | CPlusPlusStyle | HashStyle | OCamlStyle | HaskellStyle | PODCommentStyle diff --git a/generator/utils.mli b/generator/utils.mli index b559baf76..c6ed61ce0 100644 --- a/generator/utils.mli +++ b/generator/utils.mli @@ -29,6 +29,8 @@ type comment_style type chan = NoOutput | OutChannel of out_channel | Buffer of Buffer.t +type location = string * int (** source location: file, line number *) + val failwithf : ('a, unit, string, 'b) format4 -> 'a val filter_map : ('a -> 'b option) -> 'a list -> 'b list @@ -51,6 +53,10 @@ 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 noloc : location +val string_of_location : location -> string +val line_directive_of_location : location -> string + type cache_key = string type cache_value = string list val pod2text : cache_key -> cache_value -- 2.32.0
Richard W.M. Jones
2021-Dec-03 19:02 UTC
[Libguestfs] [PATCH libnbd 2/3] generator: Maintain current line number in output internally
This keeps track of the current line number in the output file internally (counting from 1). It is not used for any purpose in this commit. --- generator/utils.ml | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/generator/utils.ml b/generator/utils.ml index b8f394ce2..48669f9b7 100644 --- a/generator/utils.ml +++ b/generator/utils.ml @@ -124,28 +124,25 @@ let cspan str reject in loop 0 -(* Last output column. *) -let col = ref 0 +(* Current output line and column. *) +let lineno = ref 1 and col = ref 0 type chan = NoOutput | OutChannel of out_channel | Buffer of Buffer.t let chan = ref NoOutput let pr fs ksprintf ( fun str -> - (* Maintain the current output column. We can simply do this - * by counting backwards from the end of the string until we - * reach a \n (or the beginning). The number we count is - * the new column. This only works for 7 bit ASCII but - * that's enough for what we need this for. + (* Maintain the current output row & column. This only + * works for 7 bit ASCII but that's enough for what we need + * this for. *) - let rec loop i acc - if i >= 0 then ( - if String.unsafe_get str i = '\n' then acc - else loop (i-1) (acc+1) - ) - else !col + acc - in - col := loop (String.length str - 1) 0; + for i = 0 to String.length str - 1 do + if String.unsafe_get str i = '\n' then ( + col := 0; + incr lineno + ) else + incr col + done; match !chan with | NoOutput -> failwithf "use ?output_to? to set output" | OutChannel chan -> output_string chan str @@ -250,6 +247,7 @@ let files_equal n1 n2 | i -> failwithf "%s: failed with error code %d" cmd i let output_to filename k + lineno := 1; col := 0; let filename_new = filename ^ ".new" in let c = open_out filename_new in chan := OutChannel c; -- 2.32.0
Richard W.M. Jones
2021-Dec-03 19:02 UTC
[Libguestfs] [PATCH libnbd 3/3] generator: Reset line directive after included code in lib/states.c
--- TODO | 6 ------ generator/state_machine_generator.ml | 2 ++ generator/utils.ml | 2 ++ generator/utils.mli | 1 + 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/TODO b/TODO index 3861edc40..39642bc15 100644 --- a/TODO +++ b/TODO @@ -5,12 +5,6 @@ Bindings in other languages. - Latest attempt at adding Rust: https://www.redhat.com/archives/libguestfs/2019-August/msg00416.html -Additional #line directives in generated lib/states.c that track -position of output file when no longer copying lines from -generator/states-*.c. Probably requires moving type location, noloc, -and line_directive_of_location to utils.ml, and teaching pr to track -lines as well as columns. - Example code integrating with ppoll, pollfd, APR pollset (and others?). NBD resize extension. diff --git a/generator/state_machine_generator.ml b/generator/state_machine_generator.ml index 4e4751b76..2f4837f85 100644 --- a/generator/state_machine_generator.ml +++ b/generator/state_machine_generator.ml @@ -360,6 +360,8 @@ let generate_lib_states_c () pr " return 0;\n"; pr "}\n"; pr "\n"; + let output_loc = "lib/states.c", output_lineno () in + pr "%s\n" (line_directive_of_location output_loc); pr "int\n"; pr "nbd_internal_enter_%s (struct nbd_handle *h, bool *blocked)\n" state_enum; diff --git a/generator/utils.ml b/generator/utils.ml index 48669f9b7..499e8f8ec 100644 --- a/generator/utils.ml +++ b/generator/utils.ml @@ -190,6 +190,8 @@ let pr_wrap ?(maxcol = 76) c code *) pr "%s" (String.concat "\n" rest) +let output_lineno () = !lineno + let string_of_location (file, lineno) = sprintf "%s:%d" file lineno let line_directive_of_location (file, lineno) sprintf "#line %d \"%s\"" lineno file diff --git a/generator/utils.mli b/generator/utils.mli index c6ed61ce0..21afe5529 100644 --- a/generator/utils.mli +++ b/generator/utils.mli @@ -52,6 +52,7 @@ val generate_header : ?extra_sources:string list -> comment_style -> unit 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 output_lineno : unit -> int val noloc : location val string_of_location : location -> string -- 2.32.0
Richard W.M. Jones
2021-Dec-03 19:11 UTC
[Libguestfs] [PATCH libnbd 0/3] generator: Reset line directive after included code in lib/states.c
On Fri, Dec 03, 2021 at 07:02:07PM +0000, Richard W.M. Jones wrote:> This restores the #line directives (probably?) The output looks > right, but I didn't test it beyond opening it in the editor. Do #line > directives have a way to indicate "current file"?What I mean is that if you have: lib/states.c ---------------------------------------- #line 10 "generator/states.c" ... #line 20 -------------------- does the second #line refer to generator/states.c or lib/states.c? Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v