core: add nm_match_spec_join() function
We have a special implemenation nm_match_spec_split() to split a string. We also need the reverse operation to be able to convert a list of specs to string without loss.
This commit is contained in:
@@ -1419,6 +1419,85 @@ nm_match_spec_split (const char *value)
|
||||
return g_slist_reverse (pieces);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_match_spec_join:
|
||||
* @specs: the device specs to join
|
||||
*
|
||||
* This is based on g_key_file_parse_string_as_value(), analog to
|
||||
* nm_match_spec_split() which is based on g_key_file_parse_value_as_string().
|
||||
*
|
||||
* Returns: (transfer-full): a joined list of device specs that can be
|
||||
* split again with nm_match_spec_split(). Note that
|
||||
* nm_match_spec_split (nm_match_spec_join (specs)) yields the original
|
||||
* result (which is not true the other way around because there are multiple
|
||||
* ways to encode the same joined specs string).
|
||||
*/
|
||||
char *
|
||||
nm_match_spec_join (GSList *specs)
|
||||
{
|
||||
const char *p;
|
||||
GString *str;
|
||||
|
||||
str = g_string_new ("");
|
||||
|
||||
for (; specs; specs = specs->next) {
|
||||
p = specs->data;
|
||||
|
||||
if (!p || !*p)
|
||||
continue;
|
||||
|
||||
if (str->len > 0)
|
||||
g_string_append_c (str, ',');
|
||||
|
||||
/* escape leading whitespace */
|
||||
switch (*p) {
|
||||
case ' ':
|
||||
g_string_append (str, "\\s");
|
||||
p++;
|
||||
break;
|
||||
case '\t':
|
||||
g_string_append (str, "\\t");
|
||||
p++;
|
||||
break;
|
||||
}
|
||||
|
||||
for (; *p; p++) {
|
||||
switch (*p) {
|
||||
case '\n':
|
||||
g_string_append (str, "\\n");
|
||||
break;
|
||||
case '\r':
|
||||
g_string_append (str, "\\r");
|
||||
break;
|
||||
case '\\':
|
||||
g_string_append (str, "\\\\");
|
||||
break;
|
||||
case ',':
|
||||
g_string_append (str, "\\,");
|
||||
break;
|
||||
case ';':
|
||||
g_string_append (str, "\\;");
|
||||
break;
|
||||
default:
|
||||
g_string_append_c (str, *p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* escape trailing whitespaces */
|
||||
switch (str->str[str->len - 1]) {
|
||||
case ' ':
|
||||
g_string_overwrite (str, str->len - 1, "\\s");
|
||||
break;
|
||||
case '\t':
|
||||
g_string_overwrite (str, str->len - 1, "\\t");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_utils_get_shared_wifi_permission (NMConnection *connection)
|
||||
{
|
||||
|
@@ -98,6 +98,7 @@ NMMatchSpecMatchType nm_match_spec_hwaddr (const GSList *specs, const char *hwad
|
||||
NMMatchSpecMatchType nm_match_spec_s390_subchannels (const GSList *specs, const char *subchannels);
|
||||
NMMatchSpecMatchType nm_match_spec_interface_name (const GSList *specs, const char *interface_name);
|
||||
GSList *nm_match_spec_split (const char *value);
|
||||
char *nm_match_spec_join (GSList *specs);
|
||||
|
||||
const char *nm_utils_get_shared_wifi_permission (NMConnection *connection);
|
||||
|
||||
|
@@ -674,13 +674,27 @@ static void
|
||||
test_match_spec_ifname (const char *spec_str, const char **matches, const char **neg_matches)
|
||||
{
|
||||
const char *m;
|
||||
GSList *specs, *specs_reverse = NULL;
|
||||
GSList *specs, *specs_reverse = NULL, *specs_resplit, *specs_i, *specs_j;
|
||||
guint i;
|
||||
gs_free char *specs_joined = NULL;
|
||||
|
||||
g_assert (spec_str);
|
||||
|
||||
specs = nm_match_spec_split (spec_str);
|
||||
|
||||
/* assert that split(join(specs)) == specs */
|
||||
specs_joined = nm_match_spec_join (specs);
|
||||
specs_resplit = nm_match_spec_split (specs_joined);
|
||||
specs_i = specs;
|
||||
specs_j = specs_resplit;
|
||||
while (specs_i && specs_j && g_strcmp0 (specs_i->data, specs_j->data) == 0) {
|
||||
specs_i = specs_i->next;
|
||||
specs_j = specs_j->next;
|
||||
}
|
||||
g_assert (!specs_i);
|
||||
g_assert (!specs_j);
|
||||
g_slist_free_full (specs_resplit, g_free);
|
||||
|
||||
/* also check the matches in the reverse order. They must yield the same result because
|
||||
* matches are inclusive -- except "except:" which always wins. */
|
||||
specs_reverse = g_slist_reverse (g_slist_copy (specs));
|
||||
|
Reference in New Issue
Block a user