diff options
-rw-r--r-- | src/buffer2array.c | 143 | ||||
-rw-r--r-- | src/buffer2array.h | 10 | ||||
-rw-r--r-- | src/command.c | 22 | ||||
-rw-r--r-- | src/conf.c | 17 |
4 files changed, 122 insertions, 70 deletions
diff --git a/src/buffer2array.c b/src/buffer2array.c index 29dfdbce8..ef08bc32a 100644 --- a/src/buffer2array.c +++ b/src/buffer2array.c @@ -17,54 +17,111 @@ */ #include "buffer2array.h" +#ifdef UNIT_TEST +# define xstrdup(x) strdup(x) +# define xmalloc(x) malloc(x) +#else +# include "utils.h" +#endif #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <ctype.h> - -inline static -int -isWhiteSpace(char c) +int buffer2array(char *origBuffer, char ***array) { - return (c == ' ' || c == '\t'); -} + int quotes = 0; + int count = 0; + int i; + int curr; + int *beginArray; + char *buffer = xstrdup(origBuffer); + int bufferLength = strlen(buffer); + char *markArray = xmalloc(sizeof(char) * (bufferLength + 1)); + + for (curr = 0; curr < bufferLength; curr++) { + if (!quotes && (buffer[curr] == ' ' || buffer[curr] == '\t')) { + markArray[curr] = '0'; + } else if (buffer[curr] == '\"') { + if (curr > 0 && buffer[curr - 1] != '\\') { + quotes = quotes ? 0 : 1; + markArray[curr] = '0'; + } else { + markArray[curr] = '1'; + } + } else { + markArray[curr] = '1'; + } + if (markArray[curr] == '1') { + if (curr > 0) { + if (markArray[curr - 1] == '0') { + count++; + } + } else { + count++; + } + } + } + markArray[bufferLength] = '\0'; -int buffer2array(char *buffer, char *array[], const int max) -{ - int i = 0; - char *c = buffer; - - while (*c != '\0' && i < max) { - if (*c == '\"') { - array[i++] = ++c; - while (*c != '\0') { - if (*c == '\"') { - *(c++) = '\0'; - break; - } - else if (*(c++) == '\\') { - memmove(c - 1, c, strlen(c) + 1); - ++c; + if (!count) { + free(buffer); + free(markArray); + return count; + } + + beginArray = xmalloc(sizeof(int) * count); + (*array) = xmalloc(sizeof(char *) * count); + + count = 0; + + for (curr = 0; curr < bufferLength; curr++) { + if (markArray[curr] == '1') { + if (curr > 0) { + if (markArray[curr - 1] == '0') { + beginArray[count++] = curr; } + } else { + beginArray[count++] = curr; } } else { - while (isWhiteSpace(*c)) - ++c; - array[i++] = c++; - if (*c == '\0') - return i; - while (!isWhiteSpace(*c) && *c != '\0') - ++c; + buffer[curr] = '\0'; } - if (*c == '\0') - return i; - *(c++) = '\0'; - while (isWhiteSpace(*c)) - ++c; } - return i; + + for (i = 0; i < count; i++) { + int len = strlen(buffer + beginArray[i]) + 1; + int arrayCurr = 0; + (*array)[i] = xmalloc(sizeof(char) * len); + for (curr = beginArray[i]; buffer[curr] != '\0'; curr++) { + if (buffer[curr] == '\\') { + if (buffer[curr + 1] != '\0') { + curr++; + } + } + (*array)[i][arrayCurr++] = buffer[curr]; + } + (*array)[i][arrayCurr] = '\0'; + } + + free(markArray); + free(beginArray); + free(buffer); + + return count; +} + +void freeArgArray(char **array, int argArrayLength) +{ + int i; + + if (argArrayLength == 0) + return; + + for (i = 0; i < argArrayLength; i++) { + free(array[i]); + } + free(array); } #ifdef UNIT_TEST @@ -75,42 +132,42 @@ int buffer2array(char *buffer, char *array[], const int max) int main() { - char *a[4] = { NULL }; + char **a; char *b; int i, max; b = xstrdup("lsinfo \"/some/dir/name \\\"test\\\"\""); - max = buffer2array(b, a, 4); + max = buffer2array(b, &a); assert( !strcmp("lsinfo", a[0]) ); assert( !strcmp("/some/dir/name \"test\"", a[1]) ); assert( !a[2] ); b = xstrdup("lsinfo \"/some/dir/name \\\"test\\\" something else\""); - max = buffer2array(b, a, 4); + max = buffer2array(b, &a); assert( !strcmp("lsinfo", a[0]) ); assert( !strcmp("/some/dir/name \"test\" something else", a[1]) ); assert( !a[2] ); b = xstrdup("lsinfo \"/some/dir\\\\name\""); - max = buffer2array(b, a, 4); + max = buffer2array(b, &a); assert( !strcmp("lsinfo", a[0]) ); assert( !strcmp("/some/dir\\name", a[1]) ); assert( !a[2] ); b = xstrdup("lsinfo \"/some/dir name\""); - max = buffer2array(b, a, 4); + max = buffer2array(b, &a); assert( !strcmp("lsinfo", a[0]) ); assert( !strcmp("/some/dir name", a[1]) ); assert( !a[2] ); b = xstrdup("lsinfo \"\\\"/some/dir\\\"\""); - max = buffer2array(b, a, 4); + max = buffer2array(b, &a); assert( !strcmp("lsinfo", a[0]) ); assert( !strcmp("\"/some/dir\"", a[1]) ); assert( !a[2] ); b = xstrdup("lsinfo \"\\\"/some/dir\\\" x\""); - max = buffer2array(b, a, 4); + max = buffer2array(b, &a); assert( !strcmp("lsinfo", a[0]) ); assert( !strcmp("\"/some/dir\" x", a[1]) ); assert( !a[2] ); diff --git a/src/buffer2array.h b/src/buffer2array.h index e12f0ceed..fa6882fd9 100644 --- a/src/buffer2array.h +++ b/src/buffer2array.h @@ -21,12 +21,8 @@ #include "../config.h" -/* tokenizes up to max elements in buffer (a null-terminated string) and - * stores the result in array (which must be capable of holding up to - * max elements). Tokenization is based on C string quoting rules. - * The arguments buffer and array are modified. - * Returns the number of elements tokenized. - */ -int buffer2array(char *buffer, char *array[], const int max); +int buffer2array(char *buffer, char ***array); + +void freeArgArray(char **array, int argArrayLength); #endif diff --git a/src/command.c b/src/command.c index f1b98a9f3..41fdbd716 100644 --- a/src/command.c +++ b/src/command.c @@ -108,13 +108,6 @@ #define COMMAND_STATUS_AUDIO "audio" #define COMMAND_STATUS_UPDATING_DB "updating_db" -/* - * The most we ever use is for search/find, and that limits it to the - * number of tags we can have. Add one for the command, and one extra - * to catch errors clients may send us - */ -#define COMMAND_ARGV_MAX (2+(TAG_NUM_OF_ITEM_TYPES*2)) - typedef struct _CommandEntry CommandEntry; typedef int (*CommandHandlerFunction) (int, int *, int, char **); @@ -1059,28 +1052,27 @@ static CommandEntry *getCommandEntryAndCheckArgcAndPermission(int fd, static CommandEntry *getCommandEntryFromString(char *string, int *permission) { CommandEntry *cmd = NULL; - char *argv[COMMAND_ARGV_MAX] = { NULL }; - int argc = buffer2array(string, argv, COMMAND_ARGV_MAX); + char **argv; + int argc = buffer2array(string, &argv); if (0 == argc) return NULL; cmd = getCommandEntryAndCheckArgcAndPermission(0, permission, argc, argv); + freeArgArray(argv, argc); return cmd; } static int processCommandInternal(int fd, int *permission, - char *commandString, struct strnode *cmdnode) + char *string, struct strnode *cmdnode) { - int argc; - char *argv[COMMAND_ARGV_MAX] = { NULL }; + char **argv; + int argc = buffer2array(string, &argv); CommandEntry *cmd; int ret = -1; - argc = buffer2array(commandString, argv, COMMAND_ARGV_MAX); - if (argc == 0) return 0; @@ -1094,6 +1086,8 @@ static int processCommandInternal(int fd, int *permission, } } + freeArgArray(argv, argc); + current_command = NULL; return ret; diff --git a/src/conf.c b/src/conf.c index 0b3e0df5f..dc45ed2b9 100644 --- a/src/conf.c +++ b/src/conf.c @@ -41,7 +41,6 @@ #define CONF_REPEATABLE_MASK 0x01 #define CONF_BLOCK_MASK 0x02 -#define CONF_LINE_TOKEN_MAX 3 typedef struct _configEntry { unsigned char mask; @@ -194,16 +193,15 @@ static ConfigParam *readConfigBlock(FILE * fp, int *count, char *string) { ConfigParam *ret = newConfigParam(NULL, *count); + char **array; int i; int numberOfArgs; int argsMinusComment; while (myFgets(string, MAX_STRING_SIZE, fp)) { - char *array[CONF_LINE_TOKEN_MAX] = { NULL }; - (*count)++; - numberOfArgs = buffer2array(string, array, CONF_LINE_TOKEN_MAX); + numberOfArgs = buffer2array(string, &array); for (i = 0; i < numberOfArgs; i++) { if (array[i][0] == CONF_COMMENT) @@ -213,11 +211,13 @@ static ConfigParam *readConfigBlock(FILE * fp, int *count, char *string) argsMinusComment = i; if (0 == argsMinusComment) { + freeArgArray(array, numberOfArgs); continue; } if (1 == argsMinusComment && 0 == strcmp(array[0], CONF_BLOCK_END)) { + freeArgArray(array, numberOfArgs); break; } @@ -238,6 +238,8 @@ static ConfigParam *readConfigBlock(FILE * fp, int *count, char *string) } addBlockParam(ret, array[0], array[1], *count); + + freeArgArray(array, numberOfArgs); } return ret; @@ -254,6 +256,7 @@ void readConf(char *file) ConfigEntry *entry; void *voidPtr; ConfigParam *param; + char **array; if (!(fp = fopen(file, "r"))) { ERROR("problems opening file %s for reading: %s\n", file, @@ -262,10 +265,9 @@ void readConf(char *file) } while (myFgets(string, MAX_STRING_SIZE, fp)) { - char *array[CONF_LINE_TOKEN_MAX] = { NULL }; count++; - numberOfArgs = buffer2array(string, array, CONF_LINE_TOKEN_MAX); + numberOfArgs = buffer2array(string, &array); for (i = 0; i < numberOfArgs; i++) { if (array[i][0] == CONF_COMMENT) @@ -275,6 +277,7 @@ void readConf(char *file) argsMinusComment = i; if (0 == argsMinusComment) { + freeArgArray(array, numberOfArgs); continue; } @@ -313,6 +316,8 @@ void readConf(char *file) param = newConfigParam(array[1], count); insertInListWithoutKey(entry->configParamList, param); + + freeArgArray(array, numberOfArgs); } fclose(fp); } |