* Copyright (c) 1989 The Regents of the University of California.
* %sccs.include.redist.c%
"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)printf.c 5.10 (Berkeley) %G%";
(void)printf(f, fieldwidth, precision, func); \
(void)printf(f, fieldwidth, func); \
(void)printf(f, precision, func); \
static int asciicode
__P((void));
static void err
__P((const char *fmt
, ...));
static void escape
__P((char *));
static int getchr
__P((void));
static double getdouble
__P((void));
static int getint
__P((void));
static long getlong
__P((void));
static char *getstr
__P((void));
static char *mklong
__P((char *, int));
static char *skip1
, *skip2
;
register char *format
, *fmt
, *start
;
register int end
, fieldwidth
, precision
;
(void)fprintf(stderr
, "usage: printf format [arg ...]\n");
* Basic algorithm is to scan the format string for conversion
* specifications -- once one is found, find out if the field
* width or precision is a '*'; if it is, gather up value. Note,
* format strings are reused as necessary to use up the provided
* arguments, arguments of zero/null string are provided to use
escape(fmt
= format
= *++argv
); /* backslash interpretation */
/* find next format specification */
next
: for (start
= fmt
;; ++fmt
) {
/* avoid infinite loop */
err("missing format character");
(void)printf("%s", start
);
(void)printf("%s", start
);
/* skip to field width */
for (; index(skip1
, *fmt
); ++fmt
);
fieldwidth
= *fmt
== '*' ? getint() : 0;
/* skip to possible '.', get following precision */
for (; index(skip2
, *fmt
); ++fmt
);
precision
= *fmt
== '*' ? getint() : 0;
/* skip to conversion char */
for (; index(skip2
, *fmt
); ++fmt
);
err("missing format character");
case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': {
if ((f
= mklong(start
, convch
)) == NULL
)
case 'e': case 'E': case 'f': case 'g': case 'G': {
err("illegal format character.\n");
if (copy
= malloc((u_int
)len
)) { /* never freed; XXX */
bcopy(str
, copy
, len
- 3);
err("%s", strerror(errno
));
for (store
= fmt
; c
= *fmt
; ++fmt
, ++store
) {
case '\0': /* EOS, user error */
case '\\': /* backslash */
case '\'': /* single quote */
case 'a': /* bell/alert */
case 'b': /* backspace */
case 'f': /* form-feed */
case 'r': /* carriage-return */
case 't': /* horizontal tab */
case 'v': /* vertical tab */
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
c
-- && *fmt
>= '0' && *fmt
<= '7'; ++fmt
) {
static char *number
= "+-.0123456789";
if (index(number
, **gargv
))
if (index(number
, **gargv
))
return(strtol(*gargv
++, (char **)NULL
, 0));
return((long)asciicode());
if (index(number
, **gargv
))
return((double)asciicode());
if (ch
== '\'' || ch
== '"')
err(const char *fmt
, ...)
(void)fprintf(stderr
, "printf: ");
(void)vfprintf(stderr
, fmt
, ap
);
(void)fprintf(stderr
, "\n");