OSSP CVS Repository

ossp - Check-in [2526]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 2526
Date: 2002-Aug-27 21:04:33 (local)
2002-Aug-27 19:04:33 (UTC)
User:rse
Branch:
Comment: add path_canon() function for non-physical-fs-based canonifcations of a path
Tickets:
Inspections:
Files:
ossp-pkg/path/Makefile.in      1.4 -> 1.5     1 inserted, 1 deleted
ossp-pkg/path/path.h      1.4 -> 1.5     1 inserted, 0 deleted
ossp-pkg/path/path_canon.c      added-> 1.1
ossp-pkg/path/path_test.c      1.3 -> 1.4     6 inserted, 0 deleted
ossp-pkg/path/path_test.pl      1.1 -> 1.2     63 inserted, 42 deleted

ossp-pkg/path/Makefile.in 1.4 -> 1.5

--- Makefile.in  2002/08/23 15:33:18     1.4
+++ Makefile.in  2002/08/27 19:04:33     1.5
@@ -50,7 +50,7 @@
 TRUE        = true
 
 LIB_NAME    = libpath.la
-LIB_OBJS    = path_abs2rel.lo path_rel2abs.lo path_resolve.lo \
+LIB_OBJS    = path_abs2rel.lo path_rel2abs.lo path_resolve.lo path_canon.lo \
               path_dirname.lo path_basename.lo path_temp.lo path_self.lo path_util.lo
 
 TST_NAME    = path_test


ossp-pkg/path/path.h 1.4 -> 1.5

--- path.h       2002/08/23 15:33:18     1.4
+++ path.h       2002/08/27 19:04:33     1.5
@@ -52,6 +52,7 @@
 char *path_resolve  (char *, size_t, const char *);
 char *path_dirname  (char *, size_t, const char *);
 char *path_basename (char *, size_t, const char *);
+path_rc_t path_canon(char *res_buf, size_t res_len, const char *path_buf, size_t path_len);
 path_rc_t path_temp(path_temp_t id, const char *tmpl, char **res_ptr, size_t *res_size, int *res_fd);
 path_rc_t path_self (char *res_buf, size_t res_size, const char *argv0);
 


ossp-pkg/path/path_canon.c -> 1.1

*** /dev/null    Sat Nov 23 01:17:29 2024
--- -    Sat Nov 23 01:17:34 2024
***************
*** 0 ****
--- 1,144 ----
+ /*
+ **  OSSP path - Filesystem Path Manipulation
+ **  Copyright (c) 2002 Ralf S. Engelschall <rse@engelschall.com>
+ **  Copyright (c) 2002 The OSSP Project <http://www.ossp.org/>
+ **  Copyright (c) 2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
+ **
+ **  This file is part of OSSP path, a filesystem path manipulation library
+ **  which can be found at http://www.ossp.org/pkg/lib/path/.
+ **
+ **  Permission to use, copy, modify, and distribute this software for
+ **  any purpose with or without fee is hereby granted, provided that
+ **  the above copyright notice and this permission notice appear in all
+ **  copies.
+ **
+ **  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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ **  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.
+ **
+ **  src_canon.c: pathname canonification
+ */
+ 
+ #include <stdio.h>
+ #include <string.h>
+ 
+ #include "path.h"
+ 
+ path_rc_t 
+ path_canon(
+     char       *res_buf, size_t res_len,
+     const char *src_buf, size_t src_len)
+ {
+     char *res_ptr;
+     char *res_end;
+     const char *src_ptr;
+     const char *src_end;
+     size_t l;
+ 
+     /* argument sanity checking */
+     if (src_buf == NULL)
+         return PATH_ERR_ARG;
+ 
+     /* argument default provision */
+     if (src_len == 0)
+         src_len = strlen(src_buf);
+     if (res_buf == NULL) {
+         res_buf = (char *)src_buf;
+         if (res_len == 0)
+             res_len = src_len;
+     }
+     if (res_len == 0)
+         res_len = strlen(res_buf);
+ 
+     /* perform processing 
+        (keep in mind that source and target can overlap) */
+     res_ptr = res_buf;
+     res_end = res_buf+res_len;
+     src_ptr = src_buf;
+     src_end = src_buf+src_len;
+     
+     while (src_ptr < src_end && res_ptr < res_end) {
+         /* recognize path separator */
+         if (*src_ptr == '/') {
+             /* take over separator character once */
+             *res_ptr++ = *src_ptr++;
+             /* skip multiple separator characters */
+             while (src_ptr < src_end && *src_ptr == '/')
+                 src_ptr++;
+             continue;
+         }
+ 
+         /* determine length of path element */
+         l = 0;
+         while (src_ptr+l < src_end && src_ptr[l] != '/')
+             l++;
+         if (l == 0)
+             break;
+ 
+         /* handle path element */
+         if (l == 1 && src_ptr[0] == '.') {
+             /* path element is current directory ("."),
+                so just skip over to next path element in source */
+             src_ptr += 1;
+             while (src_ptr < src_end && *src_ptr == '/')
+                 src_ptr++;
+         }
+         else if (l == 2 && src_ptr[0] == '.' && src_ptr[1] == '.') {
+             /* path element is parent directory (".."),
+                so skip over to next path element in source and
+                skip back last path element in result */
+             if (   res_ptr == res_buf 
+                 || (   res_ptr >= res_buf+3 
+                     && res_ptr[-1] == '/' && res_ptr[-2] == '.' && res_ptr[-3] == '.')) {
+                 /* path is relative and empty or already explicit directing
+                    to the parent directory, so keep explicit parent specification */
+                 while (src_ptr < src_end && res_ptr < res_end && src_ptr[0] != '/')
+                     *res_ptr++ = *src_ptr++;
+             }
+             else {
+                 /* there is already a path element in the 
+                    result which can be removed */
+                 src_ptr += 2;
+                 while (res_ptr > res_buf && res_ptr[-1] == '/')
+                     res_ptr--;
+                 while (res_ptr > res_buf && res_ptr[-1] != '/')
+                     res_ptr--;
+                 if (res_ptr == res_buf && res_ptr[0] == '/')
+                     res_ptr++;
+                 while (src_ptr < src_end && src_ptr[0] == '/')
+                     src_ptr++;
+             }
+         }
+         else {
+             /* path element something else, so copy 
+                it over from source to the result */
+             while (src_ptr < src_end && res_ptr < res_end && src_ptr[0] != '/')
+                 *res_ptr++ = *src_ptr++;
+         }
+     }
+ 
+     /* remove tailing path separators */
+     if (res_ptr > res_buf+1 && res_ptr[-1] == '/')
+         res_ptr--;
+ 
+     /* make sure we do not reduce to an empty (invalid) path */
+     if (res_ptr == res_buf && res_ptr < res_end)
+         *res_ptr++ = '.';
+ 
+     /* append NUL terminating character */
+     if (res_ptr >= res_end)
+         return PATH_ERR_MEM;
+     *res_ptr++ = '\0';
+ 
+     return PATH_OK;
+ }
+ 


ossp-pkg/path/path_test.c 1.3 -> 1.4

--- path_test.c  2002/08/23 15:33:18     1.3
+++ path_test.c  2002/08/27 19:04:33     1.4
@@ -95,6 +95,12 @@
         else
             printf("ERROR\n");
     }
+    else if (argc == 3 && strcmp(argv[1], "canon") == 0) {
+        if (path_canon(res, sizeof(res), argv[2], 0) == PATH_OK)
+            printf("%s\n", res);
+        else
+            printf("ERROR\n");
+    }
     else if (argc == 3 && strcmp(argv[1], "dirname") == 0) {
         rv = path_dirname(res, sizeof(res), argv[2]);
         if (rv != NULL)


ossp-pkg/path/path_test.pl 1.1 -> 1.2

--- path_test.pl 2002/01/21 13:32:35     1.1
+++ path_test.pl 2002/08/27 19:04:33     1.2
@@ -1,52 +1,63 @@
 
 @abs2rel = (
-        'a/b/c          /               a/b/c',
-        'a/b/c          /a              a/b/c',
-        '/a/b/c         a               ERROR',
+    'a/b/c          /               a/b/c',
+    'a/b/c          /a              a/b/c',
+    '/a/b/c         a               ERROR',
 );
 
 @rel2abs = (
-        '/a/b/c         /               /a/b/c',
-        '/a/b/c         /a              /a/b/c',
-        'a/b/c          a               ERROR',
-        '..             /a              /',
-        '../            /a              /',
-        '../..          /a              /',
-        '../../         /a              /',
-        '../../..       /a              /',
-        '../../../      /a              /',
-        '../b           /a              /b',
-        '../b/          /a              /b/',
-        '../../b        /a              /b',
-        '../../b/       /a              /b/',
-        '../../../b     /a              /b',
-        '../../../b/    /a              /b/',
-        '../b/c         /a              /b/c',
-        '../b/c/        /a              /b/c/',
-        '../../b/c      /a              /b/c',
-        '../../b/c/     /a              /b/c/',
-        '../../../b/c   /a              /b/c',
-        '../../../b/c/  /a              /b/c/',
+    '/a/b/c         /               /a/b/c',
+    '/a/b/c         /a              /a/b/c',
+    'a/b/c          a               ERROR',
+    '..             /a              /',
+    '../            /a              /',
+    '../..          /a              /',
+    '../../         /a              /',
+    '../../..       /a              /',
+    '../../../      /a              /',
+    '../b           /a              /b',
+    '../b/          /a              /b/',
+    '../../b        /a              /b',
+    '../../b/       /a              /b/',
+    '../../../b     /a              /b',
+    '../../../b/    /a              /b/',
+    '../b/c         /a              /b/c',
+    '../b/c/        /a              /b/c/',
+    '../../b/c      /a              /b/c',
+    '../../b/c/     /a              /b/c/',
+    '../../../b/c   /a              /b/c',
+    '../../../b/c/  /a              /b/c/',
 );
 
 @common = (
-        '/a/b/c         /a/b/c          .',
-        '/a/b/c         /a/b/           c',
-        '/a/b/c         /a/b            c',
-        '/a/b/c         /a/             b/c',
-        '/a/b/c         /a              b/c',
-        '/a/b/c         /               a/b/c',
-        '/a/b/c         /a/b/c          .',
-        '/a/b/c         /a/b/c/         .',
-        '/a/b/c/        /a/b/c          ./',
-        '/a/b/          /a/b/c          ../',
-        '/a/b           /a/b/c          ..',
-        '/a/            /a/b/c          ../../',
-        '/a             /a/b/c          ../..',
-        '/              /a/b/c          ../../../',
-        '/a/b/c         /a/b/z          ../c',
-        '/a/b/c         /a/y/z          ../../b/c',
-        '/a/b/c         /x/y/z          ../../../a/b/c',
+    '/a/b/c         /a/b/c          .',
+    '/a/b/c         /a/b/           c',
+    '/a/b/c         /a/b            c',
+    '/a/b/c         /a/             b/c',
+    '/a/b/c         /a              b/c',
+    '/a/b/c         /               a/b/c',
+    '/a/b/c         /a/b/c          .',
+    '/a/b/c         /a/b/c/         .',
+    '/a/b/c/        /a/b/c          ./',
+    '/a/b/          /a/b/c          ../',
+    '/a/b           /a/b/c          ..',
+    '/a/            /a/b/c          ../../',
+    '/a             /a/b/c          ../..',
+    '/              /a/b/c          ../../../',
+    '/a/b/c         /a/b/z          ../c',
+    '/a/b/c         /a/y/z          ../../b/c',
+    '/a/b/c         /x/y/z          ../../../a/b/c',
+);
+
+@canon = (
+    'a              a',
+    'a/             a',
+    'a/b            a/b',
+    'a////b         a/b',
+    '.              .',
+    'a/..           .',
+    'a/../../..     ../..',
+    '/a/../../../b  /b',
 );
 
 $cnt = 0;
@@ -90,11 +101,21 @@
     if ($d[0] eq $result) {
         print STDERR "OK: rel2abs: $d[0] $d[1] -> $result\n";
     } else {
-        print 'X';
         print STDERR "ERROR: rel2abs: $d[0] $d[1] -> $result (It should be '$d[2]')\n";
         $cnt++;
     }
 }
+
+foreach (@canon) {
+    @d = split;
+    chop($result = `./$progname canon $d[0]`);
+    if ($d[1] eq $result) {
+        print STDERR "OK: canon: $d[0] -> $result\n";
+    } else {
+        print STDERR "ERROR: canon: $d[0] -> $result (It should be '$d[1]')\n";
+        $cnt++;
+    }
+}
 
 close(LOG);
 

CVSTrac 2.0.1