summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-04-02 12:39:47 +0200
committerThomas Haller <thaller@redhat.com>2019-04-04 21:01:15 +0200
commit26d144d5a030875c3eaf62eb437a270f64ff729a (patch)
tree71114c46ada32a71d8c1b64c5a49e9eef99224a9
parent08c327f8a60e884752092a27195c3f2725a95790 (diff)
downloadNetworkManager-26d144d5a030875c3eaf62eb437a270f64ff729a.tar.gz
shared: move nm_memdup(), nm_strndup_a(), and nm_strdup_int() to "nm-macros-internal.h"
The main difference between "shared/nm-utils/nm-macros-internal.h" and "shared/nm-utils/nm-shared-utils.h" is that the former is header-only while the latter has a source file as well. Apart from that, both headers are included everywhere. The next commit will add nm_strstrip_avoid_copy_a() to "nm-macros-internal.h" header, which will use nm_strndup_a(). Hence, also nm_strndup_a() should be in "nm-macros-internal.h".
-rw-r--r--shared/nm-utils/nm-macros-internal.h112
-rw-r--r--shared/nm-utils/nm-shared-utils.h112
2 files changed, 112 insertions, 112 deletions
diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h
index 33ed5980d4..b2668f8e37 100644
--- a/shared/nm-utils/nm-macros-internal.h
+++ b/shared/nm-utils/nm-macros-internal.h
@@ -1464,6 +1464,118 @@ nm_strcmp_p (gconstpointer a, gconstpointer b)
/*****************************************************************************/
+/* like g_memdup(). The difference is that the @size argument is of type
+ * gsize, while g_memdup() has type guint. Since, the size of container types
+ * like GArray is guint as well, this means trying to g_memdup() an
+ * array,
+ * g_memdup (array->data, array->len * sizeof (ElementType))
+ * will lead to integer overflow, if there are more than G_MAXUINT/sizeof(ElementType)
+ * bytes. That seems unnecessarily dangerous to me.
+ * nm_memdup() avoids that, because its size argument is always large enough
+ * to contain all data that a GArray can hold.
+ *
+ * Another minor difference to g_memdup() is that the glib version also
+ * returns %NULL if @data is %NULL. E.g. g_memdup(NULL, 1)
+ * gives %NULL, but nm_memdup(NULL, 1) crashes. I think that
+ * is desirable, because @size MUST be correct at all times. @size
+ * may be zero, but one must not claim to have non-zero bytes when
+ * passing a %NULL @data pointer.
+ */
+static inline gpointer
+nm_memdup (gconstpointer data, gsize size)
+{
+ gpointer p;
+
+ if (size == 0)
+ return NULL;
+ p = g_malloc (size);
+ memcpy (p, data, size);
+ return p;
+}
+
+static inline char *
+_nm_strndup_a_step (char *s, const char *str, gsize len)
+{
+ NM_PRAGMA_WARNING_DISABLE ("-Wstringop-truncation");
+ if (len > 0)
+ strncpy (s, str, len);
+ s[len] = '\0';
+ return s;
+ NM_PRAGMA_WARNING_REENABLE;
+}
+
+/* Similar to g_strndup(), however, if the string (including the terminating
+ * NUL char) fits into alloca_maxlen, this will alloca() the memory.
+ *
+ * It's a mix of strndup() and strndupa(), but deciding based on @alloca_maxlen
+ * which one to use.
+ *
+ * In case malloc() is necessary, @out_str_free will be set (this string
+ * must be freed afterwards). It is permissible to pass %NULL as @out_str_free,
+ * if you ensure that len < alloca_maxlen.
+ *
+ * Note that just like g_strndup(), this always returns a buffer with @len + 1
+ * bytes, even if strlen(@str) is shorter than that (NUL terminated early). We fill
+ * the buffer with strncpy(), which means, that @str is copied up to the first
+ * NUL character and then filled with NUL characters. */
+#define nm_strndup_a(alloca_maxlen, str, len, out_str_free) \
+ ({ \
+ const gsize _alloca_maxlen_snd = (alloca_maxlen); \
+ const char *const _str_snd = (str); \
+ const gsize _len_snd = (len); \
+ char **const _out_str_free_snd = (out_str_free); \
+ char *_s_snd; \
+ \
+ G_STATIC_ASSERT_EXPR ((alloca_maxlen) <= 300); \
+ \
+ if ( _out_str_free_snd \
+ && _len_snd >= _alloca_maxlen_snd) { \
+ _s_snd = g_malloc (_len_snd + 1); \
+ *_out_str_free_snd = _s_snd; \
+ } else { \
+ g_assert (_len_snd < _alloca_maxlen_snd); \
+ _s_snd = g_alloca (_len_snd + 1); \
+ } \
+ _nm_strndup_a_step (_s_snd, _str_snd, _len_snd); \
+ })
+
+/*****************************************************************************/
+
+/* generic macro to convert an int to a (heap allocated) string.
+ *
+ * Usually, an inline function nm_strdup_int64() would be enough. However,
+ * that cannot be used for guint64. So, we would also need nm_strdup_uint64().
+ * This causes subtle error potential, because the caller needs to ensure to
+ * use the right one (and compiler isn't going to help as it silently casts).
+ *
+ * Instead, this generic macro is supposed to handle all integers correctly. */
+#if _NM_CC_SUPPORT_GENERIC
+#define nm_strdup_int(val) \
+ _Generic ((val), \
+ char: g_strdup_printf ("%d", (int) (val)), \
+ \
+ signed char: g_strdup_printf ("%d", (signed) (val)), \
+ signed short: g_strdup_printf ("%d", (signed) (val)), \
+ signed: g_strdup_printf ("%d", (signed) (val)), \
+ signed long: g_strdup_printf ("%ld", (signed long) (val)), \
+ signed long long: g_strdup_printf ("%lld", (signed long long) (val)), \
+ \
+ unsigned char: g_strdup_printf ("%u", (unsigned) (val)), \
+ unsigned short: g_strdup_printf ("%u", (unsigned) (val)), \
+ unsigned: g_strdup_printf ("%u", (unsigned) (val)), \
+ unsigned long: g_strdup_printf ("%lu", (unsigned long) (val)), \
+ unsigned long long: g_strdup_printf ("%llu", (unsigned long long) (val)) \
+ )
+#else
+#define nm_strdup_int(val) \
+ ( ( sizeof (val) == sizeof (guint64) \
+ && ((typeof (val)) -1) > 0) \
+ ? g_strdup_printf ("%"G_GUINT64_FORMAT, (guint64) (val)) \
+ : g_strdup_printf ("%"G_GINT64_FORMAT, (gint64) (val)))
+#endif
+
+/*****************************************************************************/
+
static inline guint
nm_encode_version (guint major, guint minor, guint micro)
{
diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h
index 3132d155b1..95ed5c946f 100644
--- a/shared/nm-utils/nm-shared-utils.h
+++ b/shared/nm-utils/nm-shared-utils.h
@@ -258,118 +258,6 @@ gboolean nm_utils_memeqzero (gconstpointer data, gsize length);
/*****************************************************************************/
-/* like g_memdup(). The difference is that the @size argument is of type
- * gsize, while g_memdup() has type guint. Since, the size of container types
- * like GArray is guint as well, this means trying to g_memdup() an
- * array,
- * g_memdup (array->data, array->len * sizeof (ElementType))
- * will lead to integer overflow, if there are more than G_MAXUINT/sizeof(ElementType)
- * bytes. That seems unnecessarily dangerous to me.
- * nm_memdup() avoids that, because its size argument is always large enough
- * to contain all data that a GArray can hold.
- *
- * Another minor difference to g_memdup() is that the glib version also
- * returns %NULL if @data is %NULL. E.g. g_memdup(NULL, 1)
- * gives %NULL, but nm_memdup(NULL, 1) crashes. I think that
- * is desirable, because @size MUST be correct at all times. @size
- * may be zero, but one must not claim to have non-zero bytes when
- * passing a %NULL @data pointer.
- */
-static inline gpointer
-nm_memdup (gconstpointer data, gsize size)
-{
- gpointer p;
-
- if (size == 0)
- return NULL;
- p = g_malloc (size);
- memcpy (p, data, size);
- return p;
-}
-
-static inline char *
-_nm_strndup_a_step (char *s, const char *str, gsize len)
-{
- NM_PRAGMA_WARNING_DISABLE ("-Wstringop-truncation");
- if (len > 0)
- strncpy (s, str, len);
- s[len] = '\0';
- return s;
- NM_PRAGMA_WARNING_REENABLE;
-}
-
-/* Similar to g_strndup(), however, if the string (including the terminating
- * NUL char) fits into alloca_maxlen, this will alloca() the memory.
- *
- * It's a mix of strndup() and strndupa(), but deciding based on @alloca_maxlen
- * which one to use.
- *
- * In case malloc() is necessary, @out_str_free will be set (this string
- * must be freed afterwards). It is permissible to pass %NULL as @out_str_free,
- * if you ensure that len < alloca_maxlen.
- *
- * Note that just like g_strndup(), this always returns a buffer with @len + 1
- * bytes, even if strlen(@str) is shorter than that (NUL terminated early). We fill
- * the buffer with strncpy(), which means, that @str is copied up to the first
- * NUL character and then filled with NUL characters. */
-#define nm_strndup_a(alloca_maxlen, str, len, out_str_free) \
- ({ \
- const gsize _alloca_maxlen_snd = (alloca_maxlen); \
- const char *const _str_snd = (str); \
- const gsize _len_snd = (len); \
- char **const _out_str_free_snd = (out_str_free); \
- char *_s_snd; \
- \
- G_STATIC_ASSERT_EXPR ((alloca_maxlen) <= 300); \
- \
- if ( _out_str_free_snd \
- && _len_snd >= _alloca_maxlen_snd) { \
- _s_snd = g_malloc (_len_snd + 1); \
- *_out_str_free_snd = _s_snd; \
- } else { \
- g_assert (_len_snd < _alloca_maxlen_snd); \
- _s_snd = g_alloca (_len_snd + 1); \
- } \
- _nm_strndup_a_step (_s_snd, _str_snd, _len_snd); \
- })
-
-/*****************************************************************************/
-
-/* generic macro to convert an int to a (heap allocated) string.
- *
- * Usually, an inline function nm_strdup_int64() would be enough. However,
- * that cannot be used for guint64. So, we would also need nm_strdup_uint64().
- * This causes subtle error potential, because the caller needs to ensure to
- * use the right one (and compiler isn't going to help as it silently casts).
- *
- * Instead, this generic macro is supposed to handle all integers correctly. */
-#if _NM_CC_SUPPORT_GENERIC
-#define nm_strdup_int(val) \
- _Generic ((val), \
- char: g_strdup_printf ("%d", (int) (val)), \
- \
- signed char: g_strdup_printf ("%d", (signed) (val)), \
- signed short: g_strdup_printf ("%d", (signed) (val)), \
- signed: g_strdup_printf ("%d", (signed) (val)), \
- signed long: g_strdup_printf ("%ld", (signed long) (val)), \
- signed long long: g_strdup_printf ("%lld", (signed long long) (val)), \
- \
- unsigned char: g_strdup_printf ("%u", (unsigned) (val)), \
- unsigned short: g_strdup_printf ("%u", (unsigned) (val)), \
- unsigned: g_strdup_printf ("%u", (unsigned) (val)), \
- unsigned long: g_strdup_printf ("%lu", (unsigned long) (val)), \
- unsigned long long: g_strdup_printf ("%llu", (unsigned long long) (val)) \
- )
-#else
-#define nm_strdup_int(val) \
- ( ( sizeof (val) == sizeof (guint64) \
- && ((typeof (val)) -1) > 0) \
- ? g_strdup_printf ("%"G_GUINT64_FORMAT, (guint64) (val)) \
- : g_strdup_printf ("%"G_GINT64_FORMAT, (gint64) (val)))
-#endif
-
-/*****************************************************************************/
-
extern const void *const _NM_PTRARRAY_EMPTY[1];
#define NM_PTRARRAY_EMPTY(type) ((type const*) _NM_PTRARRAY_EMPTY)