+2003-09-19 Hrvoje Niksic <hniksic@xemacs.org>
+
+ * wget.h (BOUNDED_TO_ALLOCA): Evaluate PLACE only once.
+ (ARRAY_SIZE): Renamed to countof. All callers updated.
+
2003-09-19 Hrvoje Niksic <hniksic@xemacs.org>
* main.c (main): New option --strict-comments.
static char *known_toplevel_domains[] = {
".com", ".edu", ".net", ".org", ".gov", ".mil", ".int"
};
- for (i = 0; i < ARRAY_SIZE (known_toplevel_domains); i++)
+ for (i = 0; i < countof (known_toplevel_domains); i++)
if (match_tail (cookie_domain, known_toplevel_domains[i], 1))
{
known_toplevel = 1;
{
struct cookie *chain_default_store[20];
struct cookie **all_chains = chain_default_store;
- int chain_store_size = ARRAY_SIZE (chain_default_store);
+ int chain_store_size = countof (chain_default_store);
int chain_count;
struct cookie *cookie;
};
int i;
- for (i = 0; i < ARRAY_SIZE (tests_succ); i++)
+ for (i = 0; i < countof (tests_succ); i++)
{
int ind;
char *data = tests_succ[i].data;
printf ("Unmatched number of results: %s\n", data);
}
- for (i = 0; i < ARRAY_SIZE (tests_fail); i++)
+ for (i = 0; i < countof (tests_fail); i++)
{
struct cookie *c;
char *data = tests_fail[i];
};
int i;
- for (i = 0; i < ARRAY_SIZE (skey_head); i++)
+ for (i = 0; i < countof (skey_head); i++)
{
if (strncasecmp (skey_head[i], respline, strlen (skey_head[i])) == 0)
break;
}
- if (i < ARRAY_SIZE (skey_head))
+ if (i < countof (skey_head))
{
const char *cp;
int skey_sequence = 0;
};
int i = *prime_offset;
- for (; i < ARRAY_SIZE (primes); i++)
+ for (; i < countof (primes); i++)
if (primes[i] >= size)
{
/* Set the offset to the next prime. That is safe because,
{
int i, ind = 0;
- int size = ARRAY_SIZE (known_tags);
+ int size = countof (known_tags);
interesting_tags = (const char **)xmalloc ((size + 1) * sizeof (char *));
for (i = 0; i < size; i++)
unique, and to include the attributes from additional_attributes. */
{
int i, ind;
- const char **att = xmalloc ((ARRAY_SIZE (additional_attributes) + 1)
+ const char **att = xmalloc ((countof (additional_attributes) + 1)
* sizeof (char *));
/* First copy the "additional" attributes. */
- for (i = 0; i < ARRAY_SIZE (additional_attributes); i++)
+ for (i = 0; i < countof (additional_attributes); i++)
att[i] = additional_attributes[i];
ind = i;
att[ind] = NULL;
- for (i = 0; i < ARRAY_SIZE (tag_url_attributes); i++)
+ for (i = 0; i < countof (tag_url_attributes); i++)
{
int j, seen = 0;
const char *look_for = tag_url_attributes[i].attr_name;
/* This is linear search; if the number of tags grow, we can switch
to binary search. */
- for (i = 0; i < ARRAY_SIZE (known_tags); i++)
+ for (i = 0; i < countof (known_tags); i++)
{
int cmp = strcasecmp (known_tags[i].name, tag_name);
/* known_tags are sorted alphabetically, so we can
tag_find_urls (int tagid, struct taginfo *tag, struct map_context *ctx)
{
int i, attrind, first = -1;
- int size = ARRAY_SIZE (tag_url_attributes);
+ int size = countof (tag_url_attributes);
for (i = 0; i < size; i++)
if (tag_url_attributes[i].tagid == tagid)
GNU strptime does not have this problem because it recognizes
both international and local dates. */
- for (i = 0; i < ARRAY_SIZE (time_formats); i++)
+ for (i = 0; i < countof (time_formats); i++)
if (check_end (strptime (time_string, time_formats[i], &t)))
return mktime_from_utc (&t);
for (i = 0; i < MD5_HASHLEN; i++, hash++)
{
- *buf++ = XDIGIT_TO_xchar (*hash >> 4);
- *buf++ = XDIGIT_TO_xchar (*hash & 0xf);
+ *buf++ = XNUM_TO_digit (*hash >> 4);
+ *buf++ = XNUM_TO_digit (*hash & 0xf);
}
*buf = '\0';
}
int i;
au += skip_lws (au);
- for (i = 0; i < ARRAY_SIZE (options); i++)
+ for (i = 0; i < countof (options); i++)
{
int skip = extract_header_attr (au, options[i].name,
options[i].variable);
break;
}
}
- if (i == ARRAY_SIZE (options))
+ if (i == countof (options))
{
while (*au && *au != '=')
au++;
static int
comind (const char *com)
{
- int lo = 0, hi = ARRAY_SIZE (commands) - 1;
+ int lo = 0, hi = countof (commands) - 1;
while (lo <= hi)
{
char *colon = strchr (name, ':');
int namelen = colon ? colon - name : strlen (name);
- for (i = 0; i < ARRAY_SIZE (implementations); i++, pi++)
+ for (i = 0; i < countof (implementations); i++, pi++)
if (!strncmp (pi->name, name, namelen))
return 1;
return 0;
colon = strchr (name, ':');
namelen = colon ? colon - name : strlen (name);
- for (i = 0; i < ARRAY_SIZE (implementations); i++, pi++)
+ for (i = 0; i < countof (implementations); i++, pi++)
if (!strncmp (pi->name, name, namelen))
{
current_impl = pi;
that number is not a numerical representation of '/', decode C and
advance the pointer. */
-#define DECODE_MAYBE(c, ptr) do { \
- if (c == '%' && ISXDIGIT (ptr[1]) && ISXDIGIT (ptr[2])) \
- { \
- char decoded \
- = (XCHAR_TO_XDIGIT (ptr[1]) << 4) + XCHAR_TO_XDIGIT (ptr[2]); \
- if (decoded != '/') \
- { \
- c = decoded; \
- ptr += 2; \
- } \
- } \
+#define DECODE_MAYBE(c, ptr) do { \
+ if (c == '%' && ISXDIGIT (ptr[1]) && ISXDIGIT (ptr[2])) \
+ { \
+ char decoded = X2DIGITS_TO_NUM (ptr[1], ptr[2]); \
+ if (decoded != '/') \
+ { \
+ c = decoded; \
+ ptr += 2; \
+ } \
+ } \
} while (0)
/* The inner matching engine: return non-zero if RECORD_PATH matches
else
{
/* Do nothing if '%' is not followed by two hex digits. */
- if (!*(h + 1) || !*(h + 2)
- || !(ISXDIGIT (*(h + 1)) && ISXDIGIT (*(h + 2))))
+ if (!h[1] || !h[2] || !(ISXDIGIT (h[1]) && ISXDIGIT (h[2])))
goto copychar;
- *t = (XCHAR_TO_XDIGIT (*(h + 1)) << 4) + XCHAR_TO_XDIGIT (*(h + 2));
+ *t = X2DIGITS_TO_NUM (h[1], h[2]);
h += 2;
}
}
{
unsigned char c = *p1++;
*p2++ = '%';
- *p2++ = XDIGIT_TO_XCHAR (c >> 4);
- *p2++ = XDIGIT_TO_XCHAR (c & 0xf);
+ *p2++ = XNUM_TO_digit (c >> 4);
+ *p2++ = XNUM_TO_digit (c & 0xf);
}
else
*p2++ = *p1++;
/* %xx sequence: decode it, unless it would decode to an
unsafe or a reserved char; in that case, leave it as
is. */
- char preempt = (XCHAR_TO_XDIGIT (*(p + 1)) << 4) +
- XCHAR_TO_XDIGIT (*(p + 2));
-
+ char preempt = X2DIGITS_TO_NUM (*(p + 1), *(p + 2));
if (URL_UNSAFE_CHAR (preempt) || URL_RESERVED_CHAR (preempt))
return CM_PASSTHROUGH;
else
{
unsigned char c = *p1++;
*p2++ = '%';
- *p2++ = XDIGIT_TO_XCHAR (c >> 4);
- *p2++ = XDIGIT_TO_XCHAR (c & 0xf);
+ *p2++ = XNUM_TO_DIGIT (c >> 4);
+ *p2++ = XNUM_TO_DIGIT (c & 0xf);
}
break;
case CM_DECODE:
- *p2++ = ((XCHAR_TO_XDIGIT (*(p1 + 1)) << 4)
- + (XCHAR_TO_XDIGIT (*(p1 + 2))));
+ *p2++ = X2DIGITS_TO_NUM (p1[1], p1[2]);
p1 += 3; /* skip %xx */
break;
case CM_PASSTHROUGH:
const char *
url_error (int error_code)
{
- assert (error_code >= 0 && error_code < ARRAY_SIZE (parse_errors));
+ assert (error_code >= 0 && error_code < countof (parse_errors));
return parse_errors[error_code];
}
{
unsigned char ch = *p;
*q++ = '%';
- *q++ = XDIGIT_TO_XCHAR (ch >> 4);
- *q++ = XDIGIT_TO_XCHAR (ch & 0xf);
+ *q++ = XNUM_TO_DIGIT (ch >> 4);
+ *q++ = XNUM_TO_DIGIT (ch & 0xf);
}
}
assert (q - TAIL (dest) == outlen);
};
int i;
- for (i = 0; i < ARRAY_SIZE (tests); i++)
+ for (i = 0; i < countof (tests); i++)
{
char *test = tests[i].test;
char *expected_result = tests[i].result;
/* Now run all the tests with a leading slash before the test case,
to prove that the slash is being preserved. */
- for (i = 0; i < ARRAY_SIZE (tests); i++)
+ for (i = 0; i < countof (tests); i++)
{
char *test, *expected_result;
int expected_change = tests[i].should_modify;
register_ptr (void *ptr, const char *file, int line)
{
int i;
- for (i = 0; i < ARRAY_SIZE (malloc_debug); i++)
+ for (i = 0; i < countof (malloc_debug); i++)
if (malloc_debug[i].ptr == NULL)
{
malloc_debug[i].ptr = ptr;
unregister_ptr (void *ptr)
{
int i;
- for (i = 0; i < ARRAY_SIZE (malloc_debug); i++)
+ for (i = 0; i < countof (malloc_debug); i++)
if (malloc_debug[i].ptr == ptr)
{
malloc_debug[i].ptr = NULL;
int i;
printf ("\nMalloc: %d\nFree: %d\nBalance: %d\n\n",
malloc_count, free_count, malloc_count - free_count);
- for (i = 0; i < ARRAY_SIZE (malloc_debug); i++)
+ for (i = 0; i < countof (malloc_debug); i++)
if (malloc_debug[i].ptr != NULL)
printf ("0x%08ld: %s:%d\n", (long)malloc_debug[i].ptr,
malloc_debug[i].file, malloc_debug[i].line);
cnt = 16;
while (cnt--)
{
- *p2++ = XDIGIT_TO_xchar (*p1 >> 4);
- *p2++ = XDIGIT_TO_xchar (*p1 & 0xf);
+ *p2++ = XNUM_TO_digit (*p1 >> 4);
+ *p2++ = XNUM_TO_digit (*p1 & 0xf);
++p1;
}
*p2 = '\0';
/* The smaller value of the two. */
#define MINVAL(x, y) ((x) < (y) ? (x) : (y))
-/* Convert the ASCII character that represents a hexadecimal digit to
- the number in range [0, 16) that corresponds to the digit. X
- should be between '0' and '9', or between 'A' and 'F', or between
- 'a' and 'f'. If X is not a hexadecimal digit character, the result
- is undefined. */
-#define XCHAR_TO_XDIGIT(x) \
- (((x) >= '0' && (x) <= '9') ? ((x) - '0') : (TOUPPER(x) - 'A' + 10))
-
-/* The reverse of the above: convert a digit number in the [0, 16)
- range to an ASCII character. The A-F characters are in upper
+/* Convert an ASCII hex digit to the corresponding number between 0
+ and 15. X should be a hexadecimal digit that satisfies isxdigit;
+ otherwise, the result is undefined. */
+#define XDIGIT_TO_NUM(x) ((x) < 'A' ? (x) - '0' : TOUPPER (x) - 'A' + 10)
+
+/* Convert a sequence of ASCII hex digits X and Y to a number betewen
+ 0 and 255. Uses XDIGIT_TO_NUM for conversion of individual
+ digits. */
+#define X2DIGITS_TO_NUM(h1, h2) ((XDIGIT_TO_NUM (h1) << 4) + XDIGIT_TO_NUM (h2))
+
+/* The reverse of the above: convert a number in the [0, 16) range to
+ its ASCII representation in hex. The A-F characters are in upper
case. */
-#define XDIGIT_TO_XCHAR(x) ("0123456789ABCDEF"[x])
+#define XNUM_TO_DIGIT(x) ("0123456789ABCDEF"[x])
-/* Like XDIGIT_TO_XCHAR, but generates lower-case characters. */
-#define XDIGIT_TO_xchar(x) ("0123456789abcdef"[x])
+/* Like XNUM_TO_DIGIT, but generates lower-case characters. */
+#define XNUM_TO_digit(x) ("0123456789abcdef"[x])
/* Returns the number of elements in an array with fixed
initialization. For example:
} */
#define countof(array) (sizeof (array) / sizeof (*(array)))
-#define ARRAY_SIZE(array) countof (array)
-
/* Copy the data delimited with BEG and END to alloca-allocated
- storage, and zero-terminate it. BEG and END are evaluated only
- once, in that order. */
+ storage, and zero-terminate it. Arguments are evaluated only once,
+ in the order BEG, END, PLACE. */
#define BOUNDED_TO_ALLOCA(beg, end, place) do { \
- const char *DTA_beg = (beg); \
- int DTA_len = (end) - DTA_beg; \
- place = alloca (DTA_len + 1); \
- memcpy (place, DTA_beg, DTA_len); \
- place[DTA_len] = '\0'; \
+ const char *BTA_beg = (beg); \
+ int BTA_len = (end) - BTA_beg; \
+ char **BTA_dest = &(place); \
+ *BTA_dest = alloca (BTA_len + 1); \
+ memcpy (*BTA_dest, BTA_beg, BTA_len); \
+ (*BTA_dest)[BTA_len] = '\0'; \
} while (0)
/* Return non-zero if string bounded between BEG and END is equal to
ADDED_HTML_EXTENSION = 0x0020 /* added ".html" extension due to -E */
};
-/* Universal error type -- used almost everywhere.
- This is, of course, utter crock. */
+/* Universal error type -- used almost everywhere. Error reporting of
+ this detail is not generally used or needed and should be
+ simplified. */
typedef enum
{
NOCONERROR, HOSTERR, CONSOCKERR, CONERROR, CONSSLERR,