Annotation of qemu/roms/qemu-palcode/printf.c, revision 1.1

1.1     ! root        1: /* A reduced version of the printf function.
        !             2: 
        !             3:    Copyright (C) 2011 Richard Henderson
        !             4: 
        !             5:    This file is part of QEMU PALcode.
        !             6: 
        !             7:    This program is free software; you can redistribute it and/or modify
        !             8:    it under the terms of the GNU General Public License as published by
        !             9:    the Free Software Foundation; either version 2 of the License or
        !            10:    (at your option) any later version.
        !            11: 
        !            12:    This program is distributed in the hope that it will be useful,
        !            13:    but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the text
        !            15:    of the GNU General Public License for more details.
        !            16: 
        !            17:    You should have received a copy of the GNU General Public License
        !            18:    along with this program; see the file COPYING.  If not see
        !            19:    <http://www.gnu.org/licenses/>.  */
        !            20: 
        !            21: #include <stdarg.h>
        !            22: #include <stdbool.h>
        !            23: #include <string.h>
        !            24: #include "console.h"
        !            25: 
        !            26: static int print_buf_pad(char *buf, int buflen, char *p, int width, int pad)
        !            27: {
        !            28:   int len = buf + buflen - p;
        !            29:   int r = 0;
        !            30: 
        !            31:   if (width > len)
        !            32:     {
        !            33:       *--p = pad;
        !            34:       len++;
        !            35: 
        !            36:       while (width > buflen)
        !            37:        {
        !            38:          crb_puts(0, p, 1);
        !            39:          width--;
        !            40:          r++;
        !            41:        }
        !            42:       while (width > len)
        !            43:        *--p = pad, len++;
        !            44:     }
        !            45: 
        !            46:   crb_puts(0, p, len);
        !            47:   return r + len;
        !            48: }
        !            49: 
        !            50: static int print_decimal(unsigned long val, int width, int pad)
        !            51: {
        !            52:   char buf[32];
        !            53:   char *p = buf + sizeof(buf);
        !            54: 
        !            55:   if (val == 0)
        !            56:     *--p = '0';
        !            57:   else
        !            58:     {
        !            59:       do
        !            60:        {
        !            61:          unsigned long d, r;
        !            62: 
        !            63:          /* Compiling with -Os results in a call to the division routine.
        !            64:             Do what the compiler ought to have done.  */
        !            65:          d = __builtin_alpha_umulh(val, 0xcccccccccccccccd);
        !            66:          d >>= 3;
        !            67:          r = val - (d * 10);
        !            68: 
        !            69:          *--p = r + '0';
        !            70:          val = d;
        !            71:        }
        !            72:       while (val);
        !            73:     }
        !            74: 
        !            75:   return print_buf_pad(buf, sizeof(buf), p, width, pad);
        !            76: }
        !            77: 
        !            78: static int print_hex(unsigned long val, int width, char pad)
        !            79: {
        !            80:   char buf[32];
        !            81:   char *p = buf + sizeof(buf);
        !            82: 
        !            83:   if (val == 0)
        !            84:     *--p = '0';
        !            85:   else
        !            86:     {
        !            87:       do
        !            88:        {
        !            89:          int d = val % 16;
        !            90:          *--p = (d < 10 ? '0' : 'a' - 10) + d;
        !            91:          val /= 16;
        !            92:        }
        !            93:       while (val);
        !            94:     }
        !            95: 
        !            96:   return print_buf_pad(buf, sizeof(buf), p, width, pad);
        !            97: }
        !            98: 
        !            99: int printf(const char *fmt, ...)
        !           100: {
        !           101:   va_list args;
        !           102:   unsigned long val;
        !           103:   int r = 0;
        !           104: 
        !           105:   va_start(args, fmt);
        !           106: 
        !           107:   for (; *fmt ; fmt++)
        !           108:     if (*fmt != '%')
        !           109:       {
        !           110:         crb_puts(0, fmt, 1);
        !           111:        r++;
        !           112:       }
        !           113:     else
        !           114:       {
        !           115:         const char *percent = fmt;
        !           116:        bool is_long = false;
        !           117:         char pad = ' ';
        !           118:         int width = 0;
        !           119: 
        !           120:       restart:
        !           121:         switch (*++fmt)
        !           122:          {
        !           123:          case '%':
        !           124:            crb_puts(0, "%", 1);
        !           125:            r++;
        !           126:            break;
        !           127: 
        !           128:          case 'l':
        !           129:            is_long = true;
        !           130:            goto restart;
        !           131: 
        !           132:          case 'd':
        !           133:            if (is_long)
        !           134:              {
        !           135:                long d = va_arg (args, long);
        !           136:                if (d < 0)
        !           137:                  {
        !           138:                    crb_puts(0, "-", 1);
        !           139:                    d = -d;
        !           140:                  }
        !           141:                val = d;
        !           142:              }
        !           143:            else
        !           144:              {
        !           145:                int d = va_arg (args, int);
        !           146:                if (d < 0)
        !           147:                  {
        !           148:                    crb_puts(0, "-", 1);
        !           149:                    d = -d;
        !           150:                    r++;
        !           151:                  }
        !           152:                val = d;
        !           153:              }
        !           154:            goto do_unsigned;
        !           155: 
        !           156:          case 'u':
        !           157:            if (is_long)
        !           158:              val = va_arg (args, unsigned long);
        !           159:            else
        !           160:              val = va_arg (args, unsigned int);
        !           161: 
        !           162:          do_unsigned:
        !           163:            r += print_decimal (val, width, pad);
        !           164:            break;
        !           165: 
        !           166:          case 'x':
        !           167:            if (is_long)
        !           168:              val = va_arg (args, unsigned long);
        !           169:            else
        !           170:              val = va_arg (args, unsigned int);
        !           171:            r += print_hex (val, width, pad);
        !           172:            break;
        !           173: 
        !           174:          case 's':
        !           175:            {
        !           176:              const char *s = va_arg (args, const char *);
        !           177:              int len = strlen(s);
        !           178:              crb_puts(0, s, len);
        !           179:              r += len;
        !           180:            }
        !           181:            break;
        !           182: 
        !           183:          case '0':
        !           184:            pad = '0';
        !           185:           case '1' ... '9':
        !           186:            width = *fmt - '0';
        !           187:            while (fmt[1] >= '0' && fmt[1] <= '9')
        !           188:              width = width * 10 + *++fmt - '0';
        !           189:            goto restart;
        !           190: 
        !           191:          default:
        !           192:            {
        !           193:              int len = fmt - percent;
        !           194:              crb_puts(0, percent, len);
        !           195:              r += len;
        !           196:            }
        !           197:            break;
        !           198:          }
        !           199:       }
        !           200: 
        !           201:   va_end(args);
        !           202:   return r;
        !           203: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.