11 /* Sets the SIZE bytes in DST to VALUE. */
13 memset (void *dst_, int value, size_t size)
15 unsigned char *dst = dst_;
17 ASSERT (dst != NULL || size == 0);
25 /* Copies SIZE bytes from SRC to DST, which must not overlap.
28 memcpy (void *dst_, const void *src_, size_t size)
30 unsigned char *dst = dst_;
31 const unsigned char *src = src_;
33 ASSERT (dst != NULL || size == 0);
34 ASSERT (src != NULL || size == 0);
42 /* Copies SIZE bytes from SRC to DST, which are allowed to
43 overlap. Returns DST. */
45 memmove (void *dst_, const void *src_, size_t size)
47 unsigned char *dst = dst_;
48 const unsigned char *src = src_;
50 ASSERT (dst != NULL || size == 0);
51 ASSERT (src != NULL || size == 0);
69 /* Returns a pointer to the first occurrence of CH in the first
70 SIZE bytes starting at BLOCK. Returns a null pointer if CH
71 does not occur in BLOCK. */
73 memchr (const void *block_, int ch_, size_t size)
75 const unsigned char *block = block_;
76 unsigned char ch = ch_;
78 ASSERT (block != NULL || size == 0);
80 for (; size-- > 0; block++)
82 return (void *) block;
87 /* Find the first differing byte in the two blocks of SIZE bytes
88 at A and B. Returns a positive value if the byte in A is
89 greater, a negative value if the byte in B is greater, or zero
90 if blocks A and B are equal. */
92 memcmp (const void *a_, const void *b_, size_t size)
94 const unsigned char *a = a_;
95 const unsigned char *b = b_;
97 ASSERT (a != NULL || size == 0);
98 ASSERT (b != NULL || size == 0);
100 for (; size-- > 0; a++, b++)
102 return *a > *b ? +1 : -1;
106 /* Copies string SRC to DST. If SRC is longer than SIZE - 1
107 characters, only SIZE - 1 characters are copied. A null
108 terminator is always written to DST, unless SIZE is 0.
109 Returns the length of SRC. */
111 strlcpy (char *dst, const char *src, size_t size)
115 ASSERT (dst != NULL);
116 ASSERT (src != NULL);
118 src_len = strlen (src);
121 size_t dst_len = size - 1;
122 if (src_len < dst_len)
124 memcpy (dst, src, dst_len);
130 /* Returns the length of STRING. */
132 strlen (const char *string)
136 ASSERT (string != NULL);
138 for (p = string; *p != '\0'; p++)
143 /* Finds and returns the first occurrence of C in STRING, or a
144 null pointer if C does not appear in STRING. If C == '\0'
145 then returns a pointer to the null terminator at the end of
148 strchr (const char *string, int c_)
152 ASSERT (string != NULL);
156 return (char *) string;
157 else if (*string == '\0')
163 /* Finds the first differing characters in strings A and B.
164 Returns a positive value if the character in A (as an unsigned
165 char) is greater, a negative value if the character in B (as
166 an unsigned char) is greater, or zero if strings A and B are
169 strcmp (const char *a_, const char *b_)
171 const unsigned char *a = (const unsigned char *) a_;
172 const unsigned char *b = (const unsigned char *) b_;
177 while (*a != '\0' && *a == *b)
183 return *a < *b ? -1 : *a > *b;
187 strtok_r (char *s, const char *delimiters, char **save_ptr)
191 ASSERT (delimiters != NULL);
192 ASSERT (save_ptr != NULL);
194 /* If S is nonnull, start from it.
195 If S is null, start from saved position. */
200 /* Skip any DELIMITERS at our current position. */
201 while (strchr (delimiters, *s) != NULL)
203 /* strchr() will always return nonnull if we're searching
204 for a null byte, because every string contains a null
205 byte (at the end). */
215 /* Skip any non-DELIMITERS up to the end of the string. */
217 while (strchr (delimiters, *s) == NULL)
235 /* Skip white space. */
249 /* Parse digits. We always initially parse the value as
250 negative, and then make it positive later, because the
251 negative range of an int is bigger than the positive range
252 on a 2's complement system. */
253 for (value = 0; isdigit (*s); s++)
254 value = value * 10 - (*s - '0');
262 vprintf_core (const char *format, va_list args,
263 void (*output) (char, void *), void *aux);
266 vprintk_helper (char ch, void *aux UNUSED)
273 vprintk (const char *format, va_list args)
275 enum intr_level old_level = intr_disable ();
276 vprintf_core (format, args, vprintk_helper, NULL);
277 intr_set_level (old_level);
281 printk (const char *format, ...)
285 va_start (args, format);
286 vprintk (format, args);
298 vsnprintf_helper (char ch, void *aux_)
300 struct vsnprintf_aux *aux = aux_;
302 if (aux->length++ < aux->max_length)
307 vsnprintf (char *buffer, size_t buf_size,
308 const char *format, va_list args)
310 struct vsnprintf_aux aux;
313 aux.max_length = buf_size > 0 ? buf_size - 1 : 0;
315 vprintf_core (format, args, vsnprintf_helper, &aux);
324 snprintf (char *buffer, size_t buf_size,
325 const char *format, ...)
330 va_start (args, format);
331 retval = vsnprintf (buffer, buf_size, format, args);
337 /* printf() and friends internals. You do not need to understand
340 struct printf_conversion
371 parse_conversion (const char *format, struct printf_conversion *c,
374 /* Parse flag characters. */
404 if (c->flags & MINUS)
409 /* Parse field width. */
414 c->width = va_arg (*args, int);
418 for (; isdigit (*format); format++)
419 c->width = c->width * 10 + *format - '0';
423 c->width = -c->width;
427 /* Parse precision. */
435 c->precision = va_arg (*args, int);
440 for (; isdigit (*format); format++)
441 c->precision = c->precision * 10 + *format - '0';
443 if (c->precision < 0)
446 if (c->precision >= 0)
500 output_dup (char ch, size_t cnt, void (*output) (char, void *), void *aux)
507 printf_integer (uintmax_t value, bool negative, const char *digits,
508 struct printf_conversion *c,
509 void (*output) (char, void *), void *aux)
514 const char *base_name;
515 int pad_cnt, group_cnt;
517 base = strlen (digits);
519 /* Accumulate digits into buffer.
520 This algorithm produces digits in reverse order, so later we
521 will output the buffer's content in reverse. This is also
522 the reason that later we append zeros and the sign. */
527 if ((c->flags & GROUP) && group_cnt++ == 3)
532 *cp++ = digits[value % base];
536 /* Append enough zeros to match precision.
537 If precision is 0, then a value of zero is rendered as a
538 null string. Otherwise at least one digit is presented. */
539 if (c->precision < 0)
541 while (cp - buf < c->precision && cp - buf < (int) sizeof buf - 8)
546 *cp++ = negative ? '-' : '+';
547 else if (c->flags & SPACE)
548 *cp++ = negative ? '-' : ' ';
552 /* Get name of base. */
554 if (c->flags & POUND)
559 base_name = digits[0xa] == 'a' ? "0x" : "0X";
562 /* Calculate number of pad characters to fill field width. */
563 pad_cnt = c->width - (cp - buf) - strlen (base_name);
568 if ((c->flags & (MINUS | ZERO)) == 0)
569 output_dup (' ', pad_cnt, output, aux);
570 while (*base_name != '\0')
571 output (*base_name++, aux);
573 output_dup ('0', pad_cnt, output, aux);
576 if (c->flags & MINUS)
577 output_dup (' ', pad_cnt, output, aux);
581 printf_string (const char *string, size_t length,
582 struct printf_conversion *c,
583 void (*output) (char, void *), void *aux)
585 if (c->width > 1 && (c->flags & MINUS) == 0)
586 output_dup (' ', c->width - 1, output, aux);
588 output (*string++, aux);
589 if (c->width > 1 && (c->flags & MINUS) != 0)
590 output_dup (' ', c->width - 1, output, aux);
594 printf_core (const char *format,
595 void (*output) (char, void *), void *aux, ...)
599 va_start (args, aux);
600 vprintf_core (format, args, output, aux);
605 vprintf_core (const char *format, va_list args,
606 void (*output) (char, void *), void *aux)
608 for (; *format != '\0'; format++)
610 struct printf_conversion c;
612 /* Literally copy non-conversions to output. */
615 output (*format, aux);
627 format = parse_conversion (format, &c, &args);
635 bool negative = false;
640 value = (signed char) va_arg (args, int);
643 value = (short) va_arg (args, int);
646 value = va_arg (args, int);
649 value = va_arg (args, long);
652 value = va_arg (args, long long);
655 value = va_arg (args, ptrdiff_t);
658 value = va_arg (args, size_t);
672 printf_integer (abs_value, negative, "0123456789",
688 value = (unsigned char) va_arg (args, unsigned);
691 value = (unsigned short) va_arg (args, unsigned);
694 value = va_arg (args, unsigned);
697 value = va_arg (args, unsigned long);
700 value = va_arg (args, unsigned long long);
703 value = va_arg (args, ptrdiff_t);
706 value = va_arg (args, size_t);
718 digits = "0123456789";
721 digits = "0123456789abcdef";
724 digits = "0123456789ABCDEF";
730 printf_integer (value, false, digits, &c, output, aux);
736 char ch = va_arg (args, int);
737 printf_string (&ch, 1, &c, output, aux);
746 s = va_arg (args, char *);
750 if (c.precision >= 0)
752 const char *zero = memchr (s, '\0', c.precision);
756 length = c.precision;
761 printf_string (s, length, &c, output, aux);
767 void *p = va_arg (args, void *);
771 printf_integer ((uintptr_t) p,
772 false, "0123456789abcdef", &c,
775 printf_string ("(nil)", 5, &c, output, aux);
785 printf_core ("<<no %%%c in kernel>>", output, aux, *format);
789 printf_core ("<<no %%%c conversion>>", output, aux, *format);
796 hex_dump (const void *buffer, size_t size, bool ascii)
798 const size_t n_per_line = 16;
799 const uint8_t *p = buffer;
806 printk ("%08zx", ofs);
807 n = size >= n_per_line ? n_per_line : size;
808 for (i = 0; i < n; i++)
809 printk ("%c%02x", i == n_per_line / 2 ? '-' : ' ', (unsigned) p[i]);
813 for (; i < n_per_line; i++)
816 for (i = 0; i < n; i++)
817 printk ("%c", isprint (p[i]) ? p[i] : '.');
818 for (; i < n_per_line; i++)