11 memset (void *dst_, int value, size_t cnt)
22 memcpy (void *dst_, const void *src_, size_t cnt)
25 const uint8_t *src = src_;
34 memmove (void *dst_, const void *src_, size_t cnt)
37 const uint8_t *src = src_;
56 memchr (const void *block_, int ch_, size_t size)
58 const uint8_t *block = block_;
61 for (; size-- > 0; block++)
63 return (void *) block;
69 strlcpy (char *dst, const char *src, size_t size)
71 size_t src_len = strlen (src);
74 size_t dst_len_max = size - 1;
75 size_t dst_len = src_len < dst_len_max ? src_len : dst_len_max;
76 memcpy (dst, src, dst_len);
83 strlen (const char *string)
87 for (p = string; *p != '\0'; p++)
93 strchr (const char *string, int c_)
99 return (char *) string;
100 else if (*string == '\0')
106 vprintf_core (const char *format, va_list args,
107 void (*output) (char, void *), void *aux);
110 output_console (char ch, void *aux __attribute__ ((unused)))
117 vprintk (const char *format, va_list args)
119 vprintf_core (format, args, output_console, NULL);
123 printk (const char *format, ...)
127 va_start (args, format);
128 vprintk (format, args);
132 /* printf() and friends internals. You do not need to understand
135 struct printf_conversion
165 parse_conversion (const char *format, struct printf_conversion *c, va_list *args)
167 /* Parse flag characters. */
194 if (c->flags & MINUS)
199 /* Parse field width. */
204 c->width = va_arg (*args, int);
208 for (; isdigit (*format); format++)
209 c->width = c->width * 10 + *format - '0';
213 c->width = -c->width;
217 /* Parse precision. */
225 c->precision = va_arg (*args, int);
230 for (; isdigit (*format); format++)
231 c->precision = c->precision * 10 + *format - '0';
233 if (c->precision < 0)
236 if (c->precision >= 0)
290 output_dup (char ch, size_t cnt, void (*output) (char, void *), void *aux)
297 printf_integer (uintmax_t value, bool negative, const char *digits,
298 struct printf_conversion *c,
299 void (*output) (char, void *), void *aux)
302 int base = strlen (digits);
305 char *const buf_end = buf + sizeof buf;
310 /* Accumulate digits into buffer.
311 This algorithm produces digits in reverse order, so we count
312 backward from the end of the array. */
316 *--bp = digits[value % base];
320 /* Prepend enough zeros to match precision.
321 If precision is 0, then a value of zero is rendered as a
322 null string. Otherwise at least one digit is presented. */
323 if (c->precision < 0)
325 while (buf_end - bp < c->precision && bp > buf + 3)
330 *--bp = negative ? '-' : '+';
331 else if (c->flags & SPACE)
332 *--bp = negative ? '-' : ' ';
337 if ((c->flags & POUND) && base != 10)
339 *--bp = digits[0xa] == 'a' ? 'x' : 'X';
343 /* Calculate number of pad characters to fill field width. */
344 pad = c->width - (buf_end - bp);
349 if ((c->flags & (MINUS | ZERO)) == 0)
350 output_dup (' ', pad, output, aux);
351 if (bp < buf_end && strchr (digits, *bp) == NULL)
354 output_dup ('0', pad, output, aux);
357 if (c->flags & MINUS)
358 output_dup (' ', pad, output, aux);
362 printf_string (const char *string, size_t length,
363 struct printf_conversion *c,
364 void (*output) (char, void *), void *aux)
366 if (c->width > 1 && (c->flags & MINUS) == 0)
367 output_dup (' ', c->width - 1, output, aux);
369 output (*string++, aux);
370 if (c->width > 1 && (c->flags & MINUS) != 0)
371 output_dup (' ', c->width - 1, output, aux);
375 printf_core (const char *format,
376 void (*output) (char, void *), void *aux, ...)
380 va_start (args, aux);
381 vprintf_core (format, args, output, aux);
386 vprintf_core (const char *format, va_list args,
387 void (*output) (char, void *), void *aux)
389 for (; *format != '\0'; format++)
391 struct printf_conversion c;
393 /* Literally copy non-conversions to output. */
396 output (*format, aux);
408 format = parse_conversion (format, &c, &args);
416 bool negative = false;
421 value = (signed char) va_arg (args, int);
424 value = (short) va_arg (args, int);
427 value = va_arg (args, int);
430 value = va_arg (args, long);
433 value = va_arg (args, long long);
436 value = va_arg (args, ptrdiff_t);
439 value = va_arg (args, size_t);
453 printf_integer (abs_value, negative, "0123456789",
469 value = (unsigned char) va_arg (args, unsigned);
472 value = (unsigned short) va_arg (args, unsigned);
475 value = va_arg (args, unsigned);
478 value = va_arg (args, unsigned long);
481 value = va_arg (args, unsigned long long);
484 value = va_arg (args, ptrdiff_t);
487 value = va_arg (args, size_t);
499 digits = "0123456789";
502 digits = "0123456789abcdef";
505 digits = "0123456789ABCDEF";
511 printf_integer (value, false, digits, &c, output, aux);
517 char ch = va_arg (args, int);
518 printf_string (&ch, 1, &c, output, aux);
527 s = va_arg (args, char *);
531 if (c.precision >= 0)
533 const char *zero = memchr (s, '\0', c.precision);
537 length = c.precision;
542 printf_string (s, length, &c, output, aux);
548 void *p = va_arg (args, void *);
552 printf_integer ((uintptr_t) p,
553 false, "0123456789abcdef", &c,
556 printf_string ("(nil)", 5, &c, output, aux);
566 printf_core ("<<no %%%c in kernel>>", output, aux, *format);
570 printf_core ("<<no %%%c conversion>>", output, aux, *format);