^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* -*- linux-c -*- ------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 1991, 1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2007 rPath, Inc. - All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * ----------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Oh, it's a waste of space, but oh-so-yummy for debugging. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * version of printf() does not include 64-bit support. "Live with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * it."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "boot.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static int skip_atoi(const char **s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) while (isdigit(**s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) i = i * 10 + *((*s)++) - '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define ZEROPAD 1 /* pad with zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define SIGN 2 /* unsigned/signed long */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define PLUS 4 /* show plus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define SPACE 8 /* space if plus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define LEFT 16 /* left justified */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define SMALL 32 /* Must be 32 == 0x20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define SPECIAL 64 /* 0x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define __do_div(n, base) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int __res; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) __res = ((unsigned long) n) % (unsigned) base; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) n = ((unsigned long) n) / (unsigned) base; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) __res; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static char *number(char *str, long num, int base, int size, int precision,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* we are called with base 8, 10 or 16, only, thus don't need "G..." */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) char tmp[66];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) char c, sign, locase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* locase = 0 or 0x20. ORing digits or letters with 'locase'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * produces same digits or (maybe lowercased) letters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) locase = (type & SMALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (type & LEFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) type &= ~ZEROPAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (base < 2 || base > 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) c = (type & ZEROPAD) ? '0' : ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) sign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (type & SIGN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (num < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) sign = '-';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) num = -num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) size--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) } else if (type & PLUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) sign = '+';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) size--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) } else if (type & SPACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) sign = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) size--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (type & SPECIAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (base == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) size -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) else if (base == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) size--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (num == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) tmp[i++] = '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) while (num != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) tmp[i++] = (digits[__do_div(num, base)] | locase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (i > precision)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) precision = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) size -= precision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (!(type & (ZEROPAD + LEFT)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) while (size-- > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) *str++ = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) *str++ = sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (type & SPECIAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (base == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) *str++ = '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) else if (base == 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) *str++ = '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) *str++ = ('X' | locase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (!(type & LEFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) while (size-- > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) *str++ = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) while (i < precision--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) *str++ = '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) while (i-- > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) *str++ = tmp[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) while (size-- > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) *str++ = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int vsprintf(char *buf, const char *fmt, va_list args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) unsigned long num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) int i, base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) const char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) int flags; /* flags to number() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int field_width; /* width of output field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int precision; /* min. # of digits for integers; max
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) number of chars for from string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int qualifier; /* 'h', 'l', or 'L' for integer fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) for (str = buf; *fmt; ++fmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (*fmt != '%') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *str++ = *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) continue;
^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) /* process flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) repeat:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ++fmt; /* this also skips first '%' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) switch (*fmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) case '-':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) flags |= LEFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) case '+':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) flags |= PLUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) case ' ':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) flags |= SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) case '#':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) flags |= SPECIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) case '0':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) flags |= ZEROPAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* get field width */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) field_width = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (isdigit(*fmt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) field_width = skip_atoi(&fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) else if (*fmt == '*') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ++fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* it's the next argument */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) field_width = va_arg(args, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (field_width < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) field_width = -field_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) flags |= LEFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^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) /* get the precision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) precision = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (*fmt == '.') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) ++fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (isdigit(*fmt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) precision = skip_atoi(&fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) else if (*fmt == '*') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ++fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* it's the next argument */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) precision = va_arg(args, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (precision < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) precision = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* get the conversion qualifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) qualifier = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) qualifier = *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ++fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /* default base */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) base = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) switch (*fmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) case 'c':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (!(flags & LEFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) while (--field_width > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) *str++ = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) *str++ = (unsigned char)va_arg(args, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) while (--field_width > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) *str++ = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) s = va_arg(args, char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) len = strnlen(s, precision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (!(flags & LEFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) while (len < field_width--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) *str++ = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) for (i = 0; i < len; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) *str++ = *s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) while (len < field_width--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) *str++ = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) case 'p':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (field_width == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) field_width = 2 * sizeof(void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) flags |= ZEROPAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) str = number(str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) (unsigned long)va_arg(args, void *), 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) field_width, precision, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (qualifier == 'l') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) long *ip = va_arg(args, long *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) *ip = (str - buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int *ip = va_arg(args, int *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) *ip = (str - buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) case '%':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) *str++ = '%';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* integer number formats - set up the flags and "break" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) base = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) case 'x':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) flags |= SMALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) case 'X':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) base = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) case 'i':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) flags |= SIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) case 'u':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) *str++ = '%';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (*fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) *str++ = *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) --fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (qualifier == 'l')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) num = va_arg(args, unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) else if (qualifier == 'h') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) num = (unsigned short)va_arg(args, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (flags & SIGN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) num = (short)num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) } else if (flags & SIGN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) num = va_arg(args, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) num = va_arg(args, unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) str = number(str, num, base, field_width, precision, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) *str = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return str - buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int sprintf(char *buf, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) i = vsprintf(buf, fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int printf(const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) char printf_buf[1024];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) printed = vsprintf(printf_buf, fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) puts(printf_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }