aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2015-07-16 21:58:49 +0200
committerPřemysl Janouch <p.janouch@gmail.com>2015-07-16 22:12:59 +0200
commit403dbc83abab3441281d1b2d21b152e73284613c (patch)
tree71d4d931cfa78e611d248395a7782307ca1d4a51
parent1b56b4ee72451a36fefe4fcda35980975166ee94 (diff)
downloadxK-403dbc83abab3441281d1b2d21b152e73284613c.tar.gz
xK-403dbc83abab3441281d1b2d21b152e73284613c.tar.xz
xK-403dbc83abab3441281d1b2d21b152e73284613c.zip
degesch: allow multiple commands in aliases
Separated by ;, which can be escaped as $;
-rw-r--r--degesch.c118
1 files changed, 75 insertions, 43 deletions
diff --git a/degesch.c b/degesch.c
index 8562946..a570733 100644
--- a/degesch.c
+++ b/degesch.c
@@ -8034,59 +8034,75 @@ process_user_command
return true;
}
-static char *
-expand_alias_definition (const struct str *definition, const char *arguments)
+static const char *
+expand_alias_escape (const char *p, const char *arguments, struct str *output)
{
- struct str_vector v;
- str_vector_init (&v);
- cstr_split_ignore_empty (arguments, ' ', &v);
+ struct str_vector words;
+ str_vector_init (&words);
+ cstr_split_ignore_empty (arguments, ' ', &words);
+
+ // TODO: eventually also add support for argument ranges
+ int as_number = *p - '0';
+ if (as_number > 0 && as_number <= 9
+ && (size_t) as_number <= words.len)
+ str_append (output, words.vector[as_number - 1]);
+ else if (*p == '*')
+ str_append (output, arguments);
+ else if (strchr ("$;", *p))
+ str_append_c (output, *p);
+ else
+ str_append_printf (output, "$%c", *p);
+
+ str_vector_free (&words);
+ return ++p;
+}
+static void
+expand_alias_definition (const struct str *definition, const char *arguments,
+ struct str_vector *commands)
+{
struct str expanded;
str_init (&expanded);
- // TODO: eventually also support argument ranges
bool escape = false;
for (const char *p = definition->str; *p; p++)
{
- if (!escape)
+ if (escape)
{
- if (*p == '$' && p[1])
- escape = true;
- else
- str_append_c (&expanded, *p);
- continue;
+ p = expand_alias_escape (p, arguments, &expanded);
+ escape = false;
}
-
- int as_number = *p - '0';
- if (as_number > 0 && as_number <= 9
- && (size_t) as_number <= v.len)
- str_append (&expanded, v.vector[as_number - 1]);
- else if (*p == '*')
- str_append (&expanded, arguments);
- else if (*p == '$')
- str_append_c (&expanded, '$');
+ else if (*p == ';')
+ {
+ str_vector_add_owned (commands, str_steal (&expanded));
+ str_init (&expanded);
+ }
+ else if (*p == '$' && p[1])
+ escape = true;
else
- str_append_printf (&expanded, "$%c", *p);
- escape = false;
+ str_append_c (&expanded, *p);
}
- str_vector_free (&v);
- return str_steal (&expanded);
+ str_vector_add_owned (commands, str_steal (&expanded));
}
-static char *
-expand_alias (struct app_context *ctx, const char *alias_name, char *input)
+static bool
+expand_alias (struct app_context *ctx,
+ const char *alias_name, char *input, struct str_vector *commands)
{
struct config_item_ *entry =
str_map_find (get_aliases_config (ctx), alias_name);
if (!entry)
- return NULL;
+ return false;
- if (config_item_type_is_string (entry->type))
- return expand_alias_definition (&entry->value.string, input);
+ if (!config_item_type_is_string (entry->type))
+ {
+ log_global_error (ctx, "Error executing `/%s': %s",
+ alias_name, "alias definition is not a string");
+ return false;
+ }
- log_global_error (ctx, "Error executing `/%s': %s",
- alias_name, "alias definition is not a string");
- return NULL;
+ expand_alias_definition (&entry->value.string, input, commands);
+ return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -8123,30 +8139,46 @@ send_message_to_current_buffer (struct app_context *ctx, char *message)
}
}
-static void
+static bool process_input_utf8 (struct app_context *, char *, int);
+
+static bool
+process_alias (struct app_context *ctx, struct str_vector *commands, int level)
+{
+ for (size_t i = 0; i < commands->len; i++)
+ log_global_debug (ctx, "Alias expanded to: ###d: \"#s\"",
+ (int) i, commands->vector[i]);
+ for (size_t i = 0; i < commands->len; i++)
+ if (!process_input_utf8 (ctx, commands->vector[i], ++level))
+ return false;
+ return true;
+}
+
+static bool
process_input_utf8 (struct app_context *ctx, char *input, int alias_level)
{
if (*input != '/' || *++input == '/')
{
send_message_to_current_buffer (ctx, input);
- return;
+ return true;
}
char *name = cut_word (&input);
if (process_user_command (ctx, name, input))
- return;
+ return true;
- char *expanded = expand_alias (ctx, name, input);
- if (expanded)
- log_global_debug (ctx, "Alias expanded to \"#s\"", expanded);
+ struct str_vector commands;
+ str_vector_init (&commands);
- if (!expanded)
+ bool result = false;
+ if (!expand_alias (ctx, name, input, &commands))
log_global_error (ctx, "#s: /#s", "No such command or alias", name);
else if (alias_level != 0)
log_global_error (ctx, "#s: /#s", "Aliases can't nest", name);
else
- process_input_utf8 (ctx, expanded, ++alias_level);
- free (expanded);
+ result = process_alias (ctx, &commands, alias_level);
+
+ str_vector_free (&commands);
+ return result;
}
static void
@@ -8156,7 +8188,7 @@ process_input (struct app_context *ctx, char *user_input)
if (!(input = iconv_xstrdup (ctx->term_to_utf8, user_input, -1, NULL)))
print_error ("character conversion failed for `%s'", "user input");
else
- process_input_utf8 (ctx, input, 0);
+ (void) process_input_utf8 (ctx, input, 0);
free (input);
}