aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/buffer2array.c143
-rw-r--r--src/buffer2array.h10
-rw-r--r--src/command.c22
-rw-r--r--src/conf.c17
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);
}