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 output_console (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, output_console, NULL);
134 intr_set_level (old_level);
138 printk (const char *format, ...)
142 va_start (args, format);
143 vprintk (format, args);
147 /* printf() and friends internals. You do not need to understand
150 struct printf_conversion
180 parse_conversion (const char *format, struct printf_conversion *c, va_list *args)
182 /* Parse flag characters. */
209 if (c->flags & MINUS)
214 /* Parse field width. */
219 c->width = va_arg (*args, int);
223 for (; isdigit (*format); format++)
224 c->width = c->width * 10 + *format - '0';
228 c->width = -c->width;
232 /* Parse precision. */
240 c->precision = va_arg (*args, int);
245 for (; isdigit (*format); format++)
246 c->precision = c->precision * 10 + *format - '0';
248 if (c->precision < 0)
251 if (c->precision >= 0)
305 output_dup (char ch, size_t cnt, void (*output) (char, void *), void *aux)
312 printf_integer (uintmax_t value, bool negative, const char *digits,
313 struct printf_conversion *c,
314 void (*output) (char, void *), void *aux)
319 const char *base_name;
322 base = strlen (digits);
324 /* Accumulate digits into buffer.
325 This algorithm produces digits in reverse order, so we count
326 backward from the end of the array. */
330 *cp++ = digits[value % base];
334 /* Prepend enough zeros to match precision.
335 If precision is 0, then a value of zero is rendered as a
336 null string. Otherwise at least one digit is presented. */
337 if (c->precision < 0)
339 while (cp - buf < c->precision && cp - buf > (int) sizeof buf - 8)
344 *cp++ = negative ? '-' : '+';
345 else if (c->flags & SPACE)
346 *cp++ = negative ? '-' : ' ';
350 /* Get name of base. */
352 if (c->flags & POUND)
357 base_name = digits[0xa] == 'a' ? "0x" : "0X";
360 /* Calculate number of pad characters to fill field width. */
361 pad_cnt = c->width - (cp - buf) - strlen (base_name);
366 if ((c->flags & (MINUS | ZERO)) == 0)
367 output_dup (' ', pad_cnt, output, aux);
368 while (*base_name != '\0')
369 output (*base_name++, aux);
371 output_dup ('0', pad_cnt, output, aux);
374 if (c->flags & MINUS)
375 output_dup (' ', pad_cnt, output, aux);
379 printf_string (const char *string, size_t length,
380 struct printf_conversion *c,
381 void (*output) (char, void *), void *aux)
383 if (c->width > 1 && (c->flags & MINUS) == 0)
384 output_dup (' ', c->width - 1, output, aux);
386 output (*string++, aux);
387 if (c->width > 1 && (c->flags & MINUS) != 0)
388 output_dup (' ', c->width - 1, output, aux);
392 printf_core (const char *format,
393 void (*output) (char, void *), void *aux, ...)
397 va_start (args, aux);
398 vprintf_core (format, args, output, aux);
403 vprintf_core (const char *format, va_list args,
404 void (*output) (char, void *), void *aux)
406 for (; *format != '\0'; format++)
408 struct printf_conversion c;
410 /* Literally copy non-conversions to output. */
413 output (*format, aux);
425 format = parse_conversion (format, &c, &args);
433 bool negative = false;
438 value = (signed char) va_arg (args, int);
441 value = (short) va_arg (args, int);
444 value = va_arg (args, int);
447 value = va_arg (args, long);
450 value = va_arg (args, long long);
453 value = va_arg (args, ptrdiff_t);
456 value = va_arg (args, size_t);
470 printf_integer (abs_value, negative, "0123456789",
486 value = (unsigned char) va_arg (args, unsigned);
489 value = (unsigned short) va_arg (args, unsigned);
492 value = va_arg (args, unsigned);
495 value = va_arg (args, unsigned long);
498 value = va_arg (args, unsigned long long);
501 value = va_arg (args, ptrdiff_t);
504 value = va_arg (args, size_t);
516 digits = "0123456789";
519 digits = "0123456789abcdef";
522 digits = "0123456789ABCDEF";
528 printf_integer (value, false, digits, &c, output, aux);
534 char ch = va_arg (args, int);
535 printf_string (&ch, 1, &c, output, aux);
544 s = va_arg (args, char *);
548 if (c.precision >= 0)
550 const char *zero = memchr (s, '\0', c.precision);
554 length = c.precision;
559 printf_string (s, length, &c, output, aux);
565 void *p = va_arg (args, void *);
569 printf_integer ((uintptr_t) p,
570 false, "0123456789abcdef", &c,
573 printf_string ("(nil)", 5, &c, output, aux);
583 printf_core ("<<no %%%c in kernel>>", output, aux, *format);
587 printf_core ("<<no %%%c conversion>>", output, aux, *format);