QDNix
Quick’n’dirty *NIX
printk.c
1 /*
2  * BSD 3-Clause License
3  *
4  * Copyright (c) 2022, d0p1
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice, this
11  * list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 OR
26  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <stddef.h>
33 #include <stdarg.h>
34 #include <stdint.h>
35 
36 #include <sys/console.h>
37 
38 static inline void
39 printstr(const char *str)
40 {
41  if (str == NULL)
42  {
43  printstr("(null)");
44  return;
45  }
46 
47  while (*str != '\0')
48  {
49  console_putchar(*str++);
50  }
51 }
52 
53 static inline void
54 printuint(uintptr_t u, int base)
55 {
56  static const char digits[] = "0123456789abcdef";
57  static char buff[20];
58  int idx;
59 
60  idx = 0;
61  do
62  {
63  buff[idx++] = digits[u % base];
64  } while((u /= base) != 0);
65 
66  for (; idx > 0; idx--)
67  {
68  console_putchar(buff[idx-1]);
69  }
70 }
71 
72 void
73 printk(const char *fmt, ...)
74 {
75  va_list args;
76  char *ptr;
77  int tmp;
78 
79  va_start(args, fmt);
80  for (ptr = (char *)fmt; *ptr != '\0'; ptr++)
81  {
82  if (*ptr != '%')
83  {
84  /* TODO: tty/console */
85  console_putchar(*ptr);
86  continue;
87  }
88 
89  ptr++;
90  switch (*ptr)
91  {
92  case '%':
93  console_putchar('%');
94  break;
95 
96  case 'd':
97  case 'i':
98  tmp = va_arg(args, int);
99  if (tmp < 0)
100  {
101  console_putchar('-');
102  printuint(-tmp, 10);
103  }
104  else
105  {
106  printuint(tmp, 10);
107  }
108  break;
109 
110  case 'u':
111  printuint((va_arg(args, unsigned)), 10);
112  break;
113 
114  case 'x':
115  printuint((va_arg(args, unsigned)), 16);
116  break;
117 
118  case 'o':
119  console_putchar('0');
120  printuint((va_arg(args, unsigned)), 8);
121  break;
122 
123  case 's':
124  printstr(va_arg(args, const char *));
125  break;
126 
127  case 'c':
128  console_putchar(va_arg(args, int));
129  break;
130 
131  case 'p':
132  case 'a':
133  printstr("0x");
134 #ifdef __pdp11__
135  printuint((va_arg(args, unsigned)), 16);
136 #else
137  printuint((va_arg(args, uintptr_t)), 16);
138 #endif
139  break;
140 
141  default:
142  console_putchar('%');
143  console_putchar(*ptr);
144  }
145  }
146  va_end(args);
147  console_flush();
148 }