diff --git a/src/ChangeLog b/src/ChangeLog index efc3f891..67975977 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2003-09-19 Hrvoje Niksic + + * wget.h (BOUNDED_TO_ALLOCA): Evaluate PLACE only once. + (ARRAY_SIZE): Renamed to countof. All callers updated. + 2003-09-19 Hrvoje Niksic * main.c (main): New option --strict-comments. diff --git a/src/cookies.c b/src/cookies.c index 96a72eb5..d8c2faea 100644 --- a/src/cookies.c +++ b/src/cookies.c @@ -748,7 +748,7 @@ check_domain_match (const char *cookie_domain, const char *host) 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; @@ -1060,7 +1060,7 @@ cookie_jar_generate_cookie_header (struct cookie_jar *jar, const char *host, { 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; @@ -1488,7 +1488,7 @@ test_cookies (void) }; 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; @@ -1518,7 +1518,7 @@ test_cookies (void) 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]; diff --git a/src/ftp-basic.c b/src/ftp-basic.c index 512b2b31..0201b6d7 100644 --- a/src/ftp-basic.c +++ b/src/ftp-basic.c @@ -195,12 +195,12 @@ ftp_login (struct rbuf *rbuf, const char *acc, const char *pass) }; 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; diff --git a/src/hash.c b/src/hash.c index 854ef463..eeb98c5f 100644 --- a/src/hash.c +++ b/src/hash.c @@ -205,7 +205,7 @@ prime_size (int size, int *prime_offset) }; 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, diff --git a/src/html-url.c b/src/html-url.c index 3327a7b6..a3208e46 100644 --- a/src/html-url.c +++ b/src/html-url.c @@ -181,7 +181,7 @@ init_interesting (void) { 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++) @@ -241,14 +241,14 @@ init_interesting (void) 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; @@ -277,7 +277,7 @@ find_tag (const char *tag_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 @@ -421,7 +421,7 @@ static void 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) diff --git a/src/http.c b/src/http.c index 62ab5c37..31e0bfdc 100644 --- a/src/http.c +++ b/src/http.c @@ -2211,7 +2211,7 @@ http_atotm (const char *time_string) 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); @@ -2341,8 +2341,8 @@ dump_hash (unsigned char *buf, const unsigned char *hash) 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'; } @@ -2373,7 +2373,7 @@ digest_authentication_encode (const char *au, const char *user, 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); @@ -2390,7 +2390,7 @@ digest_authentication_encode (const char *au, const char *user, break; } } - if (i == ARRAY_SIZE (options)) + if (i == countof (options)) { while (*au && *au != '=') au++; diff --git a/src/init.c b/src/init.c index 9ce9b166..b4ab130a 100644 --- a/src/init.c +++ b/src/init.c @@ -224,7 +224,7 @@ static struct { static int comind (const char *com) { - int lo = 0, hi = ARRAY_SIZE (commands) - 1; + int lo = 0, hi = countof (commands) - 1; while (lo <= hi) { diff --git a/src/progress.c b/src/progress.c index 0e626796..ab99caf1 100644 --- a/src/progress.c +++ b/src/progress.c @@ -100,7 +100,7 @@ valid_progress_implementation_p (const char *name) 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; @@ -121,7 +121,7 @@ set_progress_implementation (const char *name) 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; diff --git a/src/res.c b/src/res.c index 6e3da144..239666f6 100644 --- a/src/res.c +++ b/src/res.c @@ -417,17 +417,16 @@ free_specs (struct robot_specs *specs) 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 diff --git a/src/url.c b/src/url.c index c50bcacd..4f5c7f8e 100644 --- a/src/url.c +++ b/src/url.c @@ -170,10 +170,9 @@ url_unescape (char *s) 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; } } @@ -214,8 +213,8 @@ url_escape_1 (const char *s, unsigned char mask, int allow_passthrough) { 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++; @@ -258,9 +257,7 @@ decide_copy_method (const char *p) /* %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 @@ -403,13 +400,12 @@ reencode_escapes (const char *s) { 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: @@ -1043,7 +1039,7 @@ url_parse (const char *url, int *error) 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]; } @@ -1602,8 +1598,8 @@ append_uri_pathel (const char *b, const char *e, struct growable *dest) { 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); @@ -2868,7 +2864,7 @@ test_path_simplify (void) }; 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; @@ -2878,7 +2874,7 @@ test_path_simplify (void) /* 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; diff --git a/src/utils.c b/src/utils.c index 481e5b78..bb45665f 100644 --- a/src/utils.c +++ b/src/utils.c @@ -241,7 +241,7 @@ static void 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; @@ -259,7 +259,7 @@ static void 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; @@ -279,7 +279,7 @@ print_malloc_debug_stats (void) 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); @@ -1903,8 +1903,8 @@ debug_test_md5 (char *buf) 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'; diff --git a/src/wget.h b/src/wget.h index bcd72f28..8851b3e0 100644 --- a/src/wget.h +++ b/src/wget.h @@ -157,21 +157,23 @@ char *xstrdup_debug PARAMS ((const char *, const char *, int)); /* 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)) +/* 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) -/* 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 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: @@ -192,17 +194,16 @@ char *xstrdup_debug PARAMS ((const char *, const char *, int)); } */ #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 @@ -306,8 +307,9 @@ enum 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,