diff options
Diffstat (limited to 'tc.printf.c')
-rw-r--r-- | tc.printf.c | 118 |
1 files changed, 73 insertions, 45 deletions
diff --git a/tc.printf.c b/tc.printf.c index 8db69d5fff9c..1acc3a11b5f4 100644 --- a/tc.printf.c +++ b/tc.printf.c @@ -1,4 +1,4 @@ -/* $Header: /p/tcsh/cvsroot/tcsh/tc.printf.c,v 3.35 2006/03/02 18:46:45 christos Exp $ */ +/* $Header: /p/tcsh/cvsroot/tcsh/tc.printf.c,v 3.38 2015/06/06 21:19:08 christos Exp $ */ /* * tc.printf.c: A public-domain, minimal printf/sprintf routine that prints * through the putchar() routine. Feel free to use for @@ -34,7 +34,7 @@ */ #include "sh.h" -RCSID("$tcsh: tc.printf.c,v 3.35 2006/03/02 18:46:45 christos Exp $") +RCSID("$tcsh: tc.printf.c,v 3.38 2015/06/06 21:19:08 christos Exp $") #ifdef lint #undef va_arg @@ -46,9 +46,9 @@ RCSID("$tcsh: tc.printf.c,v 3.35 2006/03/02 18:46:45 christos Exp $") static char snil[] = "(nil)"; static void xaddchar (int); -static void doprnt (void (*) (int), const char *, va_list); +static int doprnt (void (*) (int), const char *, va_list); -static void +static int doprnt(void (*addchar) (int), const char *sfmt, va_list ap) { char *bp; @@ -68,8 +68,8 @@ doprnt(void (*addchar) (int), const char *sfmt, va_list ap) int fmt; unsigned char pad = ' '; int flush_left = 0, f_width = 0, prec = INF, hash = 0; - int do_long = 0, do_size_t = 0; - int sign = 0; + int do_long = 0, do_size_t = 0, do_ptrdiff_t = 0; + int sign = 0, count = 0; int attributes = 0; @@ -77,6 +77,7 @@ doprnt(void (*addchar) (int), const char *sfmt, va_list ap) for (; *f; f++) { if (*f != '%') { /* then just out the char */ (*addchar) (((unsigned char)*f) | attributes); + count++; } else { f++; /* skip the % */ @@ -131,6 +132,10 @@ doprnt(void (*addchar) (int), const char *sfmt, va_list ap) do_size_t++; f++; } + if (*f == 't') { /* ptrdiff_t format */ + do_ptrdiff_t++; + f++; + } fmt = (unsigned char) *f; if (fmt != 'S' && fmt != 'Q' && isupper(fmt)) { @@ -171,13 +176,19 @@ doprnt(void (*addchar) (int), const char *sfmt, va_list ap) *bp++ = '-'; f_width = f_width - (int) (bp - buf); if (!flush_left) - while (f_width-- > 0) + while (f_width-- > 0) { (*addchar) (pad | attributes); - for (bp--; bp >= buf; bp--) + count++; + } + for (bp--; bp >= buf; bp--) { (*addchar) (((unsigned char) *bp) | attributes); + count++; + } if (flush_left) - while (f_width-- > 0) + while (f_width-- > 0) { (*addchar) (' ' | attributes); + count++; + } break; case 'p': @@ -192,6 +203,8 @@ doprnt(void (*addchar) (int), const char *sfmt, va_list ap) case 0: if (do_size_t) u = va_arg(ap, size_t); + else if (do_ptrdiff_t) + u = va_arg(ap, ptrdiff_t); else u = va_arg(ap, unsigned int); break; @@ -234,19 +247,24 @@ doprnt(void (*addchar) (int), const char *sfmt, va_list ap) } i = f_width - (int) (bp - buf); if (!flush_left) - while (i-- > 0) + while (i-- > 0) { (*addchar) (pad | attributes); + count++; + } for (bp--; bp >= buf; bp--) (*addchar) (((unsigned char) *bp) | attributes); if (flush_left) - while (i-- > 0) + while (i-- > 0) { (*addchar) (' ' | attributes); + count++; + } break; case 'c': i = va_arg(ap, int); (*addchar) (i | attributes); + count++; break; case 'S': @@ -259,23 +277,31 @@ doprnt(void (*addchar) (int), const char *sfmt, va_list ap) } f_width = f_width - Strlen(Bp); if (!flush_left) - while (f_width-- > 0) + while (f_width-- > 0) { (*addchar) ((int) (pad | attributes)); + count++; + } for (i = 0; *Bp && i < prec; i++) { char cbuf[MB_LEN_MAX]; size_t pos, len; - if (fmt == 'Q' && *Bp & QUOTE) + if (fmt == 'Q' && *Bp & QUOTE) { (*addchar) ('\\' | attributes); - len = one_wctomb(cbuf, *Bp & CHAR); - for (pos = 0; pos < len; pos++) + count++; + } + len = one_wctomb(cbuf, *Bp); + for (pos = 0; pos < len; pos++) { (*addchar) ((unsigned char)cbuf[pos] | attributes | (*Bp & ATTRIBUTES)); + count++; + } Bp++; } if (flush_left) - while (f_width-- > 0) + while (f_width-- > 0) { (*addchar) (' ' | attributes); + count++; + } break; #endif /* SHORT_STRINGS */ @@ -287,17 +313,24 @@ lcase_s: bp = snil; f_width = f_width - strlen(bp); if (!flush_left) - while (f_width-- > 0) + while (f_width-- > 0) { (*addchar) (pad | attributes); + count++; + } for (i = 0; *bp && i < prec; i++) { - if (fmt == 'q' && *bp & QUOTE) + if (fmt == 'q' && *bp & QUOTE) { (*addchar) ('\\' | attributes); + count++; + } (*addchar) (((unsigned char) *bp & TRIM) | attributes); + count++; bp++; } if (flush_left) - while (f_width-- > 0) + while (f_width-- > 0) { (*addchar) (' ' | attributes); + count++; + } break; case 'a': @@ -306,17 +339,19 @@ lcase_s: case '%': (*addchar) ('%' | attributes); + count++; break; default: break; } flush_left = 0, f_width = 0, prec = INF, hash = 0; - do_size_t = 0, do_long = 0; + do_ptrdiff_t = 0, do_size_t = 0, do_long = 0; sign = 0; pad = ' '; } } + return count; } @@ -331,56 +366,49 @@ xaddchar(int c) } -pret_t +int /*VARARGS*/ xsnprintf(char *str, size_t size, const char *fmt, ...) { + int count; va_list va; va_start(va, fmt); xstring = str; xestring = str + size - 1; - doprnt(xaddchar, fmt, va); + count = doprnt(xaddchar, fmt, va); va_end(va); *xstring++ = '\0'; -#ifdef PURIFY - return 1; -#endif + return count; } -pret_t +int /*VARARGS*/ xprintf(const char *fmt, ...) { + int count; va_list va; va_start(va, fmt); - doprnt(xputchar, fmt, va); + count = doprnt(xputchar, fmt, va); va_end(va); -#ifdef PURIFY - return 1; -#endif + return count; } - -pret_t +int xvprintf(const char *fmt, va_list va) { - doprnt(xputchar, fmt, va); -#ifdef PURIFY - return 1; -#endif + return doprnt(xputchar, fmt, va); } -pret_t +int xvsnprintf(char *str, size_t size, const char *fmt, va_list va) { + int count; xstring = str; xestring = str + size - 1; - doprnt(xaddchar, fmt, va); + count = doprnt(xaddchar, fmt, va); *xstring++ = '\0'; -#ifdef PURIFY - return 1; -#endif + return count; } char * @@ -435,18 +463,18 @@ xasprintf(const char *fmt, ...) int fprintf(FILE *fp, const char* fmt, ...) { + int count; va_list va; va_start(va, fmt); - doprnt(xputchar, fmt, va); + count = doprnt(xputchar, fmt, va); va_end(va); - return 1; + return count; } int vfprintf(FILE *fp, const char *fmt, va_list va) { - doprnt(xputchar, fmt, va); - return 1; + return doprnt(xputchar, fmt, va); } #endif /* PURIFY */ |