File indexing completed on 2025-05-11 08:24:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 #include <rtems/dev/io.h>
0047
0048 #include <sys/cdefs.h>
0049 #include <sys/param.h>
0050 #include <string.h>
0051
0052
0053 #define MAXNBUF (howmany(sizeof(intmax_t) * NBBY, 3) + 1)
0054
0055 static inline int imax(int a, int b) { return (a > b ? a : b); }
0056
0057 static char const hex2ascii_data[2][16] = {
0058 { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
0059 'a', 'b', 'c', 'd', 'e', 'f' },
0060 { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
0061 'A', 'B', 'C', 'D', 'E', 'F' }
0062 };
0063
0064 static inline char
0065 hex2ascii(int hex)
0066 {
0067
0068 return (hex2ascii_data[0][hex]);
0069 }
0070
0071
0072
0073
0074
0075
0076
0077 static inline char *
0078 ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
0079 {
0080 char *p;
0081
0082 p = nbuf;
0083 *p = '\0';
0084 do {
0085 *++p = hex2ascii_data[upper][num % base];
0086 } while (num /= base);
0087 *lenp = p - nbuf;
0088 return (p);
0089 }
0090
0091 int
0092 _IO_Vprintf(IO_Put_char put_char, void *arg, char const *fmt, va_list ap)
0093 {
0094 #define PCHAR(c) {int cc=(c); (*put_char)(cc, arg); retval++; }
0095 char nbuf[MAXNBUF];
0096 const char *p, *percent, *q;
0097 u_char *up;
0098 int ch, n, sign;
0099 uintmax_t num;
0100 int base, lflag, tmp, width, ladjust, sharpflag, dot;
0101 int cflag, hflag, jflag;
0102 RTEMS_STATIC_ASSERT(sizeof(intmax_t) == sizeof(long long), _IO_Vprintf_j);
0103 #if __SIZEOF_PTRDIFF_T__ == __SIZEOF_LONG__
0104 #define tflag lflag
0105 #else
0106 int tflag;
0107 #endif
0108 #if __SIZEOF_SIZE_T__ == __SIZEOF_LONG__
0109 #define zflag lflag
0110 #else
0111 int zflag;
0112 #endif
0113 int dwidth, upper;
0114 char padc;
0115 int stop = 0, retval = 0;
0116
0117 num = 0;
0118
0119 if (fmt == NULL)
0120 fmt = "(fmt null)\n";
0121
0122 for (;;) {
0123 padc = ' ';
0124 width = 0;
0125 while ((ch = (u_char)*fmt++) != '%' || stop) {
0126 if (ch == '\0')
0127 return (retval);
0128 PCHAR(ch);
0129 }
0130 percent = fmt - 1;
0131 lflag = 0; ladjust = 0; sharpflag = 0;
0132 sign = 0; dot = 0; dwidth = 0; upper = 0;
0133 cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
0134 reswitch: switch (ch = (u_char)*fmt++) {
0135 case '.':
0136 dot = 1;
0137 goto reswitch;
0138 case '#':
0139 sharpflag = 1;
0140 goto reswitch;
0141 case '+':
0142 sign = '+';
0143 goto reswitch;
0144 case '-':
0145 ladjust = 1;
0146 goto reswitch;
0147 case '%':
0148 PCHAR(ch);
0149 break;
0150 case '*':
0151 if (!dot) {
0152 width = va_arg(ap, int);
0153 if (width < 0) {
0154 ladjust = !ladjust;
0155 width = -width;
0156 }
0157 } else {
0158 dwidth = va_arg(ap, int);
0159 }
0160 goto reswitch;
0161 case '0':
0162 if (!dot) {
0163 padc = '0';
0164 goto reswitch;
0165 }
0166
0167 case '1': case '2': case '3': case '4':
0168 case '5': case '6': case '7': case '8': case '9':
0169 for (n = 0;; ++fmt) {
0170 n = n * 10 + ch - '0';
0171 ch = *fmt;
0172 if (ch < '0' || ch > '9')
0173 break;
0174 }
0175 if (dot)
0176 dwidth = n;
0177 else
0178 width = n;
0179 goto reswitch;
0180 case 'c':
0181 width -= 1;
0182
0183 if (!ladjust && width > 0)
0184 while (width--)
0185 PCHAR(padc);
0186 PCHAR(va_arg(ap, int));
0187 if (ladjust && width > 0)
0188 while (width--)
0189 PCHAR(padc);
0190 break;
0191 case 'D':
0192 up = va_arg(ap, u_char *);
0193 p = va_arg(ap, char *);
0194 if (!width)
0195 width = 16;
0196 while(width--) {
0197 PCHAR(hex2ascii(*up >> 4));
0198 PCHAR(hex2ascii(*up & 0x0f));
0199 up++;
0200 if (width)
0201 for (q=p;*q;q++)
0202 PCHAR(*q);
0203 }
0204 break;
0205 case 'd':
0206 case 'i':
0207 base = 10;
0208 goto handle_sign;
0209 case 'h':
0210 if (hflag) {
0211 hflag = 0;
0212 cflag = 1;
0213 } else
0214 hflag = 1;
0215 goto reswitch;
0216 case 'j':
0217 jflag = 1;
0218 goto reswitch;
0219 case 'l':
0220 if (lflag) {
0221 jflag = 1;
0222 } else
0223 lflag = 1;
0224 goto reswitch;
0225 case 'o':
0226 base = 8;
0227 goto handle_nosign;
0228 case 'p':
0229 base = 16;
0230 sharpflag = (width == 0);
0231 sign = 0;
0232 num = (uintptr_t)va_arg(ap, void *);
0233 goto number;
0234 case 's':
0235 p = va_arg(ap, char *);
0236 if (p == NULL)
0237 p = "(null)";
0238 if (!dot)
0239 n = strlen (p);
0240 else
0241 for (n = 0; n < dwidth && p[n]; n++)
0242 continue;
0243
0244 width -= n;
0245
0246 if (!ladjust && width > 0)
0247 while (width--)
0248 PCHAR(padc);
0249 while (n--)
0250 PCHAR(*p++);
0251 if (ladjust && width > 0)
0252 while (width--)
0253 PCHAR(padc);
0254 break;
0255 case 't':
0256 tflag = 1;
0257 goto reswitch;
0258 case 'u':
0259 base = 10;
0260 goto handle_nosign;
0261 case 'X':
0262 upper = 1;
0263
0264 case 'x':
0265 base = 16;
0266 goto handle_nosign;
0267 case 'y':
0268 base = 16;
0269 goto handle_sign;
0270 case 'z':
0271 zflag = 1;
0272 goto reswitch;
0273 handle_nosign:
0274 if (jflag)
0275 num = va_arg(ap, uintmax_t);
0276 #if __SIZEOF_PTRDIFF_T__ != __SIZEOF_LONG__
0277 else if (tflag)
0278 num = va_arg(ap, ptrdiff_t);
0279 #endif
0280 else if (lflag)
0281 num = va_arg(ap, u_long);
0282 #if __SIZEOF_SIZE_T__ != __SIZEOF_LONG__
0283 else if (zflag)
0284 num = va_arg(ap, size_t);
0285 #endif
0286 else if (hflag)
0287 num = (u_short)va_arg(ap, int);
0288 else if (cflag)
0289 num = (u_char)va_arg(ap, int);
0290 else
0291 num = va_arg(ap, u_int);
0292 goto number;
0293 handle_sign:
0294 if (jflag)
0295 num = va_arg(ap, intmax_t);
0296 #if __SIZEOF_PTRDIFF_T__ != __SIZEOF_LONG__
0297 else if (tflag)
0298 num = va_arg(ap, ptrdiff_t);
0299 #endif
0300 else if (lflag)
0301 num = va_arg(ap, long);
0302 #if __SIZEOF_SIZE_T__ != __SIZEOF_LONG__
0303 else if (zflag)
0304 num = va_arg(ap, ssize_t);
0305 #endif
0306 else if (hflag)
0307 num = (short)va_arg(ap, int);
0308 else if (cflag)
0309 num = (signed char)va_arg(ap, int);
0310 else
0311 num = va_arg(ap, int);
0312 if ((intmax_t)num < 0) {
0313 sign = '-';
0314 num = -(intmax_t)num;
0315 }
0316 number:
0317 p = ksprintn(nbuf, num, base, &n, upper);
0318 tmp = 0;
0319 if (sharpflag && num != 0) {
0320 if (base == 8)
0321 tmp++;
0322 else if (base == 16)
0323 tmp += 2;
0324 }
0325 if (sign)
0326 tmp++;
0327
0328 if (!ladjust && padc == '0')
0329 dwidth = width - tmp;
0330 width -= tmp + imax(dwidth, n);
0331 dwidth -= n;
0332 if (!ladjust)
0333 while (width-- > 0)
0334 PCHAR(' ');
0335 if (sign)
0336 PCHAR(sign);
0337 if (sharpflag && num != 0) {
0338 if (base == 8) {
0339 PCHAR('0');
0340 } else if (base == 16) {
0341 PCHAR('0');
0342 PCHAR('x');
0343 }
0344 }
0345 while (dwidth-- > 0)
0346 PCHAR('0');
0347
0348 while (*p)
0349 PCHAR(*p--);
0350
0351 if (ladjust)
0352 while (width-- > 0)
0353 PCHAR(' ');
0354
0355 break;
0356 default:
0357 while (percent < fmt)
0358 PCHAR(*percent++);
0359
0360
0361
0362
0363
0364
0365 stop = 1;
0366 break;
0367 }
0368 }
0369 #undef PCHAR
0370 }