Skip to content

Commit

Permalink
[libc] Add thousands grouping to printf
Browse files Browse the repository at this point in the history
  • Loading branch information
ghaerr committed Sep 14, 2024
1 parent 870f159 commit 584cb9f
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 31 deletions.
5 changes: 3 additions & 2 deletions elkscmd/file_utils/cat.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ static char readbuf[BUFSIZ]; /* use disk block size for stack limit and effic
#if TEST
void test(void)
{
printf("#04X: '%#04X'\n", 0x2ab);
printf(" p: '%p'\n", 0x18AF);
printf(" lp: '%lp'\n", 0x02d018AFL);
printf("04X: '%04X'\n", 0x2ab);
printf("04x: '%04x'\n", 0x2ab);
printf(" 4x: '%4x'\n", 0x2ab);
Expand All @@ -25,7 +26,7 @@ void test(void)
printf(" 5d: '%5d'\n", -20);
printf("+5d: '%5d'\n", -20);
printf("+5d: '%5d'\n", 20);
printf(" ld: '%ld'\n", -123456789L);
printf(",ld: '%,ld'\n", -123456789L);
printf(" lx: '%lx'\n", 0x87654321L);
printf(" lo: '%lo'\n", 0xFFFFFFFFL);
printf(" s: '%s'\n", "thisisatest");
Expand Down
91 changes: 62 additions & 29 deletions libc/stdio/vfprintf.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
/*
* This file based on printf.c from 'Dlibs' on the atari ST (RdeBath)
* vfprintf - A small implementation of printf-style format string processor
*
* Only the following basic types are supported:
* %% literal % sign
* %c char
* %d/%i signed decimal
* %u unsigned decimal
* %o octal
* %b binary
* %s string
* %x/%X hexadecimal with lower/upper case letters
* %p pointer - same as %04x
* %k pticks (0.838usec intervals auto displayed as us, ms or s)
* %efgEG optional floating point formatting using dtostr
* The following flags preceding the format type are supported:
* 0 fill with leading zeros
* 1-9 minimum field width
* . precision followed by 0-9 (strings only)
* - left justifiy
* + begin signed conversion with + or -
* SP (space) replace + with space if not negative
* , thousands separator (can also use ' and _)
* l long data
* h short data
*
* This file originally based on printf.c from 'Dlibs' on the atari ST (RdeBath)
*
* 19-OCT-88: Dale Schumacher
* > John Stanley has again been a great help in debugging, particularly
Expand All @@ -10,19 +35,13 @@
* [email protected] United States of America
* "It's not reality that's important, but how you perceive things."
*
*/

/* Altered to use stdarg, made the core function vfprintf.
* Hooked into the stdio package using 'inside information'
* Altered sizeof() assumptions, now assumes all integers except chars
* will be either
* sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short)
* Altered to use stdarg, made the core function vfprintf.
* Hooked into the stdio package using 'inside information' -RDB
*
* -RDB
* Greg Haerr enhanced for speed, new features
*/

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <arch/divmod.h>
Expand Down Expand Up @@ -107,21 +126,22 @@ vfprintf(FILE *op, const char *fmt, va_list ap)
int preci, width, radix;
unsigned int c;
char pad, dpoint;
char sign, hash;
char sign, quot;
unsigned long v;
int buffer_mode;
char *p;
//char hash;
char buf[64];

/* This speeds things up a bit for unbuffered */
/* turn off putc calling fputc every time for non or line buffered */
buffer_mode = op->mode & __MODE_BUF;
op->mode &= ~__MODE_BUF;

while (*fmt) {
if (*fmt == '%') {
if( buffer_mode == _IONBF ) fflush(op);
ljustf = 0; /* left justify flag */
hash = 0;
//hash = 0; /* alternate output */
quot = 0; /* thousands grouping */
dpoint = 0; /* found decimal point */
sign = '\0'; /* sign char & status */
pad = ' '; /* justification padding char */
Expand Down Expand Up @@ -157,6 +177,19 @@ vfprintf(FILE *op, const char *fmt, va_list ap)
sign = *fmt;
goto fmtnxt;

case '\'': /* thousands grouping */
case ',':
case '_':
quot = *fmt;
goto fmtnxt;

//case '#':
//hash = 1;
//goto fmtnxt;

case '\0': /* early EOS */
continue;

case '*': /* parameter width value */
i = va_arg(ap, int);
if (dpoint)
Expand Down Expand Up @@ -190,10 +223,10 @@ vfprintf(FILE *op, const char *fmt, va_list ap)
goto usproc;

case 'p': /* Pointer */
lval = sizeof(char *) == sizeof(long);
if (sizeof(char *) == sizeof(long))
lval = 1;
width = lval? 8: 4;
pad = '0';
width = 4;
preci = 8;
/* fall thru */

case 'x': /* Unsigned hexadecimal */
Expand Down Expand Up @@ -226,7 +259,7 @@ vfprintf(FILE *op, const char *fmt, va_list ap)
convert:
p = buf + sizeof(buf) - 1;
*p = '\0';
do {
for (i = 0;;) {
#if 1
c = radix;
v = __divmod(v, &c); /* remainder returned in c */
Expand All @@ -238,18 +271,21 @@ vfprintf(FILE *op, const char *fmt, va_list ap)
*--p = ((*fmt == 'X')? 'A': 'a') - 10 + c;
else
*--p = '0' + c;
} while (v != 0);

if (!v)
break;
if (quot && ++i == 3) {
*--p = quot;
i = 0;
}
}
#if 0
if (hash && radix == 8) {
width = strlen(p)+1;
width = strlen(p) + 1;
pad = '0';
}
#endif
goto printit;

case '#':
hash = 1;
goto fmtnxt;

case 'c': /* Character */
p[0] = va_arg(ap, int);
p[1] = '\0';
Expand Down Expand Up @@ -280,17 +316,14 @@ vfprintf(FILE *op, const char *fmt, va_list ap)
/* fall thru if dotostr not linked in */
#endif

case '\0': /* early EOS */
--fmt;
/* fall thru */
default: /* unknown character */
goto charout;
}
} else {
charout:
putc(*fmt, op); /* normal char out */
++cnt;
if( *fmt == '\n' && buffer_mode == _IOLBF ) fflush(op);
++cnt;
}
++fmt;
}
Expand Down

0 comments on commit 584cb9f

Please sign in to comment.