11 memset (void *dst_, int value, size_t cnt)
13 unsigned char *dst = dst_;
22 memcpy (void *dst_, const void *src_, size_t cnt)
24 unsigned char *dst = dst_;
25 const unsigned char *src = src_;
34 memmove (void *dst_, const void *src_, size_t cnt)
36 unsigned char *dst = dst_;
37 const unsigned char *src = src_;
56 memchr (const void *block_, int ch_, size_t size)
58 const unsigned char *block = block_;
59 unsigned char ch = ch_;
61 for (; size-- > 0; block++)
63 return (void *) block;
69 memcmp (const void *a_, const void *b_, size_t size)
71 const unsigned char *a = a_;
72 const unsigned char *b = b_;
74 for (; size-- > 0; a++, b++)
76 return *a > *b ? +1 : -1;
81 strlcpy (char *dst, const char *src, size_t size)
83 size_t src_len = strlen (src);
86 size_t dst_len_max = size - 1;
87 size_t dst_len = src_len < dst_len_max ? src_len : dst_len_max;
88 memcpy (dst, src, dst_len);
95 strlen (const char *string)
99 for (p = string; *p != '\0'; p++)
105 strchr (const char *string, int c_)
111 return (char *) string;
112 else if (*string == '\0')
118 vprintf_core (const char *format, va_list args,
119 void (*output) (char, void *), void *aux);
122 output_console (char ch, void *aux __attribute__ ((unused)))
129 vprintk (const char *format, va_list args)
131 vprintf_core (format, args, output_console, NULL);
135 printk (const char *format, ...)
139 va_start (args, format);
140 vprintk (format, args);
144 /* printf() and friends internals. You do not need to understand
147 struct printf_conversion
177 parse_conversion (const char *format, struct printf_conversion *c, va_list *args)
179 /* Parse flag characters. */
206 if (c->flags & MINUS)
211 /* Parse field width. */
216 c->width = va_arg (*args, int);
220 for (; isdigit (*format); format++)
221 c->width = c->width * 10 + *format - '0';
225 c->width = -c->width;
229 /* Parse precision. */
237 c->precision = va_arg (*args, int);
242 for (; isdigit (*format); format++)
243 c->precision = c->precision * 10 + *format - '0';
245 if (c->precision < 0)
248 if (c->precision >= 0)
302 output_dup (char ch, size_t cnt, void (*output) (char, void *), void *aux)
309 printf_integer (uintmax_t value, bool negative, const char *digits,
310 struct printf_conversion *c,
311 void (*output) (char, void *), void *aux)
314 int base = strlen (digits);
317 char *const buf_end = buf + sizeof buf;
322 /* Accumulate digits into buffer.
323 This algorithm produces digits in reverse order, so we count
324 backward from the end of the array. */
328 *--bp = digits[value % base];
332 /* Prepend enough zeros to match precision.
333 If precision is 0, then a value of zero is rendered as a
334 null string. Otherwise at least one digit is presented. */
335 if (c->precision < 0)
337 while (buf_end - bp < c->precision && bp > buf + 3)
342 *--bp = negative ? '-' : '+';
343 else if (c->flags & SPACE)
344 *--bp = negative ? '-' : ' ';
349 if ((c->flags & POUND) && base != 10)
351 *--bp = digits[0xa] == 'a' ? 'x' : 'X';
355 /* Calculate number of pad characters to fill field width. */
356 pad = c->width - (buf_end - bp);
361 if ((c->flags & (MINUS | ZERO)) == 0)
362 output_dup (' ', pad, output, aux);
363 if (bp < buf_end && strchr (digits, *bp) == NULL)
366 output_dup ('0', pad, output, aux);
369 if (c->flags & MINUS)
370 output_dup (' ', pad, output, aux);
374 printf_string (const char *string, size_t length,
375 struct printf_conversion *c,
376 void (*output) (char, void *), void *aux)
378 if (c->width > 1 && (c->flags & MINUS) == 0)
379 output_dup (' ', c->width - 1, output, aux);
381 output (*string++, aux);
382 if (c->width > 1 && (c->flags & MINUS) != 0)
383 output_dup (' ', c->width - 1, output, aux);
387 printf_core (const char *format,
388 void (*output) (char, void *), void *aux, ...)
392 va_start (args, aux);
393 vprintf_core (format, args, output, aux);
398 vprintf_core (const char *format, va_list args,
399 void (*output) (char, void *), void *aux)
401 for (; *format != '\0'; format++)
403 struct printf_conversion c;
405 /* Literally copy non-conversions to output. */
408 output (*format, aux);
420 format = parse_conversion (format, &c, &args);
428 bool negative = false;
433 value = (signed char) va_arg (args, int);
436 value = (short) va_arg (args, int);
439 value = va_arg (args, int);
442 value = va_arg (args, long);
445 value = va_arg (args, long long);
448 value = va_arg (args, ptrdiff_t);
451 value = va_arg (args, size_t);
465 printf_integer (abs_value, negative, "0123456789",
481 value = (unsigned char) va_arg (args, unsigned);
484 value = (unsigned short) va_arg (args, unsigned);
487 value = va_arg (args, unsigned);
490 value = va_arg (args, unsigned long);
493 value = va_arg (args, unsigned long long);
496 value = va_arg (args, ptrdiff_t);
499 value = va_arg (args, size_t);
511 digits = "0123456789";
514 digits = "0123456789abcdef";
517 digits = "0123456789ABCDEF";
523 printf_integer (value, false, digits, &c, output, aux);
529 char ch = va_arg (args, int);
530 printf_string (&ch, 1, &c, output, aux);
539 s = va_arg (args, char *);
543 if (c.precision >= 0)
545 const char *zero = memchr (s, '\0', c.precision);
549 length = c.precision;
554 printf_string (s, length, &c, output, aux);
560 void *p = va_arg (args, void *);
564 printf_integer ((uintptr_t) p,
565 false, "0123456789abcdef", &c,
568 printf_string ("(nil)", 5, &c, output, aux);
578 printf_core ("<<no %%%c in kernel>>", output, aux, *format);
582 printf_core ("<<no %%%c conversion>>", output, aux, *format);