put back np's supperrior buffer2array, and fix my bug fix from change 4872

git-svn-id: https://svn.musicpd.org/mpd/trunk@4875 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
Warren Dukes 2006-10-06 10:33:27 +00:00
parent e3222d807a
commit e198826606
4 changed files with 70 additions and 123 deletions

View File

@ -17,111 +17,53 @@
*/
#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>
int buffer2array(char *origBuffer, char ***array)
inline static
int
isWhiteSpace(char c)
{
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';
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 {
buffer[curr] = '\0';
}
}
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;
return (c == ' ' || c == '\t');
}
void freeArgArray(char **array, int argArrayLength)
int buffer2array(char *buffer, char *array[], const int max)
{
int i;
int i = 0;
char *c = buffer;
if (argArrayLength == 0)
return;
for (i = 0; i < argArrayLength; i++) {
free(array[i]);
while (*c != '\0' && i < max) {
if (*c == '\"') {
array[i++] = ++c;
while (*c != '\0') {
if (*c == '\"') {
*(c++) = '\0';
break;
}
else if (*(c++) == '\\' && *c != '\0') {
memmove(c - 1, c, strlen(c) + 1);
}
}
} else {
while (isWhiteSpace(*c))
++c;
array[i++] = c++;
if (*c == '\0')
return i;
while (!isWhiteSpace(*c) && *c != '\0')
++c;
}
if (*c == '\0')
return i;
*(c++) = '\0';
while (isWhiteSpace(*c))
++c;
}
free(array);
return i;
}
#ifdef UNIT_TEST
@ -132,42 +74,42 @@ void freeArgArray(char **array, int argArrayLength)
int main()
{
char **a;
char *a[4] = { NULL };
char *b;
int i, max;
b = xstrdup("lsinfo \"/some/dir/name \\\"test\\\"\"");
max = buffer2array(b, &a);
max = buffer2array(b, a, 4);
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);
max = buffer2array(b, a, 4);
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);
max = buffer2array(b, a, 4);
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);
max = buffer2array(b, a, 4);
assert( !strcmp("lsinfo", a[0]) );
assert( !strcmp("/some/dir name", a[1]) );
assert( !a[2] );
b = xstrdup("lsinfo \"\\\"/some/dir\\\"\"");
max = buffer2array(b, &a);
max = buffer2array(b, a, 4);
assert( !strcmp("lsinfo", a[0]) );
assert( !strcmp("\"/some/dir\"", a[1]) );
assert( !a[2] );
b = xstrdup("lsinfo \"\\\"/some/dir\\\" x\"");
max = buffer2array(b, &a);
max = buffer2array(b, a, 4);
assert( !strcmp("lsinfo", a[0]) );
assert( !strcmp("\"/some/dir\" x", a[1]) );
assert( !a[2] );

View File

@ -21,8 +21,12 @@
#include "../config.h"
int buffer2array(char *buffer, char ***array);
void freeArgArray(char **array, int argArrayLength);
/* 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);
#endif

View File

@ -108,6 +108,13 @@
#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 **);
@ -1052,27 +1059,28 @@ static CommandEntry *getCommandEntryAndCheckArgcAndPermission(int fd,
static CommandEntry *getCommandEntryFromString(char *string, int *permission)
{
CommandEntry *cmd = NULL;
char **argv;
int argc = buffer2array(string, &argv);
char *argv[COMMAND_ARGV_MAX] = { NULL };
int argc = buffer2array(string, argv, COMMAND_ARGV_MAX);
if (0 == argc)
return NULL;
cmd = getCommandEntryAndCheckArgcAndPermission(0, permission,
argc, argv);
freeArgArray(argv, argc);
return cmd;
}
static int processCommandInternal(int fd, int *permission,
char *string, struct strnode *cmdnode)
char *commandString, struct strnode *cmdnode)
{
char **argv;
int argc = buffer2array(string, &argv);
int argc;
char *argv[COMMAND_ARGV_MAX] = { NULL };
CommandEntry *cmd;
int ret = -1;
argc = buffer2array(commandString, argv, COMMAND_ARGV_MAX);
if (argc == 0)
return 0;
@ -1086,8 +1094,6 @@ static int processCommandInternal(int fd, int *permission,
}
}
freeArgArray(argv, argc);
current_command = NULL;
return ret;

View File

@ -41,6 +41,7 @@
#define CONF_REPEATABLE_MASK 0x01
#define CONF_BLOCK_MASK 0x02
#define CONF_LINE_TOKEN_MAX 3
typedef struct _configEntry {
unsigned char mask;
@ -193,15 +194,16 @@ 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);
numberOfArgs = buffer2array(string, array, CONF_LINE_TOKEN_MAX);
for (i = 0; i < numberOfArgs; i++) {
if (array[i][0] == CONF_COMMENT)
@ -211,13 +213,11 @@ 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,8 +238,6 @@ static ConfigParam *readConfigBlock(FILE * fp, int *count, char *string)
}
addBlockParam(ret, array[0], array[1], *count);
freeArgArray(array, numberOfArgs);
}
return ret;
@ -256,7 +254,6 @@ 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,
@ -265,9 +262,10 @@ void readConf(char *file)
}
while (myFgets(string, MAX_STRING_SIZE, fp)) {
char *array[CONF_LINE_TOKEN_MAX] = { NULL };
count++;
numberOfArgs = buffer2array(string, &array);
numberOfArgs = buffer2array(string, array, CONF_LINE_TOKEN_MAX);
for (i = 0; i < numberOfArgs; i++) {
if (array[i][0] == CONF_COMMENT)
@ -277,7 +275,6 @@ void readConf(char *file)
argsMinusComment = i;
if (0 == argsMinusComment) {
freeArgArray(array, numberOfArgs);
continue;
}
@ -316,8 +313,6 @@ void readConf(char *file)
param = newConfigParam(array[1], count);
insertInListWithoutKey(entry->configParamList, param);
freeArgArray(array, numberOfArgs);
}
fclose(fp);
}