12 memset (void *dst_, int value, size_t cnt)
14 unsigned char *dst = dst_;
23 memcpy (void *dst_, const void *src_, size_t cnt)
25 unsigned char *dst = dst_;
26 const unsigned char *src = src_;
35 memmove (void *dst_, const void *src_, size_t cnt)
37 unsigned char *dst = dst_;
38 const unsigned char *src = src_;
57 memchr (const void *block_, int ch_, size_t size)
59 const unsigned char *block = block_;
60 unsigned char ch = ch_;
62 for (; size-- > 0; block++)
64 return (void *) block;
70 memcmp (const void *a_, const void *b_, size_t size)
72 const unsigned char *a = a_;
73 const unsigned char *b = b_;
75 for (; size-- > 0; a++, b++)
77 return *a > *b ? +1 : -1;
82 strlcpy (char *dst, const char *src, size_t size)
84 size_t src_len = strlen (src);
87 size_t dst_len_max = size - 1;
88 size_t dst_len = src_len < dst_len_max ? src_len : dst_len_max;
89 memcpy (dst, src, dst_len);
96 strlen (const char *string)
100 for (p = string; *p != '\0'; p++)
106 strchr (const char *string, int c_)
112 return (char *) string;
113 else if (*string == '\0')
119 vprintf_core (const char *format, va_list args,
120 void (*output) (char, void *), void *aux);
123 vprintk_helper (char ch, void *aux __attribute__ ((unused)))
130 vprintk (const char *format, va_list args)
132 enum if_level old_level = intr_disable ();
133 vprintf_core (format, args, vprintk_helper, NULL);
134 intr_set_level (old_level);
138 printk (const char *format, ...)
142 va_start (args, format);
143 vprintk (format, args);
155 vsnprintf_helper (char ch, void *aux_)
157 struct vsnprintf_aux *aux = aux_;
159 if (aux->length++ < aux->max_length)
164 vsnprintf (char *buffer, size_t buf_size,
165 const char *format, va_list args)
167 struct vsnprintf_aux aux;
170 aux.max_length = buf_size > 0 ? buf_size - 1 : 0;
172 vprintf_core (format, args, vsnprintf_helper, &aux);
181 snprintf (char *buffer, size_t buf_size,
182 const char *format, ...)
187 va_start (args, format);
188 retval = vsnprintf (buffer, buf_size, format, args);
194 /* printf() and friends internals. You do not need to understand
197 struct printf_conversion
228 parse_conversion (const char *format, struct printf_conversion *c,
231 /* Parse flag characters. */
261 if (c->flags & MINUS)
266 /* Parse field width. */
271 c->width = va_arg (*args, int);
275 for (; isdigit (*format); format++)
276 c->width = c->width * 10 + *format - '0';
280 c->width = -c->width;
284 /* Parse precision. */
292 c->precision = va_arg (*args, int);
297 for (; isdigit (*format); format++)
298 c->precision = c->precision * 10 + *format - '0';
300 if (c->precision < 0)
303 if (c->precision >= 0)
357 output_dup (char ch, size_t cnt, void (*output) (char, void *), void *aux)
364 printf_integer (uintmax_t value, bool negative, const char *digits,
365 struct printf_conversion *c,
366 void (*output) (char, void *), void *aux)
371 const char *base_name;
374 base = strlen (digits);
376 /* Accumulate digits into buffer.
377 This algorithm produces digits in reverse order, so later we
378 will output the buffer's content in reverse. This is also
379 the reason that later we append zeros and the sign. */
383 if ((c->flags & GROUP) && cp > buf && (cp - buf) % 3 == 0)
385 *cp++ = digits[value % base];
389 /* Append enough zeros to match precision.
390 If precision is 0, then a value of zero is rendered as a
391 null string. Otherwise at least one digit is presented. */
392 if (c->precision < 0)
394 while (cp - buf < c->precision && cp - buf < (int) sizeof buf - 8)
399 *cp++ = negative ? '-' : '+';
400 else if (c->flags & SPACE)
401 *cp++ = negative ? '-' : ' ';
405 /* Get name of base. */
407 if (c->flags & POUND)
412 base_name = digits[0xa] == 'a' ? "0x" : "0X";
415 /* Calculate number of pad characters to fill field width. */
416 pad_cnt = c->width - (cp - buf) - strlen (base_name);
421 if ((c->flags & (MINUS | ZERO)) == 0)
422 output_dup (' ', pad_cnt, output, aux);
423 while (*base_name != '\0')
424 output (*base_name++, aux);
426 output_dup ('0', pad_cnt, output, aux);
429 if (c->flags & MINUS)
430 output_dup (' ', pad_cnt, output, aux);
434 printf_string (const char *string, size_t length,
435 struct printf_conversion *c,
436 void (*output) (char, void *), void *aux)
438 if (c->width > 1 && (c->flags & MINUS) == 0)
439 output_dup (' ', c->width - 1, output, aux);
441 output (*string++, aux);
442 if (c->width > 1 && (c->flags & MINUS) != 0)
443 output_dup (' ', c->width - 1, output, aux);
447 printf_core (const char *format,
448 void (*output) (char, void *), void *aux, ...)
452 va_start (args, aux);
453 vprintf_core (format, args, output, aux);
458 vprintf_core (const char *format, va_list args,
459 void (*output) (char, void *), void *aux)
461 for (; *format != '\0'; format++)
463 struct printf_conversion c;
465 /* Literally copy non-conversions to output. */
468 output (*format, aux);
480 format = parse_conversion (format, &c, &args);
488 bool negative = false;
493 value = (signed char) va_arg (args, int);
496 value = (short) va_arg (args, int);
499 value = va_arg (args, int);
502 value = va_arg (args, long);
505 value = va_arg (args, long long);
508 value = va_arg (args, ptrdiff_t);
511 value = va_arg (args, size_t);
525 printf_integer (abs_value, negative, "0123456789",
541 value = (unsigned char) va_arg (args, unsigned);
544 value = (unsigned short) va_arg (args, unsigned);
547 value = va_arg (args, unsigned);
550 value = va_arg (args, unsigned long);
553 value = va_arg (args, unsigned long long);
556 value = va_arg (args, ptrdiff_t);
559 value = va_arg (args, size_t);
571 digits = "0123456789";
574 digits = "0123456789abcdef";
577 digits = "0123456789ABCDEF";
583 printf_integer (value, false, digits, &c, output, aux);
589 char ch = va_arg (args, int);
590 printf_string (&ch, 1, &c, output, aux);
599 s = va_arg (args, char *);
603 if (c.precision >= 0)
605 const char *zero = memchr (s, '\0', c.precision);
609 length = c.precision;
614 printf_string (s, length, &c, output, aux);
620 void *p = va_arg (args, void *);
624 printf_integer ((uintptr_t) p,
625 false, "0123456789abcdef", &c,
628 printf_string ("(nil)", 5, &c, output, aux);
638 printf_core ("<<no %%%c in kernel>>", output, aux, *format);
642 printf_core ("<<no %%%c conversion>>", output, aux, *format);
649 hex_dump (const void *buffer, size_t size)
651 const size_t n_per_line = 16;
652 const uint8_t *p = buffer;
659 printk ("%08zx", ofs);
660 n = size >= n_per_line ? n_per_line : size;
661 for (i = 0; i < n; i++)
662 printk ("%c%02x", i == n / 2 ? '-' : ' ', (unsigned) p[i]);
663 for (; i < n_per_line; i++)
666 for (i = 0; i < n; i++)
667 printk ("%c", isprint (p[i]) ? p[i] : '.');
668 for (; i < n_per_line; i++)