Implement yaz_filepath_comp which splits a path into file path
authorAdam Dickmeiss <adam@indexdata.dk>
Wed, 11 Oct 2006 08:43:21 +0000 (08:43 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Wed, 11 Oct 2006 08:43:21 +0000 (08:43 +0000)
components.

include/yaz/tpath.h
src/tpath.c
test/tst_tpath.c

index cda60cb..4369cd0 100644 (file)
@@ -24,7 +24,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-/* $Id: tpath.h,v 1.12 2006-10-09 21:02:41 adam Exp $ */
+/* $Id: tpath.h,v 1.13 2006-10-11 08:43:21 adam Exp $ */
 
 /**
  * \file tpath.h
@@ -41,11 +41,25 @@ YAZ_BEGIN_CDECL
 
 /** \brief checks whether path is absolute
     \param path path to checked
-
-    Returns 1 if path is absolute, 0 if relative
+    \retval 1 path is absolute
+    \retval 0 path is relative
 */
 YAZ_EXPORT int yaz_is_abspath (const char *path);
 
+/** \brief get next path component in filepath
+    \param path_p pointer to path (updated to "next" entry if any)
+    \param comp upon pointer to component (if component is found)
+    \retval 0 no component found (and no more componennts)
+    \retval >0 length of component (length of *comp)
+    
+    A filepath has components separted by colon. For example
+    /usr/lib/modules:c:/my:/:lib
+    which has these components
+    "/usr/lib/modules", "c:/my", "/", "lib"
+*/
+YAZ_EXPORT size_t yaz_filepath_comp(const char **path_p, const char **comp);
+
+
 /** \brief resolve file on path 
     \param fname "short" filename (without path)
     \param path the path (dir1:dir2,..) - ala Unix
@@ -86,7 +100,8 @@ YAZ_EXPORT FILE *yaz_path_fopen(const char *path, const char *fname,
 /** \brief closes file
     \param f FILE handle
 
-    Returns -1 on failure; 0 on success
+    \retval -1 on failure
+    \retval 0 on success
 */
 YAZ_EXPORT int yaz_fclose(FILE *f);
 
index 9dd8637..2cd900d 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2006, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: tpath.c,v 1.11 2006-06-08 20:55:38 adam Exp $
+ * $Id: tpath.c,v 1.12 2006-10-11 08:43:22 adam Exp $
  */
 /**
  * \file tpath.c
@@ -36,43 +36,62 @@ int yaz_fclose (FILE *f)
 }
 
 
+size_t yaz_filepath_comp(const char **path_p, const char **comp)
+{
+    const char *path = *path_p;
+    size_t len;
+    const char *path_sep;
+
+    /* somewhat dirty since we have to consider Windows
+     * drive letters..
+     */
+    if (path[0] && strchr ("/\\.", path[0]))
+        path_sep = strchr (path+1, ':');
+    else if (path[0] && path[1])
+        path_sep = strchr (path+2, ':');
+    else
+        path_sep = 0;
+    
+    if (path_sep)
+    {
+        len = path_sep - path;
+        *path_p = path + len + 1;
+    }
+    else
+    {
+        len = strlen(path);
+        *path_p = path + len;
+    }
+    *comp = path;
+    return len;
+}
+
 char *yaz_filepath_resolve(const char *fname, const char *path,
                            const char *base, char *fullpath)
 {
     for(;;)
     {
         struct stat stat_buf;
-        const char *path_sep = 0;
-        size_t len = 0;
         size_t slen = 0;
        
         *fullpath = '\0';
         if (path)
         {
-            /* somewhat dirty since we have to consider Windows
-             * drive letters..
-             */
-            if (path[0] && strchr ("/\\.", *path))
-                path_sep = strchr (path+1, ':');
-            else if (path[0] && path[1])
-                path_sep = strchr (path+2, ':');
-            else
-                path_sep = 0;
+            const char *comp;
+            size_t len = 0;
+
+            len = yaz_filepath_comp(&path, &comp);
+            if (!len)
+                break;
 
-            if (path_sep)
-                len = path_sep - path;
-            else
-                len = strlen(path);
-            /* is path is relative and base is to be used */
-            if (!strchr ("/\\", *path) && base)
+            if (!strchr ("/\\", *comp) && base)
             {
                 /* yes: make base the first part */
                 strcpy (fullpath, base);
                 slen = strlen(fullpath);
                 fullpath[slen++] = '/';
             }
-            if (len)
-                memcpy (fullpath+slen, path, len);
+            memcpy (fullpath+slen, comp, len);
             slen += len;
             if (slen > 0 && !strchr("/\\", fullpath[slen-1]))
                 fullpath[slen++] = '/';
@@ -80,10 +99,8 @@ char *yaz_filepath_resolve(const char *fname, const char *path,
         strcpy (fullpath+slen, fname);
         if (stat(fullpath, &stat_buf) == 0)
             return fullpath;
-        
-        if (!path_sep)
+        if (!path)
             break;
-        path = path_sep+1;
     }
     return 0;
 }
index eca34a1..cbec193 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 2005-2006, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: tst_tpath.c,v 1.1 2006-06-08 10:26:10 adam Exp $
+ * $Id: tst_tpath.c,v 1.2 2006-10-11 08:43:22 adam Exp $
  *
  */
 #include <yaz/tpath.h>
@@ -17,7 +17,7 @@
 
 static void tst_tpath(void)
 {
-    char fullpath[1024];
+    char fullpath[FILENAME_MAX];
 
     YAZ_CHECK(!yaz_filepath_resolve("etc", 0, 0, fullpath));
     YAZ_CHECK(!yaz_filepath_resolve("etc", "", 0, fullpath)); /* bug #606 */
@@ -25,13 +25,16 @@ static void tst_tpath(void)
     YAZ_CHECK(!yaz_filepath_resolve("does_not_exist", "", 0, fullpath));
     YAZ_CHECK(!yaz_filepath_resolve("does_not_exist", ".", 0, fullpath));
     YAZ_CHECK(yaz_filepath_resolve("tst_tpath", 0, 0, fullpath));
-    YAZ_CHECK(yaz_filepath_resolve("tst_tpath", "", 0, fullpath));
+
+    YAZ_CHECK(!yaz_filepath_resolve("tst_tpath", "", 0, fullpath));
     YAZ_CHECK(yaz_filepath_resolve("tst_tpath", ".", 0, fullpath));
+
     YAZ_CHECK(!yaz_filepath_resolve("tst_tpath", "unknown_dir", 0, fullpath));
     YAZ_CHECK(yaz_filepath_resolve("tst_tpath", "unknown_dir:.", 0, fullpath));
-    YAZ_CHECK(yaz_filepath_resolve("tst_tpath", "unknown_dir:", 0, fullpath));
+    YAZ_CHECK(!yaz_filepath_resolve("tst_tpath", "unknown_dir:", 0, fullpath));
     YAZ_CHECK(!yaz_filepath_resolve("tst_tpath", "unknown_dir:c:", 0, fullpath));
     YAZ_CHECK(!yaz_filepath_resolve("tst_tpath", "unknown_dir:c:\\other", 0, fullpath));
+
 }
 
 int main(int argc, char **argv)