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 See http://www.courtesan.com/todd/papers/strlcpy.html for
112 information on strlcpy(). */
114 strlcpy (char *dst, const char *src, size_t size)
118 ASSERT (dst != NULL);
119 ASSERT (src != NULL);
121 src_len = strlen (src);
124 size_t dst_len = size - 1;
125 if (src_len < dst_len)
127 memcpy (dst, src, dst_len);
133 /* Returns the length of STRING. */
135 strlen (const char *string)
139 ASSERT (string != NULL);
141 for (p = string; *p != '\0'; p++)
146 /* Finds and returns the first occurrence of C in STRING, or a
147 null pointer if C does not appear in STRING. If C == '\0'
148 then returns a pointer to the null terminator at the end of
151 strchr (const char *string, int c_)
155 ASSERT (string != NULL);
159 return (char *) string;
160 else if (*string == '\0')
166 /* Finds the first differing characters in strings A and B.
167 Returns a positive value if the character in A (as an unsigned
168 char) is greater, a negative value if the character in B (as
169 an unsigned char) is greater, or zero if strings A and B are
172 strcmp (const char *a_, const char *b_)
174 const unsigned char *a = (const unsigned char *) a_;
175 const unsigned char *b = (const unsigned char *) b_;
180 while (*a != '\0' && *a == *b)
186 return *a < *b ? -1 : *a > *b;
190 strtok_r (char *s, const char *delimiters, char **save_ptr)
194 ASSERT (delimiters != NULL);
195 ASSERT (save_ptr != NULL);
197 /* If S is nonnull, start from it.
198 If S is null, start from saved position. */
203 /* Skip any DELIMITERS at our current position. */
204 while (strchr (delimiters, *s) != NULL)
206 /* strchr() will always return nonnull if we're searching
207 for a null byte, because every string contains a null
208 byte (at the end). */
218 /* Skip any non-DELIMITERS up to the end of the string. */
220 while (strchr (delimiters, *s) == NULL)
238 /* Skip white space. */
252 /* Parse digits. We always initially parse the value as
253 negative, and then make it positive later, because the
254 negative range of an int is bigger than the positive range
255 on a 2's complement system. */
256 for (value = 0; isdigit (*s); s++)
257 value = value * 10 - (*s - '0');
265 vprintf_core (const char *format, va_list args,
266 void (*output) (char, void *), void *aux);
269 vprintk_helper (char ch, void *aux UNUSED)
276 vprintk (const char *format, va_list args)
278 enum intr_level old_level = intr_disable ();
279 vprintf_core (format, args, vprintk_helper, NULL);
280 intr_set_level (old_level);
284 printk (const char *format, ...)
288 va_start (args, format);
289 vprintk (format, args);
301 vsnprintf_helper (char ch, void *aux_)
303 struct vsnprintf_aux *aux = aux_;
305 if (aux->length++ < aux->max_length)
310 vsnprintf (char *buffer, size_t buf_size,
311 const char *format, va_list args)
313 struct vsnprintf_aux aux;
316 aux.max_length = buf_size > 0 ? buf_size - 1 : 0;
318 vprintf_core (format, args, vsnprintf_helper, &aux);
327 snprintf (char *buffer, size_t buf_size,
328 const char *format, ...)
333 va_start (args, format);
334 retval = vsnprintf (buffer, buf_size, format, args);
340 /* printf() and friends internals. You do not need to understand
343 struct printf_conversion
374 parse_conversion (const char *format, struct printf_conversion *c,
377 /* Parse flag characters. */
407 if (c->flags & MINUS)
412 /* Parse field width. */
417 c->width = va_arg (*args, int);
421 for (; isdigit (*format); format++)
422 c->width = c->width * 10 + *format - '0';
426 c->width = -c->width;
430 /* Parse precision. */
438 c->precision = va_arg (*args, int);
443 for (; isdigit (*format); format++)
444 c->precision = c->precision * 10 + *format - '0';
446 if (c->precision < 0)
449 if (c->precision >= 0)
503 output_dup (char ch, size_t cnt, void (*output) (char, void *), void *aux)
510 printf_integer (uintmax_t value, bool negative, const char *digits,
511 struct printf_conversion *c,
512 void (*output) (char, void *), void *aux)
517 const char *base_name;
518 int pad_cnt, group_cnt;
520 base = strlen (digits);
522 /* Accumulate digits into buffer.
523 This algorithm produces digits in reverse order, so later we
524 will output the buffer's content in reverse. This is also
525 the reason that later we append zeros and the sign. */
530 if ((c->flags & GROUP) && group_cnt++ == 3)
535 *cp++ = digits[value % base];
539 /* Append enough zeros to match precision.
540 If precision is 0, then a value of zero is rendered as a
541 null string. Otherwise at least one digit is presented. */
542 if (c->precision < 0)
544 while (cp - buf < c->precision && cp - buf < (int) sizeof buf - 8)
549 *cp++ = negative ? '-' : '+';
550 else if (c->flags & SPACE)
551 *cp++ = negative ? '-' : ' ';
555 /* Get name of base. */
557 if (c->flags & POUND)
562 base_name = digits[0xa] == 'a' ? "0x" : "0X";
565 /* Calculate number of pad characters to fill field width. */
566 pad_cnt = c->width - (cp - buf) - strlen (base_name);
571 if ((c->flags & (MINUS | ZERO)) == 0)
572 output_dup (' ', pad_cnt, output, aux);
573 while (*base_name != '\0')
574 output (*base_name++, aux);
576 output_dup ('0', pad_cnt, output, aux);
579 if (c->flags & MINUS)
580 output_dup (' ', pad_cnt, output, aux);
584 printf_string (const char *string, size_t length,
585 struct printf_conversion *c,
586 void (*output) (char, void *), void *aux)
588 if (c->width > 1 && (c->flags & MINUS) == 0)
589 output_dup (' ', c->width - 1, output, aux);
591 output (*string++, aux);
592 if (c->width > 1 && (c->flags & MINUS) != 0)
593 output_dup (' ', c->width - 1, output, aux);
597 printf_core (const char *format,
598 void (*output) (char, void *), void *aux, ...)
602 va_start (args, aux);
603 vprintf_core (format, args, output, aux);
608 vprintf_core (const char *format, va_list args,
609 void (*output) (char, void *), void *aux)
611 for (; *format != '\0'; format++)
613 struct printf_conversion c;
615 /* Literally copy non-conversions to output. */
618 output (*format, aux);
630 format = parse_conversion (format, &c, &args);
638 bool negative = false;
643 value = (signed char) va_arg (args, int);
646 value = (short) va_arg (args, int);
649 value = va_arg (args, int);
652 value = va_arg (args, long);
655 value = va_arg (args, long long);
658 value = va_arg (args, ptrdiff_t);
661 value = va_arg (args, size_t);
675 printf_integer (abs_value, negative, "0123456789",
691 value = (unsigned char) va_arg (args, unsigned);
694 value = (unsigned short) va_arg (args, unsigned);
697 value = va_arg (args, unsigned);
700 value = va_arg (args, unsigned long);
703 value = va_arg (args, unsigned long long);
706 value = va_arg (args, ptrdiff_t);
709 value = va_arg (args, size_t);
721 digits = "0123456789";
724 digits = "0123456789abcdef";
727 digits = "0123456789ABCDEF";
733 printf_integer (value, false, digits, &c, output, aux);
739 char ch = va_arg (args, int);
740 printf_string (&ch, 1, &c, output, aux);
749 s = va_arg (args, char *);
753 if (c.precision >= 0)
755 const char *zero = memchr (s, '\0', c.precision);
759 length = c.precision;
764 printf_string (s, length, &c, output, aux);
770 void *p = va_arg (args, void *);
774 printf_integer ((uintptr_t) p,
775 false, "0123456789abcdef", &c,
778 printf_string ("(nil)", 5, &c, output, aux);
788 printf_core ("<<no %%%c in kernel>>", output, aux, *format);
792 printf_core ("<<no %%%c conversion>>", output, aux, *format);
799 hex_dump (const void *buffer, size_t size, bool ascii)
801 const size_t n_per_line = 16;
802 const uint8_t *p = buffer;
809 printk ("%08zx", ofs);
810 n = size >= n_per_line ? n_per_line : size;
811 for (i = 0; i < n; i++)
812 printk ("%c%02x", i == n_per_line / 2 ? '-' : ' ', (unsigned) p[i]);
816 for (; i < n_per_line; i++)
819 for (i = 0; i < n; i++)
820 printk ("%c", isprint (p[i]) ? p[i] : '.');
821 for (; i < n_per_line; i++)