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)
208 /* Skip white space. */
222 /* Parse digits. We always initially parse the value as
223 negative, and then make it positive later, because the
224 negative range of an int is bigger than the positive range
225 on a 2's complement system. */
226 for (value = 0; isdigit (*s); s++)
227 value = value * 10 - (*s - '0');
235 vprintf_core (const char *format, va_list args,
236 void (*output) (char, void *), void *aux);
239 vprintk_helper (char ch, void *aux UNUSED)
246 vprintk (const char *format, va_list args)
248 enum intr_level old_level = intr_disable ();
249 vprintf_core (format, args, vprintk_helper, NULL);
250 intr_set_level (old_level);
254 printk (const char *format, ...)
258 va_start (args, format);
259 vprintk (format, args);
271 vsnprintf_helper (char ch, void *aux_)
273 struct vsnprintf_aux *aux = aux_;
275 if (aux->length++ < aux->max_length)
280 vsnprintf (char *buffer, size_t buf_size,
281 const char *format, va_list args)
283 struct vsnprintf_aux aux;
286 aux.max_length = buf_size > 0 ? buf_size - 1 : 0;
288 vprintf_core (format, args, vsnprintf_helper, &aux);
297 snprintf (char *buffer, size_t buf_size,
298 const char *format, ...)
303 va_start (args, format);
304 retval = vsnprintf (buffer, buf_size, format, args);
310 /* printf() and friends internals. You do not need to understand
313 struct printf_conversion
344 parse_conversion (const char *format, struct printf_conversion *c,
347 /* Parse flag characters. */
377 if (c->flags & MINUS)
382 /* Parse field width. */
387 c->width = va_arg (*args, int);
391 for (; isdigit (*format); format++)
392 c->width = c->width * 10 + *format - '0';
396 c->width = -c->width;
400 /* Parse precision. */
408 c->precision = va_arg (*args, int);
413 for (; isdigit (*format); format++)
414 c->precision = c->precision * 10 + *format - '0';
416 if (c->precision < 0)
419 if (c->precision >= 0)
473 output_dup (char ch, size_t cnt, void (*output) (char, void *), void *aux)
480 printf_integer (uintmax_t value, bool negative, const char *digits,
481 struct printf_conversion *c,
482 void (*output) (char, void *), void *aux)
487 const char *base_name;
488 int pad_cnt, group_cnt;
490 base = strlen (digits);
492 /* Accumulate digits into buffer.
493 This algorithm produces digits in reverse order, so later we
494 will output the buffer's content in reverse. This is also
495 the reason that later we append zeros and the sign. */
500 if ((c->flags & GROUP) && group_cnt++ == 3)
505 *cp++ = digits[value % base];
509 /* Append enough zeros to match precision.
510 If precision is 0, then a value of zero is rendered as a
511 null string. Otherwise at least one digit is presented. */
512 if (c->precision < 0)
514 while (cp - buf < c->precision && cp - buf < (int) sizeof buf - 8)
519 *cp++ = negative ? '-' : '+';
520 else if (c->flags & SPACE)
521 *cp++ = negative ? '-' : ' ';
525 /* Get name of base. */
527 if (c->flags & POUND)
532 base_name = digits[0xa] == 'a' ? "0x" : "0X";
535 /* Calculate number of pad characters to fill field width. */
536 pad_cnt = c->width - (cp - buf) - strlen (base_name);
541 if ((c->flags & (MINUS | ZERO)) == 0)
542 output_dup (' ', pad_cnt, output, aux);
543 while (*base_name != '\0')
544 output (*base_name++, aux);
546 output_dup ('0', pad_cnt, output, aux);
549 if (c->flags & MINUS)
550 output_dup (' ', pad_cnt, output, aux);
554 printf_string (const char *string, size_t length,
555 struct printf_conversion *c,
556 void (*output) (char, void *), void *aux)
558 if (c->width > 1 && (c->flags & MINUS) == 0)
559 output_dup (' ', c->width - 1, output, aux);
561 output (*string++, aux);
562 if (c->width > 1 && (c->flags & MINUS) != 0)
563 output_dup (' ', c->width - 1, output, aux);
567 printf_core (const char *format,
568 void (*output) (char, void *), void *aux, ...)
572 va_start (args, aux);
573 vprintf_core (format, args, output, aux);
578 vprintf_core (const char *format, va_list args,
579 void (*output) (char, void *), void *aux)
581 for (; *format != '\0'; format++)
583 struct printf_conversion c;
585 /* Literally copy non-conversions to output. */
588 output (*format, aux);
600 format = parse_conversion (format, &c, &args);
608 bool negative = false;
613 value = (signed char) va_arg (args, int);
616 value = (short) va_arg (args, int);
619 value = va_arg (args, int);
622 value = va_arg (args, long);
625 value = va_arg (args, long long);
628 value = va_arg (args, ptrdiff_t);
631 value = va_arg (args, size_t);
645 printf_integer (abs_value, negative, "0123456789",
661 value = (unsigned char) va_arg (args, unsigned);
664 value = (unsigned short) va_arg (args, unsigned);
667 value = va_arg (args, unsigned);
670 value = va_arg (args, unsigned long);
673 value = va_arg (args, unsigned long long);
676 value = va_arg (args, ptrdiff_t);
679 value = va_arg (args, size_t);
691 digits = "0123456789";
694 digits = "0123456789abcdef";
697 digits = "0123456789ABCDEF";
703 printf_integer (value, false, digits, &c, output, aux);
709 char ch = va_arg (args, int);
710 printf_string (&ch, 1, &c, output, aux);
719 s = va_arg (args, char *);
723 if (c.precision >= 0)
725 const char *zero = memchr (s, '\0', c.precision);
729 length = c.precision;
734 printf_string (s, length, &c, output, aux);
740 void *p = va_arg (args, void *);
744 printf_integer ((uintptr_t) p,
745 false, "0123456789abcdef", &c,
748 printf_string ("(nil)", 5, &c, output, aux);
758 printf_core ("<<no %%%c in kernel>>", output, aux, *format);
762 printf_core ("<<no %%%c conversion>>", output, aux, *format);
769 hex_dump (const void *buffer, size_t size, bool ascii)
771 const size_t n_per_line = 16;
772 const uint8_t *p = buffer;
779 printk ("%08zx", ofs);
780 n = size >= n_per_line ? n_per_line : size;
781 for (i = 0; i < n; i++)
782 printk ("%c%02x", i == n_per_line / 2 ? '-' : ' ', (unsigned) p[i]);
786 for (; i < n_per_line; i++)
789 for (i = 0; i < n; i++)
790 printk ("%c", isprint (p[i]) ? p[i] : '.');
791 for (; i < n_per_line; i++)