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;
189 /* Breaks a string into tokens separated by DELIMITERS. The
190 first time this function is called, S should be the string to
191 tokenize, and in subsequent calls it must be a null pointer.
192 SAVE_PTR is the address of a `char *' variable used to keep
193 track of the tokenizer's position. The return value each time
194 is the next token in the string, or a null pointer if no
197 This function treats multiple adjacent delimiters as a single
198 delimiter. The returned tokens will never be length 0.
199 DELIMITERS may change from one call to the next within a
202 strtok_r() modifies the string S, changing delimiters to null
203 bytes. Thus, S must be a modifiable string.
207 char s[] = " String to tokenize. ";
208 char *token, *save_ptr;
210 for (token = strtok_r (s, " ", &save_ptr); token != NULL;
211 token = strtok_r (NULL, " ", &save_ptr))
212 printf ("'%s'\n", token);
221 strtok_r (char *s, const char *delimiters, char **save_ptr)
225 ASSERT (delimiters != NULL);
226 ASSERT (save_ptr != NULL);
228 /* If S is nonnull, start from it.
229 If S is null, start from saved position. */
234 /* Skip any DELIMITERS at our current position. */
235 while (strchr (delimiters, *s) != NULL)
237 /* strchr() will always return nonnull if we're searching
238 for a null byte, because every string contains a null
239 byte (at the end). */
249 /* Skip any non-DELIMITERS up to the end of the string. */
251 while (strchr (delimiters, *s) == NULL)
269 /* Skip white space. */
283 /* Parse digits. We always initially parse the value as
284 negative, and then make it positive later, because the
285 negative range of an int is bigger than the positive range
286 on a 2's complement system. */
287 for (value = 0; isdigit (*s); s++)
288 value = value * 10 - (*s - '0');
296 vprintf_core (const char *format, va_list args,
297 void (*output) (char, void *), void *aux);
300 vprintk_helper (char ch, void *aux UNUSED)
307 vprintk (const char *format, va_list args)
309 enum intr_level old_level = intr_disable ();
310 vprintf_core (format, args, vprintk_helper, NULL);
311 intr_set_level (old_level);
315 printk (const char *format, ...)
319 va_start (args, format);
320 vprintk (format, args);
332 vsnprintf_helper (char ch, void *aux_)
334 struct vsnprintf_aux *aux = aux_;
336 if (aux->length++ < aux->max_length)
341 vsnprintf (char *buffer, size_t buf_size,
342 const char *format, va_list args)
344 struct vsnprintf_aux aux;
347 aux.max_length = buf_size > 0 ? buf_size - 1 : 0;
349 vprintf_core (format, args, vsnprintf_helper, &aux);
358 snprintf (char *buffer, size_t buf_size,
359 const char *format, ...)
364 va_start (args, format);
365 retval = vsnprintf (buffer, buf_size, format, args);
371 /* printf() and friends internals. You do not need to understand
374 struct printf_conversion
405 parse_conversion (const char *format, struct printf_conversion *c,
408 /* Parse flag characters. */
438 if (c->flags & MINUS)
443 /* Parse field width. */
448 c->width = va_arg (*args, int);
452 for (; isdigit (*format); format++)
453 c->width = c->width * 10 + *format - '0';
457 c->width = -c->width;
461 /* Parse precision. */
469 c->precision = va_arg (*args, int);
474 for (; isdigit (*format); format++)
475 c->precision = c->precision * 10 + *format - '0';
477 if (c->precision < 0)
480 if (c->precision >= 0)
534 output_dup (char ch, size_t cnt, void (*output) (char, void *), void *aux)
541 printf_integer (uintmax_t value, bool negative, const char *digits,
542 struct printf_conversion *c,
543 void (*output) (char, void *), void *aux)
548 const char *base_name;
549 int pad_cnt, group_cnt;
551 base = strlen (digits);
553 /* Accumulate digits into buffer.
554 This algorithm produces digits in reverse order, so later we
555 will output the buffer's content in reverse. This is also
556 the reason that later we append zeros and the sign. */
561 if ((c->flags & GROUP) && group_cnt++ == 3)
566 *cp++ = digits[value % base];
570 /* Append enough zeros to match precision.
571 If precision is 0, then a value of zero is rendered as a
572 null string. Otherwise at least one digit is presented. */
573 if (c->precision < 0)
575 while (cp - buf < c->precision && cp - buf < (int) sizeof buf - 8)
580 *cp++ = negative ? '-' : '+';
581 else if (c->flags & SPACE)
582 *cp++ = negative ? '-' : ' ';
586 /* Get name of base. */
588 if (c->flags & POUND)
593 base_name = digits[0xa] == 'a' ? "0x" : "0X";
596 /* Calculate number of pad characters to fill field width. */
597 pad_cnt = c->width - (cp - buf) - strlen (base_name);
602 if ((c->flags & (MINUS | ZERO)) == 0)
603 output_dup (' ', pad_cnt, output, aux);
604 while (*base_name != '\0')
605 output (*base_name++, aux);
607 output_dup ('0', pad_cnt, output, aux);
610 if (c->flags & MINUS)
611 output_dup (' ', pad_cnt, output, aux);
615 printf_string (const char *string, size_t length,
616 struct printf_conversion *c,
617 void (*output) (char, void *), void *aux)
619 if (c->width > 1 && (c->flags & MINUS) == 0)
620 output_dup (' ', c->width - 1, output, aux);
622 output (*string++, aux);
623 if (c->width > 1 && (c->flags & MINUS) != 0)
624 output_dup (' ', c->width - 1, output, aux);
628 printf_core (const char *format,
629 void (*output) (char, void *), void *aux, ...)
633 va_start (args, aux);
634 vprintf_core (format, args, output, aux);
639 vprintf_core (const char *format, va_list args,
640 void (*output) (char, void *), void *aux)
642 for (; *format != '\0'; format++)
644 struct printf_conversion c;
646 /* Literally copy non-conversions to output. */
649 output (*format, aux);
661 format = parse_conversion (format, &c, &args);
669 bool negative = false;
674 value = (signed char) va_arg (args, int);
677 value = (short) va_arg (args, int);
680 value = va_arg (args, int);
683 value = va_arg (args, long);
686 value = va_arg (args, long long);
689 value = va_arg (args, ptrdiff_t);
692 value = va_arg (args, size_t);
706 printf_integer (abs_value, negative, "0123456789",
722 value = (unsigned char) va_arg (args, unsigned);
725 value = (unsigned short) va_arg (args, unsigned);
728 value = va_arg (args, unsigned);
731 value = va_arg (args, unsigned long);
734 value = va_arg (args, unsigned long long);
737 value = va_arg (args, ptrdiff_t);
740 value = va_arg (args, size_t);
752 digits = "0123456789";
755 digits = "0123456789abcdef";
758 digits = "0123456789ABCDEF";
764 printf_integer (value, false, digits, &c, output, aux);
770 char ch = va_arg (args, int);
771 printf_string (&ch, 1, &c, output, aux);
780 s = va_arg (args, char *);
784 if (c.precision >= 0)
786 const char *zero = memchr (s, '\0', c.precision);
790 length = c.precision;
795 printf_string (s, length, &c, output, aux);
801 void *p = va_arg (args, void *);
805 printf_integer ((uintptr_t) p,
806 false, "0123456789abcdef", &c,
809 printf_string ("(nil)", 5, &c, output, aux);
819 printf_core ("<<no %%%c in kernel>>", output, aux, *format);
823 printf_core ("<<no %%%c conversion>>", output, aux, *format);
830 hex_dump (const void *buffer, size_t size, bool ascii)
832 const size_t n_per_line = 16;
833 const uint8_t *p = buffer;
840 printk ("%08zx", ofs);
841 n = size >= n_per_line ? n_per_line : size;
842 for (i = 0; i < n; i++)
843 printk ("%c%02x", i == n_per_line / 2 ? '-' : ' ', (unsigned) p[i]);
847 for (; i < n_per_line; i++)
850 for (i = 0; i < n; i++)
851 printk ("%c", isprint (p[i]) ? p[i] : '.');
852 for (; i < n_per_line; i++)