summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBranko Čibej <brane@apache.org>2003-02-12 20:20:56 +0000
committerBranko Čibej <brane@apache.org>2003-02-12 20:20:56 +0000
commit8dc33467727dfa3e6484b19637a6b97447ffb2e0 (patch)
tree716428703f123dc6bf5507b8d5e8dd778487696b
parent80bbefa0f622a8e0c1081b9d5a66aed89fb017df (diff)
downloadapr-8dc33467727dfa3e6484b19637a6b97447ffb2e0.tar.gz
Added two new functions, apr_filepath_list_split and apr_filepath_list_merge,
for managing search paths. The common implementation is in a new file, file_io/unix/filepath_util.c. Also added tests for these functions a new file in the test suite, testpath.c. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@64349 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES3
-rw-r--r--NWGNUmakefile1
-rw-r--r--apr.dsp4
-rw-r--r--file_io/unix/Makefile.in1
-rw-r--r--file_io/unix/filepath.c23
-rw-r--r--file_io/unix/filepath_util.c147
-rw-r--r--file_io/win32/filepath.c24
-rw-r--r--include/apr_file_info.h31
-rw-r--r--include/apr_pools.h3
-rw-r--r--libapr.dsp4
-rw-r--r--test/Makefile.in2
-rw-r--r--test/Makefile.win4
-rw-r--r--test/aprtest.dsp4
-rw-r--r--test/test_apr.h1
-rw-r--r--test/testall.c1
-rw-r--r--test/testall.dsp4
-rw-r--r--test/testpath.c176
17 files changed, 430 insertions, 3 deletions
diff --git a/CHANGES b/CHANGES
index 51cdd495e..cd66b3580 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,8 @@
Changes with APR 0.9.2
+ *) Add functions apr_filepath_list_split and apr_filepath_list_merge
+ for managing search paths. [Branko Cibej]
+
*) Introduce Release mode debugging symbols for Win32 builds of apr.
All library builds gain /Zi for debug symbols (which are discarded
at link time if some flavor of the /debug flag isn't passed to link)
diff --git a/NWGNUmakefile b/NWGNUmakefile
index b57e51dbb..3f074e9e4 100644
--- a/NWGNUmakefile
+++ b/NWGNUmakefile
@@ -255,6 +255,7 @@ FILES_lib_objs = \
$(OBJDIR)/fileacc.o \
$(OBJDIR)/filedup.o \
$(OBJDIR)/filepath.o \
+ $(OBJDIR)/filepath_util.o \
$(OBJDIR)/filestat.o \
$(OBJDIR)/filesys.o \
$(OBJDIR)/flock.o \
diff --git a/apr.dsp b/apr.dsp
index c61e5312a..6015d284b 100644
--- a/apr.dsp
+++ b/apr.dsp
@@ -117,6 +117,10 @@ SOURCE=.\file_io\win32\filepath.c
# End Source File
# Begin Source File
+SOURCE=.\file_io\unix\filepath_util.c
+# End Source File
+# Begin Source File
+
SOURCE=.\file_io\win32\filestat.c
# End Source File
# Begin Source File
diff --git a/file_io/unix/Makefile.in b/file_io/unix/Makefile.in
index ce62475b1..01473a801 100644
--- a/file_io/unix/Makefile.in
+++ b/file_io/unix/Makefile.in
@@ -7,6 +7,7 @@ TARGETS = \
fileacc.lo \
filedup.lo \
filepath.lo \
+ filepath_util.lo \
filestat.lo \
flock.lo \
fullrw.lo \
diff --git a/file_io/unix/filepath.c b/file_io/unix/filepath.c
index f273621aa..91321ba07 100644
--- a/file_io/unix/filepath.c
+++ b/file_io/unix/filepath.c
@@ -326,6 +326,29 @@ APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,
}
+apr_status_t apr_filepath_list_split_impl(apr_array_header_t **pathelts,
+ const char *liststr,
+ char separator,
+ apr_pool_t *p);
+apr_status_t apr_filepath_list_merge_impl(char **liststr,
+ apr_array_header_t *pathelts,
+ char separator,
+ apr_pool_t *p);
+
+APR_DECLARE(apr_status_t) apr_filepath_list_split(apr_array_header_t **pathelts,
+ const char *liststr,
+ apr_pool_t *p)
+{
+ return apr_filepath_list_split_impl(pathelts, liststr, ':', p);
+}
+APR_DECLARE(apr_status_t) apr_filepath_list_merge(char **liststr,
+ apr_array_header_t *pathelts,
+ apr_pool_t *p)
+{
+ return apr_filepath_list_merge_impl(liststr, pathelts, ':', p);
+}
+
+
APR_DECLARE(apr_status_t) apr_filepath_encoding(int *style, apr_pool_t *p)
{
*style = APR_FILEPATH_ENCODING_LOCALE;
diff --git a/file_io/unix/filepath_util.c b/file_io/unix/filepath_util.c
new file mode 100644
index 000000000..190c30218
--- /dev/null
+++ b/file_io/unix/filepath_util.c
@@ -0,0 +1,147 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+#define APR_WANT_STRFUNC
+#define APR_WANT_MEMFUNC
+#include "apr_want.h"
+
+#include "apr_errno.h"
+#include "apr_pools.h"
+#include "apr_strings.h"
+#include "apr_tables.h"
+
+
+apr_status_t apr_filepath_list_split_impl(apr_array_header_t **pathelts,
+ const char *liststr,
+ char separator,
+ apr_pool_t *p)
+{
+ char *path, *part, *ptr;
+ char separator_string[2] = { separator, '\0' };
+ apr_array_header_t *elts;
+ int nelts;
+
+ /* Count the number of path elements. We know there'll be at least
+ one even if path is an empty string. */
+ path = apr_pstrdup(p, liststr);
+ for (nelts = 0, ptr = path; ptr != NULL; ++nelts)
+ {
+ ptr = strchr(ptr, separator);
+ if (ptr)
+ ++ptr;
+ }
+
+ /* Split the path into the array. */
+ elts = apr_array_make(p, nelts, sizeof(char*));
+ while ((part = apr_strtok(path, separator_string, &ptr)) != NULL)
+ {
+ if (*part == '\0') /* Ignore empty path components. */
+ continue;
+
+ *(char**)apr_array_push(elts) = part;
+ path = NULL; /* For the next call to apr_strtok */
+ }
+
+ *pathelts = elts;
+ return APR_SUCCESS;
+}
+
+
+apr_status_t apr_filepath_list_merge_impl(char **liststr,
+ apr_array_header_t *pathelts,
+ char separator,
+ apr_pool_t *p)
+{
+ apr_size_t path_size = 0;
+ char *path;
+ int i;
+
+ /* This test isn't 100% certain, but it'll catch at least some
+ invalid uses... */
+ if (pathelts->elt_size != sizeof(char*))
+ return APR_EINVAL;
+
+ /* Calculate the size of the merged path */
+ for (i = 0; i < pathelts->nelts; ++i)
+ path_size += strlen(((char**)pathelts->elts)[i]);
+
+ if (path_size == 0)
+ {
+ *liststr = NULL;
+ return APR_SUCCESS;
+ }
+
+ if (i > 0) /* Add space for the separators */
+ path_size += (i - 1);
+
+ /* Merge the path components */
+ path = *liststr = apr_palloc(p, path_size + 1);
+ for (i = 0; i < pathelts->nelts; ++i)
+ {
+ /* ### Hmmmm. Calling strlen twice on the same string. Yuck.
+ But is is better than reallocation in apr_pstrcat? */
+ const char *part = ((char**)pathelts->elts)[i];
+ apr_size_t part_size = strlen(part);
+ if (part_size == 0) /* Ignore empty path components. */
+ continue;
+
+ if (i > 0)
+ *path++ = separator;
+ memcpy(path, part, part_size);
+ path += part_size;
+ }
+ *path = '\0';
+ return APR_SUCCESS;
+}
diff --git a/file_io/win32/filepath.c b/file_io/win32/filepath.c
index a09b5a315..5ae8a54b4 100644
--- a/file_io/win32/filepath.c
+++ b/file_io/win32/filepath.c
@@ -54,6 +54,7 @@
#include "apr.h"
#include "apr_arch_file_io.h"
+#include "apr_arch_utf8.h"
#include "apr_strings.h"
#include "apr_lib.h"
#include <string.h>
@@ -977,6 +978,29 @@ APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,
}
+apr_status_t apr_filepath_list_split_impl(apr_array_header_t **pathelts,
+ const char *liststr,
+ char separator,
+ apr_pool_t *p);
+apr_status_t apr_filepath_list_merge_impl(char **liststr,
+ apr_array_header_t *pathelts,
+ char separator,
+ apr_pool_t *p);
+
+APR_DECLARE(apr_status_t) apr_filepath_list_split(apr_array_header_t **pathelts,
+ const char *liststr,
+ apr_pool_t *p)
+{
+ return apr_filepath_list_split_impl(pathelts, liststr, ';', p);
+}
+APR_DECLARE(apr_status_t) apr_filepath_list_merge(char **liststr,
+ apr_array_header_t *pathelts,
+ apr_pool_t *p)
+{
+ return apr_filepath_list_merge_impl(liststr, pathelts, ';', p);
+}
+
+
APR_DECLARE(apr_status_t) apr_filepath_encoding(int *style, apr_pool_t *p)
{
#if APR_HAS_UNICODE_FS
diff --git a/include/apr_file_info.h b/include/apr_file_info.h
index 5b2ee8f75..7e69aea13 100644
--- a/include/apr_file_info.h
+++ b/include/apr_file_info.h
@@ -58,6 +58,7 @@
#include "apr.h"
#include "apr_user.h"
#include "apr_pools.h"
+#include "apr_tables.h"
#include "apr_time.h"
#include "apr_errno.h"
@@ -386,6 +387,36 @@ APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,
apr_pool_t *p);
/**
+ * Split a search path into separate components
+ * @ingroup apr_filepath
+ * @param pathelts the returned components of the search path
+ * @param liststr the search path (e.g., <tt>getenv("PATH")</tt>)
+ * @param p the pool to allocate the array and path components from
+ * @deffunc apr_status_t apr_filepath_list_split(apr_array_header_t **pathelts, const char *liststr, apr_pool_t *p)
+ * @remark empty path componenta do not become part of @a pathelts.
+ * @remark the path separator in @a liststr is system specific;
+ * e.g., ':' on Unix, ';' on Windows, etc.
+ */
+APR_DECLARE(apr_status_t) apr_filepath_list_split(apr_array_header_t **pathelts,
+ const char *liststr,
+ apr_pool_t *p);
+
+/**
+ * Merge a list of search path components into a single search path
+ * @ingroup apr_filepath
+ * @param liststr the returned search path; may be NULL if @a pathelts is empty
+ * @param pathelts the components of the search path
+ * @param p the pool to allocate the search path from
+ * @deffunc apr_status_t apr_filepath_list_merge(char **liststr, apr_array_header_t *pathelts, apr_pool_t *p)
+ * @remark emtpy strings in the source array are ignored.
+ * @remark the path separator in @a liststr is system specific;
+ * e.g., ':' on Unix, ';' on Windows, etc.
+ */
+APR_DECLARE(apr_status_t) apr_filepath_list_merge(char **liststr,
+ apr_array_header_t *pathelts,
+ apr_pool_t *p);
+
+/**
* Return the default file path (for relative file names)
* @ingroup apr_filepath
* @param path the default path string returned
diff --git a/include/apr_pools.h b/include/apr_pools.h
index fcacd5662..d9a03c2a1 100644
--- a/include/apr_pools.h
+++ b/include/apr_pools.h
@@ -157,6 +157,9 @@ typedef struct apr_pool_t apr_pool_t;
* If level 0 was specified, debugging is switched off
* </pre>
*/
+
+#define APR_POOL_DEBUG 1 /* FIXME: Don't commit this! */
+
#if defined(APR_POOL_DEBUG)
#if (APR_POOL_DEBUG != 0) && (APR_POOL_DEBUG - 0 == 0)
#undef APR_POOL_DEBUG
diff --git a/libapr.dsp b/libapr.dsp
index 87872996b..d9636e52e 100644
--- a/libapr.dsp
+++ b/libapr.dsp
@@ -132,6 +132,10 @@ SOURCE=.\file_io\win32\filepath.c
# End Source File
# Begin Source File
+SOURCE=.\file_io\unix\filepath_util.c
+# End Source File
+# Begin Source File
+
SOURCE=.\file_io\win32\filestat.c
# End Source File
# Begin Source File
diff --git a/test/Makefile.in b/test/Makefile.in
index 56b9d56b7..70f73cdfd 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -102,7 +102,7 @@ TESTS = testall.lo testtime.lo teststr.lo testvsn.lo testipsub.lo \
testfmt.lo testfile.lo testdir.lo testfileinfo.lo testrand.lo \
testdso.lo testoc.lo testdup.lo testsockets.lo testproc.lo \
testpoll.lo testlock.lo testsockopt.lo testpipe.lo testthread.lo \
- testhash.lo testargs.lo testnames.lo testuser.lo
+ testhash.lo testargs.lo testnames.lo testuser.lo testpath.lo
testall: $(TESTS) mod_test.la libmod_test.la occhild@EXEEXT@ \
CuTest.lo proc_child@EXEEXT@ $(LOCAL_LIBS)
diff --git a/test/Makefile.win b/test/Makefile.win
index f1ff00190..3437f45aa 100644
--- a/test/Makefile.win
+++ b/test/Makefile.win
@@ -99,11 +99,11 @@ TESTS = testall.obj testtime.obj teststr.obj testvsn.obj testipsub.obj \
testfmt.obj testfile.obj testdir.obj testfileinfo.obj testrand.obj \
testdso.obj testoc.obj testdup.obj testsockets.obj testproc.obj \
testpoll.obj testlock.obj testsockopt.obj testpipe.obj testthread.obj \
- testhash.obj testargs.obj testnames.obj testuser.obj
+ testhash.obj testargs.obj testnames.obj testuser.obj testpath.obj
testall.exe: $(TESTS) CuTest.obj $(LOCAL_LIBS)
$(LINK) /debug /subsystem:console /machine:I386 $(TESTS) CuTest.obj \
$(LOCAL_LIBS) $(ALL_LIBS)
-
+
# DO NOT REMOVE
diff --git a/test/aprtest.dsp b/test/aprtest.dsp
index ffc1be08b..e31b898d0 100644
--- a/test/aprtest.dsp
+++ b/test/aprtest.dsp
@@ -140,6 +140,10 @@ SOURCE=.\testoc.c
# End Source File
# Begin Source File
+SOURCE=.\testpath.c
+# End Source File
+# Begin Source File
+
SOURCE=.\testpipe.c
# End Source File
# Begin Source File
diff --git a/test/test_apr.h b/test/test_apr.h
index 9c51256cf..4f0d57682 100644
--- a/test/test_apr.h
+++ b/test/test_apr.h
@@ -94,6 +94,7 @@ CuSuite *testthread(void);
CuSuite *testgetopt(void);
CuSuite *testnames(void);
CuSuite *testuser(void);
+CuSuite *testpath(void);
/* Assert that RV is an APR_SUCCESS value; else fail giving strerror
* for RV and CONTEXT message. */
diff --git a/test/testall.c b/test/testall.c
index b9ea4e564..da24dd52e 100644
--- a/test/testall.c
+++ b/test/testall.c
@@ -106,6 +106,7 @@ static const struct testlist {
{"testargs", testgetopt},
{"testnames", testnames},
{"testuser", testuser},
+ {"testpath", testpath},
{"LastTest", NULL}
};
diff --git a/test/testall.dsp b/test/testall.dsp
index c2673fddc..12f031cb7 100644
--- a/test/testall.dsp
+++ b/test/testall.dsp
@@ -167,6 +167,10 @@ SOURCE=.\testoc.c
# End Source File
# Begin Source File
+SOURCE=.\testpath.c
+# End Source File
+# Begin Source File
+
SOURCE=.\testpipe.c
# End Source File
# Begin Source File
diff --git a/test/testpath.c b/test/testpath.c
new file mode 100644
index 000000000..81efecea2
--- /dev/null
+++ b/test/testpath.c
@@ -0,0 +1,176 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+#include "test_apr.h"
+#include "apr_file_info.h"
+#include "apr_errno.h"
+#include "apr_pools.h"
+#include "apr_tables.h"
+
+#if defined(WIN32) || defined(NETWARE) || defined(OS2)
+#define PSEP ";"
+#define DSEP "\\"
+#else
+#define PSEP ":"
+#define DSEP "/"
+#endif
+
+#define PX ""
+#define P1 "first path"
+#define P2 "second" DSEP "path"
+#define P3 "th ird" DSEP "path"
+#define P4 "fourth" DSEP "pa th"
+#define P5 "fifthpath"
+
+static const char *parts_in[] = { P1, P2, P3, PX, P4, P5 };
+static const char *path_in = P1 PSEP P2 PSEP P3 PSEP PX PSEP P4 PSEP P5;
+static const int parts_in_count = sizeof(parts_in)/sizeof(*parts_in);
+
+static const char *parts_out[] = { P1, P2, P3, P4, P5 };
+static const char *path_out = P1 PSEP P2 PSEP P3 PSEP P4 PSEP P5;
+static const int parts_out_count = sizeof(parts_out)/sizeof(*parts_out);
+
+static void list_split_multi(CuTest *tc)
+{
+ int i;
+ apr_status_t rv;
+ apr_array_header_t *pathelts;
+
+ pathelts = NULL;
+ rv = apr_filepath_list_split(&pathelts, path_in, p);
+ CuAssertPtrNotNull(tc, pathelts);
+ CuAssertIntEquals(tc, APR_SUCCESS, rv);
+ CuAssertIntEquals(tc, parts_out_count, pathelts->nelts);
+ for (i = 0; i < pathelts->nelts; ++i)
+ CuAssertStrEquals(tc, parts_out[i], ((char**)pathelts->elts)[i]);
+}
+
+static void list_split_single(CuTest *tc)
+{
+ int i;
+ apr_status_t rv;
+ apr_array_header_t *pathelts;
+
+ for (i = 0; i < parts_in_count; ++i)
+ {
+ pathelts = NULL;
+ rv = apr_filepath_list_split(&pathelts, parts_in[i], p);
+ CuAssertPtrNotNull(tc, pathelts);
+ CuAssertIntEquals(tc, APR_SUCCESS, rv);
+ if (parts_in[i][0] == '\0')
+ CuAssertIntEquals(tc, 0, pathelts->nelts);
+ else
+ {
+ CuAssertIntEquals(tc, 1, pathelts->nelts);
+ CuAssertStrEquals(tc, parts_in[i], *(char**)pathelts->elts);
+ }
+ }
+}
+
+static void list_merge_multi(CuTest *tc)
+{
+ int i;
+ char *liststr;
+ apr_status_t rv;
+ apr_array_header_t *pathelts;
+
+ pathelts = apr_array_make(p, parts_in_count, sizeof(const char*));
+ for (i = 0; i < parts_in_count; ++i)
+ *(const char**)apr_array_push(pathelts) = parts_in[i];
+
+ liststr = NULL;
+ rv = apr_filepath_list_merge(&liststr, pathelts, p);
+ CuAssertPtrNotNull(tc, liststr);
+ CuAssertIntEquals(tc, APR_SUCCESS, rv);
+ CuAssertStrEquals(tc, liststr, path_out);
+}
+
+static void list_merge_single(CuTest *tc)
+{
+ int i;
+ char *liststr;
+ apr_status_t rv;
+ apr_array_header_t *pathelts;
+
+ pathelts = apr_array_make(p, 1, sizeof(const char*));
+ apr_array_push(pathelts);
+ for (i = 0; i < parts_in_count; ++i)
+ {
+ *(const char**)pathelts->elts = parts_in[i];
+ liststr = NULL;
+ rv = apr_filepath_list_merge(&liststr, pathelts, p);
+ if (parts_in[i][0] == '\0')
+ CuAssertPtrEquals(tc, NULL, liststr);
+ else
+ {
+ CuAssertPtrNotNull(tc, liststr);
+ CuAssertIntEquals(tc, APR_SUCCESS, rv);
+ CuAssertStrEquals(tc, liststr, parts_in[i]);
+ }
+ }
+}
+
+
+CuSuite *testpath(void)
+{
+ CuSuite *suite = CuSuiteNew("Path lists");
+
+ SUITE_ADD_TEST(suite, list_split_multi);
+ SUITE_ADD_TEST(suite, list_split_single);
+ SUITE_ADD_TEST(suite, list_merge_multi);
+ SUITE_ADD_TEST(suite, list_merge_single);
+
+ return suite;
+}
+