11 memset (void *dst_, int value, size_t cnt)
13 unsigned char *dst = dst_;
22 memcpy (void *dst_, const void *src_, size_t cnt)
24 unsigned char *dst = dst_;
25 const unsigned char *src = src_;
34 memmove (void *dst_, const void *src_, size_t cnt)
36 unsigned char *dst = dst_;
37 const unsigned char *src = src_;
56 memchr (const void *block_, int ch_, size_t size)
58 const unsigned char *block = block_;
59 unsigned char ch = ch_;
61 for (; size-- > 0; block++)
63 return (void *) block;
69 memcmp (const void *a_, const void *b_, size_t size)
71 const unsigned char *a = a_;
72 const unsigned char *b = b_;
74 for (; size-- > 0; a++, b++)
76 return *a > *b ? +1 : -1;
81 strlcpy (char *dst, const char *src, size_t size)
83 size_t src_len = strlen (src);
86 size_t dst_len_max = size - 1;
87 size_t dst_len = src_len < dst_len_max ? src_len : dst_len_max;
88 memcpy (dst, src, dst_len);
95 strlen (const char *string)
99 for (p = string; *p != '\0'; p++)
105 strchr (const char *string, int c_)
111 return (char *) string;
112 else if (*string == '\0')
118 vprintf_core (const char *format, va_list args,
119 void (*output) (char, void *), void *aux);
122 output_console (char ch, void *aux __attribute__ ((unused)))
129 vprintk (const char *format, va_list args)
131 vprintf_core (format, args, output_console, NULL);
135 printk (const char *format, ...)
139 va_start (args, format);
140 vprintk (format, args);
144 /* printf() and friends internals. You do not need to understand
147 struct printf_conversion
177 parse_conversion (const char *format, struct printf_conversion *c, va_list *args)
179 /* Parse flag characters. */
206 if (c->flags & MINUS)
211 /* Parse field width. */
216 c->width = va_arg (*args, int);
220 for (; isdigit (*format); format++)
221 c->width = c->width * 10 + *format - '0';
225 c->width = -c->width;
229 /* Parse precision. */
237 c->precision = va_arg (*args, int);
242 for (; isdigit (*format); format++)
243 c->precision = c->precision * 10 + *format - '0';
245 if (c->precision < 0)
248 if (c->precision >= 0)
302 output_dup (char ch, size_t cnt, void (*output) (char, void *), void *aux)
309 printf_integer (uintmax_t value, bool negative, const char *digits,
310 struct printf_conversion *c,
311 void (*output) (char, void *), void *aux)
316 const char *base_name;
319 base = strlen (digits);
321 /* Accumulate digits into buffer.
322 This algorithm produces digits in reverse order, so we count
323 backward from the end of the array. */
327 *cp++ = digits[value % base];
331 /* Prepend enough zeros to match precision.
332 If precision is 0, then a value of zero is rendered as a
333 null string. Otherwise at least one digit is presented. */
334 if (c->precision < 0)
336 while (cp - buf < c->precision && cp - buf > (int) sizeof buf - 8)
341 *cp++ = negative ? '-' : '+';
342 else if (c->flags & SPACE)
343 *cp++ = negative ? '-' : ' ';
347 /* Get name of base. */
349 if (c->flags & POUND)
354 base_name = digits[0xa] == 'a' ? "0x" : "0X";
357 /* Calculate number of pad characters to fill field width. */
358 pad_cnt = c->width - (cp - buf) - strlen (base_name);
363 if ((c->flags & (MINUS | ZERO)) == 0)
364 output_dup (' ', pad_cnt, output, aux);
365 while (*base_name != '\0')
366 output (*base_name++, aux);
368 output_dup ('0', pad_cnt, output, aux);
371 if (c->flags & MINUS)
372 output_dup (' ', pad_cnt, output, aux);
376 printf_string (const char *string, size_t length,
377 struct printf_conversion *c,
378 void (*output) (char, void *), void *aux)
380 if (c->width > 1 && (c->flags & MINUS) == 0)
381 output_dup (' ', c->width - 1, output, aux);
383 output (*string++, aux);
384 if (c->width > 1 && (c->flags & MINUS) != 0)
385 output_dup (' ', c->width - 1, output, aux);
389 printf_core (const char *format,
390 void (*output) (char, void *), void *aux, ...)
394 va_start (args, aux);
395 vprintf_core (format, args, output, aux);
400 vprintf_core (const char *format, va_list args,
401 void (*output) (char, void *), void *aux)
403 for (; *format != '\0'; format++)
405 struct printf_conversion c;
407 /* Literally copy non-conversions to output. */
410 output (*format, aux);
422 format = parse_conversion (format, &c, &args);
430 bool negative = false;
435 value = (signed char) va_arg (args, int);
438 value = (short) va_arg (args, int);
441 value = va_arg (args, int);
444 value = va_arg (args, long);
447 value = va_arg (args, long long);
450 value = va_arg (args, ptrdiff_t);
453 value = va_arg (args, size_t);
467 printf_integer (abs_value, negative, "0123456789",
483 value = (unsigned char) va_arg (args, unsigned);
486 value = (unsigned short) va_arg (args, unsigned);
489 value = va_arg (args, unsigned);
492 value = va_arg (args, unsigned long);
495 value = va_arg (args, unsigned long long);
498 value = va_arg (args, ptrdiff_t);
501 value = va_arg (args, size_t);
513 digits = "0123456789";
516 digits = "0123456789abcdef";
519 digits = "0123456789ABCDEF";
525 printf_integer (value, false, digits, &c, output, aux);
531 char ch = va_arg (args, int);
532 printf_string (&ch, 1, &c, output, aux);
541 s = va_arg (args, char *);
545 if (c.precision >= 0)
547 const char *zero = memchr (s, '\0', c.precision);
551 length = c.precision;
556 printf_string (s, length, &c, output, aux);
562 void *p = va_arg (args, void *);
566 printf_integer ((uintptr_t) p,
567 false, "0123456789abcdef", &c,
570 printf_string ("(nil)", 5, &c, output, aux);
580 printf_core ("<<no %%%c in kernel>>", output, aux, *format);
584 printf_core ("<<no %%%c conversion>>", output, aux, *format);