]> sjero.net Git - wget/commitdiff
[svn] Better document the workings of construct_relative().
authorhniksic <devnull@localhost>
Sat, 25 Oct 2003 11:58:24 +0000 (04:58 -0700)
committerhniksic <devnull@localhost>
Sat, 25 Oct 2003 11:58:24 +0000 (04:58 -0700)
Reformat is_valid_ipv6_address() to GNU formatting style.

src/ChangeLog
src/convert.c
src/url.c

index 05861c9483e569e2d2c7d0d0c295fad64a505756..f7e0e94fb4bc64e12068b0e92e80d2d9cf582b1a 100644 (file)
@@ -1,3 +1,11 @@
+2003-10-25  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * url.c (is_valid_ipv6_address): Reformat to GNU coding style.
+       Use enums for NS_IN* constants.  Use ISXDIGIT.
+
+       * convert.c (construct_relative): Document better how the function
+       works.
+
 2003-10-23  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * config.h.in: Deploy preprocessor magic to avoid Ultrix's
index cb8dbb85bfaa48b6cd150dd153ea5c03bc2803cf..941bf05dfb2083c8ee19e841b2bf8186e902fe73 100644 (file)
@@ -327,52 +327,67 @@ convert_links (const char *file, struct urlpos *links)
   logprintf (LOG_VERBOSE, "%d-%d\n", to_file_count, to_url_count);
 }
 
-/* Construct and return a link that points from S1's position to S2.
-   Both files should be local file names, S1 of the referrering file,
-   and S2 of the referred file.
+/* Construct and return a link that points from BASEFILE to LINKFILE.
+   Both files should be local file names, BASEFILE of the referrering
+   file, and LINKFILE of the referred file.
 
-   So, if S1 is "H/index.html" and S2 is "H/images/news.gif", this
-   function will return "images/news.gif".  On the other hand, if S1
-   is "H/ioccc/index.html", and S2 is "H/images/fly.gif", it will
-   return "../images/fly.gif".
+   Examples:
 
-   Caveats: S1 should not begin with `/', unless S2 also begins with
-   '/'.  S1 should not contain things like ".." and such --
-   construct_relative ("fly/ioccc/../index.html",
-   "fly/images/fly.gif") will fail.  (A workaround is to call
-   something like path_simplify() on S1).  */
+   cr("foo", "bar")         -> "bar"
+   cr("A/foo", "A/bar")     -> "bar"
+   cr("A/foo", "A/B/bar")   -> "B/bar"
+   cr("A/X/foo", "A/Y/bar") -> "../Y/bar"
+   cr("X/", "Y/bar")        -> "../Y/bar" (trailing slash does matter in BASE)
+
+   Both files should be absolute or relative, otherwise strange
+   results might ensue.  The function makes no special efforts to
+   handle "." and ".." in links, so make sure they're not there
+   (e.g. using path_simplify).  */
 
 static char *
-construct_relative (const char *s1, const char *s2)
+construct_relative (const char *basefile, const char *linkfile)
 {
-  int i, cnt, sepdirs1;
-  char *res;
+  char *link;
+  int basedirs;
+  const char *b, *l;
+  int i, start;
+
+  /* First, skip the initial directory components common to both
+     files.  */
+  start = 0;
+  for (b = basefile, l = linkfile; *b == *l && *b != '\0'; ++b, ++l)
+    {
+      if (*b == '/')
+       start = (b - basefile) + 1;
+    }
+  basefile += start;
+  linkfile += start;
+
+  /* With common directories out of the way, the situation we have is
+     as follows:
+         b - b1/b2/[...]/bfile
+         l - l1/l2/[...]/lfile
 
-  i = cnt = 0;
-  /* Skip the directories common to both strings.  */
-  while (1)
+     The link we're constructing needs to be:
+       lnk - ../../l1/l2/[...]/lfile
+
+     Where the number of ".."'s equals the number of bN directory
+     components in B.  */
+
+  /* Count the directory components in B. */
+  basedirs = 0;
+  for (b = basefile; *b; b++)
     {
-      while (s1[i] && s2[i]
-            && (s1[i] == s2[i])
-            && (s1[i] != '/')
-            && (s2[i] != '/'))
-       ++i;
-      if (s1[i] == '/' && s2[i] == '/')
-       cnt = ++i;
-      else
-       break;
+      if (*b == '/')
+       ++basedirs;
     }
-  for (sepdirs1 = 0; s1[i]; i++)
-    if (s1[i] == '/')
-      ++sepdirs1;
-  /* Now, construct the file as of:
-     - ../ repeated sepdirs1 time
-     - all the non-mutual directories of S2.  */
-  res = (char *)xmalloc (3 * sepdirs1 + strlen (s2 + cnt) + 1);
-  for (i = 0; i < sepdirs1; i++)
-    memcpy (res + 3 * i, "../", 3);
-  strcpy (res + 3 * i, s2 + cnt);
-  return res;
+
+  /* Construct LINK as explained above. */
+  link = (char *)xmalloc (3 * basedirs + strlen (linkfile) + 1);
+  for (i = 0; i < basedirs; i++)
+    memcpy (link + 3 * i, "../", 3);
+  strcpy (link + 3 * i, linkfile);
+  return link;
 }
 
 static void
index 9f50127cbb9f7f743aef05700a0e601c8e684e78..ecb79b9c4c8cfa077d6a2b9c508df2eb6ab8768f 100644 (file)
--- a/src/url.c
+++ b/src/url.c
@@ -641,48 +641,52 @@ static char *parse_errors[] = {
 static int
 is_valid_ipv4_address (const char *str, const char *end)
 {
-  int saw_digit, octets;
-  int val;
+  int saw_digit = 0;
+  int octets = 0;
+  int val = 0;
 
-  saw_digit = 0;
-  octets = 0;
-  val = 0;
-
-  while (str < end) {
-    int ch = *str++;
+  while (str < end)
+    {
+      int ch = *str++;
 
-    if (ch >= '0' && ch <= '9') {
-      val = val * 10 + (ch - '0');
+      if (ch >= '0' && ch <= '9')
+       {
+         val = val * 10 + (ch - '0');
 
-      if (val > 255)
-        return 0;
-      if (saw_digit == 0) {
-        if (++octets > 4)
-          return 0;
-        saw_digit = 1;
-      }
-    } else if (ch == '.' && saw_digit == 1) {
-      if (octets == 4)
-        return 0;
-      val = 0;
-      saw_digit = 0;
-    } else
-      return 0;
-  }
+         if (val > 255)
+           return 0;
+         if (saw_digit == 0)
+           {
+             if (++octets > 4)
+               return 0;
+             saw_digit = 1;
+           }
+       }
+      else if (ch == '.' && saw_digit == 1)
+       {
+         if (octets == 4)
+           return 0;
+         val = 0;
+         saw_digit = 0;
+       }
+      else
+       return 0;
+    }
   if (octets < 4)
     return 0;
   
   return 1;
 }
 
-static const int NS_INADDRSZ  = 4;
-static const int NS_IN6ADDRSZ = 16;
-static const int NS_INT16SZ   = 2;
-
 static int
 is_valid_ipv6_address (const char *str, const char *end)
 {
-  static const char xdigits[] = "0123456789abcdef";
+  enum {
+    NS_INADDRSZ  = 4,
+    NS_IN6ADDRSZ = 16,
+    NS_INT16SZ   = 2
+  };
+
   const char *curtok;
   int tp;
   const char *colonp;
@@ -707,62 +711,67 @@ is_valid_ipv6_address (const char *str, const char *end)
   saw_xdigit = 0;
   val = 0;
 
-  while (str < end) {
-    int ch = *str++;
-    const char *pch;
+  while (str < end)
+    {
+      int ch = *str++;
 
-    /* if ch is a number, add it to val. */
-    pch = strchr(xdigits, ch);
-    if (pch != NULL) {
-      val <<= 4;
-      val |= (pch - xdigits);
-      if (val > 0xffff)
-       return 0;
-      saw_xdigit = 1;
-      continue;
+      /* if ch is a number, add it to val. */
+      if (ISXDIGIT (ch))
+       {
+         val <<= 4;
+         val |= XDIGIT_TO_NUM (ch);
+         if (val > 0xffff)
+           return 0;
+         saw_xdigit = 1;
+         continue;
+       }
+
+      /* if ch is a colon ... */
+      if (ch == ':')
+       {
+         curtok = str;
+         if (saw_xdigit == 0)
+           {
+             if (colonp != NULL)
+               return 0;
+             colonp = str + tp;
+             continue;
+           }
+         else if (str == end)
+           return 0;
+         if (tp > NS_IN6ADDRSZ - NS_INT16SZ)
+           return 0;
+         tp += NS_INT16SZ;
+         saw_xdigit = 0;
+         val = 0;
+         continue;
+       }
+
+      /* if ch is a dot ... */
+      if (ch == '.' && (tp <= NS_IN6ADDRSZ - NS_INADDRSZ)
+         && is_valid_ipv4_address (curtok, end) == 1)
+       {
+         tp += NS_INADDRSZ;
+         saw_xdigit = 0;
+         break;
+       }
+    
+      return 0;
     }
 
-    /* if ch is a colon ... */
-    if (ch == ':') {
-      curtok = str;
-      if (saw_xdigit == 0) {
-       if (colonp != NULL)
-         return 0;
-       colonp = str + tp;
-       continue;
-      } else if (str == end) {
-       return 0;
-      }
-      if (tp > NS_IN6ADDRSZ - NS_INT16SZ)
+  if (saw_xdigit == 1)
+    {
+      if (tp > NS_IN6ADDRSZ - NS_INT16SZ) 
        return 0;
       tp += NS_INT16SZ;
-      saw_xdigit = 0;
-      val = 0;
-      continue;
     }
 
-    /* if ch is a dot ... */
-    if (ch == '.' && (tp <= NS_IN6ADDRSZ - NS_INADDRSZ) &&
-       is_valid_ipv4_address(curtok, end) == 1) {
-      tp += NS_INADDRSZ;
-      saw_xdigit = 0;
-      break;
+  if (colonp != NULL)
+    {
+      if (tp == NS_IN6ADDRSZ) 
+       return 0;
+      tp = NS_IN6ADDRSZ;
     }
-    
-    return 0;
-  }
-
-  if (saw_xdigit == 1) {
-    if (tp > NS_IN6ADDRSZ - NS_INT16SZ) 
-      return 0;
-    tp += NS_INT16SZ;
-  }
-
-  if (colonp != NULL) {
-    if (tp == NS_IN6ADDRSZ) 
-      return 0;
-    tp = NS_IN6ADDRSZ;
-  }
 
   if (tp != NS_IN6ADDRSZ)
     return 0;