diff --git a/bin/sh/Makefile b/bin/sh/Makefile index 1b0738b4dfbd..a606c9be9716 100644 --- a/bin/sh/Makefile +++ b/bin/sh/Makefile @@ -5,7 +5,7 @@ PROG= sh INSTALLFLAGS= -S SHSRCS= alias.c arith.y arith_lex.l cd.c echo.c error.c eval.c exec.c expand.c \ histedit.c input.c jobs.c mail.c main.c memalloc.c miscbltin.c \ - mystring.c options.c output.c parser.c redir.c show.c \ + mystring.c options.c output.c parser.c printf.c redir.c show.c \ test.c trap.c var.c GENSRCS= builtins.c init.c nodes.c syntax.c GENHDRS= builtins.h nodes.h syntax.h token.h @@ -26,7 +26,8 @@ WARNS?= 2 WFORMAT=0 .PATH: ${.CURDIR}/bltin \ - ${.CURDIR}/../test + ${.CURDIR}/../test \ + ${.CURDIR}/../../usr.bin/printf CLEANFILES+= mkinit mkinit.o mknodes mknodes.o \ mksyntax mksyntax.o diff --git a/bin/sh/builtins.def b/bin/sh/builtins.def index 75f83b54e526..b72f8873386b 100644 --- a/bin/sh/builtins.def +++ b/bin/sh/builtins.def @@ -71,7 +71,7 @@ histcmd -h fc jobidcmd jobid jobscmd jobs localcmd local -#printfcmd printf +printfcmd printf pwdcmd pwd readcmd read returncmd -s return diff --git a/bin/sh/sh.1 b/bin/sh/sh.1 index 7b1eb611f71d..ba06a0c60579 100644 --- a/bin/sh/sh.1 +++ b/bin/sh/sh.1 @@ -32,7 +32,7 @@ .\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95 .\" $FreeBSD$ .\" -.Dd November 12, 2010 +.Dd November 19, 2010 .Dt SH 1 .Os .Sh NAME @@ -2049,6 +2049,9 @@ line. See the .Sx Functions subsection. +.It Ic printf +A built-in equivalent of +.Xr printf 1 . .It Ic pwd Op Fl L | P Print the path of the current directory. The built-in command may @@ -2470,6 +2473,7 @@ will return the argument. .Xr echo 1 , .Xr ed 1 , .Xr emacs 1 , +.Xr printf 1 , .Xr pwd 1 , .Xr test 1 , .Xr vi 1 , diff --git a/share/man/man1/builtin.1 b/share/man/man1/builtin.1 index cbfc873d01dd..5a6b5ae739ea 100644 --- a/share/man/man1/builtin.1 +++ b/share/man/man1/builtin.1 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 9, 2010 +.Dd November 19, 2010 .Dt BUILTIN 1 .Os .Sh NAME @@ -99,6 +99,7 @@ .Nm onintr , .Nm popd , .Nm printenv , +.Nm printf , .Nm pushd , .Nm pwd , .Nm read , @@ -263,6 +264,7 @@ but are implemented as scripts using a builtin command of the same name. .It Ic onintr Ta \&No Ta Yes Ta \&No .It Ic popd Ta \&No Ta Yes Ta \&No .It Ic printenv Ta Yes Ta Yes Ta \&No +.It Ic printf Ta Yes Ta \&No Ta Yes .It Ic pushd Ta \&No Ta Yes Ta \&No .It Ic pwd Ta Yes Ta \&No Ta Yes .It Ic read Ta No** Ta \&No Ta Yes @@ -313,6 +315,7 @@ but are implemented as scripts using a builtin command of the same name. .Xr nice 1 , .Xr nohup 1 , .Xr printenv 1 , +.Xr printf 1 , .Xr pwd 1 , .Xr sh 1 , .Xr test 1 , diff --git a/usr.bin/printf/printf.1 b/usr.bin/printf/printf.1 index 6caea65c6df2..6008b68b4cbd 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 5e7a9353aa32..4ac23c65fb38 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,8 +115,11 @@ 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) { @@ -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";