From 7621553f68acbcb6dbc9be782c599b77246cce29 Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Wed, 5 May 2021 14:05:20 +0300 Subject: [PATCH 01/10] [glibutil] Slightly optimized gutil_parse_int() Avoided unnecessary duplication of the input string and removed unnecessary errno check. --- src/gutil_misc.c | 37 ++++++++++++++++++++++++++----------- test/test_misc/test_misc.c | 12 +++++++++--- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/gutil_misc.c b/src/gutil_misc.c index dd8cf19..5fd0149 100644 --- a/src/gutil_misc.c +++ b/src/gutil_misc.c @@ -36,7 +36,6 @@ #include #include -#include void gutil_disconnect_handlers( @@ -153,36 +152,52 @@ gutil_hexdump( return bytes_dumped; } -/* Since 1.0.30 */ +static +const char* +gutil_strstrip( + const char* str, + char** tmp) +{ + /* Caller makes sure that str isn't NULL */ + const gsize len = strlen(str); + + if (g_ascii_isspace(str[0]) || g_ascii_isspace(str[len - 1])) { + /* Need to modify the original string */ + return (*tmp = g_strstrip(gutil_memdup(str, len + 1))); + } else { + /* The original string is fine as is */ + return str; + } +} + gboolean gutil_parse_int( const char* str, int base, - int* value) + int* value) /* Since 1.0.30 */ { gboolean ok = FALSE; if (str && str[0]) { - char* str2 = g_strstrip(g_strdup(str)); - char* end = str2; + char* tmp = NULL; + char* end = NULL; + const char* stripped = gutil_strstrip(str, &tmp); gint64 l; - errno = 0; - l = g_ascii_strtoll(str2, &end, base); - ok = !*end && errno != ERANGE && l >= INT_MIN && l <= INT_MAX; + l = g_ascii_strtoll(stripped, &end, base); + ok = !*end && l >= INT_MIN && l <= INT_MAX; if (ok && value) { *value = (int)l; } - g_free(str2); + g_free(tmp); } return ok; } -/* since 1.0.31 */ gboolean gutil_data_equal( const GUtilData* data1, - const GUtilData* data2) + const GUtilData* data2) /* Since 1.0.31 */ { if (data1 == data2) { return TRUE; diff --git a/test/test_misc/test_misc.c b/test/test_misc/test_misc.c index 8742c76..781eedb 100644 --- a/test/test_misc/test_misc.c +++ b/test/test_misc/test_misc.c @@ -175,14 +175,20 @@ test_parse_int( g_assert(!gutil_parse_int("0 trailing garbage", 0, NULL)); g_assert(gutil_parse_int("0", 0, NULL)); g_assert(gutil_parse_int("0", 0, &value)); - g_assert(value == 0); + g_assert_cmpint(value, == ,0); + g_assert(gutil_parse_int("-1", 0, &value)); + g_assert_cmpint(value, == ,-1); + g_assert(gutil_parse_int("42", 0, &value)); + g_assert_cmpint(value, == ,42); g_assert(!gutil_parse_int("0x10000000000000000", 0, &value)); g_assert(!gutil_parse_int("-2147483649", 0, &value)); g_assert(!gutil_parse_int("4294967295", 0, &value)); g_assert(gutil_parse_int(" 0x7fffffff ", 0, &value)); - g_assert(value == 0x7fffffff); + g_assert_cmpint(value, == ,0x7fffffff); g_assert(gutil_parse_int(" 7fffffff ", 16, &value)); - g_assert(value == 0x7fffffff); + g_assert_cmpint(value, == ,0x7fffffff); + g_assert(gutil_parse_int("7ffffffe ", 16, &value)); + g_assert_cmpint(value, == ,0x7ffffffe); g_assert(!gutil_parse_int("0xffffffff", 0, &value)); } From 75f1a27bb6932b2c8b88b45ec5fda5fcf3e80507 Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Wed, 5 May 2021 15:29:10 +0300 Subject: [PATCH 02/10] [glibutil] Added gutil_parse_uint() --- include/gutil_misc.h | 6 ++++++ src/gutil_misc.c | 24 ++++++++++++++++++++++++ test/test_misc/test_misc.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/include/gutil_misc.h b/include/gutil_misc.h index 4f322e0..a195a6d 100644 --- a/include/gutil_misc.h +++ b/include/gutil_misc.h @@ -69,6 +69,12 @@ gutil_parse_int( int base, int* value); /* Since 1.0.30 */ +gboolean +gutil_parse_uint( + const char* str, + int base, + unsigned int* value); /* Since 1.0.53 */ + gboolean gutil_data_equal( const GUtilData* data1, diff --git a/src/gutil_misc.c b/src/gutil_misc.c index 5fd0149..743a917 100644 --- a/src/gutil_misc.c +++ b/src/gutil_misc.c @@ -194,6 +194,30 @@ gutil_parse_int( return ok; } +gboolean +gutil_parse_uint( + const char* str, + int base, + unsigned int* value) /* Since 1.0.53 */ +{ + gboolean ok = FALSE; + + if (str && str[0]) { + char* tmp = NULL; + char* end = NULL; + const char* stripped = gutil_strstrip(str, &tmp); + guint64 ull; + + ull = g_ascii_strtoull(stripped, &end, base); + ok = !*end && ull <= UINT_MAX; + if (ok && value) { + *value = (unsigned int)ull; + } + g_free(tmp); + } + return ok; +} + gboolean gutil_data_equal( const GUtilData* data1, diff --git a/test/test_misc/test_misc.c b/test/test_misc/test_misc.c index 781eedb..aff5606 100644 --- a/test/test_misc/test_misc.c +++ b/test/test_misc/test_misc.c @@ -192,6 +192,41 @@ test_parse_int( g_assert(!gutil_parse_int("0xffffffff", 0, &value)); } +/*==========================================================================* + * parse_uint + *==========================================================================*/ + +static +void +test_parse_uint( + void) +{ + unsigned int value; + + g_assert(!gutil_parse_uint(NULL, 0, NULL)); + g_assert(!gutil_parse_uint("", 0, NULL)); + g_assert(!gutil_parse_uint("garbage", 0, NULL)); + g_assert(!gutil_parse_uint("0 trailing garbage", 0, NULL)); + g_assert(gutil_parse_uint("0", 0, NULL)); + g_assert(gutil_parse_uint("0", 0, &value)); + g_assert_cmpuint(value, == ,0); + g_assert(gutil_parse_uint("42", 0, &value)); + g_assert_cmpuint(value, == ,42); + g_assert(!gutil_parse_uint("0x10000000000000000", 0, &value)); + g_assert(!gutil_parse_uint("-2147483649", 0, &value)); + g_assert(!gutil_parse_uint("-1", 0, &value)); + g_assert(gutil_parse_uint("4294967295", 0, &value)); + g_assert_cmpuint(value, == ,4294967295); + g_assert(gutil_parse_uint(" 0x7fffffff ", 0, &value)); + g_assert_cmpuint(value, == ,0x7fffffff); + g_assert(gutil_parse_uint(" 7fffffff ", 16, &value)); + g_assert_cmpuint(value, == ,0x7fffffff); + g_assert(gutil_parse_uint("7ffffffe ", 16, &value)); + g_assert_cmpuint(value, == ,0x7ffffffe); + g_assert(gutil_parse_uint("0xffffffff", 0, &value)); + g_assert_cmpuint(value, == ,0xffffffff); +} + /*==========================================================================* * data_equal *==========================================================================*/ @@ -567,6 +602,7 @@ int main(int argc, char* argv[]) g_test_add_func(TEST_("hex2bin"), test_hex2bin); g_test_add_func(TEST_("hexdump"), test_hexdump); g_test_add_func(TEST_("parse_int"), test_parse_int); + g_test_add_func(TEST_("parse_uint"), test_parse_uint); g_test_add_func(TEST_("data_equal"), test_data_equal); g_test_add_func(TEST_("data_prefix"), test_data_prefix); g_test_add_func(TEST_("data_suffix"), test_data_suffix); From 5de5f472c3263cf5b32c1c8d31c26396e0893a38 Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Wed, 5 May 2021 16:26:36 +0300 Subject: [PATCH 03/10] [glibutil] Housekeeping --- src/gutil_misc.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/gutil_misc.c b/src/gutil_misc.c index 743a917..796a81f 100644 --- a/src/gutil_misc.c +++ b/src/gutil_misc.c @@ -45,6 +45,7 @@ gutil_disconnect_handlers( { if (G_LIKELY(instance) && G_LIKELY(ids)) { int i; + for (i=0; i 0 && !(len & 1)) { gssize i; guint8* ptr = data; + for (i=0; i 0 && !(len & 1)) { - void* data = g_malloc(len/2); + const gsize n = len/2; + void* data = g_malloc(n); + if (gutil_hex2bin(str, len, data)) { - return g_bytes_new_take(data, len/2); + return g_bytes_new_take(data, n); } g_free(data); } @@ -182,12 +187,11 @@ gutil_parse_int( char* tmp = NULL; char* end = NULL; const char* stripped = gutil_strstrip(str, &tmp); - gint64 l; + const gint64 ll = g_ascii_strtoll(stripped, &end, base); - l = g_ascii_strtoll(stripped, &end, base); - ok = !*end && l >= INT_MIN && l <= INT_MAX; + ok = !*end && ll >= INT_MIN && ll <= INT_MAX; if (ok && value) { - *value = (int)l; + *value = (int)ll; } g_free(tmp); } @@ -206,9 +210,8 @@ gutil_parse_uint( char* tmp = NULL; char* end = NULL; const char* stripped = gutil_strstrip(str, &tmp); - guint64 ull; + const guint64 ull = g_ascii_strtoull(stripped, &end, base); - ull = g_ascii_strtoull(stripped, &end, base); ok = !*end && ull <= UINT_MAX; if (ok && value) { *value = (unsigned int)ull; From c988372b9183d66233b70c29adba7a4bbd405528 Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Wed, 5 May 2021 16:26:57 +0300 Subject: [PATCH 04/10] Version 1.0.53 --- Makefile | 2 +- debian/changelog | 7 +++++++ rpm/libglibutil.spec | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 78b50d5..9e8e43b 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ all: debug release pkgconfig VERSION_MAJOR = 1 VERSION_MINOR = 0 -VERSION_RELEASE = 52 +VERSION_RELEASE = 53 # Version for pkg-config PCVERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE) diff --git a/debian/changelog b/debian/changelog index 9167c24..52e401a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +libglibutil (1.0.53) unstable; urgency=low + + * Optimized gutil_parse_int() + * Added gutil_parse_uint() + + -- Slava Monich Wed, 05 May 2021 15:30:57 +0300 + libglibutil (1.0.52) unstable; urgency=low * Added gutil_memdup() diff --git a/rpm/libglibutil.spec b/rpm/libglibutil.spec index e656a2c..ac9d047 100644 --- a/rpm/libglibutil.spec +++ b/rpm/libglibutil.spec @@ -1,5 +1,5 @@ Name: libglibutil -Version: 1.0.52 +Version: 1.0.53 Release: 0 Summary: Library of glib utilities License: BSD From 24ca68f072cf789301f53470e68b3f4adeb768b1 Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Sat, 8 May 2021 00:37:20 +0300 Subject: [PATCH 05/10] [glibutil] Tweaked interpretation of environment variables Two subsequent checks for (val > 0) didn't make any sense. --- src/gutil_log.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gutil_log.c b/src/gutil_log.c index 27162dc..ce99f31 100644 --- a/src/gutil_log.c +++ b/src/gutil_log.c @@ -657,12 +657,12 @@ gutil_log_init() GDEBUG("Default log level %d", val); } - if (gutil_parse_int(getenv("GUTIL_LOG_TIMESTAMP"), 0, &val) && val > 0) { + if (gutil_parse_int(getenv("GUTIL_LOG_TIMESTAMP"), 0, &val) && val >= 0) { gutil_log_timestamp = (val > 0); GDEBUG("Timestamps %s", (val > 0) ? "enabled" : "disabled"); } - if (gutil_parse_int(getenv("GUTIL_LOG_TID"), 0, &val) && val > 0) { + if (gutil_parse_int(getenv("GUTIL_LOG_TID"), 0, &val) && val >= 0) { gutil_log_tid = (val > 0); GDEBUG("Thread id prefix %s", (val > 0) ? "enabled" : "disabled"); } From aa396ac95852961a80cb0633906a223a51bb6407 Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Mon, 17 May 2021 16:05:37 +0300 Subject: [PATCH 06/10] [glibutil] Added GUtilRange type --- include/gutil_types.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/include/gutil_types.h b/include/gutil_types.h index 6fc4b85..907ecdd 100644 --- a/include/gutil_types.h +++ b/include/gutil_types.h @@ -1,6 +1,6 @@ /* - * Copyright (C) 2014-2018 Jolla Ltd. - * Copyright (C) 2014-2018 Slava Monich + * Copyright (C) 2014-2021 Jolla Ltd. + * Copyright (C) 2014-2021 Slava Monich * * You may use this file under the terms of BSD license as follows: * @@ -14,8 +14,8 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -54,6 +54,11 @@ typedef struct gutil_data { gsize size; } GUtilData; +typedef struct gutil_range { + const guint8* ptr; + const guint8* end; +} GUtilRange; /* Since 1.0.54 */ + #define GLOG_MODULE_DECL(m) extern GLogModule m; typedef struct glog_module GLogModule; From b5359fbc20f5130f281f5031be4b240001b96878 Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Mon, 17 May 2021 16:08:22 +0300 Subject: [PATCH 07/10] Version 1.0.54 --- Makefile | 2 +- debian/changelog | 7 +++++++ rpm/libglibutil.spec | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 9e8e43b..f4a5343 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ all: debug release pkgconfig VERSION_MAJOR = 1 VERSION_MINOR = 0 -VERSION_RELEASE = 53 +VERSION_RELEASE = 54 # Version for pkg-config PCVERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE) diff --git a/debian/changelog b/debian/changelog index 52e401a..65679e0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +libglibutil (1.0.54) unstable; urgency=low + + * Added GUtilRange type + * Tweaked interpretation of environment variables + + -- Slava Monich Mon, 17 May 2021 16:06:25 +0300 + libglibutil (1.0.53) unstable; urgency=low * Optimized gutil_parse_int() diff --git a/rpm/libglibutil.spec b/rpm/libglibutil.spec index ac9d047..daebeb5 100644 --- a/rpm/libglibutil.spec +++ b/rpm/libglibutil.spec @@ -1,5 +1,5 @@ Name: libglibutil -Version: 1.0.53 +Version: 1.0.54 Release: 0 Summary: Library of glib utilities License: BSD From b6d240ca18754e957d6a66f2b258caed6f370622 Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Sun, 23 May 2021 02:51:15 +0300 Subject: [PATCH 08/10] [glibutil] Added range utilities New functions are useful for parsing binary data: gutil_range_init_with_bytes() gutil_range_has_prefix() gutil_range_skip_prefix() --- include/gutil_misc.h | 15 ++++++++ src/gutil_misc.c | 46 ++++++++++++++++++++++ test/test_misc/test_misc.c | 78 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) diff --git a/include/gutil_misc.h b/include/gutil_misc.h index a195a6d..96f113d 100644 --- a/include/gutil_misc.h +++ b/include/gutil_misc.h @@ -136,6 +136,21 @@ gutil_memdup( const void* ptr, gsize size); /* Since 1.0.52 */ +gsize +gutil_range_init_with_bytes( + GUtilRange* range, + GBytes* bytes); /* Since 1.0.55 */ + +gboolean +gutil_range_has_prefix( + const GUtilRange* range, + const GUtilData* prefix); /* Since 1.0.55 */ + +gboolean +gutil_range_skip_prefix( + GUtilRange* range, + const GUtilData* prefix); /* Since 1.0.55 */ + G_END_DECLS #endif /* GUTIL_MISC_H */ diff --git a/src/gutil_misc.c b/src/gutil_misc.c index 796a81f..31a3d86 100644 --- a/src/gutil_misc.c +++ b/src/gutil_misc.c @@ -502,6 +502,52 @@ gutil_memdup( } } +gsize +gutil_range_init_with_bytes( + GUtilRange* range, + GBytes* bytes) /* Since 1.0.55 */ +{ + gsize size = 0; + + if (G_LIKELY(range)) { + if (G_LIKELY(bytes)) { + range->ptr = (const guint8*) g_bytes_get_data(bytes, &size); + range->end = range->ptr + size; + } else { + memset(range, 0, sizeof(*range)); + } + } + return size; +} + +gboolean +gutil_range_has_prefix( + const GUtilRange* range, + const GUtilData* prefix) /* Since 1.0.55 */ +{ + if (G_LIKELY(range) && G_LIKELY(range->ptr) && G_LIKELY(prefix)) { + if (range->end > range->ptr) { + return (gsize)(range->end - range->ptr) >= prefix->size && + !memcmp(range->ptr, prefix->bytes, prefix->size); + } else { + return !prefix->size; + } + } + return FALSE; +} + +gboolean +gutil_range_skip_prefix( + GUtilRange* range, + const GUtilData* prefix) /* Since 1.0.55 */ +{ + if (gutil_range_has_prefix(range, prefix)) { + range->ptr += prefix->size; + return TRUE; + } + return FALSE; +} + /* * Local Variables: * mode: C diff --git a/test/test_misc/test_misc.c b/test/test_misc/test_misc.c index aff5606..31de279 100644 --- a/test/test_misc/test_misc.c +++ b/test/test_misc/test_misc.c @@ -581,6 +581,82 @@ test_memdup( g_assert(!gutil_memdup(NULL, 1)); } +/*==========================================================================* + * range_init + *==========================================================================*/ + +static +void +test_range_init( + void) +{ + static const guint8 data[] = { 0x01, 0x02, 0x03 }; + GBytes* bytes = g_bytes_new_static(data, sizeof(data)); + GUtilRange range; + + g_assert(!gutil_range_init_with_bytes(NULL, NULL)); + g_assert(!gutil_range_init_with_bytes(&range, NULL)); + g_assert(!range.ptr); + g_assert(!range.end); + + g_assert(gutil_range_init_with_bytes(&range, bytes) == sizeof(data)); + g_assert(range.ptr == data); + g_assert(range.end == (data + sizeof(data))); + g_bytes_unref(bytes); +} + +/*==========================================================================* + * range_prefix + *==========================================================================*/ + +static +void +test_range_prefix( + void) +{ + static const guint8 data[] = { 0x01, 0x02, 0x03, 0x04 }; + static const guint8 prefix[] = { 0x01, 0x02 }; + static const guint8 not_prefix[] = { 0x03, 0x04 }; + static const guint8 too_long[] = { 0x01, 0x02, 0x03, 0x04, 0x05 }; + GUtilData prefix_data, not_prefix_data, too_long_data; + GUtilRange range; + + memset(&range, 0, sizeof(range)); + g_assert(!gutil_range_has_prefix(NULL, NULL)); + g_assert(!gutil_range_has_prefix(&range, NULL)); + + not_prefix_data.bytes = not_prefix; + not_prefix_data.size = sizeof(not_prefix); + too_long_data.bytes = too_long; + too_long_data.size = sizeof(too_long); + + range.end = range.ptr = data; /* Empty range */ + memset(&prefix_data, 0, sizeof(prefix_data)); /* Empty prefix */ + /* Empty range doesn't have NULL prefix */ + g_assert(!gutil_range_has_prefix(&range, NULL)); + /* But does have empty prefix */ + g_assert(gutil_range_has_prefix(&range, &prefix_data)); + + /* And doesn't have non-empty prefix */ + g_assert(!gutil_range_has_prefix(&range, ¬_prefix_data)); + prefix_data.bytes = prefix; + prefix_data.size = sizeof(prefix); + g_assert(!gutil_range_has_prefix(&range, &prefix_data)); + + range.end = range.ptr + sizeof(data); + + g_assert(gutil_range_has_prefix(&range, &prefix_data)); + g_assert(!gutil_range_has_prefix(&range, ¬_prefix_data)); + g_assert(!gutil_range_has_prefix(&range, &too_long_data)); + + /* Test skipping */ + g_assert(!gutil_range_skip_prefix(&range, ¬_prefix_data)); + g_assert(range.ptr == data); + + g_assert(gutil_range_skip_prefix(&range, &prefix_data)); + g_assert(range.ptr == (data + prefix_data.size)); +} + /*==========================================================================* * Common *==========================================================================*/ @@ -614,6 +690,8 @@ int main(int argc, char* argv[]) g_test_add_func(TEST_("ptrv_lenght"), test_ptrv_length); g_test_add_func(TEST_("ptrv_free"), test_ptrv_free); g_test_add_func(TEST_("memdup"), test_memdup); + g_test_add_func(TEST_("range_init"), test_range_init); + g_test_add_func(TEST_("range_prefix"), test_range_prefix); test_init(&test_opt, argc, argv); return g_test_run(); } From b4d1bf7c1c36388a72d52797eb5ee9167472c1e8 Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Sun, 23 May 2021 03:29:16 +0300 Subject: [PATCH 09/10] [glibutil] Added gutil_log_dump function It's intended to be used via GDEBUG_DUMP macro. --- include/gutil_log.h | 15 +++++- src/gutil_log.c | 24 +++++++++ test/test_log/test_log.c | 110 +++++++++++++++++++++++++++------------ 3 files changed, 114 insertions(+), 35 deletions(-) diff --git a/include/gutil_log.h b/include/gutil_log.h index e07f2fb..46f51ad 100644 --- a/include/gutil_log.h +++ b/include/gutil_log.h @@ -14,8 +14,8 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -139,6 +139,14 @@ gutil_logv( const char* format, va_list va); +void +gutil_log_dump( + const GLogModule* module, + int level, + const char* prefix, + const void* data, + gsize size); /* Since 1.0.55 */ + /* Check if logging is enabled for the specified log level */ gboolean gutil_log_enabled( @@ -318,9 +326,12 @@ gutil_log_assert( GLOG_LEVEL_DEBUG, f, ##args) # define GDEBUG_(f,args...) gutil_log(GLOG_MODULE_CURRENT, \ GLOG_LEVEL_DEBUG, "%s() " f, __FUNCTION__, ##args) +# define GDEBUG_DUMP(buf,n) gutil_log_dump(GLOG_MODULE_CURRENT, \ + GLOG_LEVEL_DEBUG, NULL, buf, n) /* Since 1.0.55 */ # else # define GDEBUG(f,args...) GLOG_NOTHING # define GDEBUG_(f,args...) GLOG_NOTHING +# define GDEBUG_DUMP(buf,n) GLOG_NOTHING /* Since 1.0.55 */ # endif /* GUTIL_LOG_DEBUG */ #else # define GDEBUG_ GDEBUG diff --git a/src/gutil_log.c b/src/gutil_log.c index ce99f31..c95b403 100644 --- a/src/gutil_log.c +++ b/src/gutil_log.c @@ -490,6 +490,30 @@ gutil_log_enabled( return FALSE; } +void +gutil_log_dump( + const GLogModule* module, + int level, + const char* prefix, + const void* data, + gsize size) /* Since 1.0.55 */ +{ + if (gutil_log_enabled(module, level)) { + const guint8* ptr = data; + guint off = 0; + + if (!prefix) prefix = ""; + while (size > 0) { + char buf[GUTIL_HEXDUMP_BUFSIZE]; + const guint consumed = gutil_hexdump(buf, ptr + off, size); + + gutil_log(module, level, "%s%04X: %s", prefix, off, buf); + size -= consumed; + off += consumed; + } + } +} + /* gutil_log_parse_option helper */ static int diff --git a/test/test_log/test_log.c b/test/test_log/test_log.c index 80f262d..8b32e1f 100644 --- a/test/test_log/test_log.c +++ b/test/test_log/test_log.c @@ -1,6 +1,6 @@ /* - * Copyright (C) 2017-2019 Jolla Ltd. - * Copyright (C) 2017-2019 Slava Monich + * Copyright (C) 2017-2021 Jolla Ltd. + * Copyright (C) 2017-2021 Slava Monich * * You may use this file under the terms of BSD license as follows: * @@ -14,8 +14,8 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -41,24 +41,24 @@ #include "gutil_log.h" static TestOpt test_opt; - -/*==========================================================================* - * Basic - *==========================================================================*/ - -static GString* test_log_basic_buf; +static GString* test_log_buf; static void -test_log_basic_fn( +test_log_fn( const char* name, int level, const char* format, va_list va) { - g_string_append_vprintf(test_log_basic_buf, format, va); + g_string_append_vprintf(test_log_buf, format, va); + g_string_append_c(test_log_buf, '\n'); } +/*==========================================================================* + * Basic + *==========================================================================*/ + static void test_log_basic( @@ -68,8 +68,8 @@ test_log_basic( const GLogProc2 fn2 = gutil_log_func2; const int level = gutil_log_default.level; GLOG_MODULE_DEFINE2_(module, "test", gutil_log_default); - test_log_basic_buf = g_string_new(NULL); - gutil_log_func = test_log_basic_fn; + test_log_buf = g_string_new(NULL); + gutil_log_func = test_log_fn; module.level = GLOG_LEVEL_INHERIT; gutil_log_default.level = GLOG_LEVEL_ERR; @@ -77,10 +77,10 @@ test_log_basic( gutil_log(NULL, GLOG_LEVEL_DEBUG, "Debug!"); gutil_log(&module, GLOG_LEVEL_DEBUG, "Debug!"); gutil_log_assert(NULL, GLOG_LEVEL_WARN, "Test!", __FILE__, __LINE__); - g_assert(!test_log_basic_buf->len); + g_assert(!test_log_buf->len); gutil_log(&module, GLOG_LEVEL_ERR, "Err!"); - g_assert(test_log_basic_buf->len); - g_string_set_size(test_log_basic_buf, 0); + g_assert(test_log_buf->len); + g_string_set_size(test_log_buf, 0); /* With NULL parent, still gutil_log_default is going to be checked */ module.parent = NULL; @@ -88,19 +88,19 @@ test_log_basic( gutil_log(NULL, GLOG_LEVEL_DEBUG, "Debug!"); gutil_log(&module, GLOG_LEVEL_DEBUG, "Debug!"); gutil_log_assert(NULL, GLOG_LEVEL_WARN, "Test!", __FILE__, __LINE__); - g_assert(!test_log_basic_buf->len); + g_assert(!test_log_buf->len); gutil_log(&module, GLOG_LEVEL_ERR, "Err!"); - g_assert(test_log_basic_buf->len); - g_string_set_size(test_log_basic_buf, 0); + g_assert(test_log_buf->len); + g_string_set_size(test_log_buf, 0); gutil_log(&module, GLOG_LEVEL_ALWAYS, "Always!"); - g_assert(test_log_basic_buf->len); - g_string_set_size(test_log_basic_buf, 0); + g_assert(test_log_buf->len); + g_string_set_size(test_log_buf, 0); /* Test GLOG_FLAG_DISABLE */ module.flags |= GLOG_FLAG_DISABLE; gutil_log(&module, GLOG_LEVEL_ALWAYS, "Always!"); - g_assert(!test_log_basic_buf->len); + g_assert(!test_log_buf->len); module.flags &= ~GLOG_FLAG_DISABLE; /* Without log functions these calls have no effect */ @@ -109,8 +109,8 @@ test_log_basic( gutil_log_func2 = NULL; gutil_log(NULL, GLOG_LEVEL_ALWAYS, "Always!"); - g_string_free(test_log_basic_buf, TRUE); - test_log_basic_buf = NULL; + g_string_free(test_log_buf, TRUE); + test_log_buf = NULL; gutil_log_default.level = level; gutil_log_func = fn; gutil_log_func2 = fn2; @@ -169,7 +169,7 @@ test_log_file( stdout = default_stdout; g_assert(fflush(out) == 0); GDEBUG("%s", buf->str); - g_assert(!g_strcmp0(buf->str, "WARNING: Test\n")); + g_assert_cmpstr(buf->str, == ,"WARNING: Test\n"); g_string_set_size(buf, 0); /* Error prefix */ @@ -178,7 +178,7 @@ test_log_file( stdout = default_stdout; g_assert(fflush(out) == 0); GDEBUG("%s", buf->str); - g_assert(!g_strcmp0(buf->str, "ERROR: Test\n")); + g_assert_cmpstr(buf->str, == ,"ERROR: Test\n"); g_string_set_size(buf, 0); /* Empty name (dropped) */ @@ -188,7 +188,7 @@ test_log_file( stdout = default_stdout; g_assert(fflush(out) == 0); GDEBUG("%s", buf->str); - g_assert(!g_strcmp0(buf->str, "Test\n")); + g_assert_cmpstr(buf->str, == ,"Test\n"); g_string_set_size(buf, 0); /* Non-empty name */ @@ -198,7 +198,7 @@ test_log_file( stdout = default_stdout; g_assert(fflush(out) == 0); GDEBUG("%s", buf->str); - g_assert(!g_strcmp0(buf->str, "[test] Test\n")); + g_assert_cmpstr(buf->str, == ,"[test] Test\n"); g_string_set_size(buf, 0); /* Hide the name */ @@ -208,7 +208,7 @@ test_log_file( stdout = default_stdout; g_assert(fflush(out) == 0); GDEBUG("%s", buf->str); - g_assert(!g_strcmp0(buf->str, "Test\n")); + g_assert_cmpstr(buf->str, == ,"Test\n"); g_string_set_size(buf, 0); /* Forward output to test_log_drop */ @@ -284,13 +284,56 @@ test_log_misc( const GLogProc fn = gutil_log_func; g_assert(gutil_log_set_type(GLOG_TYPE_STDOUT, "test")); g_assert(gutil_log_func == gutil_log_stdout); - g_assert(!g_strcmp0(gutil_log_get_type(), GLOG_TYPE_STDOUT)); + g_assert_cmpstr(gutil_log_get_type(), == ,GLOG_TYPE_STDOUT); g_assert(gutil_log_set_type(GLOG_TYPE_STDERR, "test")); g_assert(gutil_log_func == gutil_log_stderr); - g_assert(!g_strcmp0(gutil_log_get_type(), GLOG_TYPE_STDERR)); + g_assert_cmpstr(gutil_log_get_type(), == ,GLOG_TYPE_STDERR); g_assert(!gutil_log_set_type("whatever", "test")); gutil_log_func = NULL; - g_assert(!g_strcmp0(gutil_log_get_type(), GLOG_TYPE_CUSTOM)); + g_assert_cmpstr(gutil_log_get_type(), == ,GLOG_TYPE_CUSTOM); + gutil_log_func = fn; +} + +/*==========================================================================* + * Dump + *==========================================================================*/ + +static +void +test_log_dump( + void) +{ + static const guint8 short_data[] = { 0x01, 0x02, 0x03, 0x04 }; + static const guint8 long_data[] = { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x00 + }; + + const GLogProc fn = gutil_log_func; + test_log_buf = g_string_new(NULL); + gutil_log_func = test_log_fn; + + gutil_log_dump(&gutil_log_default, GLOG_LEVEL_NONE, NULL, + short_data, sizeof(short_data)); + g_assert_cmpuint(test_log_buf->len, == ,0); + + gutil_log_dump(&gutil_log_default, GLOG_LEVEL_ALWAYS, " ", + short_data, sizeof(short_data)); + g_assert_cmpstr(test_log_buf->str, == , + " 0000: 01 02 03 04 ....\n"); + + g_string_set_size(test_log_buf, 0); + gutil_log_dump(&gutil_log_default, GLOG_LEVEL_ALWAYS, NULL, + long_data, sizeof(long_data)); + g_assert_cmpstr(test_log_buf->str, == , + "0000: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f " + "01234567 89:;<=>?\n" + "0010: 00 " + ".\n"); + + g_string_free(test_log_buf, TRUE); + test_log_buf = NULL; gutil_log_func = fn; } @@ -309,6 +352,7 @@ int main(int argc, char* argv[]) #endif g_test_add_func(TEST_PREFIX "enabled", test_log_enabled); g_test_add_func(TEST_PREFIX "misc", test_log_misc); + g_test_add_func(TEST_PREFIX "dump", test_log_dump); test_init(&test_opt, argc, argv); return g_test_run(); } From 7321c8e782bbe5a679446d9df03d7c22abe8e73b Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Sun, 23 May 2021 03:36:01 +0300 Subject: [PATCH 10/10] Version 1.0.55 --- Makefile | 2 +- debian/changelog | 9 +++++++++ rpm/libglibutil.spec | 4 +++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f4a5343..1947290 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ all: debug release pkgconfig VERSION_MAJOR = 1 VERSION_MINOR = 0 -VERSION_RELEASE = 54 +VERSION_RELEASE = 55 # Version for pkg-config PCVERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE) diff --git a/debian/changelog b/debian/changelog index 65679e0..5ee5a32 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +libglibutil (1.0.55) unstable; urgency=low + + * Added gutil_log_dump() + * Added gutil_range_init_with_bytes() + * Added gutil_range_has_prefix() + * Added gutil_range_skip_prefix() + + -- Slava Monich Sun, 23 May 2021 03:33:58 +0300 + libglibutil (1.0.54) unstable; urgency=low * Added GUtilRange type diff --git a/rpm/libglibutil.spec b/rpm/libglibutil.spec index daebeb5..faa7f25 100644 --- a/rpm/libglibutil.spec +++ b/rpm/libglibutil.spec @@ -1,10 +1,12 @@ Name: libglibutil -Version: 1.0.54 + +Version: 1.0.55 Release: 0 Summary: Library of glib utilities License: BSD URL: https://git.sailfishos.org/mer-core/libglibutil Source: %{name}-%{version}.tar.bz2 + BuildRequires: pkgconfig(glib-2.0) Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig