Annotation of qemu/roms/qemu-palcode/printf.c, revision 1.1.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.