The macro verified that its input was in the range '1' to '9' by using a
subtraction and a single conditional. This commit generalizes this
non-obvious method of avoiding a conditional, and moves it to handy.h so
it can be used in other places.
#define FITS_IN_8_BITS(c) (1)
#endif
#define FITS_IN_8_BITS(c) (1)
#endif
+/* Returns true if c is in the range l..u
+ * Written with the cast so it only needs one conditional test
+ */
+#define inRANGE(c, l, u) (__ASSERT_((u) >= (l)) \
+ ((WIDEST_UTYPE) (((c) - (l)) | 0) <= ((WIDEST_UTYPE) ((u) - (l)))))
+
#ifdef EBCDIC
# ifndef _ALL_SOURCE
/* The native libc isascii() et.al. functions return the wrong results
#ifdef EBCDIC
# ifndef _ALL_SOURCE
/* The native libc isascii() et.al. functions return the wrong results
-
-/* Returns true if c is in the range '1'..'9'
- * Written with the cast so it only needs one conditional test
- */
-#define IS_1_TO_9(c) ((U8)(c - '1') <= 8)
-
/* Read in and return a number. Updates *pattern to point to the char
* following the number. Expects the first char to 1..9.
* Croaks if the number exceeds 1/4 of the maximum value of STRLEN.
/* Read in and return a number. Updates *pattern to point to the char
* following the number. Expects the first char to 1..9.
* Croaks if the number exceeds 1/4 of the maximum value of STRLEN.
PERL_ARGS_ASSERT_EXPECT_NUMBER;
PERL_ARGS_ASSERT_EXPECT_NUMBER;
- assert(IS_1_TO_9(**pattern));
+ assert(inRANGE(**pattern, '1', '9'));
var = *(*pattern)++ - '0';
while (isDIGIT(**pattern)) {
var = *(*pattern)++ - '0';
while (isDIGIT(**pattern)) {
[%bcdefginopsuxDFOUX] format (mandatory)
*/
[%bcdefginopsuxDFOUX] format (mandatory)
*/
+ if (inRANGE(*q, '1', '9')) {
width = expect_number(&q);
if (*q == '$') {
if (args)
width = expect_number(&q);
if (*q == '$') {
if (args)
if (*q == '*') {
STRLEN ix; /* explicit width/vector separator index */
q++;
if (*q == '*') {
STRLEN ix; /* explicit width/vector separator index */
q++;
+ if (inRANGE(*q, '1', '9')) {
ix = expect_number(&q);
if (*q++ == '$') {
if (args)
ix = expect_number(&q);
if (*q++ == '$') {
if (args)
+ if (inRANGE(*q, '1', '9'))
width = expect_number(&q);
}
width = expect_number(&q);
}
if (*q == '*') {
STRLEN ix; /* explicit precision index */
q++;
if (*q == '*') {
STRLEN ix; /* explicit precision index */
q++;
+ if (inRANGE(*q, '1', '9')) {
ix = expect_number(&q);
if (*q++ == '$') {
if (args)
ix = expect_number(&q);
if (*q++ == '$') {
if (args)
*/
while (*q == '0')
q++;
*/
while (*q == '0')
q++;
- precis = IS_1_TO_9(*q) ? expect_number(&q) : 0;
+ precis = inRANGE(*q, '1', '9') ? expect_number(&q) : 0;