[BACK]Return to printf.c CVS log [TXT][DIR] Up to [local] / funnyos / libkern

Annotation of funnyos/libkern/printf.c, Revision 1.1

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

CVSweb