12 memset (void *dst_, int value, size_t cnt)
14 unsigned char *dst = dst_;
23 memcpy (void *dst_, const void *src_, size_t cnt)
25 unsigned char *dst = dst_;
26 const unsigned char *src = src_;
35 memmove (void *dst_, const void *src_, size_t cnt)
37 unsigned char *dst = dst_;
38 const unsigned char *src = src_;
57 memchr (const void *block_, int ch_, size_t size)
59 const unsigned char *block = block_;
60 unsigned char ch = ch_;
62 for (; size-- > 0; block++)
64 return (void *) block;
70 memcmp (const void *a_, const void *b_, size_t size)
72 const unsigned char *a = a_;
73 const unsigned char *b = b_;
75 for (; size-- > 0; a++, b++)
77 return *a > *b ? +1 : -1;
82 strlcpy (char *dst, const char *src, size_t size)
84 size_t src_len = strlen (src);
87 size_t dst_len_max = size - 1;
88 size_t dst_len = src_len < dst_len_max ? src_len : dst_len_max;
89 memcpy (dst, src, dst_len);
96 strlen (const char *string)
100 for (p = string; *p != '\0'; p++)
106 strchr (const char *string, int c_)
112 return (char *) string;
113 else if (*string == '\0')
119 vprintf_core (const char *format, va_list args,
120 void (*output) (char, void *), void *aux);
123 vprintk_helper (char ch, void *aux __attribute__ ((unused)))
130 vprintk (const char *format, va_list args)
132 enum if_level old_level = intr_disable ();
133 vprintf_core (format, args, vprintk_helper, NULL);
134 intr_set_level (old_level);
138 printk (const char *format, ...)
142 va_start (args, format);
143 vprintk (format, args);
155 vsnprintf_helper (char ch, void *aux_)
157 struct vsnprintf_aux *aux = aux_;
159 if (aux->length++ < aux->max_length)
164 vsnprintf (char *buffer, size_t buf_size,
165 const char *format, va_list args)
167 struct vsnprintf_aux aux;
170 aux.max_length = buf_size > 0 ? buf_size - 1 : 0;
172 vprintf_core (format, args, vsnprintf_helper, &aux);
181 snprintf (char *buffer, size_t buf_size,
182 const char *format, ...)
187 va_start (args, format);
188 retval = vsnprintf (buffer, buf_size, format, args);
194 /* printf() and friends internals. You do not need to understand
197 struct printf_conversion
228 parse_conversion (const char *format, struct printf_conversion *c,
231 /* Parse flag characters. */
261 if (c->flags & MINUS)
266 /* Parse field width. */
271 c->width = va_arg (*args, int);
275 for (; isdigit (*format); format++)
276 c->width = c->width * 10 + *format - '0';
280 c->width = -c->width;
284 /* Parse precision. */
292 c->precision = va_arg (*args, int);
297 for (; isdigit (*format); format++)
298 c->precision = c->precision * 10 + *format - '0';
300 if (c->precision < 0)
303 if (c->precision >= 0)
357 output_dup (char ch, size_t cnt, void (*output) (char, void *), void *aux)
364 printf_integer (uintmax_t value, bool negative, const char *digits,
365 struct printf_conversion *c,
366 void (*output) (char, void *), void *aux)
371 const char *base_name;
372 int pad_cnt, group_cnt;
374 base = strlen (digits);
376 /* Accumulate digits into buffer.
377 This algorithm produces digits in reverse order, so later we
378 will output the buffer's content in reverse. This is also
379 the reason that later we append zeros and the sign. */
384 if ((c->flags & GROUP) && group_cnt++ == 3)
389 *cp++ = digits[value % base];
393 /* Append enough zeros to match precision.
394 If precision is 0, then a value of zero is rendered as a
395 null string. Otherwise at least one digit is presented. */
396 if (c->precision < 0)
398 while (cp - buf < c->precision && cp - buf < (int) sizeof buf - 8)
403 *cp++ = negative ? '-' : '+';
404 else if (c->flags & SPACE)
405 *cp++ = negative ? '-' : ' ';
409 /* Get name of base. */
411 if (c->flags & POUND)
416 base_name = digits[0xa] == 'a' ? "0x" : "0X";
419 /* Calculate number of pad characters to fill field width. */
420 pad_cnt = c->width - (cp - buf) - strlen (base_name);
425 if ((c->flags & (MINUS | ZERO)) == 0)
426 output_dup (' ', pad_cnt, output, aux);
427 while (*base_name != '\0')
428 output (*base_name++, aux);
430 output_dup ('0', pad_cnt, output, aux);
433 if (c->flags & MINUS)
434 output_dup (' ', pad_cnt, output, aux);
438 printf_string (const char *string, size_t length,
439 struct printf_conversion *c,
440 void (*output) (char, void *), void *aux)
442 if (c->width > 1 && (c->flags & MINUS) == 0)
443 output_dup (' ', c->width - 1, output, aux);
445 output (*string++, aux);
446 if (c->width > 1 && (c->flags & MINUS) != 0)
447 output_dup (' ', c->width - 1, output, aux);
451 printf_core (const char *format,
452 void (*output) (char, void *), void *aux, ...)
456 va_start (args, aux);
457 vprintf_core (format, args, output, aux);
462 vprintf_core (const char *format, va_list args,
463 void (*output) (char, void *), void *aux)
465 for (; *format != '\0'; format++)
467 struct printf_conversion c;
469 /* Literally copy non-conversions to output. */
472 output (*format, aux);
484 format = parse_conversion (format, &c, &args);
492 bool negative = false;
497 value = (signed char) va_arg (args, int);
500 value = (short) va_arg (args, int);
503 value = va_arg (args, int);
506 value = va_arg (args, long);
509 value = va_arg (args, long long);
512 value = va_arg (args, ptrdiff_t);
515 value = va_arg (args, size_t);
529 printf_integer (abs_value, negative, "0123456789",
545 value = (unsigned char) va_arg (args, unsigned);
548 value = (unsigned short) va_arg (args, unsigned);
551 value = va_arg (args, unsigned);
554 value = va_arg (args, unsigned long);
557 value = va_arg (args, unsigned long long);
560 value = va_arg (args, ptrdiff_t);
563 value = va_arg (args, size_t);
575 digits = "0123456789";
578 digits = "0123456789abcdef";
581 digits = "0123456789ABCDEF";
587 printf_integer (value, false, digits, &c, output, aux);
593 char ch = va_arg (args, int);
594 printf_string (&ch, 1, &c, output, aux);
603 s = va_arg (args, char *);
607 if (c.precision >= 0)
609 const char *zero = memchr (s, '\0', c.precision);
613 length = c.precision;
618 printf_string (s, length, &c, output, aux);
624 void *p = va_arg (args, void *);
628 printf_integer ((uintptr_t) p,
629 false, "0123456789abcdef", &c,
632 printf_string ("(nil)", 5, &c, output, aux);
642 printf_core ("<<no %%%c in kernel>>", output, aux, *format);
646 printf_core ("<<no %%%c conversion>>", output, aux, *format);
653 hex_dump (const void *buffer, size_t size)
655 const size_t n_per_line = 16;
656 const uint8_t *p = buffer;
663 printk ("%08zx", ofs);
664 n = size >= n_per_line ? n_per_line : size;
665 for (i = 0; i < n; i++)
666 printk ("%c%02x", i == n / 2 ? '-' : ' ', (unsigned) p[i]);
667 for (; i < n_per_line; i++)
670 for (i = 0; i < n; i++)
671 printk ("%c", isprint (p[i]) ? p[i] : '.');
672 for (; i < n_per_line; i++)