printf: replace strtonum with strtol functions in conversions
Use strtol and strtoul respectively for d, i and o, u, x, X conversions. This way we can convert other bases than 10, which strtonum doesn't provide. Also don't exit on conversion error but display a warning, set a return error code, and continue.
This commit is contained in:
parent
243cdb6669
commit
3da450e203
24
printf.c
24
printf.c
@ -1,5 +1,6 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -21,7 +22,7 @@ main(int argc, char *argv[])
|
||||
size_t i, j, argi, lastargi, formatlen;
|
||||
long long num;
|
||||
double dou;
|
||||
int cooldown = 0, width, precision;
|
||||
int cooldown = 0, width, precision, ret = 0;
|
||||
char *format, *tmp, *arg, *fmt, flag;
|
||||
|
||||
argv0 = argv[0];
|
||||
@ -134,8 +135,25 @@ main(int argc, char *argv[])
|
||||
rarg = ereallocarray(NULL, utflen(arg) + 1, sizeof(*rarg));
|
||||
utftorunestr(arg, rarg);
|
||||
num = rarg[0];
|
||||
} else if (arg[0]) {
|
||||
errno = 0;
|
||||
if (format[i] == 'd' || format[i] == 'i')
|
||||
num = strtol(arg, &tmp, 0);
|
||||
else
|
||||
num = strtoul(arg, &tmp, 0);
|
||||
|
||||
if (tmp == arg || *tmp != '\0') {
|
||||
ret = 1;
|
||||
weprintf("%%%c %s: conversion error\n",
|
||||
format[i], arg);
|
||||
}
|
||||
if (errno == ERANGE) {
|
||||
ret = 1;
|
||||
weprintf("%%%c %s: out of range\n",
|
||||
format[i], arg);
|
||||
}
|
||||
} else {
|
||||
num = (strlen(arg) > 0) ? estrtonum(arg, LLONG_MIN, LLONG_MAX) : 0;
|
||||
num = 0;
|
||||
}
|
||||
fmt = estrdup(flag ? "%#*.*ll#" : "%*.*ll#");
|
||||
if (flag)
|
||||
@ -160,5 +178,5 @@ main(int argc, char *argv[])
|
||||
cooldown = 1;
|
||||
}
|
||||
|
||||
return fshut(stdout, "<stdout>");
|
||||
return fshut(stdout, "<stdout>") | ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user