-/* Helper for parse_device_name; returns a list of un-escaped strings for
- * the first "component" of str, where a component is a plain string or a
- * brace-enclosed set of alternatives. str is pointing to the first character
- * of the next component on return. */
-static GPtrArray *
-parse_device_name_component(char **str)
-{
- GPtrArray *result = g_ptr_array_new();
-
- if (**str == '{') {
- char *p = (*str)+1;
- char *local = g_malloc(strlen(*str)+1);
- char *current = local;
- char *c = current;
-
- while (1) {
- if (*p == '\0' || *p == '{') {
- /* unterminated { .. } or extra '{' */
- amfree(local);
- g_ptr_array_free(result, TRUE);
- return NULL;
- }
-
- if (*p == '}' || *p == ',') {
- *c = '\0';
- g_ptr_array_add(result, g_strdup(current));
- current = ++c;
-
- if (*p == '}')
- break;
- else
- p++;
- }
-
- if (*p == '\\') {
- if (*(p+1) == '{' || *(p+1) == '}' || *(p+1) == '\\' || *(p+1) == ',')
- p++;
- }
- *(c++) = *(p++);
- }
-
- amfree(local);
-
- if (*p)
- *str = p+1;
- else
- *str = p;
- } else {
- /* no braces -- just un-escape a plain string */
- char *local = g_malloc(strlen(*str)+1);
- char *r = local;
- char *p = *str;
-
- while (*p && *p != '{') {
- if (*p == '\\') {
- if (*(p+1) == '{' || *(p+1) == '}' || *(p+1) == '\\' || *(p+1) == ',')
- p++;
- }
- *(r++) = *(p++);
- }
- *r = '\0';
- g_ptr_array_add(result, local);
- *str = p;
- }
-
- return result;
-}
-
-/* Take a text string user_name, and break it out into an argv-style
- array of strings, using a {..,..} syntax similar to shell brace expansion.
- For example:
-
- "{foo,bar,bat}" -> [ "foo", "bar", "bat" ]
- "foo{1,2}bar" -> [ "foo1bar", "foo2bar" ]
- "foo{1\,2,3}bar" -> [ "foo1,2bar", "foo3bar" ]
- "{a,b}-{1,2}" -> [ "a-1", "a-2", "b-1", "b-2" ]
-
- Note that nested braces are not processed. Braces, commas, and backslashes
- may be escaped with backslashes. Returns NULL on invalid strings.
- */
-
-static GPtrArray *
-parse_device_name(char * user_name)
-{
- GPtrArray *rval = g_ptr_array_new();
-
- g_ptr_array_add(rval, g_strdup(""));
-
- while (*user_name) {
- GPtrArray *new_components;
- GPtrArray *new_rval;
- guint i, j;
-
- new_components = parse_device_name_component(&user_name);
- if (!new_components) {
- /* parse error */
- g_ptr_array_free(rval, TRUE);
- return NULL;
- }
-
- new_rval = g_ptr_array_new();
-
- /* do a cartesian join of rval and new_components */
- for (i = 0; i < rval->len; i++) {
- for (j = 0; j < new_components->len; j++) {
- g_ptr_array_add(new_rval, g_strconcat(
- g_ptr_array_index(rval, i),
- g_ptr_array_index(new_components, j),
- NULL));
- }
- }
-
- g_ptr_array_free(rval, TRUE);
- g_ptr_array_free(new_components, TRUE);
- rval = new_rval;
- }
-
- return rval;
-}
-