diff options
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | NWGNUmakefile | 1 | ||||
-rw-r--r-- | apr.dsp | 4 | ||||
-rw-r--r-- | file_io/unix/Makefile.in | 1 | ||||
-rw-r--r-- | file_io/unix/filepath.c | 23 | ||||
-rw-r--r-- | file_io/unix/filepath_util.c | 147 | ||||
-rw-r--r-- | file_io/win32/filepath.c | 24 | ||||
-rw-r--r-- | include/apr_file_info.h | 31 | ||||
-rw-r--r-- | include/apr_pools.h | 3 | ||||
-rw-r--r-- | libapr.dsp | 4 | ||||
-rw-r--r-- | test/Makefile.in | 2 | ||||
-rw-r--r-- | test/Makefile.win | 4 | ||||
-rw-r--r-- | test/aprtest.dsp | 4 | ||||
-rw-r--r-- | test/test_apr.h | 1 | ||||
-rw-r--r-- | test/testall.c | 1 | ||||
-rw-r--r-- | test/testall.dsp | 4 | ||||
-rw-r--r-- | test/testpath.c | 176 |
17 files changed, 430 insertions, 3 deletions
@@ -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 \ @@ -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; +} + |