12 memset (void *dst_, int value, size_t size)
14 unsigned char *dst = dst_;
16 ASSERT (dst != NULL || size == 0);
25 memcpy (void *dst_, const void *src_, size_t size)
27 unsigned char *dst = dst_;
28 const unsigned char *src = src_;
30 ASSERT (dst != NULL || size == 0);
31 ASSERT (src != NULL || size == 0);
40 memmove (void *dst_, const void *src_, size_t size)
42 unsigned char *dst = dst_;
43 const unsigned char *src = src_;
45 ASSERT (dst != NULL || size == 0);
46 ASSERT (src != NULL || size == 0);
65 memchr (const void *block_, int ch_, size_t size)
67 const unsigned char *block = block_;
68 unsigned char ch = ch_;
70 ASSERT (block != NULL || size == 0);
72 for (; size-- > 0; block++)
74 return (void *) block;
80 memcmp (const void *a_, const void *b_, size_t size)
82 const unsigned char *a = a_;
83 const unsigned char *b = b_;
85 ASSERT (a != NULL || size == 0);
86 ASSERT (b != NULL || size == 0);
88 for (; size-- > 0; a++, b++)
90 return *a > *b ? +1 : -1;
95 strlcpy (char *dst, const char *src, size_t size)
100 ASSERT (src != NULL);
102 src_len = strlen (src);
105 size_t dst_len_max = size - 1;
106 size_t dst_len = src_len < dst_len_max ? src_len : dst_len_max;
107 memcpy (dst, src, dst_len);
114 strlen (const char *string)
118 ASSERT (string != NULL);
120 for (p = string; *p != '\0'; p++)
126 strchr (const char *string, int c_)
130 ASSERT (string != NULL);
134 return (char *) string;
135 else if (*string == '\0')
142 strcmp (const char *a_, const char *b_)
144 const unsigned char *a = (const unsigned char *) a_;
145 const unsigned char *b = (const unsigned char *) b_;
150 while (*a != '\0' && *a == *b)
156 return *a < *b ? -1 : *a > *b;
160 vprintf_core (const char *format, va_list args,
161 void (*output) (char, void *), void *aux);
164 vprintk_helper (char ch, void *aux UNUSED)
171 vprintk (const char *format, va_list args)
173 enum if_level old_level = intr_disable ();
174 vprintf_core (format, args, vprintk_helper, NULL);
175 intr_set_level (old_level);
179 printk (const char *format, ...)
183 va_start (args, format);
184 vprintk (format, args);
196 vsnprintf_helper (char ch, void *aux_)
198 struct vsnprintf_aux *aux = aux_;
200 if (aux->length++ < aux->max_length)
205 vsnprintf (char *buffer, size_t buf_size,
206 const char *format, va_list args)
208 struct vsnprintf_aux aux;
211 aux.max_length = buf_size > 0 ? buf_size - 1 : 0;
213 vprintf_core (format, args, vsnprintf_helper, &aux);
222 snprintf (char *buffer, size_t buf_size,
223 const char *format, ...)
228 va_start (args, format);
229 retval = vsnprintf (buffer, buf_size, format, args);
235 /* printf() and friends internals. You do not need to understand
238 struct printf_conversion
269 parse_conversion (const char *format, struct printf_conversion *c,
272 /* Parse flag characters. */
302 if (c->flags & MINUS)
307 /* Parse field width. */
312 c->width = va_arg (*args, int);
316 for (; isdigit (*format); format++)
317 c->width = c->width * 10 + *format - '0';
321 c->width = -c->width;
325 /* Parse precision. */
333 c->precision = va_arg (*args, int);
338 for (; isdigit (*format); format++)
339 c->precision = c->precision * 10 + *format - '0';
341 if (c->precision < 0)
344 if (c->precision >= 0)
398 output_dup (char ch, size_t cnt, void (*output) (char, void *), void *aux)
405 printf_integer (uintmax_t value, bool negative, const char *digits,
406 struct printf_conversion *c,
407 void (*output) (char, void *), void *aux)
412 const char *base_name;
413 int pad_cnt, group_cnt;
415 base = strlen (digits);
417 /* Accumulate digits into buffer.
418 This algorithm produces digits in reverse order, so later we
419 will output the buffer's content in reverse. This is also
420 the reason that later we append zeros and the sign. */
425 if ((c->flags & GROUP) && group_cnt++ == 3)
430 *cp++ = digits[value % base];
434 /* Append enough zeros to match precision.
435 If precision is 0, then a value of zero is rendered as a
436 null string. Otherwise at least one digit is presented. */
437 if (c->precision < 0)
439 while (cp - buf < c->precision && cp - buf < (int) sizeof buf - 8)
444 *cp++ = negative ? '-' : '+';
445 else if (c->flags & SPACE)
446 *cp++ = negative ? '-' : ' ';
450 /* Get name of base. */
452 if (c->flags & POUND)
457 base_name = digits[0xa] == 'a' ? "0x" : "0X";
460 /* Calculate number of pad characters to fill field width. */
461 pad_cnt = c->width - (cp - buf) - strlen (base_name);
466 if ((c->flags & (MINUS | ZERO)) == 0)
467 output_dup (' ', pad_cnt, output, aux);
468 while (*base_name != '\0')
469 output (*base_name++, aux);
471 output_dup ('0', pad_cnt, output, aux);
474 if (c->flags & MINUS)
475 output_dup (' ', pad_cnt, output, aux);
479 printf_string (const char *string, size_t length,
480 struct printf_conversion *c,
481 void (*output) (char, void *), void *aux)
483 if (c->width > 1 && (c->flags & MINUS) == 0)
484 output_dup (' ', c->width - 1, output, aux);
486 output (*string++, aux);
487 if (c->width > 1 && (c->flags & MINUS) != 0)
488 output_dup (' ', c->width - 1, output, aux);
492 printf_core (const char *format,
493 void (*output) (char, void *), void *aux, ...)
497 va_start (args, aux);
498 vprintf_core (format, args, output, aux);
503 vprintf_core (const char *format, va_list args,
504 void (*output) (char, void *), void *aux)
506 for (; *format != '\0'; format++)
508 struct printf_conversion c;
510 /* Literally copy non-conversions to output. */
513 output (*format, aux);
525 format = parse_conversion (format, &c, &args);
533 bool negative = false;
538 value = (signed char) va_arg (args, int);
541 value = (short) va_arg (args, int);
544 value = va_arg (args, int);
547 value = va_arg (args, long);
550 value = va_arg (args, long long);
553 value = va_arg (args, ptrdiff_t);
556 value = va_arg (args, size_t);
570 printf_integer (abs_value, negative, "0123456789",
586 value = (unsigned char) va_arg (args, unsigned);
589 value = (unsigned short) va_arg (args, unsigned);
592 value = va_arg (args, unsigned);
595 value = va_arg (args, unsigned long);
598 value = va_arg (args, unsigned long long);
601 value = va_arg (args, ptrdiff_t);
604 value = va_arg (args, size_t);
616 digits = "0123456789";
619 digits = "0123456789abcdef";
622 digits = "0123456789ABCDEF";
628 printf_integer (value, false, digits, &c, output, aux);
634 char ch = va_arg (args, int);
635 printf_string (&ch, 1, &c, output, aux);
644 s = va_arg (args, char *);
648 if (c.precision >= 0)
650 const char *zero = memchr (s, '\0', c.precision);
654 length = c.precision;
659 printf_string (s, length, &c, output, aux);
665 void *p = va_arg (args, void *);
669 printf_integer ((uintptr_t) p,
670 false, "0123456789abcdef", &c,
673 printf_string ("(nil)", 5, &c, output, aux);
683 printf_core ("<<no %%%c in kernel>>", output, aux, *format);
687 printf_core ("<<no %%%c conversion>>", output, aux, *format);
694 hex_dump (const void *buffer, size_t size)
696 const size_t n_per_line = 16;
697 const uint8_t *p = buffer;
704 printk ("%08zx", ofs);
705 n = size >= n_per_line ? n_per_line : size;
706 for (i = 0; i < n; i++)
707 printk ("%c%02x", i == n / 2 ? '-' : ' ', (unsigned) p[i]);
708 for (; i < n_per_line; i++)
711 for (i = 0; i < n; i++)
712 printk ("%c", isprint (p[i]) ? p[i] : '.');
713 for (; i < n_per_line; i++)