1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

[svn] Better document the workings of construct_relative().

Reformat is_valid_ipv6_address() to GNU formatting style.
This commit is contained in:
hniksic 2003-10-25 04:58:24 -07:00
parent cf01276391
commit 27d5becdaf
3 changed files with 148 additions and 116 deletions

View 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> 2003-10-23 Hrvoje Niksic <hniksic@xemacs.org>
* config.h.in: Deploy preprocessor magic to avoid Ultrix's * config.h.in: Deploy preprocessor magic to avoid Ultrix's

View 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); 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. /* Construct and return a link that points from BASEFILE to LINKFILE.
Both files should be local file names, S1 of the referrering file, Both files should be local file names, BASEFILE of the referrering
and S2 of the referred file. file, and LINKFILE of the referred file.
So, if S1 is "H/index.html" and S2 is "H/images/news.gif", this Examples:
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".
Caveats: S1 should not begin with `/', unless S2 also begins with cr("foo", "bar") -> "bar"
'/'. S1 should not contain things like ".." and such -- cr("A/foo", "A/bar") -> "bar"
construct_relative ("fly/ioccc/../index.html", cr("A/foo", "A/B/bar") -> "B/bar"
"fly/images/fly.gif") will fail. (A workaround is to call cr("A/X/foo", "A/Y/bar") -> "../Y/bar"
something like path_simplify() on S1). */ 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 * static char *
construct_relative (const char *s1, const char *s2) construct_relative (const char *basefile, const char *linkfile)
{ {
int i, cnt, sepdirs1; char *link;
char *res; int basedirs;
const char *b, *l;
int i, start;
i = cnt = 0; /* First, skip the initial directory components common to both
/* Skip the directories common to both strings. */ files. */
while (1) start = 0;
for (b = basefile, l = linkfile; *b == *l && *b != '\0'; ++b, ++l)
{ {
while (s1[i] && s2[i] if (*b == '/')
&& (s1[i] == s2[i]) start = (b - basefile) + 1;
&& (s1[i] != '/')
&& (s2[i] != '/'))
++i;
if (s1[i] == '/' && s2[i] == '/')
cnt = ++i;
else
break;
} }
for (sepdirs1 = 0; s1[i]; i++) basefile += start;
if (s1[i] == '/') linkfile += start;
++sepdirs1;
/* Now, construct the file as of: /* With common directories out of the way, the situation we have is
- ../ repeated sepdirs1 time as follows:
- all the non-mutual directories of S2. */ b - b1/b2/[...]/bfile
res = (char *)xmalloc (3 * sepdirs1 + strlen (s2 + cnt) + 1); l - l1/l2/[...]/lfile
for (i = 0; i < sepdirs1; i++)
memcpy (res + 3 * i, "../", 3); The link we're constructing needs to be:
strcpy (res + 3 * i, s2 + cnt); lnk - ../../l1/l2/[...]/lfile
return res;
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++)
{
if (*b == '/')
++basedirs;
}
/* 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 static void

165
src/url.c
View File

@ -641,48 +641,52 @@ static char *parse_errors[] = {
static int static int
is_valid_ipv4_address (const char *str, const char *end) is_valid_ipv4_address (const char *str, const char *end)
{ {
int saw_digit, octets; int saw_digit = 0;
int val; int octets = 0;
int val = 0;
saw_digit = 0; while (str < end)
octets = 0; {
val = 0; int ch = *str++;
while (str < end) { if (ch >= '0' && ch <= '9')
int ch = *str++; {
val = val * 10 + (ch - '0');
if (ch >= '0' && ch <= '9') { if (val > 255)
val = val * 10 + (ch - '0'); return 0;
if (saw_digit == 0)
if (val > 255) {
return 0; if (++octets > 4)
if (saw_digit == 0) { return 0;
if (++octets > 4) saw_digit = 1;
return 0; }
saw_digit = 1; }
} else if (ch == '.' && saw_digit == 1)
} else if (ch == '.' && saw_digit == 1) { {
if (octets == 4) if (octets == 4)
return 0; return 0;
val = 0; val = 0;
saw_digit = 0; saw_digit = 0;
} else }
return 0; else
} return 0;
}
if (octets < 4) if (octets < 4)
return 0; return 0;
return 1; return 1;
} }
static const int NS_INADDRSZ = 4;
static const int NS_IN6ADDRSZ = 16;
static const int NS_INT16SZ = 2;
static int static int
is_valid_ipv6_address (const char *str, const char *end) 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; const char *curtok;
int tp; int tp;
const char *colonp; const char *colonp;
@ -707,62 +711,67 @@ is_valid_ipv6_address (const char *str, const char *end)
saw_xdigit = 0; saw_xdigit = 0;
val = 0; val = 0;
while (str < end) { while (str < end)
int ch = *str++; {
const char *pch; int ch = *str++;
/* if ch is a number, add it to val. */ /* if ch is a number, add it to val. */
pch = strchr(xdigits, ch); if (ISXDIGIT (ch))
if (pch != NULL) { {
val <<= 4; val <<= 4;
val |= (pch - xdigits); val |= XDIGIT_TO_NUM (ch);
if (val > 0xffff) if (val > 0xffff)
return 0; return 0;
saw_xdigit = 1; saw_xdigit = 1;
continue; 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 (saw_xdigit == 1)
if (ch == ':') { {
curtok = str; if (tp > NS_IN6ADDRSZ - NS_INT16SZ)
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; return 0;
tp += NS_INT16SZ; tp += NS_INT16SZ;
saw_xdigit = 0;
val = 0;
continue;
} }
/* if ch is a dot ... */ if (colonp != NULL)
if (ch == '.' && (tp <= NS_IN6ADDRSZ - NS_INADDRSZ) && {
is_valid_ipv4_address(curtok, end) == 1) { if (tp == NS_IN6ADDRSZ)
tp += NS_INADDRSZ; return 0;
saw_xdigit = 0; tp = NS_IN6ADDRSZ;
break;
} }
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) if (tp != NS_IN6ADDRSZ)
return 0; return 0;