[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Libguestfs] [PATCH libnbd] lib: Use symbol versions.



This changes the libnbd.syms file (the linker script) to use symbol
versions.  The only version currently used is ‘LIBNBD_1.0’ for a
notional stable 1.0 release in the future.  It is expected that future
stable releases will use ‘LIBNBD_1.2’ etc.

Note this only deals with new symbols, not with the question of how to
deal with symbols which we decide to change incompatibly, if that
issue ever arises.
---
 generator/generator | 72 +++++++++++++++++++++++++++++++++++++--------
 1 file changed, 60 insertions(+), 12 deletions(-)

diff --git a/generator/generator b/generator/generator
index 60e0ab5..cc3d12d 100755
--- a/generator/generator
+++ b/generator/generator
@@ -840,6 +840,11 @@ type call = {
    * setting this to false.
    *)
   may_set_error : bool;
+  (* The first stable version that the symbol appeared in, for
+   * example (1, 2) if the symbol was added in development cycle
+   * 1.1.x and thus was the first stable version was 1.2
+   *)
+  first_version : int * int;
 }
 and arg =
 | ArrayAndLen of arg * string (* array + number of entries *)
@@ -884,7 +889,8 @@ and permitted_state =
 let default_call = { args = []; ret = RErr;
                      shortdesc = ""; longdesc = "";
                      permitted_states = [];
-                     is_locked = true; may_set_error = true }
+                     is_locked = true; may_set_error = true;
+                     first_version = (1, 0) }
 
 (* Calls.
  *
@@ -2318,6 +2324,20 @@ let rec filter_map f = function
       | Some y -> y :: filter_map f xs
       | None -> filter_map f xs
 
+(* group_by [1, "foo"; 2, "bar"; 2, "baz"; 2, "biz"; 3, "boo"; 4, "fizz"]
+ * - : (int * string list) list =
+ * [(1, ["foo"]); (2, ["bar"; "baz"; "biz"]); (3, ["boo"]); (4, ["fizz"])]
+ *)
+let rec group_by = function
+| [] -> []
+| [day, x] -> [day, [x]]
+| (day1, x1) :: (day2, x2) :: rest when day1 = day2 ->
+   let rest = group_by ((day2, x2) :: rest) in
+   let day, xs = List.hd rest in
+   (day, x1 :: xs) :: List.tl rest
+| (day, x) :: rest ->
+   (day, [x]) :: group_by rest
+
 let chan = ref Pervasives.stdout
 let pr fs = ksprintf (fun str -> output_string !chan str) fs
 
@@ -3067,22 +3087,50 @@ let () =
     | name, { ret = RUInt; may_set_error = true } ->
        failwithf "%s: if ret is RUInt, may_set_error must be false" name
     | _ -> ()
+  ) handle_calls;
+
+  (* First stable version must be 1.x where x is even. *)
+  List.iter (
+    fun (name, { first_version = (major, minor) }) ->
+      if major <> 1 then
+        failwithf "%s: first_version must be 1.x" name;
+      if minor mod 2 <> 0 then
+        failwithf "%s: first_version must refer to a stable release" name
   ) handle_calls
 
 let generate_lib_libnbd_syms () =
   generate_header HashStyle;
 
-  pr "{\n";
-  pr "  global:\n";
-  pr "    nbd_create;\n";
-  pr "    nbd_close;\n";
-  pr "    nbd_get_errno;\n";
-  pr "    nbd_get_error;\n";
-  List.iter (fun (name, _) -> pr "    nbd_%s;\n" name) handle_calls;
-  pr "\n";
-  pr "  # Everything else is hidden.\n";
-  pr "  local: *;\n";
-  pr "};\n"
+  (* Sort and group the calls by first_version, and emit them in order. *)
+  let cmp (_, {first_version = a}) (_, {first_version = b}) = compare a b in
+  let calls = List.sort cmp handle_calls in
+  let extract ((_, {first_version}) as call) = first_version, call in
+  let calls = List.map extract calls in
+  let calls = group_by calls in
+
+  let prev = ref None in
+  List.iter (
+    fun ((major, minor), calls) ->
+      pr "LIBNBD_%d.%d {\n" major minor;
+      pr "  global:\n";
+      if (major, minor) = (1, 0) then (
+        pr "    nbd_create;\n";
+        pr "    nbd_close;\n";
+        pr "    nbd_get_errno;\n";
+        pr "    nbd_get_error;\n"
+      );
+      List.iter (fun (name, _) -> pr "    nbd_%s;\n" name) calls;
+      pr "  # Everything else is hidden.\n";
+      pr "  local: *;\n";
+      pr "}";
+      (match !prev with
+       | None -> ()
+       | Some (old_major, old_minor) ->
+          pr " LIBNBD_%d.%d" old_minor old_minor
+      );
+      pr ";\n";
+      prev := Some (major, minor)
+  ) calls
 
 let rec name_of_arg = function
 | ArrayAndLen (arg, n) -> name_of_arg arg @ [n]
-- 
2.22.0


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]