[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>
* 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);
}
/* 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;
i = cnt = 0;
/* Skip the directories common to both strings. */
while (1)
/* First, skip the initial directory components common to both
files. */
start = 0;
for (b = basefile, l = linkfile; *b == *l && *b != '\0'; ++b, ++l)
{
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 == '/')
start = (b - basefile) + 1;
}
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;
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
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++)
{
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

165
src/url.c
View File

@ -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;