sbase

suckless unix tools
git clone git://git.2f30.org/sbase.git
Log | Files | Refs | README | LICENSE

commit 3da450e20361076952483456c6f196ea7579ce7a
parent 243cdb6669544a55d84a7d223ec2517d1e2cb43a
Author: Quentin Rameau <quinq@fifth.space>
Date:   Mon Feb 29 17:34:34 +0100

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.

Diffstat:
printf.c | 24+++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/printf.c b/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; }