*/
static gboolean parse_rhs(const char **input, ExArg *arg)
{
- char quote = '\\';
- int expflags = UTIL_EXP_TILDE|UTIL_EXP_DOLLAR|UTIL_EXP_SPECIAL;
+ int expflags, flags;
if (!*input || !**input) {
return false;
}
+ flags = expflags = (arg->flags & EX_FLAG_EXP)
+ ? UTIL_EXP_TILDE|UTIL_EXP_DOLLAR|UTIL_EXP_SPECIAL
+ : 0;
+
/* get char until the end of command */
while (**input && **input != '\n' && **input != '|') {
- /* if we find a backslash this escapes the next char */
- if (**input == quote) {
- /* move pointer to the next char */
- (*input)++;
- if (!*input) {
- /* if input ends here - use only the backslash */
- g_string_append_c(arg->rhs, quote);
- } else if (**input == '|' || **input == '%') {
- /* escaped char becomes only char */
- g_string_append_c(arg->rhs, **input);
- } else {
- /* put escape char and next char into the result string */
- g_string_append_c(arg->rhs, quote);
- g_string_append_c(arg->rhs, **input);
- }
- } else { /* unquoted char */
- /* check for expansion placeholder */
- if (arg->flags & EX_FLAG_EXP) {
- util_parse_expansion(input, arg->rhs, expflags);
-
- if (VB_IS_SPACE(**input)) {
- /* add tilde expansion for next loop needs to be first
- * char or to be after a space */
- expflags |= UTIL_EXP_TILDE;
- } else {
- /* remove tile expansion for next loop */
- expflags &= ~UTIL_EXP_TILDE;
- }
- } else {
- g_string_append_c(arg->rhs, **input);
- }
+ /* check for expansion placeholder */
+ util_parse_expansion(input, arg->rhs, flags, "|~$%");
+
+ if (VB_IS_SPACE(**input)) {
+ /* add tilde expansion for next loop needs to be first char or to
+ * be after a space */
+ flags = expflags;
+ } else {
+ /* remove tile expansion for next loop */
+ flags &= ~UTIL_EXP_TILDE;
}
(*input)++;
}
int flags = expflags;
while (**input) {
- util_parse_expansion(input, dst, flags);
+ util_parse_expansion(input, dst, flags, "~$%");
if (VB_IS_SEPARATOR(**input)) {
/* after space the tilde expansion is allowed */
flags = expflags;
* not expanded char. If no expansion pattern was found, the first char is
* appended to given GString.
*
- * @input: String pointer with the content to be parsed.
- * @str: GString that will be filled with expanded content.
- * @flags Flags that determine which expansion are processed.
+ * @input: String pointer with the content to be parsed.
+ * @str: GString that will be filled with expanded content.
+ * @flags Flags that determine which expansion are processed.
+ * @quoteable String of chars that are allowed to be escaped by \.
* Returns true if input started with expandable pattern.
*/
-gboolean util_parse_expansion(const char **input, GString *str, int flags)
+gboolean util_parse_expansion(const char **input, GString *str, int flags,
+ const char *quoteable)
{
GString *name;
- const char *env, *prev;
+ const char *env, *prev, quote = '\\';
struct passwd *pwd;
gboolean expanded = false;
if (!expanded) {
/* restore the pointer position if no expansion was found */
*input = prev;
- /* take the char like it is */
- g_string_append_c(str, **input);
+
+ /* handle escaping of quoteable chars */
+ if (**input == quote) {
+ /* move pointer to the next char */
+ (*input)++;
+ if (!*input) {
+ /* if input ends here - use only the quote char */
+ g_string_append_c(str, quote);
+ } else if (strchr(quoteable, **input)) {
+ /* escaped char becomes only char */
+ g_string_append_c(str, **input);
+ } else {
+ /* put escape char and next char into the result string */
+ g_string_append_c(str, quote);
+ g_string_append_c(str, **input);
+ }
+ } else {
+ /* take the char like it is */
+ g_string_append_c(str, **input);
+ }
}
return expanded;
gboolean util_create_tmp_file(const char *content, char **file);
char *util_build_path(const char *path, const char *dir);
char *util_expand(const char *src, int expflags);
-gboolean util_parse_expansion(const char **input, GString *str, int flags);
+gboolean util_parse_expansion(const char **input, GString *str, int flags,
+ const char *quoteable);
gboolean util_fill_completion(GtkListStore *store, const char *input, GList *src);
#endif /* end of include guard: _UTIL_H */