diff options
author | jilles <jilles@FreeBSD.org> | 2010-11-19 12:56:13 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2010-11-19 12:56:13 +0000 |
commit | 129853101d5707b7d18f28f39e748fa65a36add2 (patch) | |
tree | bf15bc2b264e5ca2469d76c04865a14c1e99127c /usr.bin/printf | |
parent | 7be275d6a786ef414ab769fb1b61fa9a4b041f4d (diff) | |
download | FreeBSD-src-129853101d5707b7d18f28f39e748fa65a36add2.zip FreeBSD-src-129853101d5707b7d18f28f39e748fa65a36add2.tar.gz |
sh: Add printf builtin.
This was removed in 2001 but I think it is appropriate to add it back:
* I do not want to encourage people to write fragile and non-portable echo
commands by making printf much slower than echo.
* Recent versions of Autoconf use it a lot.
* Almost no software still wants to support systems that do not have
printf(1) at all.
* In many other shells printf is already a builtin.
Side effect: printf is now always the builtin version (which behaves
identically to /usr/bin/printf) and cannot be overridden via PATH (except
via the undocumented %builtin mechanism).
Code size increases about 5K on i386. Embedded folks might want to replace
/usr/bin/printf with a hard link to /usr/bin/alias.
Diffstat (limited to 'usr.bin/printf')
-rw-r--r-- | usr.bin/printf/printf.1 | 11 | ||||
-rw-r--r-- | usr.bin/printf/printf.c | 30 |
2 files changed, 34 insertions, 7 deletions
diff --git a/usr.bin/printf/printf.1 b/usr.bin/printf/printf.1 index 6caea65..6008b68 100644 --- a/usr.bin/printf/printf.1 +++ b/usr.bin/printf/printf.1 @@ -35,7 +35,7 @@ .\" @(#)printf.1 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd September 5, 2010 +.Dd November 19, 2010 .Dt PRINTF 1 .Os .Sh NAME @@ -306,6 +306,13 @@ character is defined in the program's locale (category In no case does a non-existent or small field width cause truncation of a field; padding takes place only if the specified field width exceeds the actual width. +.Pp +Some shells may provide a builtin +.Nm +command which is similar or identical to this utility. +Consult the +.Xr builtin 1 +manual page. .Sh EXIT STATUS .Ex -std .Sh COMPATIBILITY @@ -316,7 +323,9 @@ with a digit to the .Tn ASCII code of the first character is not supported. .Sh SEE ALSO +.Xr builtin 1 , .Xr echo 1 , +.Xr sh 1 , .Xr printf 3 .Sh STANDARDS The diff --git a/usr.bin/printf/printf.c b/usr.bin/printf/printf.c index 5e7a935..4ac23c6 100644 --- a/usr.bin/printf/printf.c +++ b/usr.bin/printf/printf.c @@ -62,6 +62,7 @@ static const char rcsid[] = #define main printfcmd #include "bltin/bltin.h" #include "memalloc.h" +#include "error.h" #else #define warnx1(a, b, c) warnx(a) #define warnx2(a, b, c) warnx(a, b) @@ -90,7 +91,7 @@ static const char rcsid[] = } while (0) static int asciicode(void); -static char *doformat(char *, int *); +static char *printf_doformat(char *, int *); static int escape(char *, int, size_t *); static int getchr(void); static int getfloating(long double *, int); @@ -114,9 +115,12 @@ main(int argc, char *argv[]) int ch, chopped, end, rval; char *format, *fmt, *start; -#ifndef BUILTIN +#if !defined(BUILTIN) && !defined(SHELL) (void) setlocale(LC_NUMERIC, ""); #endif +#ifdef SHELL + optreset = 1; optind = 1; opterr = 0; /* initialize getopt */ +#endif while ((ch = getopt(argc, argv, "")) != -1) switch (ch) { case '?': @@ -132,6 +136,9 @@ main(int argc, char *argv[]) return (1); } +#ifdef SHELL + INTOFF; +#endif /* * Basic algorithm is to scan the format string for conversion * specifications -- once one is found, find out if the field @@ -154,9 +161,13 @@ main(int argc, char *argv[]) putchar('%'); fmt += 2; } else { - fmt = doformat(fmt, &rval); - if (fmt == NULL) + fmt = printf_doformat(fmt, &rval); + if (fmt == NULL) { +#ifdef SHELL + INTON; +#endif return (1); + } end = 0; } start = fmt; @@ -166,11 +177,18 @@ main(int argc, char *argv[]) if (end == 1) { warnx1("missing format character", NULL, NULL); +#ifdef SHELL + INTON; +#endif return (1); } fwrite(start, 1, fmt - start, stdout); - if (chopped || !*gargv) + if (chopped || !*gargv) { +#ifdef SHELL + INTON; +#endif return (rval); + } /* Restart at the beginning of the format string. */ fmt = format; end = 1; @@ -180,7 +198,7 @@ main(int argc, char *argv[]) static char * -doformat(char *start, int *rval) +printf_doformat(char *start, int *rval) { static const char skip1[] = "#'-+ 0"; static const char skip2[] = "0123456789"; |