utils: strip whitespace for device spec in nm_match_spec_split()

Via escape sequences, the user still can specify trailing and leading
white spaces: such as "\s \s" will result in 3 spaces.
This commit is contained in:
Thomas Haller
2015-06-16 14:06:48 +02:00
parent 11c0e107b9
commit 7498b670a8
2 changed files with 54 additions and 10 deletions

View File

@@ -1313,11 +1313,32 @@ nm_match_spec_s390_subchannels (const GSList *specs, const char *subchannels)
return match;
}
/**
* nm_match_spec_split:
* @value: the string of device specs
*
* Splits the specs from the string and returns them as individual
* entires in a #GSList.
*
* It does not validate any specs, it basically just does a special
* strsplit with ',' or ';' as separators and supporting '\\' as
* escape character.
*
* Leading and trailing spaces of each entry are removed. But the user
* can preserve them by specifying "\\s has 2 leading" or "has 2 trailing \\s".
*
* Specs can have a qualifier like "interface-name:". We still don't strip
* any whitespace after the colon, so "interface-name: X" matches an interface
* named " X".
*
* Returns: (transfer-full): the list of device specs.
*/
GSList *
nm_match_spec_split (const char *value)
{
char *string_value, *p, *q0, *q;
GSList *pieces = NULL;
int trailing_ws;
if (!value || !*value)
return NULL;
@@ -1328,7 +1349,13 @@ nm_match_spec_split (const char *value)
string_value = g_new (gchar, strlen (value) + 1);
p = (gchar *) value;
/* skip over leading whitespace */
while (g_ascii_isspace (*p))
p++;
q0 = q = string_value;
trailing_ws = 0;
while (*p) {
if (*p == '\\') {
p++;
@@ -1360,23 +1387,34 @@ nm_match_spec_split (const char *value)
}
break;
}
if (*p == '\0')
break;
p++;
trailing_ws = 0;
} else {
*q = *p;
if (NM_IN_SET (*p, ',', ';')) {
if (q0 < q)
pieces = g_slist_prepend (pieces, g_strndup (q0, q - q0));
if (*p == '\0')
break;
if (g_ascii_isspace (*p)) {
trailing_ws++;
p++;
} else if (NM_IN_SET (*p, ',', ';')) {
if (q0 < q - trailing_ws)
pieces = g_slist_prepend (pieces, g_strndup (q0, (q - q0) - trailing_ws));
q0 = q + 1;
}
p++;
trailing_ws = 0;
while (g_ascii_isspace (*p))
p++;
} else
p++;
}
if (*p == '\0')
break;
q++;
p++;
}
*q = '\0';
if (q0 < q)
pieces = g_slist_prepend (pieces, g_strndup (q0, q - q0));
if (q0 < q - trailing_ws)
pieces = g_slist_prepend (pieces, g_strndup (q0, (q - q0) - trailing_ws));
g_free (string_value);
return g_slist_reverse (pieces);
}