-/* Is the string a hpyhen-only? */
-#define HYPHENP(x) (*(x) == '-' && !*((x) + 1))
-
-/* The smaller value of the two. */
-#define MINVAL(x, y) ((x) < (y) ? (x) : (y))
-
-/* ASCII char -> HEX digit */
-#define ASC2HEXD(x) (((x) >= '0' && (x) <= '9') ? \
- ((x) - '0') : (TOUPPER(x) - 'A' + 10))
-
-/* HEX digit -> ASCII char */
-#define HEXD2ASC(x) (((x) < 10) ? ((x) + '0') : ((x) - 10 + 'A'))
-
-#define ARRAY_SIZE(array) (sizeof (array) / sizeof (*(array)))
-
-/* Note that this much more elegant definition cannot be used:
-
- #define STRDUP_ALLOCA(str) (strcpy ((char *)alloca (strlen (str) + 1), str))
-
- This is because some compilers don't handle alloca() as argument to
- function correctly. Gcc under Intel has been reported to offend in
- this case. */
-
-#define STRDUP_ALLOCA(ptr, str) do { \
- (ptr) = (char *)alloca (strlen (str) + 1); \
- strcpy (ptr, str); \
+/* The number of elements in an array. For example:
+ static char a[] = "foo"; -- countof(a) == 4 (note terminating \0)
+ int a[5] = {1, 2}; -- countof(a) == 5
+ char *a[] = { -- countof(a) == 3
+ "foo", "bar", "baz"
+ }; */
+#define countof(array) (sizeof (array) / sizeof ((array)[0]))
+
+/* Zero out a value. */
+#define xzero(x) memset (&(x), '\0', sizeof (x))
+
+/* Convert an ASCII hex digit to the corresponding number between 0
+ and 15. H should be a hexadecimal digit that satisfies isxdigit;
+ otherwise, the result is undefined. */
+#define XDIGIT_TO_NUM(h) ((h) < 'A' ? (h) - '0' : TOUPPER (h) - 'A' + 10)
+#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
+ the ASCII representation of the corresponding hexadecimal digit.
+ `+ 0' is there so you can't accidentally use it as an lvalue. */
+#define XNUM_TO_DIGIT(x) ("0123456789ABCDEF"[x] + 0)
+#define XNUM_TO_digit(x) ("0123456789abcdef"[x] + 0)
+
+/* Copy the data delimited with BEG and END to alloca-allocated
+ 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 *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'; \