1 /*        $NetBSD: printf.c,v 1.7 2016/02/14 18:05:31 dholland Exp $  */
2 /*-
3  * Copyright (c) 1998 Robert Nordier
4  * All rights reserved.
5  * Copyright (c) 2006 M. Warner Losh
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms are freely
9  * permitted provided that the above copyright notice and this
10  * paragraph and the following disclaimer are duplicated in all
11  * such forms.
12  *
13  * This software is provided "AS IS" and without any express or
14  * implied warranties, including, without limitation, the implied
15  * warranties of merchantability and fitness for a particular
16  * purpose.
17  *
18  * $FreeBSD: src/sys/boot/mips/emips/libemips/printf.c,v 1.2 2006/10/20 09:12:05 imp Exp $
19  */
20 
21 #include <lib/libsa/stand.h>
22 #include "common.h"
23 
24 void
xputchar(int ch)25 xputchar(int ch)
26 {
27     if (ch == '\n')
28           putchar('\r');
29     putchar(ch);
30 }
31 
32 void
printf(const char * fmt,...)33 printf(const char *fmt,...)
34 {
35           va_list ap;
36           const char *hex = "0123456789abcdef";
37           char buf[10];
38           char *s;
39           unsigned u;
40           int c;
41 
42           va_start(ap, fmt);
43           while ((c = *fmt++)) {
44                     if (c == '%') {
45         again:
46                               c = *fmt++;
47                               switch (c) {
48                               case 'l':
49                                         goto again;
50                               case 'c':
51                                         xputchar(va_arg(ap, int));
52                                         continue;
53                               case 's':
54                                         for (s = va_arg(ap, char *); s && *s; s++)
55                                                   xputchar(*s);
56                                         continue;
57                               case 'd': /* A lie, always prints unsigned */
58                               case 'u':
59                                         u = va_arg(ap, unsigned);
60                                         s = buf;
61                                         do
62                                                   *s++ = '0' + u % 10U;
63                                         while (u /= 10U);
64                               dumpbuf:;
65                                         while (--s >= buf)
66                                                   xputchar(*s);
67                                         continue;
68                               case 'x':
69                               case 'p':
70                                         u = va_arg(ap, unsigned);
71                                         s = buf;
72                                         do
73                                                   *s++ = hex[u & 0xfu];
74                                         while (u >>= 4);
75                                         goto dumpbuf;
76                               case 0:
77                                         va_end(ap);
78                                         return;
79                               }
80                     }
81                     xputchar(c);
82           }
83           va_end(ap);
84 
85           return;
86 }
87