]> sjero.net Git - wget/blobdiff - src/utils.c
[svn] Minor fixes prompted by `lint'.
[wget] / src / utils.c
index e93846cb8e3684d3d3ee2e98a555ac0435d6b957..32c17b4bfd9026e4b8fb8240c62bb580edf0cfc4 100644 (file)
@@ -50,9 +50,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #endif
 #include <fcntl.h>
 #include <assert.h>
+
+/* For TIOCGWINSZ and friends: */
 #ifdef HAVE_SYS_IOCTL_H
 # include <sys/ioctl.h>
 #endif
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#endif
 
 #include "wget.h"
 #include "utils.h"
@@ -487,27 +492,30 @@ ps (char *orig)
        Non-leading `../'s and trailing `..'s are handled by removing
        portions of the path.
 
-   E.g. "a/b/c/./../d/.." will yield "a/b".  This function originates
-   from GNU Bash.
+   E.g. "a/b/c/./../d/.." will yield "a/b/".  This function originates
+   from GNU Bash and has been mutilated to unrecognition for use in
+   Wget.
 
    Changes for Wget:
        Always use '/' as stub_char.
        Don't check for local things using canon_stat.
        Change the original string instead of strdup-ing.
        React correctly when beginning with `./' and `../'.
-       Don't zip out trailing slashes.  */
+       Don't zip out trailing slashes.
+       Return a value indicating whether any modifications took place.
+
+   If you dare change this function, take a careful look at the test
+   cases below, and make sure that they pass.  */
+
 int
 path_simplify (char *path)
 {
   register int i, start;
   int changes = 0;
-  char stub_char;
 
   if (!*path)
     return 0;
 
-  stub_char = '/';
-
   if (path[0] == '/')
     /* Preserve initial '/'. */
     ++path;
@@ -600,6 +608,28 @@ path_simplify (char *path)
 
   return changes;
 }
+
+/* Test cases:
+   ps("")                   -> ""
+   ps("/")                  -> "/"
+   ps(".")                  -> ""
+   ps("..")                 -> ""
+   ps("/.")                 -> "/"
+   ps("/..")                -> "/"
+   ps("foo")                -> "foo"
+   ps("foo/bar")            -> "foo/bar"
+   ps("foo//bar")           -> "foo/bar"             (possibly a bug)
+   ps("foo/../bar")         -> "bar"
+   ps("foo/bar/..")         -> "foo/"
+   ps("foo/bar/../x")       -> "foo/x"
+   ps("foo/bar/../x/")      -> "foo/x/"
+   ps("foo/..")             -> ""
+   ps("/foo/..")            -> "/"
+   ps("a/b/../../c")        -> "c"
+   ps("/a/b/../../c")       -> "/c"
+   ps("./a/../b")           -> "b"
+   ps("/./a/../b")          -> "/b"
+*/
 \f
 /* "Touch" FILE, i.e. make its atime and mtime equal to the time
    specified with TM.  */
@@ -744,9 +774,11 @@ make_directory (const char *directory)
 }
 
 /* Merge BASE with FILE.  BASE can be a directory or a file name, FILE
-   should be a file name.  For example, file_merge("/foo/bar", "baz")
-   will return "/foo/baz".  file_merge("/foo/bar/", "baz") will return
-   "foo/bar/baz".
+   should be a file name.
+
+   file_merge("/foo/bar", "baz")  => "/foo/baz"
+   file_merge("/foo/bar/", "baz") => "/foo/bar/baz"
+   file_merge("foo", "bar")       => "bar"
 
    In other words, it's a simpler and gentler version of uri_merge_1.  */
 
@@ -757,7 +789,7 @@ file_merge (const char *base, const char *file)
   const char *cut = (const char *)strrchr (base, '/');
 
   if (!cut)
-    cut = base + strlen (base);
+    return xstrdup (file);
 
   result = (char *)xmalloc (cut - base + 1 + strlen (file) + 1);
   memcpy (result, base, cut - base);
@@ -854,8 +886,8 @@ accdir (const char *directory, enum accd flags)
    match_backwards ("abc", "bc") -> 1
    match_backwards ("abc", "ab") -> 0
    match_backwards ("abc", "abc") -> 1 */
-static int
-match_backwards (const char *string, const char *pattern)
+int
+match_tail (const char *string, const char *pattern)
 {
   int i, j;
 
@@ -870,7 +902,7 @@ match_backwards (const char *string, const char *pattern)
 }
 
 /* Checks whether string S matches each element of ACCEPTS.  A list
-   element are matched either with fnmatch() or match_backwards(),
+   element are matched either with fnmatch() or match_tail(),
    according to whether the element contains wildcards or not.
 
    If the BACKWARD is 0, don't do backward comparison -- just compare
@@ -891,7 +923,7 @@ in_acclist (const char *const *accepts, const char *s, int backward)
        {
          if (backward)
            {
-             if (match_backwards (s, *accepts))
+             if (match_tail (s, *accepts))
                return 1;
            }
          else
@@ -925,13 +957,17 @@ suffix (const char *str)
 
 /* Read a line from FP.  The function reallocs the storage as needed
    to accomodate for any length of the line.  Reallocs are done
-   storage exponentially, doubling the storage after each overflow to
-   minimize the number of calls to realloc() and fgets().  The newline
+   exponentially, doubling the storage after each overflow to minimize
+   the number of calls to realloc() and fgets().  The newline
    character at the end of line is retained.
 
    After end-of-file is encountered without anything being read, NULL
    is returned.  NULL is also returned on error.  To distinguish
-   between these two cases, use the stdio function ferror().  */
+   between these two cases, use the stdio function ferror().
+
+   A future version of this function will be rewritten to use fread()
+   instead of fgets(), and to return the length of the line, which
+   will make the function usable on files with binary content.  */
 
 char *
 read_whole_line (FILE *fp)
@@ -943,9 +979,14 @@ read_whole_line (FILE *fp)
   while (fgets (line + length, bufsize - length, fp))
     {
       length += strlen (line + length);
-      assert (length > 0);
+      if (length == 0)
+       /* Possible for example when reading from a binary file where
+          a line begins with \0.  */
+       continue;
+
       if (line[length - 1] == '\n')
        break;
+
       /* fgets() guarantees to read the whole line, or to use up the
          space we've given it.  We can double the buffer
          unconditionally.  */
@@ -1772,7 +1813,7 @@ determine_screen_width (void)
 #endif /* TIOCGWINSZ */
 }
 
-#if 1
+#if 0
 /* A debugging function for checking whether an MD5 library works. */
 
 #include "gen-md5.h"
@@ -1788,7 +1829,7 @@ debug_test_md5 (char *buf)
   ALLOCA_MD5_CONTEXT (ctx);
 
   gen_md5_init (ctx);
-  gen_md5_update (buf, strlen (buf), ctx);
+  gen_md5_update ((unsigned char *)buf, strlen (buf), ctx);
   gen_md5_finish (ctx, raw);
 
   p1 = raw;