Imported Upstream version 2.60.1 upstream/2.60.1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 7 Sep 2020 07:22:34 +0000 (00:22 -0700)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 7 Sep 2020 07:22:34 +0000 (00:22 -0700)
35 files changed:
NEWS
configure.ac
examples/properties/properties_example.cc
gio/giomm/init.h
gio/src/dbusobject.ccg
gio/src/dbusobject.hg
gio/src/drive.hg
gio/src/fileinfo.ccg
gio/src/fileinfo.hg
gio/src/mountoperation.hg
gio/src/socketcontrolmessage.ccg
gio/src/socketcontrolmessage.hg
gio/src/themedicon.hg
gio/src/tlsdatabase.ccg
gio/src/tlsdatabase.hg
gio/src/volumemonitor.hg
glib/glibmm/init.h
glib/glibmm/main.cc
glib/glibmm/object.cc
glib/glibmm/object.h
glib/glibmm/property.h
glib/glibmm/timeval.cc
glib/glibmm/timeval.h
glib/glibmm/ustring.cc
glib/glibmm/ustring.h
glib/src/checksum.hg
glib/src/date.ccg
glib/src/date.hg
glib/src/datetime.ccg
glib/src/datetime.hg
glib/src/thread.hg
glib/src/timezone.hg
glib/src/variant.hg
tools/defs_gen/h2def.py
tools/enum.pl

diff --git a/NEWS b/NEWS
index fa3375a..9c75cf6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,36 @@
+2.60.1 (stable):
+
+Glib:
+* Use convert_return_gchar_ptr_to_*() in a couple of ustring methods
+  (Martin Ejdestig) Merge request !11
+* Fix callback races in glibmm when GSource is destructed
+  (Dainis Jonitis) Issue #41
+* Fix memory leak in Variant<std::tuple<>>::create()
+  (Van de Bugger, Kjell Ahlstedt) Issue #48
+* Disable warnings from deprecated GTimeVal
+  (Kjell Ahlstedt)
+
+Gio:
+* DBus::Object: Fix refcounts in some vfuncs
+  (Kjell Ahlstedt)
+* Drive, MountOperation, ThemedIcon, TlsDatabase, VolumeMonitor:
+  Fix ownership of some lists and arrays (Fixes memory leaks
+  and dangling pointers)
+  (Kjell Ahlstedt) Issue #50 (Gary Wang)
+* SocketControlMessage: Add deserialize_vfunc_callback()
+  (Kjell Ahlstedt) Issue #52 (Ankur deep jaiswal)
+
+gmmproc:
+* Update for new glib deprecation macros
+  (Kjell Ahlstedt)
+
+Documentation:
+* Glib::init(), Gio::init(): Improve the documentation
+  (Kjell Ahlstedt) Issue #49 (Van de Bugger)
+* Glib::ustring can't always replace std::string
+  (Kjell Ahlstedt) Issue #47 (Patrick Storz)
+
+
 2.60.0 (stable):
 
 Glib:
index 1e6e40e..e8e603e 100644 (file)
@@ -15,7 +15,7 @@
 ## You should have received a copy of the GNU Lesser General Public License
 ## along with this library.  If not, see <http://www.gnu.org/licenses/>.
 
-AC_INIT([glibmm], [2.60.0],
+AC_INIT([glibmm], [2.60.1],
         [https://gitlab.gnome.org/GNOME/glibmm/issues],
         [glibmm], [http://www.gtkmm.org/])
 AC_PREREQ([2.59])
index 0d6c336..224ce2d 100644 (file)
@@ -74,6 +74,8 @@ main(int, char**)
   p.property_firstname().signal_changed().connect(sigc::ptr_fun(&on_firstname_changed));
   p.property_lastname().signal_changed().connect(sigc::ptr_fun(&on_lastname_changed));
   p.property_age().signal_changed().connect(sigc::ptr_fun(&on_age_changed));
+  std::cout << "Name, age: " << p.property_firstname() << " " << p.property_lastname()
+            << ", " << p.property_age() << std::endl;
 
   // now change the properties and see that the handlers get called
   std::cout << "Changing the properties of 'p'" << std::endl;
@@ -81,6 +83,8 @@ main(int, char**)
   p.property_lastname() = "Doe";
   p.property_age() = 43;
   std::cout << "Done changing the properties of 'p'" << std::endl;
+  std::cout << "Name, age: " << p.property_firstname() << " " << p.property_lastname()
+            << ", " << p.property_age() << std::endl;
 
   return 0;
 }
index 345e819..1ce3ac5 100644 (file)
 namespace Gio
 {
 
-/** Initialize giomm.
+/** Initialize giomm and glibmm.
+ *
+ * Call it before you use other parts of giomm. You may call it more than once.
+ * Calls after the first one have no effect. %Gio::init() calls Glib::init().
+ *
+ * You do not need to call %Gio::init() if you are using Gtk::Application,
+ * because it calls %Gio::init() for you.
  */
 void init();
 
index 7e1543d..69d4b58 100644 (file)
 #include <giomm/dbusinterface.h>
 #include <glibmm/vectorutils.h>
 
-namespace Gio
+namespace
 {
+// Used in call to g_list_copy_deep().
+void* list_copy_ref(const void* src, void* /* data */)
+{
+  return g_object_ref(const_cast<void*>(src));
+}
 
-} // namespace Gio
+// Define a replacement for Glib::unwrap_copy().
+// Can't use the template function in glibmm/wrap.h, because interface classes
+// don't override Glib::ObjectBase::gobj_copy(), which returns a GObject*.
+GDBusInterface* local_unwrap_copy(const Glib::RefPtr<Gio::DBus::Interface>& ptr)
+{
+  return ptr ? reinterpret_cast<GDBusInterface*>(ptr->gobj_copy()) : nullptr;
+}
+} // anonymous namespace
index 3be72cf..9618aa5 100644 (file)
@@ -48,11 +48,11 @@ class Object : public Glib::Interface
 public:
   _WRAP_METHOD(Glib::ustring get_object_path() const, g_dbus_object_get_object_path)
 
-#m4 _CONVERSION(`GList*',`std::vector< Glib::RefPtr<Gio::DBus::Interface> >',`Glib::ListHandler< Glib::RefPtr<Gio::DBus::Interface> >::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector< Glib::RefPtr<Gio::DBus::Interface> > get_interfaces(), g_dbus_object_get_interfaces)
+#m4 _CONVERSION(`GList*',`std::vector<Glib::RefPtr<Gio::DBus::Interface>>',`Glib::ListHandler<Glib::RefPtr<Gio::DBus::Interface>>::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(std::vector<Glib::RefPtr<Gio::DBus::Interface>> get_interfaces(), g_dbus_object_get_interfaces)
 
-#m4 _CONVERSION(`GList*',`std::vector< Glib::RefPtr<const Gio::DBus::Interface> >',`Glib::ListHandler< Glib::RefPtr<const Gio::DBus::Interface> >::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
-  _WRAP_METHOD(std::vector< Glib::RefPtr<const Gio::DBus::Interface> > get_interfaces() const, g_dbus_object_get_interfaces)
+#m4 _CONVERSION(`GList*',`std::vector<Glib::RefPtr<const Gio::DBus::Interface>>',`Glib::ListHandler<Glib::RefPtr<const Gio::DBus::Interface>>::list_to_vector($3, Glib::OWNERSHIP_DEEP)')
+  _WRAP_METHOD(std::vector<Glib::RefPtr<const Gio::DBus::Interface>> get_interfaces() const, g_dbus_object_get_interfaces)
 
   _WRAP_METHOD(Glib::RefPtr<Gio::DBus::Interface> get_interface(const Glib::ustring& interface_name), g_dbus_object_get_interface)
   _WRAP_METHOD(Glib::RefPtr<const Gio::DBus::Interface> get_interface(const Glib::ustring& interface_name) const, g_dbus_object_get_interface, constversion)
@@ -68,9 +68,13 @@ public:
 #m4 _CONVERSION(`Glib::ustring',`const gchar*',`$3.c_str()')
   _WRAP_VFUNC(Glib::ustring get_object_path() const, "get_object_path", keep_return)
 
-#m4 _CONVERSION(`std::vector< Glib::RefPtr<Gio::DBus::Interface> >',`GList*',`g_list_copy(Glib::ListHandler< Glib::RefPtr<Gio::DBus::Interface> >::vector_to_list($3).data())')
-  _WRAP_VFUNC(std::vector< Glib::RefPtr<Gio::DBus::Interface> > get_interfaces() const, "get_interfaces")
+#m4 _CONVERSION(`std::vector<Glib::RefPtr<Gio::DBus::Interface>>',`GList*',
+#m4  `g_list_copy_deep(Glib::ListHandler<Glib::RefPtr<Gio::DBus::Interface>>::vector_to_list($3).data(), list_copy_ref, nullptr)')
+  _WRAP_VFUNC(std::vector<Glib::RefPtr<Gio::DBus::Interface>> get_interfaces() const, "get_interfaces")
 
+  // Can't use refreturn_ctype here. It generates a call to Glib::unwrap_copy(), which
+  // can't be used for Glib::Interface classes. They have no gobj_copy() method.
+#m4 _CONVERSION(`Glib::RefPtr<Gio::DBus::Interface>',`GDBusInterface*',`local_unwrap_copy($3)')
   _WRAP_VFUNC(Glib::RefPtr<Gio::DBus::Interface> get_interface(const Glib::ustring& interface_name) const, "get_interface")
 };
 
index 9593de9..4871a3a 100644 (file)
@@ -61,7 +61,7 @@ public:
 
   _WRAP_METHOD(bool has_volumes() const, g_drive_has_volumes)
 
-#m4 _CONVERSION(`GList*',`Glib::ListHandle< Glib::RefPtr<Volume> >',`$2($3, Glib::OWNERSHIP_SHALLOW)')
+#m4 _CONVERSION(`GList*',`Glib::ListHandle< Glib::RefPtr<Volume> >',`$2($3, Glib::OWNERSHIP_DEEP)')
   _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<Volume> > get_volumes(), g_drive_get_volumes)
 
   _WRAP_METHOD(bool is_media_removable() const, g_drive_is_media_removable)
index d18d926..d586295 100644 (file)
@@ -27,6 +27,7 @@ FileAttributeMatcher::create(const std::string& attributes)
   return Glib::wrap(g_file_attribute_matcher_new(attributes.c_str()));
 }
 
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 Glib::TimeVal
 FileInfo::modification_time() const
 {
@@ -35,4 +36,10 @@ FileInfo::modification_time() const
   return result;
 }
 
+void FileInfo::set_modification_time(const Glib::TimeVal& mtime)
+{
+  g_file_info_set_modification_time(gobj(), const_cast<GTimeVal*>(static_cast<const GTimeVal*>(&mtime)));
+}
+G_GNUC_END_IGNORE_DEPRECATIONS
+
 } // namespace Gio
index 80399c3..9fb9594 100644 (file)
@@ -181,8 +181,11 @@ public:
 
   _WRAP_METHOD(goffset get_size() const, g_file_info_get_size)
 
+  //TODO: In the next minor stable release (glibmm 2.62.0?), deprecate modification_time()
+  // and add get_modification_date_time().
   Glib::TimeVal modification_time() const;
   _IGNORE(g_file_info_get_modification_time)
+  //_WRAP_METHOD(Glib::DateTime get_modification_date_time() const, g_file_info_get_modification_date_time)
 
   _WRAP_METHOD(std::string get_symlink_target() const, g_file_info_get_symlink_target)
 
@@ -215,7 +218,14 @@ public:
 
   _WRAP_METHOD(void set_size(goffset size), g_file_info_set_size)
 
-  _WRAP_METHOD(void set_modification_time(const Glib::TimeVal& mtime), g_file_info_set_modification_time)
+  //TODO: In the next minor stable release (glibmm 2.62.0?), deprecate set_modification_time()
+  // and add set_modification_date_time().
+  _WRAP_METHOD_DOCS_ONLY(g_file_info_set_modification_time)
+  void set_modification_time(const Glib::TimeVal& mtime);
+  //_WRAP_METHOD(void set_modification_time(const Glib::TimeVal& mtime), g_file_info_set_modification_time,
+  //  deprecated "Use set_modification_date_time() instead.")
+  //_WRAP_METHOD(void set_modification_date_time(const Glib::DateTime& mtime), g_file_info_set_modification_date_time)
+
   _WRAP_METHOD(void set_symlink_target(const std::string& symlink_target), g_file_info_set_symlink_target)
   _WRAP_METHOD(void set_sort_order(gint32 sort_order), g_file_info_set_sort_order)
 };
index 1e69765..99492b3 100644 (file)
@@ -80,7 +80,7 @@ public:
 
   //TODO: We really need some test to make sure that our use of StringArrayHandle is correct. murrayc.
 #m4 _CONVERSION(`const Glib::StringArrayHandle&',`const gchar**',`const_cast<const gchar**>(($3).data())')
-#m4 _CONVERSION(`const gchar**',`const Glib::StringArrayHandle&',`Glib::StringArrayHandle($3, Glib::OWNERSHIP_DEEP)')
+#m4 _CONVERSION(`const gchar**',`const Glib::StringArrayHandle&',`Glib::StringArrayHandle($3, Glib::OWNERSHIP_NONE)')
   _WRAP_SIGNAL(void ask_question(const Glib::ustring& message, const Glib::StringArrayHandle& choices), ask_question)
 
   _WRAP_SIGNAL(void reply(MountOperationResult result), reply)
index b921f77..06e4001 100644 (file)
 #include <gio/gio.h>
 #include <glibmm/exceptionhandler.h>
 
-namespace Gio
+namespace
+{
+
+GSocketControlMessage* deserialize_vfunc_callback(
+  int /* level */, int /* type */, gsize /* size */, gpointer /* data */)
 {
+  // Do nothing.
+
+  // Don't call the original underlying C function (GSocketControlMessage.deserialize()).
+  // Let g_socket_control_message_deserialize() do that as a last resort,
+  // if it's appropriate.
+  return nullptr;
+}
 
+} // anonymous namespace
+
+namespace Gio
+{
+//TODO: When we can add API, copy add_deserialize_func(),
+// deserialize_vfunc_callback() and m_deserialize_funcs from the master branch.
 } // namespace Gio
index 96e5f36..d4c39c1 100644 (file)
@@ -22,8 +22,8 @@ _PINCLUDE(glibmm/private/object_p.h)
 namespace Gio
 {
 
-/** SocketControlMessage - A Socket control message.
- * A SocketControlMessage is a special-purpose utility message that can be
+/** A Socket control message.
+ * A %SocketControlMessage is a special-purpose utility message that can be
  * sent to or received from a Socket. These types of messages are often
  * called "ancillary data".
  *
@@ -35,7 +35,8 @@ namespace Gio
  * Gio::Socket::receive().
  *
  * To extend the set of control message that can be sent, subclass this class
- * and override the get_size, get_level, get_type and serialize methods.
+ * and override the get_size_vfunc(), get_level_vfunc(), get_type_vfunc() and
+ * serialize_vfunc() methods.
  *
  * To extend the set of control messages that can be received, subclass this
  * class and implement the deserialize method. Also, make sure your class is
@@ -59,14 +60,31 @@ public:
   _WRAP_METHOD(gsize get_size() const, g_socket_control_message_get_size)
   _WRAP_METHOD(void serialize(gpointer data), g_socket_control_message_serialize)
 
-  //TODO: The deserialize vfunc does not have a GSocketControlMessage for its
-  //first parameter so it is difficult to wrap.
-  //_WRAP_VFUNC(Glib::RefPtr<SocketControlMessage> deserialize(int level, int type, gsize size, gpointer data), "deserialize")
-
   _WRAP_VFUNC(gsize get_size() const, "get_size")
   _WRAP_VFUNC(int get_level() const, "get_level")
   _WRAP_VFUNC(int get_type() const, "get_type")
   _WRAP_VFUNC(void serialize(gpointer data), "serialize")
+
+protected:
+  // The deserialize vfunc in GLib is a class virtual function (not associated
+  // with an instance). Such functions don't exist in C++.
+  // But it must be wrapped in one way or another. g_socket_control_message_deserialize()
+  // assumes that all subclasses of GSocketControlMessage override this vfunc.
+  // A user-program can crash, if any subclass does not.
+  // https://gitlab.gnome.org/GNOME/glibmm/issues/52
+#m4begin
+  _PUSH(SECTION_PCC_CLASS_INIT_VFUNCS)
+  klass->deserialize = &deserialize_vfunc_callback;
+  _SECTION(SECTION_PH_VFUNCS)
+  //TODO: Uncomment when we can add API.
+  //static GSocketControlMessage* deserialize_vfunc_callback(
+  //  int level, int type, gsize size, gpointer data);
+  _POP()
+#m4end
+
+  //TODO: When we can add API, add protected DeserializeFunc,
+  // add_deserialize_func() and private m_deserialize_funcs from the master branch.
+  // And update the last paragraph of the class description.
 };
 
 } // namespace Gio
index 249b1d1..7aaf233 100644 (file)
@@ -96,7 +96,7 @@ public:
   _WRAP_METHOD(void prepend_name(const std::string& iconname), g_themed_icon_prepend_name)
   _WRAP_METHOD(void append_name(const std::string& iconname), g_themed_icon_append_name)
 
-  #m4 _CONVERSION(`const gchar* const*',`Glib::StringArrayHandle',`Glib::StringArrayHandle($3, Glib::OWNERSHIP_DEEP)')
+  #m4 _CONVERSION(`const gchar* const*',`Glib::StringArrayHandle',`Glib::StringArrayHandle($3, Glib::OWNERSHIP_NONE)')
   _WRAP_METHOD(Glib::StringArrayHandle get_names() const, g_themed_icon_get_names)
 
   //There are no signals.
index e464c17..80ef0a7 100644 (file)
 #include <giomm/tlscertificate.h>
 #include <giomm/tlsinteraction.h>
 #include "slot_async.h"
+
+namespace
+{
+// Used in call to g_list_copy_deep().
+void* list_copy_ref(const void* src, void* /* data */)
+{
+  return g_object_ref(const_cast<void*>(src));
+}
+} // anonymous namespace
index 52d1a25..a99daaa 100644 (file)
@@ -91,8 +91,8 @@ public:
 #m4 _CONVERSION(`GSocketConnectable*',`const Glib::RefPtr<const SocketConnectable>&',`Glib::wrap($3, true)')
 #m4 _CONVERSION(`GTlsInteraction*',`const Glib::RefPtr<TlsInteraction>&',`Glib::wrap($3, true)')
 
-  _WRAP_VFUNC(TlsCertificateFlags verify_chain(const Glib::RefPtr<TlsCertificate>& chain, const Glib::ustring& purpose, const Glib::RefPtr<const SocketConnectable>& identity, const Glib::RefPtr<TlsInteraction>& interaction, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseVerifyFlags flags{.}) const, "verify_chain", errthrow)
-  _WRAP_VFUNC(void verify_chain_async(const Glib::RefPtr<TlsCertificate>& chain, const Glib::ustring& purpose, const Glib::RefPtr<const SocketConnectable>& identity, const Glib::RefPtr<TlsInteraction>& interaction, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseVerifyFlags flags{.}) const, "verify_chain_async", slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_VFUNC(TlsCertificateFlags verify_chain(const Glib::RefPtr<TlsCertificate>& chain, const Glib::ustring& purpose, const Glib::RefPtr<const SocketConnectable>& identity, const Glib::RefPtr<TlsInteraction>& interaction, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseVerifyFlags flags{.}) const, "verify_chain", errthrow)
+  _WRAP_VFUNC(void verify_chain_async(const Glib::RefPtr<TlsCertificate>& chain, const Glib::ustring& purpose, const Glib::RefPtr<const SocketConnectable>& identity, const Glib::RefPtr<TlsInteraction>& interaction, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseVerifyFlags flags{.}) const, "verify_chain_async", slot_name slot, slot_callback SignalProxy_async_callback)
 
 #m4 _CONVERSION(`GAsyncResult*',`const Glib::RefPtr<AsyncResult>&',`Glib::wrap($3, true)')
 
@@ -105,19 +105,20 @@ dnl// create_certificate_handle_vfunc() shall return a newly allocated string.
 
 #m4 _CONVERSION(`Glib::RefPtr<TlsCertificate>',`GTlsCertificate*',`G_TLS_CERTIFICATE(g_object_ref(Glib::unwrap($3)))')
 
-  _WRAP_VFUNC(Glib::RefPtr<TlsCertificate> lookup_certificate_for_handle(const Glib::ustring& handle, const Glib::RefPtr<TlsInteraction>& interaction, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseLookupFlags flags{.}), "lookup_certificate_for_handle", errthrow)
-  _WRAP_VFUNC(void lookup_certificate_for_handle_async(const Glib::ustring& handle, const Glib::RefPtr<TlsInteraction>& interaction, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseLookupFlags flags{.}), "lookup_certificate_for_handle_async", slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_VFUNC(Glib::RefPtr<TlsCertificate> lookup_certificate_for_handle(const Glib::ustring& handle, const Glib::RefPtr<TlsInteraction>& interaction, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseLookupFlags flags{.}), "lookup_certificate_for_handle", errthrow)
+  _WRAP_VFUNC(void lookup_certificate_for_handle_async(const Glib::ustring& handle, const Glib::RefPtr<TlsInteraction>& interaction, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseLookupFlags flags{.}), "lookup_certificate_for_handle_async", slot_name slot, slot_callback SignalProxy_async_callback)
   _WRAP_VFUNC(Glib::RefPtr<TlsCertificate> lookup_certificate_for_handle_finish(const Glib::RefPtr<AsyncResult>& result), "lookup_certificate_for_handle_finish", errthrow)
 
-  _WRAP_VFUNC(Glib::RefPtr<TlsCertificate> lookup_certificate_issuer(const Glib::RefPtr<TlsCertificate>& certificate, const Glib::RefPtr<TlsInteraction>& interaction, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseLookupFlags flags{.}), "lookup_certificate_issuer", errthrow)
-  _WRAP_VFUNC(void lookup_certificate_issuer_async(const Glib::RefPtr<TlsCertificate>& certificate, const Glib::RefPtr<TlsInteraction>& interaction, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseLookupFlags flags{.}), "lookup_certificate_issuer_async", slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_VFUNC(Glib::RefPtr<TlsCertificate> lookup_certificate_issuer(const Glib::RefPtr<TlsCertificate>& certificate, const Glib::RefPtr<TlsInteraction>& interaction, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseLookupFlags flags{.}), "lookup_certificate_issuer", errthrow)
+  _WRAP_VFUNC(void lookup_certificate_issuer_async(const Glib::RefPtr<TlsCertificate>& certificate, const Glib::RefPtr<TlsInteraction>& interaction, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseLookupFlags flags{.}), "lookup_certificate_issuer_async", slot_name slot, slot_callback SignalProxy_async_callback)
   _WRAP_VFUNC(Glib::RefPtr<TlsCertificate> lookup_certificate_issuer_finish(const Glib::RefPtr<AsyncResult>& result), "lookup_certificate_issuer_finish", errthrow)
 
-#m4 _CONVERSION(`std::vector< Glib::RefPtr<TlsCertificate> >',`GList*',`g_list_copy(Glib::ListHandler< Glib::RefPtr<TlsCertificate> >::vector_to_list($3).data())')
+#m4 _CONVERSION(`std::vector< Glib::RefPtr<TlsCertificate> >',`GList*',
+#m4  `g_list_copy_deep(Glib::ListHandler< Glib::RefPtr<TlsCertificate> >::vector_to_list($3).data(), list_copy_ref, nullptr)')
 #m4 _CONVERSION(`GByteArray*',`const Glib::RefPtr<Glib::ByteArray>&',`Glib::wrap($3, true)')
 
-  _WRAP_VFUNC(std::vector< Glib::RefPtr<TlsCertificate> > lookup_certificates_issued_by(const Glib::RefPtr<Glib::ByteArray>& issuer_raw_dn, const Glib::RefPtr<TlsInteraction>& interaction, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseLookupFlags flags{.}), "lookup_certificates_issued_by", errthrow)
-  _WRAP_VFUNC(void lookup_certificates_issued_by_async(const Glib::RefPtr<Glib::ByteArray>& issuer_raw_dn, const Glib::RefPtr<TlsInteraction>& interaction, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}, TlsDatabaseLookupFlags flags{.}), "lookup_certificates_issued_by_async", slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_VFUNC(std::vector< Glib::RefPtr<TlsCertificate> > lookup_certificates_issued_by(const Glib::RefPtr<Glib::ByteArray>& issuer_raw_dn, const Glib::RefPtr<TlsInteraction>& interaction, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseLookupFlags flags{.}), "lookup_certificates_issued_by", errthrow)
+  _WRAP_VFUNC(void lookup_certificates_issued_by_async(const Glib::RefPtr<Glib::ByteArray>& issuer_raw_dn, const Glib::RefPtr<TlsInteraction>& interaction, const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}, TlsDatabaseLookupFlags flags{.}), "lookup_certificates_issued_by_async", slot_name slot, slot_callback SignalProxy_async_callback)
   _WRAP_VFUNC(std::vector< Glib::RefPtr<TlsCertificate> > lookup_certificates_issued_by_finish(const Glib::RefPtr<AsyncResult>& result), "lookup_certificates_issued_by_finish", errthrow)
 };
 
index 24c62fb..f51ac1c 100644 (file)
@@ -42,13 +42,13 @@ public:
 
   _WRAP_METHOD(static Glib::RefPtr<VolumeMonitor> get(), g_volume_monitor_get)
 
-#m4 _CONVERSION(`GList*',`Glib::ListHandle< Glib::RefPtr<Drive> >',`$2($3, Glib::OWNERSHIP_SHALLOW)')
+#m4 _CONVERSION(`GList*',`Glib::ListHandle< Glib::RefPtr<Drive> >',`$2($3, Glib::OWNERSHIP_DEEP)')
   _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<Drive> > get_connected_drives(), g_volume_monitor_get_connected_drives)
 
-#m4 _CONVERSION(`GList*',`Glib::ListHandle< Glib::RefPtr<Volume> >',`$2($3, Glib::OWNERSHIP_SHALLOW)')
+#m4 _CONVERSION(`GList*',`Glib::ListHandle< Glib::RefPtr<Volume> >',`$2($3, Glib::OWNERSHIP_DEEP)')
   _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<Volume> > get_volumes(), g_volume_monitor_get_volumes)
 
-#m4 _CONVERSION(`GList*',`Glib::ListHandle< Glib::RefPtr<Mount> >',`$2($3, Glib::OWNERSHIP_SHALLOW)')
+#m4 _CONVERSION(`GList*',`Glib::ListHandle< Glib::RefPtr<Mount> >',`$2($3, Glib::OWNERSHIP_DEEP)')
   _WRAP_METHOD(Glib::ListHandle< Glib::RefPtr<Mount> > get_mounts(), g_volume_monitor_get_mounts)
 
   _WRAP_METHOD(Glib::RefPtr<Volume> get_volume_for_uuid(const std::string& uuid), g_volume_monitor_get_volume_for_uuid, refreturn)
index 1245cd3..509e717 100644 (file)
@@ -1,9 +1,6 @@
-// -*- c++ -*-
 #ifndef _GLIBMM_INIT_H
 #define _GLIBMM_INIT_H
 
-/* $Id$ */
-
 /* Copyright (C) 2002 The gtkmm Development Team
  *
  * This library is free software; you can redistribute it and/or
@@ -24,9 +21,12 @@ namespace Glib
 {
 
 /** Initialize glibmm.
- * You may call this more than once.
- * You do not need to call this if you are using Glib::MainLoop or Gtk::Main,
- * because they call it for you.
+ *
+ * Call it before you use other parts of glibmm. You may call it more than once.
+ * Calls after the first one have no effect.
+ *
+ * You do not need to call %Glib::init() if you are using Gtk::Application or
+ * Gio::init(), because they call %Glib::init() for you.
  */
 void init();
 
index cffa0e0..9eae11a 100644 (file)
@@ -192,13 +192,23 @@ SourceCallbackData::destroy_notify_callback(void* data)
 static SourceCallbackData*
 glibmm_source_get_callback_data(GSource* source)
 {
-  g_return_val_if_fail(source->callback_funcs != nullptr, nullptr);
+  /* There is race between iteration of sources in main loop
+   * that checks whether they are still active and source
+   * destruction happening in other threads.
+   */
+  gpointer callback_data = source->callback_data;
+  GSourceCallbackFuncs* callback_funcs = source->callback_funcs;
+
+  g_return_val_if_fail(callback_funcs != nullptr, nullptr);
+
+  if (g_source_is_destroyed(source))
+    return nullptr;
 
   GSourceFunc func;
   void* user_data = nullptr;
 
   // Retrieve the callback function and data.
-  (*source->callback_funcs->get)(source->callback_data, source, &func, &user_data);
+  (*callback_funcs->get)(callback_data, source, &func, &user_data);
 
   return static_cast<SourceCallbackData*>(user_data);
 }
@@ -981,7 +991,10 @@ Source::~Source() noexcept
   if (gobject_)
   {
     SourceCallbackData* const data = glibmm_source_get_callback_data(gobject_);
-    data->wrapper = nullptr;
+
+    if (data) {
+      data->wrapper = nullptr;
+    }
 
     GSource* const tmp_gobject = gobject_;
     gobject_ = nullptr;
@@ -1001,7 +1014,10 @@ Source::connect_generic(const sigc::slot_base& slot)
   // Don't override the callback data.  Reuse the existing one
   // calling SourceCallbackData::set_node() to register conn_node.
   SourceCallbackData* const data = glibmm_source_get_callback_data(gobject_);
-  data->set_node(conn_node);
+
+  if (data) {
+    data->set_node(conn_node);
+  }
 
   conn_node->install(gobject_);
   return connection;
@@ -1043,7 +1059,7 @@ inline // static
   Source::get_wrapper(GSource* source)
 {
   SourceCallbackData* const data = glibmm_source_get_callback_data(source);
-  return data->wrapper;
+  return (data) ? data->wrapper : nullptr;
 }
 
 // static
@@ -1053,7 +1069,7 @@ Source::prepare_vfunc(GSource* source, int* timeout)
   try
   {
     Source* const self = get_wrapper(source);
-    return self->prepare(*timeout);
+    return (self) ? self->prepare(*timeout) : 0;
   }
   catch (...)
   {
@@ -1070,7 +1086,7 @@ Source::check_vfunc(GSource* source)
   try
   {
     Source* const self = get_wrapper(source);
-    return self->check();
+    return (self) ? self->check() : 0;
   }
   catch (...)
   {
index c8370d7..2fa0910 100644 (file)
@@ -91,10 +91,12 @@ ConstructParams::ConstructParams(
       break;
     }
 
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
     if (n_parameters >= n_alloced_params)
       parameters = g_renew(GParameter, parameters, n_alloced_params += 8);
 
     GParameter& param = parameters[n_parameters];
+G_GNUC_END_IGNORE_DEPRECATIONS
 
     param.name = name;
     param.value.g_type = 0;
@@ -132,6 +134,7 @@ ConstructParams::~ConstructParams() noexcept
  * usage contexts.  This implementation is fully functional, but unlikely
  * to be ever actually called due to optimization.
  */
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 ConstructParams::ConstructParams(const ConstructParams& other)
 : glibmm_class(other.glibmm_class),
   n_parameters(other.n_parameters),
@@ -146,6 +149,7 @@ ConstructParams::ConstructParams(const ConstructParams& other)
     g_value_copy(&other.parameters[i].value, &parameters[i].value);
   }
 }
+G_GNUC_END_IGNORE_DEPRECATIONS
 
 /**** Glib::Object_Class ***************************************************/
 
@@ -230,7 +234,7 @@ Object::Object(const Glib::ConstructParams& construct_params)
 
   G_GNUC_BEGIN_IGNORE_DEPRECATIONS
   //TODO: Replace g_object_newv() by g_object_new_with_properties() when we can
-  // require glib 2.54. GParameter is also deprecated (only mentioned in a comment).
+  // require glib 2.54. GParameter is also deprecated.
   // Don't use it in ConstructParams when we can break ABI.
   void* const new_object =
     g_object_newv(object_type, construct_params.n_parameters, construct_params.parameters);
index 79b37b5..f9f316a 100644 (file)
@@ -70,7 +70,9 @@ class ConstructParams
 public:
   const Glib::Class& glibmm_class;
   unsigned int n_parameters;
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
   GParameter* parameters;
+G_GNUC_END_IGNORE_DEPRECATIONS
 
   explicit ConstructParams(const Glib::Class& glibmm_class_);
   ConstructParams(const Glib::Class& glibmm_class_, const char* first_property_name,
index 593fba1..baf09f8 100644 (file)
@@ -224,7 +224,7 @@ public:
    */
   inline operator PropertyType() const;
 
-  /** Returns a proxy object that can be used to manipulate this property.
+  /** Returns a proxy object that can be used to read or write this property.
    */
   inline Glib::PropertyProxy<T> get_proxy();
 };
@@ -271,7 +271,7 @@ public:
    */
   inline operator PropertyType() const;
 
-  /** Returns a proxy object that can be used to manipulate this property.
+  /** Returns a proxy object that can be used to read this property.
    */
   inline Glib::PropertyProxy_ReadOnly<T> get_proxy();
 };
@@ -320,7 +320,7 @@ public:
    */
   inline Property_WriteOnly<T>& operator=(const PropertyType& data);
 
-  /** Returns a proxy object that can be used to manipulate this property.
+  /** Returns a proxy object that can be used to write this property.
    */
   inline Glib::PropertyProxy_WriteOnly<T> get_proxy();
 };
index c8bb9a9..dcd39ba 100644 (file)
@@ -20,7 +20,7 @@
 
 namespace Glib
 {
-
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 void
 TimeVal::assign_current_time()
 {
@@ -32,6 +32,7 @@ TimeVal::assign_from_iso8601(const Glib::ustring& iso_date)
 {
   return g_time_val_from_iso8601(iso_date.c_str(), this);
 }
+G_GNUC_END_IGNORE_DEPRECATIONS
 
 void
 TimeVal::add(const TimeVal& rhs)
@@ -110,6 +111,7 @@ TimeVal::subtract_milliseconds(long milliseconds)
   add_milliseconds(-1 * milliseconds);
 }
 
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 void
 TimeVal::add_microseconds(long microseconds)
 {
@@ -134,5 +136,6 @@ TimeVal::as_iso8601() const
   }
   return Glib::ustring();
 }
+G_GNUC_END_IGNORE_DEPRECATIONS
 
 } // namespace Glib
index e67a9e0..f13164c 100644 (file)
 namespace Glib
 {
 
+//TODO: Deprecate TimeVal in the next minor stable release (glibmm 2.62.0?).
+// GTimeVal is deprecated.
+// Note: Before TimeVal is deprecated, check what will happen with
+// Gdk::PixbufAnimationIter::advance(const Glib::TimeVal& current_time),
+// especially if GLIBMM_DISABLE_DEPRECATED is defined but GDKMM_DISABLE_DEPRECATED is not.
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 /** Glib::TimeVal is a wrapper around the glib structure GTimeVal.
  * The glib structure GTimeVal itself is equivalent to struct timeval,
  * which is returned by the gettimeofday() UNIX call. Additionally
@@ -234,6 +240,7 @@ operator>=(const TimeVal& lhs, const TimeVal& rhs)
 {
   return ((lhs.tv_sec > rhs.tv_sec) || (lhs.tv_sec == rhs.tv_sec && lhs.tv_usec >= rhs.tv_usec));
 }
+G_GNUC_END_IGNORE_DEPRECATIONS
 
 } // namespace Glib
 
index abd1b58..a0f9ab8 100644 (file)
@@ -1236,37 +1236,32 @@ ustring::is_ascii() const
 ustring
 ustring::normalize(NormalizeMode mode) const
 {
-  const auto buf = make_unique_ptr_gfree(
+  return convert_return_gchar_ptr_to_ustring(
     g_utf8_normalize(string_.data(), string_.size(), static_cast<GNormalizeMode>(int(mode))));
-  return ustring(buf.get());
 }
 
 ustring
 ustring::uppercase() const
 {
-  const auto buf = make_unique_ptr_gfree(g_utf8_strup(string_.data(), string_.size()));
-  return ustring(buf.get());
+  return convert_return_gchar_ptr_to_ustring(g_utf8_strup(string_.data(), string_.size()));
 }
 
 ustring
 ustring::lowercase() const
 {
-  const auto buf = make_unique_ptr_gfree(g_utf8_strdown(string_.data(), string_.size()));
-  return ustring(buf.get());
+  return convert_return_gchar_ptr_to_ustring(g_utf8_strdown(string_.data(), string_.size()));
 }
 
 ustring
 ustring::casefold() const
 {
-  const auto buf = make_unique_ptr_gfree(g_utf8_casefold(string_.data(), string_.size()));
-  return ustring(buf.get());
+  return convert_return_gchar_ptr_to_ustring(g_utf8_casefold(string_.data(), string_.size()));
 }
 
 std::string
 ustring::collate_key() const
 {
-  const auto buf = make_unique_ptr_gfree(g_utf8_collate_key(string_.data(), string_.size()));
-  return std::string(buf.get());
+  return convert_return_gchar_ptr_to_stdstring(g_utf8_collate_key(string_.data(), string_.size()));
 }
 
 std::string
index 532a78f..3270075 100644 (file)
@@ -133,18 +133,18 @@ private:
  */
 gunichar get_unichar_from_std_iterator(std::string::const_iterator pos) G_GNUC_PURE;
 
-/** Glib::ustring has much the same interface as std::string, but contains
+/** %Glib::ustring has much the same interface as std::string, but contains
  * %Unicode characters encoded as UTF-8.
  *
  * @par About UTF-8 and ASCII
  * @par
  * The standard character set ANSI_X3.4-1968&nbsp;-- more commonly known as
  * ASCII&nbsp;-- is a subset of UTF-8.  So, if you want to, you can use
- * Glib::ustring without even thinking about UTF-8.
+ * %Glib::ustring without even thinking about UTF-8.
  * @par
  * Whenever ASCII is mentioned in this manual, we mean the @em real ASCII
  * (i.e. as defined in ANSI_X3.4-1968), which contains only 7-bit characters.
- * Glib::ustring can @em not be used with ASCII-compatible extended 8-bit
+ * %Glib::ustring can @em not be used with ASCII-compatible extended 8-bit
  * charsets like ISO-8859-1.  It's a good idea to avoid string literals
  * containing non-ASCII characters (e.g. German umlauts) in source code,
  * or at least you should use UTF-8 literals.
@@ -154,18 +154,28 @@ gunichar get_unichar_from_std_iterator(std::string::const_iterator pos) G_GNUC_P
  *
  * @par Glib::ustring vs. std::string
  * @par
- * Glib::ustring has implicit type conversions to and from std::string.
+ * %Glib::ustring has implicit type conversions to and from std::string.
  * These conversions do @em not convert to/from the current locale (see
  * Glib::locale_from_utf8() and Glib::locale_to_utf8() if you need that).  You
- * can always use std::string instead of Glib::ustring&nbsp;-- however, using
+ * can always use std::string instead of %Glib::ustring&nbsp;-- however, using
  * std::string with multi-byte characters is quite hard.  For instance,
  * <tt>std::string::operator[]</tt> might return a byte in the middle of a
  * character, and <tt>std::string::length()</tt> returns the number of bytes
  * rather than characters.  So don't do that without a good reason.
  * @par
- * Many member functions and operators of Glib::ustring and Glib::ustring_Iterator
+ * You cannot always use %Glib::ustring instead of std::string.
+ * @code
+ * Glib::ustring u("a_string_with_underscores");
+ * std::replace(u.begin(), u.end(), '_', ' ');  // does not compile
+ * @endcode
+ * You can't use a Glib::ustring::iterator for writing to a %Glib::ustring.
+ * See the documentation of Glib::ustring_Iterator for differences between it
+ * and std::string::iterator.
+ * @par
+ * Many member functions and operators of %Glib::ustring and Glib::ustring_Iterator
  * assume that the string contains only valid UTF-8 data. If it does not, memory
- * outside the bounds of the string can be accessed.
+ * outside the bounds of the string can be accessed. If you're uncertain, use
+ * validate().
  * @par
  * In a perfect world the C++ Standard Library would contain a UTF-8 string
  * class.  Unfortunately, the C++98 standard doesn't mention UTF-8 at all.
@@ -203,7 +213,7 @@ gunichar get_unichar_from_std_iterator(std::string::const_iterator pos) G_GNUC_P
  *
  * @par Implementation notes
  * @par
- * Glib::ustring does not inherit from std::string, because std::string was
+ * %Glib::ustring does not inherit from std::string, because std::string was
  * intended to be a final class.  For instance, it does not have a virtual
  * destructor.  Also, a HAS-A relationship is more appropriate because
  * ustring can't just enhance the std::string interface.  Rather, it has to
index a4a4d49..d7b30c4 100644 (file)
@@ -23,6 +23,10 @@ _DEFS(glibmm,glib)
 extern "C" { typedef struct _GChecksum GChecksum; }
 #endif
 
+//TODO: When we can add API, add a Glib::Value specialization, similar to the one in
+// https://mail.gnome.org/archives/gtkmm-list/2019-April/msg00012.html
+//TODO: When we can change API, make Checksum a _CLASS_BOXEDTYPE.
+
 namespace Glib
 {
 
index 7e62718..dc0cb37 100644 (file)
@@ -76,7 +76,7 @@ Date::set_parse(const Glib::ustring& str)
 }
 
 _DEPRECATE_IFDEF_START
-
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 // Avoid a build problem in the case that std::time_t is equivalent to gint32 (GTime is also gint32)
 // That would make the set_time() method overload impossible.
 #ifdef GLIBMM_HAVE_C_STD_TIME_T_IS_NOT_INT32
@@ -90,7 +90,7 @@ Date::set_time(GTime time)
   g_date_set_time_t(&gobject_, static_cast<time_t>(time));
 }
 #endif // GLIBMM_HAVE_C_STD_TIME_T_IS_NOT_INT32
-
+G_GNUC_END_IGNORE_DEPRECATIONS
 _DEPRECATE_IFDEF_END
 
 void
@@ -106,11 +106,13 @@ Date::set_time_current()
   g_date_set_time_t(&gobject_, time(nullptr));
 }
 
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 void
 Date::set_time(const GTimeVal& timeval)
 {
   g_date_set_time_val(&gobject_, const_cast<GTimeVal*>(&timeval));
 }
+G_GNUC_END_IGNORE_DEPRECATIONS
 
 void
 Date::set_month(Date::Month month)
index 4c29fb5..8b15ccb 100644 (file)
@@ -108,9 +108,8 @@ public:
    */
   void set_parse (const Glib::ustring& str);
 
-
   _DEPRECATE_IFDEF_START
-
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
   //Avoid a build problem in the case that std::time_t is equivalent to gint32 (GTime is also gint32)
   //That would make the set_time() method overload impossible.
   #ifdef GLIBMM_HAVE_C_STD_TIME_T_IS_NOT_INT32
@@ -118,14 +117,13 @@ public:
    *
    * @param time GTime value to set.
    *
-   * @deprecated Please use set_time(std::time_t) or set_time(const GTimeVal&).
+   * @deprecated Please use set_time(std::time_t) instead.
    */
   void set_time(GTime time);
   #endif //GLIBMM_HAVE_C_STD_TIME_T_IS_NOT_INT32
-
+  G_GNUC_END_IGNORE_DEPRECATIONS
   _DEPRECATE_IFDEF_END
 
-
   /** Sets the value of a date from a <type>std::time_t</type> value.
    *
    * @param timet std::time_t value to set
@@ -136,6 +134,9 @@ public:
    */
   void set_time(std::time_t timet);
 
+  //TODO: Deprecate set_time() in the next minor stable release (glibmm 2.62.0?).
+  // GTimeVal is deprecated.
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
   /** Sets the value of a date from a GTimeVal value.  Note that the
    * tv_usec member is ignored, because Glib::Date can't make use of the
    * additional precision.
@@ -147,6 +148,7 @@ public:
    * Since: 2.10
    */
   void set_time(const GTimeVal& timeval);
+  G_GNUC_END_IGNORE_DEPRECATIONS
 
   /** Set this Glib::Date to the current time.
    */
index 3295b3e..14b800a 100644 (file)
 #include <glibmm/utility.h>
 #include <glibmm/timeval.h>
 #include <glibmm/wrap.h>
+
+namespace Glib
+{
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+DateTime DateTime::create_now_local(const TimeVal& tv)
+{
+  return Glib::wrap(g_date_time_new_from_timeval_local(&(tv)));
+}
+
+DateTime DateTime::create_now_utc(const TimeVal& tv)
+{
+  return Glib::wrap(g_date_time_new_from_timeval_utc(&(tv)));
+}
+
+bool DateTime::to_timeval(TimeVal& tv) const
+{
+  return g_date_time_to_timeval(const_cast<GDateTime*>(gobj()), &(tv));
+}
+G_GNUC_END_IGNORE_DEPRECATIONS
+
+} // namespace Glib
index ac6e81d..730fcab 100644 (file)
@@ -26,6 +26,10 @@ _DEFS(glibmm,glib)
 typedef struct _GDateTime GDateTime;
 #endif
 
+//TODO: When we can add API, add a Glib::Value specialization, similar to the one in
+// https://mail.gnome.org/archives/gtkmm-list/2019-April/msg00012.html
+//TODO: When we can change API, make DateTime a _CLASS_BOXEDTYPE.
+
 namespace Glib
 {
 
@@ -49,9 +53,6 @@ using TimeSpan = GTimeSpan;
  * functions can fail due to the date or time going out of range, in which case
  * <tt>0</tt> will be returned.
  *
- * DateTime is reference counted.  When the reference count drops to 0, the
- * resources allocated by the DateTime structure are released.
- *
  * Many parts of the API may produce non-obvious results. As an example, adding
  * two months to January 31st will yield March 31st whereas adding one month
  * and then one month again will yield either March 28th or March 29th. Also
@@ -73,8 +74,17 @@ public:
   _WRAP_METHOD(static DateTime create_now_local(gint64 t), g_date_time_new_from_unix_local)
   _WRAP_METHOD(static DateTime create_now_utc(gint64 t), g_date_time_new_from_unix_utc)
 
-  _WRAP_METHOD(static DateTime create_now_local(const TimeVal& tv), g_date_time_new_from_timeval_local)
-  _WRAP_METHOD(static DateTime create_now_utc(const TimeVal& tv), g_date_time_new_from_timeval_utc)
+  _WRAP_METHOD_DOCS_ONLY(g_date_time_new_from_timeval_local)
+  static DateTime create_now_local(const TimeVal& tv);
+//TODO: Deprecate in the next minor stable release (glibmm 2.62.0?).
+//  _WRAP_METHOD(static DateTime create_now_local(const TimeVal& tv), g_date_time_new_from_timeval_local,
+//    deprecated "Use create_now_local(gint64 t) instead.")
+
+  _WRAP_METHOD_DOCS_ONLY(g_date_time_new_from_timeval_utc)
+  static DateTime create_now_utc(const TimeVal& tv);
+//TODO: Deprecate in the next minor stable release (glibmm 2.62.0?).
+//  _WRAP_METHOD(static DateTime create_now_utc(const TimeVal& tv), g_date_time_new_from_timeval_utc,
+//    deprecated "Use create_now_utc(gint64 t) instead.")
 
   _WRAP_METHOD(static DateTime create(const TimeZone& tz, int year, int month, int day, int hour, int minute, double seconds), g_date_time_new)
   _WRAP_METHOD(static DateTime create_local(int year, int month, int day, int hour, int minute, double seconds), g_date_time_new_local)
@@ -141,7 +151,13 @@ public:
   _WRAP_METHOD(int get_microsecond() const, g_date_time_get_microsecond)
   _WRAP_METHOD(double get_seconds() const, g_date_time_get_seconds)
   _WRAP_METHOD(gint64 to_unix() const, g_date_time_to_unix)
-  _WRAP_METHOD(bool to_timeval(TimeVal& tv) const, g_date_time_to_timeval)
+
+  _WRAP_METHOD_DOCS_ONLY(g_date_time_to_timeval)
+  bool to_timeval(TimeVal& tv) const;
+//TODO: Deprecate in the next minor stable release (glibmm 2.62.0?).
+//  _WRAP_METHOD(bool to_timeval(TimeVal& tv) const, g_date_time_to_timeval,
+//    deprecated "Use to_unix() instead.")
+
   _WRAP_METHOD(TimeSpan get_utc_offset() const, g_date_time_get_utc_offset)
 #m4 _CONVERSION(`GTimeZone*',`TimeZone',`Glib::wrap($3, true)')
   _WRAP_METHOD(TimeZone get_timezone() const, g_date_time_get_timezone, newin "2,60")
index 8763f87..c98a06e 100644 (file)
@@ -26,6 +26,7 @@ _IS_DEPRECATED // This whole file is deprecated.
 
 // We use GThreadFunctions in the (deprecated) API, so we must temporarily undef G_DISABLE_DEPRECATED.
 // Temporarily undef G_DISABLE_DEPRECATED, redefining it later if appropriate.
+// GLib ignores G_DISABLE_DEPRECATED since glib 2.61.2.
 #if defined(G_DISABLE_DEPRECATED) && !defined(GLIBMM_G_DISABLE_DEPRECATED_UNDEFED)
 //Stop the deprecation ifdef guards around the API declarations:
 #undef G_DISABLE_DEPRECATED
@@ -47,6 +48,9 @@ _IS_DEPRECATED // This whole file is deprecated.
 
 #include <cstddef>
 
+// Necessary for glib 2.61.2 and newer.
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+
 /* Shadow THREAD_PRIORITY_NORMAL macro (from winbase.h).
  */
 #if defined(THREAD_PRIORITY_NORMAL) && !defined(GLIBMM_MACRO_SHADOW_THREAD_PRIORITY_NORMAL)
@@ -1082,3 +1086,4 @@ void Private<T>::set(T* data)
 
 } // namespace Glib
 
+G_GNUC_END_IGNORE_DEPRECATIONS
index afa2f7f..1c2b0b5 100644 (file)
@@ -25,6 +25,10 @@ _DEFS(glibmm,glib)
 typedef struct _GTimeZone GTimeZone;
 #endif
 
+//TODO: When we can add API, add a Glib::Value specialization, similar to the one in
+// https://mail.gnome.org/archives/gtkmm-list/2019-April/msg00012.html
+//TODO: When we can change API, make TimeZone a _CLASS_BOXEDTYPE.
+
 namespace Glib
 {
 
@@ -32,7 +36,7 @@ _WRAP_ENUM(TimeType, GTimeType, NO_GTYPE)
 
 /** TimeZone - A structure representing a time zone.
  * TimeZone is a structure that represents a time zone, at no particular point
- * in time. It is refcounted and immutable.
+ * in time. It is immutable.
  *
  * A time zone contains a number of intervals. Each interval has an
  * abbreviation to describe it, an offet to UTC and a flag indicating if the
index 40732fe..662448f 100644 (file)
@@ -26,6 +26,7 @@ _DEFS(glibmm,glib)
 #include <utility>
 #include <vector>
 #include <map>
+#include <memory>
 #include <tuple>
 #include <stdexcept>
 #include <typeinfo>
@@ -1593,13 +1594,13 @@ Variant<std::tuple<Types...>>::create(const std::tuple<Types...>& data)
   detail::expand_tuple(variants, data, detail::index_sequence_for<Types...>{});
 
   using var_ptr = GVariant*;
-  var_ptr* const var_array = new var_ptr[sizeof... (Types)];
+  std::unique_ptr<var_ptr[]> var_array(new var_ptr[sizeof... (Types)]);
 
   for (std::vector<VariantBase>::size_type i = 0; i < variants.size(); i++)
     var_array[i] = const_cast<GVariant*>(variants[i].gobj());
 
   Variant<std::tuple<Types...>> result = Variant<std::tuple<Types...>>(
-          g_variant_new_tuple(var_array, variants.size()));
+          g_variant_new_tuple(var_array.get(), variants.size()));
 
   return result;
 }
index 1c0a79b..9ca95d2 100755 (executable)
 # GTK object conventions) and generates a set of scheme defs.
 #
 # h2def searches through a header file looking for function prototypes and
-# generates a scheme style defenition for each prototype.
+# generates a scheme style definition for each prototype.
 # Basically the operation of h2def is:
 #
 # - read each .h file into a buffer which is scrubbed of extraneous data
-# - find all object defenitions:
+# - find all object definitions:
 #   - find all structures that may represent a GtkObject
 #   - find all structures that might represent a class
 #   - find all structures that may represent a GtkObject subclass
 #   - find all structures that might represent a class/Iface inherited from
 #     GTypeInterface
-# - find all enum defenitions
+# - find all enum definitions
 # - write out the defs
 #
 # The command line options are:
@@ -294,8 +294,7 @@ def clean_func(buf):
     buf = pat.sub('', buf)
 
     #typedefs, structs, and enums
-    pat = re.compile(r"""^(typedef|struct|enum)(\s|.|\n)*?;\s*""",
-                     re.MULTILINE)
+    pat = re.compile(r"""^(typedef|struct|enum)(\s|.|\n)*?;\s*""", re.MULTILINE)
     buf = pat.sub('', buf)
 
     #strip DECLS macros
@@ -306,27 +305,23 @@ def clean_func(buf):
     pat = re.compile(r"""G_GNUC_WARN_UNUSED_RESULT|G_INLINE_FUNC""", re.MULTILINE)
     buf = pat.sub('', buf)
 
-    #strip *_DEPRECATED_IN_*_FOR (*)
-    #e.g. GDK_DEPRECATED_IN_*_FOR (*) and GDK_PIXBUF_DEPRECATED_IN_*_FOR (*)
-    pat = re.compile(r"""([A-Z]+_){1,2}?DEPRECATED_IN_[0-9]_([0-9]*)_FOR\s*\(.*\)\S*""", re.MULTILINE)
+    #strip G_GNUC_BEGIN_IGNORE_DEPRECATIONS and G_GNUC_END_IGNORE_DEPRECATIONS
+    pat = re.compile(r"""G_GNUC_(BEGIN|END)_IGNORE_DEPRECATIONS""", re.MULTILINE)
     buf = pat.sub('', buf)
 
-    #strip *_DEPRECATED*
-    pat = re.compile(r"""([A-Z]+_){1,2}?DEPRECATED\S*""", re.MULTILINE)
+    #strip *_DEPRECATED[_IN_n_m][_FOR (*)]
+    #e.g. GDK_DEPRECATED_IN_*_FOR (*) and GDK_PIXBUF_DEPRECATED_IN_*_FOR (*)
+    pat = re.compile(r"""([A-Z]+_){1,2}?DEPRECATED(_IN_[0-9]_[0-9]+)?(_FOR\s*\(.*?\))?""", re.MULTILINE)
     buf = pat.sub('', buf)
 
     #strip *_AVAILABLE_IN_*
-    pat = re.compile(r"""([A-Z]+_){1,2}?AVAILABLE_IN_[0-9]_[0-9]\S*""", re.MULTILINE)
+    pat = re.compile(r"""([A-Z]+_){1,2}?AVAILABLE_IN_[A-Z_0-9]+""", re.MULTILINE)
     buf = pat.sub('', buf)
 
-    #strip *_AVAILABLE_IN_ALL
-    pat = re.compile(r"""([A-Z]+_){1,2}?AVAILABLE_IN_ALL\S*""", re.MULTILINE)
+    #strip G_DECLARE_FINAL_TYPE (*) and G_DECLARE_INTERFACE (*)
+    pat = re.compile(r"""G_DECLARE_(FINAL_TYPE|INTERFACE)\s*\(.*?\)""", re.MULTILINE)
     buf = pat.sub('', buf)
 
-    #strip G_DECLARE_FINAL_TYPE (*)
-    pat = re.compile(r"""G_DECLARE_FINAL_TYPE\s*\(.*?\)""", re.MULTILINE)
-    buf = pat.sub('', buf)
-    
     #we are not stripping G_GNUC_INTERNAL
 
     #extern "C"
@@ -375,7 +370,7 @@ def clean_func(buf):
                 start = match.start()
             bracket_cnt += 1
         else:
-            if (bracket_cnt == 0): 
+            if (bracket_cnt == 0):
                 continue
             if (bracket_cnt == 1):
                 buf = buf.replace(buf[start:match.start()+1], "\n")
index 1b42a97..3091f11 100755 (executable)
@@ -68,6 +68,7 @@ sub parse($)
   my $from = 0;
   # 1, if only right bracket was found, not name.
   my $rbracket_only = 0;
+
   while(<$fd>)
   {
     my $tmp_rawline = $_;
@@ -116,7 +117,10 @@ sub parse($)
       }
       next;
     }
-    # XXX: what does it do?
+    # Replace the enumerator values ',' and '}' by strings that won't confuse
+    # process(). They are reset to the original strings when they are written
+    # to the output file.
+    # typedef enum { V1 = ',', V2 = '}' } E1; // is a legal definition.
     s/','/\%\%COMMA\%\%/;
     s/'}'/\%\%RBRACE\%\%/;
     # we have found an enum.
@@ -136,11 +140,14 @@ sub parse($)
        # between '}' and ';'.
        if (/;/)
        {
-         my $def = ($rbracket_only ? ("} " . $_) : ($_));
+         unless ($omit and /[A-Z]+_DEPRECATED_TYPE/)
+         {
+           my $def = ($rbracket_only ? ("} " . $_) : ($_));
+           print ";; Original typedef:\n";
+           print $raw_line . "\n";
+           process($line, $def);
+         }
          $enum = 0;
-         print ";; Original typedef:\n";
-         print $raw_line . "\n";
-         process($line, $def);
          $line = "";
          $raw_line = "";
          $rbracket_only = 0;
@@ -170,10 +177,11 @@ sub parse($)
 sub process($$)
 {
   my ($line,$def) = @_;
-  # strip whitespace and closing bracket before the name and whitespace and
-  # colon after the name.
-  $def =~ s/\s*\}\s*//g;
-  $def =~ s/\s*;\s*$//;
+  # The name is the first word after the closing bracket.
+  # The name can be followed by *_DEPRECATED_TYPE* or *_AVAILABLE_TYPE*
+  # before the semicolon.
+  $def =~ /^.*?(\w+)/;
+  $def = $1;
   my $c_name = $def;
   # replace all excessive whitespaces with one space.
   $line =~ s/\s+/ /g;
@@ -206,6 +214,12 @@ sub process($$)
 
   while ($iter < scalar @lines)
   {
+    # The enumerator name can be followed by *_DEPRECATED_ENUMERATOR*,
+    # *_DEPRECATED_ENUMERATOR*_FOR(*) or *_AVAILABLE_ENUMERATOR* before
+    # the equal sign or comma.
+    my $omit_enumerator = ($omit and $lines[$iter] =~ /[A-Z]+_DEPRECATED_ENUMERATOR/);
+    $lines[$iter] =~ s/^\s*(\w+)\s+\w+?_(:?DEPRECATED|AVAILABLE)_ENUMERATOR\w*(:?\s*\(.*?\))?/$1/;
+
     my $brackets_count = 0;
     my $begin = $iter;
 
@@ -225,6 +239,8 @@ sub process($$)
       } while ($iter < scalar @lines && $brackets_count != 0);
     }
 
+    next if ($omit_enumerator);
+
     my $i = join(',', @lines[$begin..$iter-1]);
 
     # remove leading and trailing spaces.
@@ -370,13 +386,14 @@ sub process($$)
       $unknown_flag = 0;
       $e_h{"enum"}++;
     }
-    # if... XXX: I do not know what is matched here.
+    # if it's one of the char values that were replaced by
+    # \%\%COMMA\%\% or \%\%RBRACE\%\%.
     elsif ($i =~ /^(\S+)\s*=\s*(\%\%[A-Z]+\%\%)$/)
     {
       my $tmp = $1;
       $_ = $2;
       s/\%\%COMMA\%\%/,/;
-      s/\%\%RBRACE\%\%/]/;
+      s/\%\%RBRACE\%\%/}/;
       push(@c_names, $tmp);
       push(@numbers, "\'$_\'");
       $val = ord($_);