^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) Paul Mackerras 1997.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <stdarg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "string.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "stdio.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "ops.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) size_t strnlen(const char * s, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) const char *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) for (sc = s; count-- && *sc != '\0'; ++sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /* nothing */;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) return sc - s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) char *strrchr(const char *s, int c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) const char *last = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) if (*s == (char)c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) last = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) } while (*s++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) return (char *)last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) # define do_div(n, base) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned int __base = (base); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) unsigned int __rem; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) __rem = ((unsigned long long)(n)) % __base; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) (n) = ((unsigned long long)(n)) / __base; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) __rem; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) extern unsigned int __div64_32(unsigned long long *dividend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned int divisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* The unnecessary pointer compare is there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * to check for type safety (n must be 64bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) # define do_div(n,base) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) unsigned int __base = (base); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) unsigned int __rem; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (((n) >> 32) == 0) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) __rem = (unsigned int)(n) % __base; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) (n) = (unsigned int)(n) / __base; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) } else \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) __rem = __div64_32(&(n), __base); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) __rem; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #endif /* __powerpc64__ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static int skip_atoi(const char **s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int i, c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) i = i*10 + c - '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define ZEROPAD 1 /* pad with zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define SIGN 2 /* unsigned/signed long */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define PLUS 4 /* show plus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define SPACE 8 /* space if plus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define LEFT 16 /* left justified */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define SPECIAL 32 /* 0x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) char c,sign,tmp[66];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (type & LARGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (type & LEFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) type &= ~ZEROPAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (base < 2 || base > 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) c = (type & ZEROPAD) ? '0' : ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) sign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (type & SIGN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if ((signed long long)num < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) sign = '-';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) num = - (signed long long)num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) size--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) } else if (type & PLUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) sign = '+';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) size--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) } else if (type & SPACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) sign = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) size--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (type & SPECIAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (base == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) size -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) else if (base == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) size--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (num == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) tmp[i++]='0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) else while (num != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) tmp[i++] = digits[do_div(num, base)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (i > precision)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) precision = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) size -= precision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (!(type&(ZEROPAD+LEFT)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) while(size-->0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) *str++ = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *str++ = sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (type & SPECIAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (base==8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) *str++ = '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) else if (base==16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *str++ = '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) *str++ = digits[33];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (!(type & LEFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) while (size-- > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) *str++ = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) while (i < precision--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) *str++ = '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) while (i-- > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) *str++ = tmp[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) while (size-- > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *str++ = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int vsprintf(char *buf, const char *fmt, va_list args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) unsigned long long num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int i, base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) char * str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) const char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int flags; /* flags to number() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int field_width; /* width of output field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int precision; /* min. # of digits for integers; max
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) number of chars for from string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) int qualifier; /* 'h', 'l', or 'L' for integer fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* 'z' support added 23/7/1999 S.H. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* 'z' changed to 'Z' --davidm 1/25/99 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) for (str=buf ; *fmt ; ++fmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (*fmt != '%') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) *str++ = *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* process flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) repeat:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) ++fmt; /* this also skips first '%' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) switch (*fmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) case '-': flags |= LEFT; goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case '+': flags |= PLUS; goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case ' ': flags |= SPACE; goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) case '#': flags |= SPECIAL; goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) case '0': flags |= ZEROPAD; goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* get field width */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) field_width = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if ('0' <= *fmt && *fmt <= '9')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) field_width = skip_atoi(&fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) else if (*fmt == '*') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ++fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* it's the next argument */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) field_width = va_arg(args, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (field_width < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) field_width = -field_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) flags |= LEFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* get the precision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) precision = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (*fmt == '.') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ++fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if ('0' <= *fmt && *fmt <= '9')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) precision = skip_atoi(&fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) else if (*fmt == '*') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ++fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* it's the next argument */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) precision = va_arg(args, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (precision < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) precision = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* get the conversion qualifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) qualifier = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (*fmt == 'l' && *(fmt + 1) == 'l') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) qualifier = 'q';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) fmt += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) } else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) || *fmt == 'Z') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) qualifier = *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ++fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* default base */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) base = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) switch (*fmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) case 'c':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!(flags & LEFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) while (--field_width > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) *str++ = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) *str++ = (unsigned char) va_arg(args, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) while (--field_width > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) *str++ = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) s = va_arg(args, char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (!s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) s = "<NULL>";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) len = strnlen(s, precision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (!(flags & LEFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) while (len < field_width--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) *str++ = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) for (i = 0; i < len; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) *str++ = *s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) while (len < field_width--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) *str++ = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) case 'p':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (field_width == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) field_width = 2*sizeof(void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) flags |= ZEROPAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) str = number(str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) (unsigned long) va_arg(args, void *), 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) field_width, precision, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (qualifier == 'l') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) long * ip = va_arg(args, long *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) *ip = (str - buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) } else if (qualifier == 'Z') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) size_t * ip = va_arg(args, size_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) *ip = (str - buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) int * ip = va_arg(args, int *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) *ip = (str - buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) case '%':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) *str++ = '%';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* integer number formats - set up the flags and "break" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) base = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) case 'X':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) flags |= LARGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) case 'x':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) base = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) case 'i':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) flags |= SIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) case 'u':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) *str++ = '%';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (*fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) *str++ = *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) --fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (qualifier == 'l') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) num = va_arg(args, unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (flags & SIGN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) num = (signed long) num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) } else if (qualifier == 'q') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) num = va_arg(args, unsigned long long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (flags & SIGN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) num = (signed long long) num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) } else if (qualifier == 'Z') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) num = va_arg(args, size_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) } else if (qualifier == 'h') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) num = (unsigned short) va_arg(args, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (flags & SIGN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) num = (signed short) num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) num = va_arg(args, unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (flags & SIGN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) num = (signed int) num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) str = number(str, num, base, field_width, precision, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) *str = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return str-buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) int sprintf(char * buf, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) i=vsprintf(buf,fmt,args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static char sprint_buf[1024];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) printf(const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) n = vsprintf(sprint_buf, fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (console_ops.write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) console_ops.write(sprint_buf, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }