CS350 COS
COS
Loading...
Searching...
No Matches
printf.c File Reference
#include <stdbool.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
Include dependency graph for printf.c:

Go to the source code of this file.

Data Structures

struct  StrState
 

Macros

#define getuint(ap, lflag)
 
#define getint(ap, lflag)
 

Typedefs

typedef struct StrState StrState
 

Functions

static void printnum (void(*func)(int, void *), void *handle, uint64_t num, int base, int width, int padc)
 
static int kvprintf (char const *fmt, void(*func)(int, void *), void *handle, va_list ap)
 
static void fileputc (int c, void *handle)
 
int printf (const char *fmt,...)
 
int fprintf (FILE *stream, const char *fmt,...)
 
static void strputc (int c, void *handle)
 
int sprintf (char *str, const char *fmt,...)
 
int snprintf (char *str, size_t n, const char *fmt,...)
 

Variables

static const char * numberstring_lower = "0123456789abcdef"
 
static const char * numberstring_upper = "0123456789ABCDEF"
 

Data Structure Documentation

◆ StrState

struct StrState

Definition at line 236 of file printf.c.

Collaboration diagram for StrState:
[legend]
Data Fields
char * buf
char * cur
size_t maxlen

Macro Definition Documentation

◆ getint

#define getint (   ap,
  lflag 
)
Value:
(lflag == 8) ? va_arg(ap, int64_t) : \
(lflag == 4) ? va_arg(ap, int32_t) : \
(lflag == 2) ? va_arg(ap, int32_t) : \
(lflag == 1) ? va_arg(ap, int32_t) : 0
#define va_arg(ap, type)
Definition: stdarg.h:12
signed int int32_t
Definition: types.h:7
signed long int64_t
Definition: types.h:8

Definition at line 20 of file printf.c.

◆ getuint

#define getuint (   ap,
  lflag 
)
Value:
(lflag == 8) ? va_arg(ap, uint64_t) : \
(lflag == 4) ? va_arg(ap, uint32_t) : \
(lflag == 2) ? va_arg(ap, uint32_t) : \
(lflag == 1) ? va_arg(ap, uint32_t) : 0
unsigned int uint32_t
Definition: types.h:12
unsigned long uint64_t
Definition: types.h:13

Definition at line 13 of file printf.c.

Typedef Documentation

◆ StrState

typedef struct StrState StrState

Function Documentation

◆ fileputc()

static void fileputc ( int  c,
void *  handle 
)
static

Definition at line 207 of file printf.c.

208{
209 fputc(c, (FILE *)handle);
210}
int fputc(int ch, FILE *fh)
Definition: file.c:124
Definition: stdio.h:8
Here is the call graph for this function:
Here is the caller graph for this function:

◆ fprintf()

int fprintf ( FILE stream,
const char *  fmt,
  ... 
)

Definition at line 224 of file printf.c.

225{
226 int ret;
227 va_list ap;
228
229 va_start(ap, fmt);
230 ret = kvprintf(fmt, fileputc, stream, ap);
231 va_end(ap);
232
233 return ret;
234}
static int kvprintf(char const *fmt, void(*func)(int, void *), void *handle, va_list ap)
Definition: printf.c:75
static void fileputc(int c, void *handle)
Definition: printf.c:207
#define va_end(ap)
Definition: stdarg.h:21
#define va_start(ap, last)
Definition: stdarg.h:9
__builtin_va_list va_list
Definition: stdarg.h:6
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kvprintf()

static int kvprintf ( char const *  fmt,
void(*)(int, void *)  func,
void *  handle,
va_list  ap 
)
static

Definition at line 75 of file printf.c.

76{
77 const char *p;
78 int ch;
79 uint64_t unum;
80 int64_t num;
81 int lflag, width, padc;
82
83 while (1) {
84 while ((ch = *(unsigned char *)fmt++) != '%') {
85 if (ch == '\0') return -1;
86 func(ch, handle);
87 }
88
89 width = -1;
90 lflag = 4;
91 padc = ' ';
92again:
93 switch (ch = *(unsigned char *)fmt++) {
94 case '-':
95 padc = '-';
96 goto again;
97 case '0':
98 padc = '0';
99 goto again;
100 case '1':
101 case '2':
102 case '3':
103 case '4':
104 case '5':
105 case '6':
106 case '7':
107 case '8':
108 case '9':
109 width = 0;
110 while (1) {
111 width = 10 * width + ch - '0';
112 ch = *fmt;
113 if (ch < '0' || ch > '9')
114 {
115 break;
116 }
117 fmt++;
118 if (ch == '\0')
119 {
120 fmt--;
121 goto again;
122 }
123 }
124 goto again;
125 case 'c':
126 func(va_arg(ap, int) & 0xff, handle);
127 break;
128 case 's': {
129 int spaces;
130
131 p = va_arg(ap, char *);
132 if (p == NULL) {
133 func('*', handle);
134 func('N', handle);
135 func('U', handle);
136 func('L', handle);
137 func('L', handle);
138 func('*', handle);
139 break;
140 }
141 spaces = width - strlen(p);
142
143 if (padc == ' ') {
144 while (spaces > 0)
145 {
146 func(' ', handle);
147 spaces--;
148 }
149 }
150
151 while (*p != '\0')
152 {
153 func(*p++, handle);
154 }
155
156 if (padc == '-') {
157 while (spaces > 0)
158 {
159 func(' ', handle);
160 spaces--;
161 }
162 }
163 break;
164 }
165 case 'd':
166 num = getint(ap, lflag);
167 if (num < 0) {
168 func('-', handle);
169 unum = -num;
170 } else {
171 unum = num;
172 }
173 printnum(func, handle, unum, 10, width, padc);
174 break;
175 case 'u':
176 unum = getuint(ap, lflag);
177 printnum(func, handle, unum, 10, width, padc);
178 break;
179 case 'o':
180 unum = getuint(ap, lflag);
181 printnum(func, handle, unum, 8, width, padc);
182 break;
183 case 'p':
184 unum = (unsigned long)va_arg(ap, void *);
185 printnum(func, handle, unum, 8, width, padc);
186 break;
187 case 'x':
188 unum = getuint(ap, lflag);
189 printnum(func, handle, unum, 16, width, padc);
190 break;
191 case 'X':
192 unum = getuint(ap, lflag);
193 printnum(func, handle, unum, -16, width, padc);
194 break;
195 case 'l':
196 lflag = 8;
197 goto again;
198 case '%':
199 default: // Print Literally
200 func(ch, handle);
201 break;
202 }
203 }
204 return 0;
205}
#define getuint(ap, lflag)
Definition: printf.c:13
static void printnum(void(*func)(int, void *), void *handle, uint64_t num, int base, int width, int padc)
Definition: printf.c:29
#define getint(ap, lflag)
Definition: printf.c:20
#define NULL
Definition: stddef.h:6
size_t strlen(const char *str)
Definition: string.c:112
Here is the call graph for this function:
Here is the caller graph for this function:

◆ printf()

int printf ( const char *  fmt,
  ... 
)

Definition at line 212 of file printf.c.

213{
214 int ret;
215 va_list ap;
216
217 va_start(ap, fmt);
218 ret = kvprintf(fmt, fileputc, (void *)stdout, ap);
219 va_end(ap);
220
221 return ret;
222}
FILE * stdout
Definition: file.c:16
Here is the call graph for this function:
Here is the caller graph for this function:

◆ printnum()

static void printnum ( void(*)(int, void *)  func,
void *  handle,
uint64_t  num,
int  base,
int  width,
int  padc 
)
static

Definition at line 29 of file printf.c.

31{
32 char buf[64];
33 char *p = buf;
34 int spaces;
35 if (base < 0)
36 {
37 base = -base;
38 do {
39 *p = numberstring_upper[num % base];
40 p++;
41 } while (num /= base);
42 } else {
43 do {
44 *p = numberstring_lower[num % base];
45 p++;
46 } while (num /= base);
47 }
48
49 // Print spacers (pre-number)
50 spaces = width - (p - buf);
51 if (padc == ' ' || padc == '0') {
52 while (spaces > 0)
53 {
54 func(padc, handle);
55 spaces--;
56 }
57 }
58
59 // Print Number
60 while (p != buf) {
61 p--;
62 func((int)*p, handle);
63 }
64
65 // Print spacers (post-number)
66 if (padc == '-') {
67 while (spaces > 0)
68 {
69 func(' ', handle);
70 spaces--;
71 }
72 }
73}
static char buf[4096]
Definition: ethdump.c:10
static const char * numberstring_upper
Definition: printf.c:27
static const char * numberstring_lower
Definition: printf.c:26
static uint16_t base
Definition: sercons.c:37
Here is the caller graph for this function:

◆ snprintf()

int snprintf ( char *  str,
size_t  n,
const char *  fmt,
  ... 
)

Definition at line 275 of file printf.c.

276{
277 int ret;
278 va_list ap;
279 StrState state;
280
281 state.buf = str;
282 state.cur = str;
283 state.maxlen = n;
284
285 va_start(ap, fmt);
286 ret = kvprintf(fmt, strputc, &state, ap);
287 va_end(ap);
288
289 state.cur[0] = '\0';
290
291 return ret;
292}
size_t maxlen
Definition: printf.c:239
char * buf
Definition: printf.c:237
char * cur
Definition: printf.c:238
static void strputc(int c, void *handle)
Definition: printf.c:242
Here is the call graph for this function:

◆ sprintf()

int sprintf ( char *  str,
const char *  fmt,
  ... 
)

Definition at line 256 of file printf.c.

257{
258 int ret;
259 va_list ap;
260 StrState state;
261
262 state.buf = str;
263 state.cur = str;
264 state.maxlen = -1;
265
266 va_start(ap, fmt);
267 ret = kvprintf(fmt, strputc, &state, ap);
268 va_end(ap);
269
270 state.cur[0] = '\0';
271
272 return ret;
273}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ strputc()

static void strputc ( int  c,
void *  handle 
)
static

Definition at line 242 of file printf.c.

243{
244 StrState *state = (StrState *)handle;
245
246 if ((state->maxlen != -1) &&
247 (state->cur - state->buf >= state->maxlen)) {
248 state->cur[0] = '\0';
249 return;
250 }
251
252 state->cur[0] = c;
253 state->cur++;
254}
Here is the caller graph for this function:

Variable Documentation

◆ numberstring_lower

const char* numberstring_lower = "0123456789abcdef"
static

Definition at line 26 of file printf.c.

◆ numberstring_upper

const char* numberstring_upper = "0123456789ABCDEF"
static

Definition at line 27 of file printf.c.