1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-27 04:40:59 +01:00

42332: Special case unsigned printf formats.

For constants we can avoid a conversion to signed by examining
the expression before passing to math eval.
This commit is contained in:
Peter Stephenson 2018-01-31 09:14:40 +00:00
parent f62af4a7ef
commit 2cbf6b6a19
3 changed files with 71 additions and 1 deletions

View file

@ -2455,6 +2455,67 @@ zstrtol_underscore(const char *s, char **t, int base, int underscore)
return neg ? -(zlong)calc : (zlong)calc;
}
/*
* If s represents a complete unsigned integer (and nothing else)
* return 1 and set retval to the value. Otherwise return 0.
*
* Underscores are always allowed.
*
* Sensitive to OCTAL_ZEROES.
*/
/**/
mod_export int
zstrtoul_underscore(const char *s, zulong *retval)
{
zulong calc = 0, newcalc = 0, base;
if (*s == '+')
s++;
if (*s != '0')
base = 10;
else if (*++s == 'x' || *s == 'X')
base = 16, s++;
else if (*s == 'b' || *s == 'B')
base = 2, s++;
else
base = isset(OCTALZEROES) ? 8 : 10;
if (base < 2 || base > 36) {
return 0;
} else if (base <= 10) {
for (; (*s >= '0' && *s < ('0' + base)) ||
*s == '_'; s++) {
if (*s == '_')
continue;
newcalc = calc * base + *s - '0';
if (newcalc < calc)
{
return 0;
}
calc = newcalc;
}
} else {
for (; idigit(*s) || (*s >= 'a' && *s < ('a' + base - 10))
|| (*s >= 'A' && *s < ('A' + base - 10))
|| *s == '_'; s++) {
if (*s == '_')
continue;
newcalc = calc*base + (idigit(*s) ? (*s - '0') : (*s & 0x1f) + 9);
if (newcalc < calc)
{
return 0;
}
calc = newcalc;
}
}
if (*s)
return 0;
*retval = calc;
return 1;
}
/**/
mod_export int
setblock_fd(int turnonblocking, int fd, long *modep)