utils: add flags2str utility functions

This commit is contained in:
Thomas Haller
2015-10-27 10:56:53 +01:00
parent 9369fac8ca
commit dae0dbd533
3 changed files with 244 additions and 0 deletions

View File

@@ -1749,6 +1749,121 @@ nm_utils_to_string_buffer_init_null (gconstpointer obj, char **buf, gsize *len)
return TRUE;
}
void
nm_utils_strbuf_append_c (char **buf, gsize *len, char c)
{
switch (*len) {
case 0:
return;
case 1:
(*buf)[0] = '\0';
*len = 0;
(*buf)++;
return;
default:
(*buf)[0] = c;
(*buf)[1] = '\0';
(*len)--;
(*buf)++;
return;
}
}
void
nm_utils_strbuf_append_str (char **buf, gsize *len, const char *str)
{
gsize src_len;
switch (*len) {
case 0:
return;
case 1:
if (!str || !*str) {
(*buf)[0] = '\0';
return;
}
(*buf)[0] = '\0';
*len = 0;
(*buf)++;
return;
default:
if (!str || !*str) {
(*buf)[0] = '\0';
return;
}
src_len = g_strlcpy (*buf, str, *len);
if (src_len >= *len) {
*buf = &(*buf)[*len];
*len = 0;
} else {
*buf = &(*buf)[src_len];
*len -= src_len;
}
return;
}
}
void
nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...)
{
char *p = *buf;
va_list args;
gint retval;
if (*len == 0)
return;
va_start (args, format);
retval = g_vsnprintf (p, *len, format, args);
va_end (args);
if (retval >= *len) {
*buf = &p[*len];
*len = 0;
} else {
*buf = &p[retval];
*len -= retval;
}
}
const char *
nm_utils_flags2str (const NMUtilsFlags2StrDesc *descs,
gsize n_descs,
unsigned flags,
char *buf,
gsize len)
{
gsize i;
char *p;
nm_utils_to_string_buffer_init (&buf, &len);
if (!len)
return buf;
buf[0] = '\0';
if (!flags) {
return buf;
}
p = buf;
for (i = 0; flags && i < n_descs; i++) {
if (NM_FLAGS_HAS (flags, descs[i].flag)) {
flags &= ~descs[i].flag;
if (buf[0] != '\0')
nm_utils_strbuf_append_c (&p, &len, ',');
nm_utils_strbuf_append_str (&p, &len, descs[i].name);
}
}
if (flags) {
if (buf[0] != '\0')
nm_utils_strbuf_append_c (&p, &len, ',');
nm_utils_strbuf_append (&p, &len, "0x%x", flags);
}
return buf;
};
/*****************************************************************************/
/**

View File

@@ -196,6 +196,23 @@ extern char _nm_utils_to_string_buffer[2096];
void nm_utils_to_string_buffer_init (char **buf, gsize *len);
gboolean nm_utils_to_string_buffer_init_null (gconstpointer obj, char **buf, gsize *len);
typedef struct {
unsigned flag;
const char *name;
} NMUtilsFlags2StrDesc;
#define NM_UTILS_FLAGS2STR(f, n) { .flag = f, .name = ""n, }
const char *nm_utils_flags2str (const NMUtilsFlags2StrDesc *descs,
gsize n_descs,
unsigned flags,
char *buf,
gsize len);
void nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...) __attribute__((__format__ (__printf__, 3, 4)));
void nm_utils_strbuf_append_c (char **buf, gsize *len, char c);
void nm_utils_strbuf_append_str (char **buf, gsize *len, const char *str);
const char *nm_utils_get_shared_wifi_permission (NMConnection *connection);
const char *nm_utils_get_ip_config_method (NMConnection *connection,

View File

@@ -971,6 +971,116 @@ test_nm_match_spec_match_config (void)
/*******************************************/
static void
test_nm_utils_strbuf_append (void)
{
#define BUF_ORIG "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define STR_ORIG "abcdefghijklmnopqrstuvwxyz"
int buf_len;
int rep;
char buf[STRLEN (BUF_ORIG) + 1];
char str[STRLEN (BUF_ORIG) + 1];
for (buf_len = 0; buf_len < 10; buf_len++) {
for (rep = 0; rep < 50; rep++) {
const int s_len = nmtst_get_rand_int () % (sizeof (str) - 5);
char *t_buf;
gsize t_len;
int test_mode;
strcpy (str, STR_ORIG);
str[s_len] = '\0';
g_assert_cmpint (str[sizeof (str) - 1], ==, '\0');
g_assert_cmpint (strlen (str), ==, s_len);
strcpy (buf, BUF_ORIG);
t_buf = buf;
t_len = buf_len;
test_mode = nmtst_get_rand_int () % 4;
switch (test_mode) {
case 0:
if (s_len == 1) {
nm_utils_strbuf_append_c (&t_buf, &t_len, str[0]);
break;
}
/* fall-through */
case 1:
nm_utils_strbuf_append_str (&t_buf, &t_len, str);
break;
case 2:
if (s_len == 1) {
nm_utils_strbuf_append (&t_buf, &t_len, "%c", str[0]);
break;
}
/* fall-through */
case 3:
nm_utils_strbuf_append (&t_buf, &t_len, "%s", str);
break;
}
/* Assert that the source-buffer is unmodified. */
g_assert_cmpint (str[s_len], ==, '\0');
str[s_len] = STR_ORIG[s_len];
g_assert (!memcmp (str, STR_ORIG, sizeof (str)));
str[s_len] = '\0';
g_assert_cmpint (t_len, >=, 0);
g_assert_cmpint (t_len, <=, buf_len);
g_assert (t_buf >= buf);
/* Assert what was written to the destination buffer. */
switch (buf_len) {
case 0:
g_assert_cmpint (t_len, ==, 0);
g_assert (t_buf == buf);
g_assert (!memcmp (buf, BUF_ORIG, sizeof (buf)));
break;
case 1:
if (s_len == 0) {
g_assert_cmpint (t_len, ==, 1);
g_assert (t_buf == buf);
g_assert (buf[0] == '\0');
g_assert (!memcmp (&buf[1], &BUF_ORIG[1], sizeof (buf) - 1));
} else {
g_assert_cmpint (t_len, ==, 0);
g_assert (t_buf == &buf[1]);
g_assert (buf[0] == '\0');
g_assert (!memcmp (&buf[1], &BUF_ORIG[1], sizeof (buf) - 1));
}
break;
default:
if (s_len == 0) {
g_assert_cmpint (t_len, ==, buf_len);
g_assert (t_buf == buf);
g_assert (buf[0] == '\0');
g_assert (!memcmp (&buf[1], &BUF_ORIG[1], sizeof (buf) - 1));
} else if (buf_len <= s_len) {
g_assert_cmpint (t_len, ==, 0);
g_assert (t_buf == &buf[buf_len]);
g_assert (!memcmp (buf, STR_ORIG, buf_len - 1));
g_assert (buf[buf_len - 1] == '\0');
g_assert (!memcmp (&buf[buf_len], &BUF_ORIG[buf_len], sizeof (buf) - buf_len));
} else {
g_assert_cmpint (t_len, >, 0);
g_assert_cmpint (buf_len - t_len, ==, s_len);
g_assert_cmpint (strlen (buf), ==, s_len);
g_assert (t_buf == &buf[s_len]);
g_assert (!memcmp (buf, STR_ORIG, s_len));
g_assert (buf[s_len] == '\0');
g_assert (!memcmp (&buf[s_len + 1], &BUF_ORIG[s_len + 1], sizeof (buf) - s_len - 1));
}
break;
}
}
}
}
/*******************************************/
NMTST_DEFINE ();
int
@@ -978,6 +1088,8 @@ main (int argc, char **argv)
{
nmtst_init_with_logging (&argc, &argv, NULL, "ALL");
g_test_add_func ("/general/nm_utils_strbuf_append", test_nm_utils_strbuf_append);
g_test_add_func ("/general/nm_utils_ip6_address_clear_host_address", test_nm_utils_ip6_address_clear_host_address);
g_test_add_func ("/general/nm_utils_log_connection_diff", test_nm_utils_log_connection_diff);