From dc1d38348efe73edaeb35c4f994d074b94673ce3 Mon Sep 17 00:00:00 2001 From: kstailey Date: Tue, 21 Jan 1997 21:14:07 +0000 Subject: from the FIXES file: Oct 20, 1988: Fixed %c: if expr is numeric, use numeric value; otherwise print 1st char of string value. still doesn't work if the value is 0 -- won't print \0. This bugged me because it prevents awk from being a general-purpose decimal to bytestream converter (also GNU awk gets this right.) Look in /usr/share/man/cat4/sun3/leds.0 and you see: # echo 0 0 0 5 0 0 0 8 254 253 250 247 239 223 175 127 | awk '{ for (i=1;i<=NF;i++) printf("%c",$i+0); }' > /dev/leds This used to fail since "0" did not produce a \0 on stdout. It doesn't make any sense to me to fix awksprintf() the same way I did awkprintf() since sticking a \0 in a string ends it. --- usr.bin/awk/FIXES | 3 +++ usr.bin/awk/run.c | 31 +++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 10 deletions(-) (limited to 'usr.bin') diff --git a/usr.bin/awk/FIXES b/usr.bin/awk/FIXES index 9cda6ca12b3..6dd455653a2 100644 --- a/usr.bin/awk/FIXES +++ b/usr.bin/awk/FIXES @@ -1,3 +1,4 @@ +/* $OpenBSD: FIXES,v 1.3 1997/01/21 21:14:03 kstailey Exp $ */ /**************************************************************** Copyright (C) AT&T and Lucent Technologies 1996 All Rights Reserved @@ -475,3 +476,5 @@ Jun 29, 1996: fixed awful bug in new field splitting; didn't get all the places where input was done. +Jan 21, 1997 + Fixed %c: works if the value is 0 -- now prints \0. diff --git a/usr.bin/awk/run.c b/usr.bin/awk/run.c index fa540f634e2..ed8efd507f8 100644 --- a/usr.bin/awk/run.c +++ b/usr.bin/awk/run.c @@ -1,3 +1,4 @@ +/* $OpenBSD: run.c,v 1.3 1997/01/21 21:14:06 kstailey Exp $ */ /**************************************************************** Copyright (C) AT&T and Lucent Technologies 1996 All Rights Reserved @@ -718,12 +719,16 @@ Cell *sindex(Node **a, int nnn) /* index(a[0], a[1]) */ return(z); } -int format(char *buf, int bufsize, char *s, Node *a) /* printf-like conversions */ +/* + * printf-like conversions + * returns len of buf or -1 on error + */ +int format(char *buf, int bufsize, char *s, Node *a) { char fmt[RECSIZE]; char *p, *t, *os; Cell *x; - int flag = 0, n; + int flag = 0, len = 0, n; os = s; p = buf; @@ -731,10 +736,12 @@ int format(char *buf, int bufsize, char *s, Node *a) /* printf-like conversions if (p - buf >= bufsize) return -1; if (*s != '%') { + len++; *p++ = *s++; continue; } if (*(s+1) == '%') { + len++; *p++ = '%'; s += 2; continue; @@ -784,6 +791,7 @@ int format(char *buf, int bufsize, char *s, Node *a) /* printf-like conversions a = a->nnext; switch (flag) { case 0: sprintf((char *)p, "%s", fmt); /* unknown, so dump it too */ + len += strlen(p); p += strlen(p); sprintf((char *)p, "%s", getsval(x)); break; @@ -799,18 +807,22 @@ int format(char *buf, int bufsize, char *s, Node *a) /* printf-like conversions sprintf((char *)p, (char *)fmt, t); break; case 5: - isnum(x) ? sprintf((char *)p, (char *)fmt, (int) getfval(x)) + isnum(x) ? + (getfval(x) ? + sprintf((char *)p, (char *)fmt, (int) getfval(x)) + : len++) : sprintf((char *)p, (char *)fmt, getsval(x)[0]); break; } tempfree(x); + len += strlen(p); p += strlen(p); s++; } *p = '\0'; for ( ; a; a = a->nnext) /* evaluate any remaining args */ execute(a); - return 0; + return (len); } Cell *awksprintf(Node **a, int n) /* sprintf(a[0]) */ @@ -837,21 +849,20 @@ Cell *awkprintf(Node **a, int n) /* printf */ Cell *x; Node *y; char buf[3*RECSIZE]; + int len; y = a[0]->nnext; x = execute(a[0]); - if (format(buf, sizeof buf, getsval(x), y) == -1) + if ((len = format(buf, sizeof buf, getsval(x), y)) == -1) ERROR "printf string %.30s... too long", buf FATAL; tempfree(x); if (a[1] == NULL) { - fputs((char *)buf, stdout); - if (ferror(stdout)) + if (write(1, buf, len) != len) ERROR "write error on stdout" FATAL; } else { fp = redirect((int)a[1], a[2]); - fputs((char *)buf, fp); - fflush(fp); - if (ferror(fp)) + ferror(fp); /* XXX paranoia */ + if (write(fileno(fp), buf, len) != len) ERROR "write error on %s", filename(fp) FATAL; } return(true); -- cgit v1.2.3