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 strtok_r (char *s, const char *delimiters, char **save_ptr)
164 ASSERT (delimiters != NULL);
165 ASSERT (save_ptr != NULL);
167 /* If S is nonnull, start from it.
168 If S is null, start from saved position. */
173 /* Skip any DELIMITERS at our current position. */
174 while (strchr (delimiters, *s) != NULL)
176 /* strchr() will always return nonnull if we're searching
177 for a null byte, because every string contains a null
178 byte (at the end). */
188 /* Skip any non-DELIMITERS up to the end of the string. */
190 while (strchr (delimiters, *s) == NULL)
203 vprintf_core (const char *format, va_list args,
204 void (*output) (char, void *), void *aux);
207 vprintk_helper (char ch, void *aux UNUSED)
214 vprintk (const char *format, va_list args)
216 enum if_level old_level = intr_disable ();
217 vprintf_core (format, args, vprintk_helper, NULL);
218 intr_set_level (old_level);
222 printk (const char *format, ...)
226 va_start (args, format);
227 vprintk (format, args);
239 vsnprintf_helper (char ch, void *aux_)
241 struct vsnprintf_aux *aux = aux_;
243 if (aux->length++ < aux->max_length)
248 vsnprintf (char *buffer, size_t buf_size,
249 const char *format, va_list args)
251 struct vsnprintf_aux aux;
254 aux.max_length = buf_size > 0 ? buf_size - 1 : 0;
256 vprintf_core (format, args, vsnprintf_helper, &aux);
265 snprintf (char *buffer, size_t buf_size,
266 const char *format, ...)
271 va_start (args, format);
272 retval = vsnprintf (buffer, buf_size, format, args);
278 /* printf() and friends internals. You do not need to understand
281 struct printf_conversion
312 parse_conversion (const char *format, struct printf_conversion *c,
315 /* Parse flag characters. */
345 if (c->flags & MINUS)
350 /* Parse field width. */
355 c->width = va_arg (*args, int);
359 for (; isdigit (*format); format++)
360 c->width = c->width * 10 + *format - '0';
364 c->width = -c->width;
368 /* Parse precision. */
376 c->precision = va_arg (*args, int);
381 for (; isdigit (*format); format++)
382 c->precision = c->precision * 10 + *format - '0';
384 if (c->precision < 0)
387 if (c->precision >= 0)
441 output_dup (char ch, size_t cnt, void (*output) (char, void *), void *aux)
448 printf_integer (uintmax_t value, bool negative, const char *digits,
449 struct printf_conversion *c,
450 void (*output) (char, void *), void *aux)
455 const char *base_name;
456 int pad_cnt, group_cnt;
458 base = strlen (digits);
460 /* Accumulate digits into buffer.
461 This algorithm produces digits in reverse order, so later we
462 will output the buffer's content in reverse. This is also
463 the reason that later we append zeros and the sign. */
468 if ((c->flags & GROUP) && group_cnt++ == 3)
473 *cp++ = digits[value % base];
477 /* Append enough zeros to match precision.
478 If precision is 0, then a value of zero is rendered as a
479 null string. Otherwise at least one digit is presented. */
480 if (c->precision < 0)
482 while (cp - buf < c->precision && cp - buf < (int) sizeof buf - 8)
487 *cp++ = negative ? '-' : '+';
488 else if (c->flags & SPACE)
489 *cp++ = negative ? '-' : ' ';
493 /* Get name of base. */
495 if (c->flags & POUND)
500 base_name = digits[0xa] == 'a' ? "0x" : "0X";
503 /* Calculate number of pad characters to fill field width. */
504 pad_cnt = c->width - (cp - buf) - strlen (base_name);
509 if ((c->flags & (MINUS | ZERO)) == 0)
510 output_dup (' ', pad_cnt, output, aux);
511 while (*base_name != '\0')
512 output (*base_name++, aux);
514 output_dup ('0', pad_cnt, output, aux);
517 if (c->flags & MINUS)
518 output_dup (' ', pad_cnt, output, aux);
522 printf_string (const char *string, size_t length,
523 struct printf_conversion *c,
524 void (*output) (char, void *), void *aux)
526 if (c->width > 1 && (c->flags & MINUS) == 0)
527 output_dup (' ', c->width - 1, output, aux);
529 output (*string++, aux);
530 if (c->width > 1 && (c->flags & MINUS) != 0)
531 output_dup (' ', c->width - 1, output, aux);
535 printf_core (const char *format,
536 void (*output) (char, void *), void *aux, ...)
540 va_start (args, aux);
541 vprintf_core (format, args, output, aux);
546 vprintf_core (const char *format, va_list args,
547 void (*output) (char, void *), void *aux)
549 for (; *format != '\0'; format++)
551 struct printf_conversion c;
553 /* Literally copy non-conversions to output. */
556 output (*format, aux);
568 format = parse_conversion (format, &c, &args);
576 bool negative = false;
581 value = (signed char) va_arg (args, int);
584 value = (short) va_arg (args, int);
587 value = va_arg (args, int);
590 value = va_arg (args, long);
593 value = va_arg (args, long long);
596 value = va_arg (args, ptrdiff_t);
599 value = va_arg (args, size_t);
613 printf_integer (abs_value, negative, "0123456789",
629 value = (unsigned char) va_arg (args, unsigned);
632 value = (unsigned short) va_arg (args, unsigned);
635 value = va_arg (args, unsigned);
638 value = va_arg (args, unsigned long);
641 value = va_arg (args, unsigned long long);
644 value = va_arg (args, ptrdiff_t);
647 value = va_arg (args, size_t);
659 digits = "0123456789";
662 digits = "0123456789abcdef";
665 digits = "0123456789ABCDEF";
671 printf_integer (value, false, digits, &c, output, aux);
677 char ch = va_arg (args, int);
678 printf_string (&ch, 1, &c, output, aux);
687 s = va_arg (args, char *);
691 if (c.precision >= 0)
693 const char *zero = memchr (s, '\0', c.precision);
697 length = c.precision;
702 printf_string (s, length, &c, output, aux);
708 void *p = va_arg (args, void *);
712 printf_integer ((uintptr_t) p,
713 false, "0123456789abcdef", &c,
716 printf_string ("(nil)", 5, &c, output, aux);
726 printf_core ("<<no %%%c in kernel>>", output, aux, *format);
730 printf_core ("<<no %%%c conversion>>", output, aux, *format);
737 hex_dump (const void *buffer, size_t size)
739 const size_t n_per_line = 16;
740 const uint8_t *p = buffer;
747 printk ("%08zx", ofs);
748 n = size >= n_per_line ? n_per_line : size;
749 for (i = 0; i < n; i++)
750 printk ("%c%02x", i == n / 2 ? '-' : ' ', (unsigned) p[i]);
751 for (; i < n_per_line; i++)
754 for (i = 0; i < n; i++)
755 printk ("%c", isprint (p[i]) ? p[i] : '.');
756 for (; i < n_per_line; i++)