aboutsummaryrefslogtreecommitdiffstats
path: root/src/buffer2array.c
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2006-10-06 08:54:43 +0000
committerEric Wong <normalperson@yhbt.net>2006-10-06 08:54:43 +0000
commite3222d807a6178e0a4a5254b8443c3432b663efb (patch)
tree9e404aedec15a6154b5f7ed891b7465181c91f9e /src/buffer2array.c
parent1a51bfb84a9d3eb6c1ae891403ab237ee24a3b12 (diff)
downloadmpd-e3222d807a6178e0a4a5254b8443c3432b663efb.tar.gz
mpd-e3222d807a6178e0a4a5254b8443c3432b663efb.tar.xz
mpd-e3222d807a6178e0a4a5254b8443c3432b663efb.zip
Revert buffer2array() behavior back to tried and true 0.11.x version
Warren's fix in r4872 made phpMp work again, but also broke the unit tests completely (they work in this version). The version in 0.12.0 is far too buggy (it was from mpd-ke, what do you expect?). This one passes all the unit tests that the mpd-ke one passed, and should also work with phpMp when used with PHP magic quotes. This also means we can search on 100 (or more) tags at once, so no more arbitrary limits other than system memory. To run the unit tests, just do this: gcc -o t -DUNIT_TEST=1 src/buffer2array.c && ./t && echo OK git-svn-id: https://svn.musicpd.org/mpd/trunk@4874 09075e82-0dd4-0310-85a5-a0d7c8717e4f
Diffstat (limited to 'src/buffer2array.c')
-rw-r--r--src/buffer2array.c143
1 files changed, 100 insertions, 43 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] );