From 3e749e32fa2c5dfd0c975e5636c8a7176c8cf16a Mon Sep 17 00:00:00 2001 From: Stefan 'psYchotic' Zwanenburg Date: Wed, 27 Jan 2010 20:14:27 +0100 Subject: [PATCH] Added a simple escaping mechanism. May need rewriting. --- ss.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/ss.c b/ss.c index 851a242..b52f154 100644 --- a/ss.c +++ b/ss.c @@ -54,26 +54,70 @@ int count_spaces(char *input) { /** * Splits the input into an array of words. + * Also implements a simple mechanism for escaping spaces. You basically use a + * single backslash to escape a space (or another backslash). In the event that + * a backslash is followed by a character other than a space or a backslash, it + * is interpreted as-is.\n * Note that the allocated memory for the returned array * may exceed what is required in order to store all words. - * This does not in any way pose a problem. - * Every element in the returned array should be freed, - * along with the array itself. + * This does not in any way pose a problem.\n + * Every element in the returned array (before the terminating NULL) + * should be freed, along with the array itself. * @param input the string to be split into words * @return an array of words */ char **split_input(char *input) { int words = count_spaces(input) + 1; - int i = 0; - char *single_word; + int i, j = 0; + char *single_word = malloc(sizeof(char) * strlen(input) + 1); + char *offset = input; + unsigned short int escaped = 0; + unsigned short int previous_was_space = 0; char **split = malloc(sizeof(char *) * (words+1)); + single_word[0] = '\0'; - single_word = strtok(input, " "); - do { - split[i++] = strdup(single_word); - } while ((single_word = strtok(NULL, " ")) != NULL); + for (i = 0; input[i] != '\0'; i++) { + if (escaped && input[i] == '\\') { + escaped = 0; + strcat(single_word, "\\"); + offset = input + i + 1; + previous_was_space = 0; + } else if (escaped && input[i] == ' ') { + escaped = 0; + strcat(single_word, " "); + offset = input + i + 1; + previous_was_space = 0; + } else if (escaped) { + escaped = 0; + previous_was_space = 0; + } else if (input[i] == '\\') { + strncat(single_word, offset, input - offset + i); + offset = input + i; + escaped = 1; + previous_was_space = 0; + } else if (input[i] == ' ') { + if (!previous_was_space) { + strncat(single_word, offset, input - offset + i); + split[j++] = strdup(single_word); + single_word[0] = '\0'; + offset = input + i + 1; + previous_was_space = 1; + } else { + offset++; + } + } else { + previous_was_space = 0; + } + } + + if (offset - input != strlen(input) || single_word[0] != '\0') { + strcat(single_word, offset); + split[j++] = strdup(single_word); + } + + split[j] = NULL; - split[i] = NULL; + free(single_word); return split; } -- 2.11.4.GIT