commit: b73bb246889cafd62e6e4799de5cad908d767004
parent 171eac505114e8e71450221269212aa8362ab58a
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Sun, 28 Apr 2024 01:14:42 +0200
cmd/printf.c,lib/truncation.c: make format
Diffstat:
2 files changed, 249 insertions(+), 171 deletions(-)
diff --git a/cmd/printf.c b/cmd/printf.c
@@ -38,8 +38,6 @@
#define _POSIX_C_SOURCE 200809L
-#include <sys/types.h>
-
#include <ctype.h>
#include <err.h>
#include <errno.h>
@@ -49,44 +47,46 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
#include <unistd.h>
#include <wchar.h>
#ifdef SHELL
-#define main printfcmd
+#define main printfcmd
#include "bltin/bltin.h"
#include "options.h"
#endif
-#define PF(f, func) do { \
- if (havewidth) \
- if (haveprec) \
- (void)printf(f, fieldwidth, precision, func); \
- else \
- (void)printf(f, fieldwidth, func); \
- else if (haveprec) \
- (void)printf(f, precision, func); \
- else \
- (void)printf(f, func); \
-} while (0)
-
-static int asciicode(void);
-static char *printf_doformat(char *, int *);
-static int escape(char *, int, size_t *);
-static int getchr(void);
-static int getfloating(long double *, int);
-static int getint(int *);
-static int getnum(intmax_t *, uintmax_t *, int);
-static const char
- *getstr(void);
-static char *mknum(char *, char);
-static void usage(void);
+#define PF(f, func) \
+ do \
+ { \
+ if(havewidth) \
+ if(haveprec) \
+ (void)printf(f, fieldwidth, precision, func); \
+ else \
+ (void)printf(f, fieldwidth, func); \
+ else if(haveprec) \
+ (void)printf(f, precision, func); \
+ else \
+ (void)printf(f, func); \
+ } while(0)
+
+static int asciicode(void);
+static char *printf_doformat(char *, int *);
+static int escape(char *, int, size_t *);
+static int getchr(void);
+static int getfloating(long double *, int);
+static int getint(int *);
+static int getnum(intmax_t *, uintmax_t *, int);
+static const char *getstr(void);
+static char *mknum(char *, char);
+static void usage(void);
static const char digits[] = "0123456789";
static char end_fmt[1];
-static int myargc;
+static int myargc;
static char **myargv;
static char **gargv;
static char **maxargv;
@@ -100,7 +100,7 @@ main(int argc, char *argv[])
#ifndef SHELL
int ch;
- (void) setlocale(LC_ALL, "");
+ (void)setlocale(LC_ALL, "");
#endif
#ifdef SHELL
@@ -108,8 +108,9 @@ main(int argc, char *argv[])
argc -= argptr - argv;
argv = argptr;
#else
- while ((ch = getopt(argc, argv, "")) != -1)
- switch (ch) {
+ while((ch = getopt(argc, argv, "")) != -1)
+ switch(ch)
+ {
case '?':
default:
usage();
@@ -119,7 +120,8 @@ main(int argc, char *argv[])
argv += optind;
#endif
- if (argc < 1) {
+ if(argc < 1)
+ {
usage();
return (1);
}
@@ -136,27 +138,34 @@ main(int argc, char *argv[])
* up the format string.
*/
fmt = format = *argv;
- escape(fmt, 1, &len); /* backslash interpretation */
+ escape(fmt, 1, &len); /* backslash interpretation */
rval = end = 0;
- gargv = ++argv;
+ gargv = ++argv;
- for (;;) {
+ for(;;)
+ {
maxargv = gargv;
myargv = gargv;
- for (myargc = 0; gargv[myargc]; myargc++)
+ for(myargc = 0; gargv[myargc]; myargc++)
/* nop */;
start = fmt;
- while (fmt < format + len) {
- if (fmt[0] == '%') {
+ while(fmt < format + len)
+ {
+ if(fmt[0] == '%')
+ {
fwrite(start, 1, fmt - start, stdout);
- if (fmt[1] == '%') {
+ if(fmt[1] == '%')
+ {
/* %% prints a % */
putchar('%');
fmt += 2;
- } else {
+ }
+ else
+ {
fmt = printf_doformat(fmt, &rval);
- if (fmt == NULL || fmt == end_fmt) {
+ if(fmt == NULL || fmt == end_fmt)
+ {
#ifdef SHELL
INTON;
#endif
@@ -165,14 +174,15 @@ main(int argc, char *argv[])
end = 0;
}
start = fmt;
- } else
+ }
+ else
fmt++;
- if (gargv > maxargv)
- maxargv = gargv;
+ if(gargv > maxargv) maxargv = gargv;
}
gargv = maxargv;
- if (end == 1) {
+ if(end == 1)
+ {
warnx("missing format character");
#ifdef SHELL
INTON;
@@ -180,7 +190,8 @@ main(int argc, char *argv[])
return (1);
}
fwrite(start, 1, fmt - start, stdout);
- if (!*gargv) {
+ if(!*gargv)
+ {
#ifdef SHELL
INTON;
#endif
@@ -193,7 +204,6 @@ main(int argc, char *argv[])
/* NOTREACHED */
}
-
static char *
printf_doformat(char *fmt, int *rval)
{
@@ -205,126 +215,153 @@ printf_doformat(char *fmt, int *rval)
char *dptr;
int l;
- dptr = start;
+ dptr = start;
*dptr++ = '%';
- *dptr = 0;
+ *dptr = 0;
fmt++;
/* look for "n$" field index specifier */
l = strspn(fmt, digits);
- if ((l > 0) && (fmt[l] == '$')) {
+ if((l > 0) && (fmt[l] == '$'))
+ {
int idx = atoi(fmt);
- if (idx <= myargc) {
+ if(idx <= myargc)
+ {
gargv = &myargv[idx - 1];
- } else {
+ }
+ else
+ {
gargv = &myargv[myargc];
}
- if (gargv > maxargv)
- maxargv = gargv;
+ if(gargv > maxargv) maxargv = gargv;
fmt += l + 1;
/* save format argument */
fargv = gargv;
- } else {
+ }
+ else
+ {
fargv = NULL;
}
/* skip to field width */
- while (*fmt && strchr(skip1, *fmt) != NULL) {
+ while(*fmt && strchr(skip1, *fmt) != NULL)
+ {
*dptr++ = *fmt++;
- *dptr = 0;
+ *dptr = 0;
}
- if (*fmt == '*') {
+ if(*fmt == '*')
+ {
fmt++;
l = strspn(fmt, digits);
- if ((l > 0) && (fmt[l] == '$')) {
+ if((l > 0) && (fmt[l] == '$'))
+ {
int idx = atoi(fmt);
- if (fargv == NULL) {
+ if(fargv == NULL)
+ {
warnx("incomplete use of n$");
return (NULL);
}
- if (idx <= myargc) {
+ if(idx <= myargc)
+ {
gargv = &myargv[idx - 1];
- } else {
+ }
+ else
+ {
gargv = &myargv[myargc];
}
fmt += l + 1;
- } else if (fargv != NULL) {
+ }
+ else if(fargv != NULL)
+ {
warnx("incomplete use of n$");
return (NULL);
}
- if (getint(&fieldwidth))
- return (NULL);
- if (gargv > maxargv)
- maxargv = gargv;
+ if(getint(&fieldwidth)) return (NULL);
+ if(gargv > maxargv) maxargv = gargv;
havewidth = 1;
*dptr++ = '*';
- *dptr = 0;
- } else {
+ *dptr = 0;
+ }
+ else
+ {
havewidth = 0;
/* skip to possible '.', get following precision */
- while (isdigit(*fmt)) {
+ while(isdigit(*fmt))
+ {
*dptr++ = *fmt++;
- *dptr = 0;
+ *dptr = 0;
}
}
- if (*fmt == '.') {
+ if(*fmt == '.')
+ {
/* precision present? */
fmt++;
*dptr++ = '.';
- if (*fmt == '*') {
+ if(*fmt == '*')
+ {
fmt++;
l = strspn(fmt, digits);
- if ((l > 0) && (fmt[l] == '$')) {
+ if((l > 0) && (fmt[l] == '$'))
+ {
int idx = atoi(fmt);
- if (fargv == NULL) {
+ if(fargv == NULL)
+ {
warnx("incomplete use of n$");
return (NULL);
}
- if (idx <= myargc) {
+ if(idx <= myargc)
+ {
gargv = &myargv[idx - 1];
- } else {
+ }
+ else
+ {
gargv = &myargv[myargc];
}
fmt += l + 1;
- } else if (fargv != NULL) {
+ }
+ else if(fargv != NULL)
+ {
warnx("incomplete use of n$");
return (NULL);
}
- if (getint(&precision))
- return (NULL);
- if (gargv > maxargv)
- maxargv = gargv;
+ if(getint(&precision)) return (NULL);
+ if(gargv > maxargv) maxargv = gargv;
haveprec = 1;
- *dptr++ = '*';
- *dptr = 0;
- } else {
+ *dptr++ = '*';
+ *dptr = 0;
+ }
+ else
+ {
haveprec = 0;
/* skip to conversion char */
- while (isdigit(*fmt)) {
+ while(isdigit(*fmt))
+ {
*dptr++ = *fmt++;
- *dptr = 0;
+ *dptr = 0;
}
}
- } else
+ }
+ else
haveprec = 0;
- if (!*fmt) {
+ if(!*fmt)
+ {
warnx("missing format character");
return (NULL);
}
*dptr++ = *fmt;
- *dptr = 0;
+ *dptr = 0;
/*
* Look for a length modifier. POSIX doesn't have these, so
@@ -336,19 +373,24 @@ printf_doformat(char *fmt, int *rval)
* because overflow is the only bad thing that can happen to
* them, but consider the command printf %a 1.1
*/
- if (*fmt == 'L') {
+ if(*fmt == 'L')
+ {
mod_ldbl = 1;
fmt++;
- if (!strchr("aAeEfFgG", *fmt)) {
+ if(!strchr("aAeEfFgG", *fmt))
+ {
warnx("bad modifier L for %%%c", *fmt);
return (NULL);
}
- } else {
+ }
+ else
+ {
mod_ldbl = 0;
}
/* save the current arg offset, and set to the format arg */
- if (fargv != NULL) {
+ if(fargv != NULL)
+ {
gargv = fargv;
}
@@ -356,15 +398,18 @@ printf_doformat(char *fmt, int *rval)
nextch = *++fmt;
*fmt = '\0';
- switch (convch) {
- case 'b': {
+ switch(convch)
+ {
+ case 'b':
+ {
size_t len;
char *p;
int getout;
/* Convert "b" to "s" for output. */
start[strlen(start) - 1] = 's';
- if ((p = strdup(getstr())) == NULL) {
+ if((p = strdup(getstr())) == NULL)
+ {
warnx("%s", strerror(ENOMEM));
return (NULL);
}
@@ -373,51 +418,59 @@ printf_doformat(char *fmt, int *rval)
/* Restore format for next loop. */
free(p);
- if (getout)
- return (end_fmt);
+ if(getout) return (end_fmt);
break;
}
- case 'c': {
+ case 'c':
+ {
char p;
p = getchr();
- if (p != '\0')
- PF(start, p);
+ if(p != '\0') PF(start, p);
break;
}
- case 's': {
+ case 's':
+ {
const char *p;
p = getstr();
PF(start, p);
break;
}
- case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ {
char *f;
intmax_t val;
uintmax_t uval;
int signedconv;
signedconv = (convch == 'd' || convch == 'i');
- if ((f = mknum(start, convch)) == NULL)
- return (NULL);
- if (getnum(&val, &uval, signedconv))
- *rval = 1;
- if (signedconv)
+ if((f = mknum(start, convch)) == NULL) return (NULL);
+ if(getnum(&val, &uval, signedconv)) *rval = 1;
+ if(signedconv)
PF(f, val);
else
PF(f, uval);
break;
}
- case 'e': case 'E':
- case 'f': case 'F':
- case 'g': case 'G':
- case 'a': case 'A': {
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ case 'a':
+ case 'A':
+ {
long double p;
- if (getfloating(&p, mod_ldbl))
- *rval = 1;
- if (mod_ldbl)
+ if(getfloating(&p, mod_ldbl)) *rval = 1;
+ if(mod_ldbl)
PF(start, p);
else
PF(start, (double)p);
@@ -441,13 +494,15 @@ mknum(char *str, char ch)
size_t len, newlen;
len = strlen(str) + 2;
- if (len > copy_size) {
+ if(len > copy_size)
+ {
newlen = ((len + 1023) >> 10) << 10;
- if ((newcopy = realloc(copy, newlen)) == NULL) {
+ if((newcopy = realloc(copy, newlen)) == NULL)
+ {
warnx("%s", strerror(ENOMEM));
return (NULL);
}
- copy = newcopy;
+ copy = newcopy;
copy_size = newlen;
}
@@ -464,64 +519,76 @@ escape(char *fmt, int percent, size_t *len)
char *save, *store, c;
int value;
- for (save = store = fmt; ((c = *fmt) != 0); ++fmt, ++store) {
- if (c != '\\') {
+ for(save = store = fmt; ((c = *fmt) != 0); ++fmt, ++store)
+ {
+ if(c != '\\')
+ {
*store = c;
continue;
}
- switch (*++fmt) {
- case '\0': /* EOS, user error */
- *store = '\\';
+ switch(*++fmt)
+ {
+ case '\0': /* EOS, user error */
+ *store = '\\';
*++store = '\0';
- *len = store - save;
+ *len = store - save;
return (0);
- case '\\': /* backslash */
- case '\'': /* single quote */
+ case '\\': /* backslash */
+ case '\'': /* single quote */
*store = *fmt;
break;
- case 'a': /* bell/alert */
+ case 'a': /* bell/alert */
*store = '\a';
break;
- case 'b': /* backspace */
+ case 'b': /* backspace */
*store = '\b';
break;
case 'c':
- if (!percent) {
+ if(!percent)
+ {
*store = '\0';
- *len = store - save;
+ *len = store - save;
return (1);
}
*store = 'c';
break;
- case 'f': /* form-feed */
+ case 'f': /* form-feed */
*store = '\f';
break;
- case 'n': /* newline */
+ case 'n': /* newline */
*store = '\n';
break;
- case 'r': /* carriage-return */
+ case 'r': /* carriage-return */
*store = '\r';
break;
- case 't': /* horizontal tab */
+ case 't': /* horizontal tab */
*store = '\t';
break;
- case 'v': /* vertical tab */
+ case 'v': /* vertical tab */
*store = '\v';
break;
- /* octal constant */
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
+ /* octal constant */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
c = (!percent && *fmt == '0') ? 4 : 3;
- for (value = 0;
- c-- && *fmt >= '0' && *fmt <= '7'; ++fmt) {
+ for(value = 0; c-- && *fmt >= '0' && *fmt <= '7'; ++fmt)
+ {
value <<= 3;
value += *fmt - '0';
}
--fmt;
- if (percent && value == '%') {
+ if(percent && value == '%')
+ {
*store++ = '%';
- *store = '%';
- } else
+ *store = '%';
+ }
+ else
*store = (char)value;
break;
default:
@@ -530,23 +597,21 @@ escape(char *fmt, int percent, size_t *len)
}
}
*store = '\0';
- *len = store - save;
+ *len = store - save;
return (0);
}
static int
getchr(void)
{
- if (!*gargv)
- return ('\0');
+ if(!*gargv) return ('\0');
return ((int)**gargv++);
}
static const char *
getstr(void)
{
- if (!*gargv)
- return ("");
+ if(!*gargv) return ("");
return (*gargv++);
}
@@ -557,10 +622,10 @@ getint(int *ip)
uintmax_t uval;
int rval;
- if (getnum(&val, &uval, 1))
- return (1);
+ if(getnum(&val, &uval, 1)) return (1);
rval = 0;
- if (val < INT_MIN || val > INT_MAX) {
+ if(val < INT_MIN || val > INT_MAX)
+ {
warnx("%s: %s", *gargv, strerror(ERANGE));
rval = 1;
}
@@ -574,32 +639,37 @@ getnum(intmax_t *ip, uintmax_t *uip, int signedconv)
char *ep;
int rval;
- if (!*gargv) {
+ if(!*gargv)
+ {
*ip = *uip = 0;
return (0);
}
- if (**gargv == '"' || **gargv == '\'') {
- if (signedconv)
+ if(**gargv == '"' || **gargv == '\'')
+ {
+ if(signedconv)
*ip = asciicode();
else
*uip = asciicode();
return (0);
}
- rval = 0;
+ rval = 0;
errno = 0;
- if (signedconv)
+ if(signedconv)
*ip = strtoimax(*gargv, &ep, 0);
else
*uip = strtoumax(*gargv, &ep, 0);
- if (ep == *gargv) {
+ if(ep == *gargv)
+ {
warnx("%s: expected numeric value", *gargv);
rval = 1;
}
- else if (*ep != '\0') {
+ else if(*ep != '\0')
+ {
warnx("%s: not completely converted", *gargv);
rval = 1;
}
- if (errno == ERANGE) {
+ if(errno == ERANGE)
+ {
warnx("%s: %s", *gargv, strerror(ERANGE));
rval = 1;
}
@@ -613,28 +683,34 @@ getfloating(long double *dp, int mod_ldbl)
char *ep;
int rval;
- if (!*gargv) {
+ if(!*gargv)
+ {
*dp = 0.0;
return (0);
}
- if (**gargv == '"' || **gargv == '\'') {
+ if(**gargv == '"' || **gargv == '\'')
+ {
*dp = asciicode();
return (0);
}
- rval = 0;
+ rval = 0;
errno = 0;
- if (mod_ldbl)
+ if(mod_ldbl)
*dp = strtold(*gargv, &ep);
else
*dp = strtod(*gargv, &ep);
- if (ep == *gargv) {
+ if(ep == *gargv)
+ {
warnx("%s: expected numeric value", *gargv);
rval = 1;
- } else if (*ep != '\0') {
+ }
+ else if(*ep != '\0')
+ {
warnx("%s: not completely converted", *gargv);
rval = 1;
}
- if (errno == ERANGE) {
+ if(errno == ERANGE)
+ {
warnx("%s: %s", *gargv, strerror(ERANGE));
rval = 1;
}
@@ -650,11 +726,13 @@ asciicode(void)
mbstate_t mbs;
ch = (unsigned char)**gargv;
- if (ch == '\'' || ch == '"') {
+ if(ch == '\'' || ch == '"')
+ {
memset(&mbs, 0, sizeof(mbs));
- switch (mbrtowc(&wch, *gargv + 1, MB_LEN_MAX, &mbs)) {
- case (size_t)-2:
- case (size_t)-1:
+ switch(mbrtowc(&wch, *gargv + 1, MB_LEN_MAX, &mbs))
+ {
+ case(size_t)-2:
+ case(size_t)-1:
wch = (unsigned char)gargv[0][1];
break;
case 0:
diff --git a/lib/truncation.c b/lib/truncation.c
@@ -136,7 +136,7 @@ parse_size(char *arg, struct truncation *buf)
op = OP_CHK_UP;
arg++;
break;
- // no default case intended
+ // no default case intended
}
assert(errno == 0);