[BACK]Return to printf.c CVS log [TXT][DIR] Up to [local] / sys / lib / libsa

Annotation of sys/lib/libsa/printf.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: printf.c,v 1.24 2006/09/18 21:11:50 mpf Exp $ */
        !             2: /*     $NetBSD: printf.c,v 1.10 1996/11/30 04:19:21 gwr Exp $  */
        !             3:
        !             4: /*-
        !             5:  * Copyright (c) 1993
        !             6:  *     The Regents of the University of California.  All rights reserved.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer.
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  * 3. Neither the name of the University nor the names of its contributors
        !            17:  *    may be used to endorse or promote products derived from this software
        !            18:  *    without specific prior written permission.
        !            19:  *
        !            20:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            21:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            22:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            23:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            24:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            25:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            26:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            27:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            28:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            29:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            30:  * SUCH DAMAGE.
        !            31:  *
        !            32:  *     @(#)printf.c    8.1 (Berkeley) 6/11/93
        !            33:  */
        !            34:
        !            35: /*
        !            36:  * Scaled down version of printf(3).
        !            37:  *
        !            38:  * One additional format:
        !            39:  *
        !            40:  * The format %b is supported to decode error registers.
        !            41:  * Its usage is:
        !            42:  *
        !            43:  *     printf("reg=%b\n", regval, "<base><arg>*");
        !            44:  *
        !            45:  * where <base> is the output base expressed as a control character, e.g.
        !            46:  * \10 gives octal; \20 gives hex.  Each arg is a sequence of characters,
        !            47:  * the first of which gives the bit number to be inspected (origin 1), and
        !            48:  * the next characters (up to a control character, i.e. a character <= 32),
        !            49:  * give the name of the register.  Thus:
        !            50:  *
        !            51:  *     printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
        !            52:  *
        !            53:  * would produce output:
        !            54:  *
        !            55:  *     reg=3<BITTWO,BITONE>
        !            56:  */
        !            57:
        !            58: #include <sys/cdefs.h>
        !            59: #include <sys/types.h>
        !            60: #include <sys/stdarg.h>
        !            61:
        !            62: #include "stand.h"
        !            63:
        !            64: void kprintn(void (*)(int), u_long, int);
        !            65: #ifdef LIBSA_LONGLONG_PRINTF
        !            66: void kprintn64(void (*)(int), u_int64_t, int);
        !            67: #endif
        !            68: void kdoprnt(void (*)(int), const char *, va_list);
        !            69:
        !            70: const char hexdig[] = "0123456789abcdef";
        !            71:
        !            72: void
        !            73: printf(const char *fmt, ...)
        !            74: {
        !            75:        va_list ap;
        !            76:
        !            77:        va_start(ap, fmt);
        !            78:        kdoprnt(putchar, fmt, ap);
        !            79:        va_end(ap);
        !            80: }
        !            81:
        !            82: void
        !            83: vprintf(const char *fmt, va_list ap)
        !            84: {
        !            85:        kdoprnt(putchar, fmt, ap);
        !            86: }
        !            87:
        !            88: void
        !            89: kdoprnt(void (*put)(int), const char *fmt, va_list ap)
        !            90: {
        !            91: #ifdef LIBSA_LONGLONG_PRINTF
        !            92:        u_int64_t ull;
        !            93: #endif
        !            94:        unsigned long ul;
        !            95:        int ch, lflag;
        !            96:        char *p;
        !            97:
        !            98:        for (;;) {
        !            99:                while ((ch = *fmt++) != '%') {
        !           100:                        if (ch == '\0')
        !           101:                                return;
        !           102:                        put(ch);
        !           103:                }
        !           104:                lflag = 0;
        !           105: reswitch:      switch (ch = *fmt++) {
        !           106:                case 'l':
        !           107:                        lflag++;
        !           108:                        goto reswitch;
        !           109: #ifndef        STRIPPED
        !           110:                case 'b':
        !           111:                {
        !           112:                        int set, n;
        !           113:
        !           114:                        ul = va_arg(ap, int);
        !           115:                        p = va_arg(ap, char *);
        !           116:                        kprintn(put, ul, *p++);
        !           117:
        !           118:                        if (!ul)
        !           119:                                break;
        !           120:
        !           121:                        for (set = 0; (n = *p++);) {
        !           122:                                if (ul & (1 << (n - 1))) {
        !           123:                                        put(set ? ',' : '<');
        !           124:                                        for (; (n = *p) > ' '; ++p)
        !           125:                                                put(n);
        !           126:                                        set = 1;
        !           127:                                } else
        !           128:                                        for (; *p > ' '; ++p)
        !           129:                                                ;
        !           130:                        }
        !           131:                        if (set)
        !           132:                                put('>');
        !           133:                }
        !           134:                        break;
        !           135: #endif
        !           136:                case 'c':
        !           137:                        ch = va_arg(ap, int);
        !           138:                        put(ch & 0x7f);
        !           139:                        break;
        !           140:                case 's':
        !           141:                        p = va_arg(ap, char *);
        !           142:                        while ((ch = *p++))
        !           143:                                put(ch);
        !           144:                        break;
        !           145:                case 'd':
        !           146: #ifdef LIBSA_LONGLONG_PRINTF
        !           147:                        if (lflag > 1) {
        !           148:                                ull = va_arg(ap, int64_t);
        !           149:                                if ((int64_t)ull < 0) {
        !           150:                                        put('-');
        !           151:                                        ull = -(int64_t)ull;
        !           152:                                }
        !           153:                                kprintn64(put, ull, 10);
        !           154:                                break;
        !           155:                        }
        !           156: #endif
        !           157:                        ul = lflag ?
        !           158:                            va_arg(ap, long) : va_arg(ap, int);
        !           159:                        if ((long)ul < 0) {
        !           160:                                put('-');
        !           161:                                ul = -(long)ul;
        !           162:                        }
        !           163:                        kprintn(put, ul, 10);
        !           164:                        break;
        !           165:                case 'o':
        !           166: #ifdef LIBSA_LONGLONG_PRINTF
        !           167:                        if (lflag > 1) {
        !           168:                                ull = va_arg(ap, u_int64_t);
        !           169:                                kprintn64(put, ull, 8);
        !           170:                                break;
        !           171:                        }
        !           172: #endif
        !           173:                        ul = lflag ?
        !           174:                            va_arg(ap, u_long) : va_arg(ap, u_int);
        !           175:                        kprintn(put, ul, 8);
        !           176:                        break;
        !           177:                case 'u':
        !           178: #ifdef LIBSA_LONGLONG_PRINTF
        !           179:                        if (lflag > 1) {
        !           180:                                ull = va_arg(ap, u_int64_t);
        !           181:                                kprintn64(put, ull, 10);
        !           182:                                break;
        !           183:                        }
        !           184: #endif
        !           185:                        ul = lflag ?
        !           186:                            va_arg(ap, u_long) : va_arg(ap, u_int);
        !           187:                        kprintn(put, ul, 10);
        !           188:                        break;
        !           189:                case 'p':
        !           190:                        put('0');
        !           191:                        put('x');
        !           192:                        lflag += sizeof(void *)==sizeof(u_long)? 1 : 0;
        !           193:                case 'x':
        !           194: #ifdef LIBSA_LONGLONG_PRINTF
        !           195:                        if (lflag > 1) {
        !           196:                                ull = va_arg(ap, u_int64_t);
        !           197:                                kprintn64(put, ull, 16);
        !           198:                                break;
        !           199:                        }
        !           200: #else
        !           201:                        if (lflag > 1) {
        !           202:                                /* hold an int64_t in base 16 */
        !           203:                                char *p, buf[(sizeof(u_int64_t) * NBBY / 4) + 1];
        !           204:                                u_int64_t ull;
        !           205:
        !           206:                                ull = va_arg(ap, u_int64_t);
        !           207:                                p = buf;
        !           208:                                do {
        !           209:                                        *p++ = hexdig[ull & 15];
        !           210:                                } while (ull >>= 4);
        !           211:                                do {
        !           212:                                        put(*--p);
        !           213:                                } while (p > buf);
        !           214:                                break;
        !           215:                        }
        !           216: #endif
        !           217:                        ul = lflag ?
        !           218:                            va_arg(ap, u_long) : va_arg(ap, u_int);
        !           219:                        kprintn(put, ul, 16);
        !           220:                        break;
        !           221:                default:
        !           222:                        put('%');
        !           223: #ifdef LIBSA_LONGLONG_PRINTF
        !           224:                        while (--lflag)
        !           225: #else
        !           226:                        if (lflag)
        !           227: #endif
        !           228:                                put('l');
        !           229:                        put(ch);
        !           230:                }
        !           231:        }
        !           232:        va_end(ap);
        !           233: }
        !           234:
        !           235: void
        !           236: kprintn(void (*put)(int), unsigned long ul, int base)
        !           237: {
        !           238:        /* hold a long in base 8 */
        !           239:        char *p, buf[(sizeof(long) * NBBY / 3) + 1];
        !           240:
        !           241:        p = buf;
        !           242:        do {
        !           243:                *p++ = hexdig[ul % base];
        !           244:        } while (ul /= base);
        !           245:        do {
        !           246:                put(*--p);
        !           247:        } while (p > buf);
        !           248: }
        !           249:
        !           250: #ifdef LIBSA_LONGLONG_PRINTF
        !           251: void
        !           252: kprintn64(void (*put)(int), u_int64_t ull, int base)
        !           253: {
        !           254:        /* hold an int64_t in base 8 */
        !           255:        char *p, buf[(sizeof(u_int64_t) * NBBY / 3) + 1];
        !           256:
        !           257:        p = buf;
        !           258:        do {
        !           259:                *p++ = hexdig[ull % base];
        !           260:        } while (ull /= base);
        !           261:        do {
        !           262:                put(*--p);
        !           263:        } while (p > buf);
        !           264: }
        !           265: #endif
        !           266:
        !           267: int donottwiddle = 0;
        !           268:
        !           269: void
        !           270: twiddle(void)
        !           271: {
        !           272:        static int pos;
        !           273:
        !           274:        if (!donottwiddle) {
        !           275:                putchar("|/-\\"[pos++ & 3]);
        !           276:                putchar('\b');
        !           277:        }
        !           278: }

CVSweb