logo

utils-std

Collection of commonly available Unix tools
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:

Mcmd/printf.c418+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mlib/truncation.c2+-
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);