diff options
author | Thorsten Wißmann <edu@thorsten-wissmann.de> | 2013-01-20 17:01:58 +0100 |
---|---|---|
committer | Thorsten Wißmann <edu@thorsten-wissmann.de> | 2013-01-20 19:05:20 +0100 |
commit | e33501e3255cde0e9685385b2b907e1976bcab18 (patch) | |
tree | 2b2403f3acada1679b148d881be8bac62dace27a /src/utils.c | |
parent | 2976f3ccbaa8c1d1b876af271b112d9197791347 (diff) |
Escape special posix sh characters when completing
Escape special posix shell characters (e.g. &;$) in the completion
results
Diffstat (limited to 'src/utils.c')
-rw-r--r-- | src/utils.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/utils.c b/src/utils.c index 34bd5d58..6d019627 100644 --- a/src/utils.c +++ b/src/utils.c @@ -438,3 +438,65 @@ int min(int a, int b) { return b; } +char* posix_sh_escape(char* source) { + size_t count = 0; + int i; + for (i = 0; source[i]; i++) { + int j = LENGTH(ESCAPE_CHARACTERS) - 1; // = strlen(ESCAPE_CHARACTERS) + slow_assert(j == strlen(ESCAPE_CHARACTERS)); + while (j--) { + slow_assert(0 <= j && j < strlen(ESCAPE_CHARACTERS)); + if (source[i] == ESCAPE_CHARACTERS[j]) { + count++; + break; + } + } + } + size_t source_len = i; + // special chars: + if (source[0] == '~') { + count++; + } + // if there is nothing to escape + if (count == 0) return NULL; + char* target = malloc(sizeof(char) * (count + source_len + 1)); + if (!target) { + die("cannot malloc - there is no memory available\n"); + } + + // do the actual escaping + // special chars: + int s = 0; // position in the source + int t = 0; // position in the target + slow_assert(s < strlen(source)); + slow_assert(t < (count + source_len)); + if (source[0] == '~') { + target[t++] = '\\'; + target[t++] = source[s++]; + } + slow_assert(s < strlen(source)); + slow_assert(t < (count + source_len)); + while (source[s]) { + // check if we need to escape the next char + int j = LENGTH(ESCAPE_CHARACTERS) - 1; // = strlen(ESCAPE_CHARACTERS) + slow_assert(s < strlen(source)); + slow_assert(t < (count + source_len)); + while (j--) { + if (source[s] == ESCAPE_CHARACTERS[j]) { + // if source[s] needs to be escape, then put an backslash first + target[t++] = '\\'; + break; + } + } + slow_assert(s < strlen(source)); + slow_assert(t < (count + source_len)); + // put the actual character + target[t++] = source[s++]; + } + slow_assert(s == strlen(source)); + slow_assert(t == (count + source_len)); + // terminate the string + target[t] = '\0'; + return target; +} + |