lib: Warn about deprecated functions (enable with -DGUESTFS_WARN_DEPRECATED=1).
authorRichard W.M. Jones <rjones@redhat.com>
Tue, 17 May 2011 13:41:54 +0000 (14:41 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Tue, 17 May 2011 16:05:12 +0000 (17:05 +0100)
This allows C API users to be warned if they are using any deprecated
functions.

We don't warn about this by default.  Users have to specifically
request this by defining the cpp symbol GUESTFS_WARN_DEPRECATED as 1.

generator/generator_c.ml

index 4405d63..771d6a2 100644 (file)
@@ -370,6 +370,15 @@ extern \"C\" {
     (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
 #endif
 
+/* Define GUESTFS_WARN_DEPRECATED=1 to warn about deprecated API functions. */
+#define GUESTFS_DEPRECATED_BY(s)
+#if GUESTFS_WARN_DEPRECATED
+#  if defined(__GNUC__) && GUESTFS_GCC_VERSION >= 30100 /* gcc >= 3.1.0 */
+#    undef GUESTFS_DEPRECATED_BY
+#    define GUESTFS_DEPRECATED_BY(s) __attribute__((__deprecated__(\"change the program to use guestfs_\" s \" instead of this deprecated function\")))
+#  endif
+#endif /* GUESTFS_WARN_DEPRECATED */
+
 /* The handle. */
 #ifndef GUESTFS_TYPEDEF_H
 #define GUESTFS_TYPEDEF_H 1
@@ -434,7 +443,7 @@ int guestfs_set_event_callback (guestfs_h *g,
 #define LIBGUESTFS_HAVE_DELETE_EVENT_CALLBACK 1
 void guestfs_delete_event_callback (guestfs_h *g, int event_handle);
 
-/* Old-style event handling.  In new code use guestfs_set_event_callback. */
+/* Old-style event handling. */
 #ifndef GUESTFS_TYPEDEF_LOG_MESSAGE_CB
 #define GUESTFS_TYPEDEF_LOG_MESSAGE_CB 1
 typedef void (*guestfs_log_message_cb) (guestfs_h *g, void *opaque, char *buf, int len);
@@ -460,13 +469,18 @@ typedef void (*guestfs_close_cb) (guestfs_h *g, void *opaque);
 typedef void (*guestfs_progress_cb) (guestfs_h *g, void *opaque, int proc_nr, int serial, uint64_t position, uint64_t total);
 #endif
 
-extern void guestfs_set_log_message_callback (guestfs_h *g, guestfs_log_message_cb cb, void *opaque);
-extern void guestfs_set_subprocess_quit_callback (guestfs_h *g, guestfs_subprocess_quit_cb cb, void *opaque);
-extern void guestfs_set_launch_done_callback (guestfs_h *g, guestfs_launch_done_cb cb, void *opaque);
+extern void guestfs_set_log_message_callback (guestfs_h *g, guestfs_log_message_cb cb, void *opaque)
+  GUESTFS_DEPRECATED_BY(\"set_event_callback\");
+extern void guestfs_set_subprocess_quit_callback (guestfs_h *g, guestfs_subprocess_quit_cb cb, void *opaque)
+  GUESTFS_DEPRECATED_BY(\"set_event_callback\");
+extern void guestfs_set_launch_done_callback (guestfs_h *g, guestfs_launch_done_cb cb, void *opaque)
+  GUESTFS_DEPRECATED_BY(\"set_event_callback\");
 #define LIBGUESTFS_HAVE_SET_CLOSE_CALLBACK 1
-extern void guestfs_set_close_callback (guestfs_h *g, guestfs_close_cb cb, void *opaque);
+extern void guestfs_set_close_callback (guestfs_h *g, guestfs_close_cb cb, void *opaque)
+  GUESTFS_DEPRECATED_BY(\"set_event_callback\");
 #define LIBGUESTFS_HAVE_SET_PROGRESS_CALLBACK 1
-extern void guestfs_set_progress_callback (guestfs_h *g, guestfs_progress_cb cb, void *opaque);
+extern void guestfs_set_progress_callback (guestfs_h *g, guestfs_progress_cb cb, void *opaque)
+  GUESTFS_DEPRECATED_BY(\"set_event_callback\");
 
 /* Private data area. */
 #define LIBGUESTFS_HAVE_SET_PRIVATE 1
@@ -531,16 +545,23 @@ extern void *guestfs_next_private (guestfs_h *g, const char **key_rtn);
   List.iter (
     fun (shortname, (ret, args, optargs as style), _, flags, _, _, _) ->
       let deprecated =
-        List.exists (function DeprecatedBy _ -> true | _ -> false) flags in
+        try
+          Some (find_map (function DeprecatedBy fn -> Some fn | _ -> None)
+                  flags)
+        with Not_found -> None in
       let test0 =
         String.length shortname >= 5 && String.sub shortname 0 5 = "test0" in
       let debug =
         String.length shortname >= 5 && String.sub shortname 0 5 = "debug" in
-      if not deprecated && not test0 && not debug then
+      if deprecated = None && not test0 && not debug then
         pr "#define LIBGUESTFS_HAVE_%s 1\n" (String.uppercase shortname);
 
-      generate_prototype ~single_line:true ~newline:true ~handle:"g"
-        ~prefix:"guestfs_" shortname style;
+      generate_prototype ~single_line:true ~semicolon:false
+        ~handle:"g" ~prefix:"guestfs_" shortname style;
+      (match deprecated with
+       | Some fn -> pr "\n  GUESTFS_DEPRECATED_BY (%S);\n" fn
+       | None -> pr ";\n"
+      );
 
       if optargs <> [] then (
         generate_prototype ~single_line:true ~newline:true ~handle:"g"