/** * 格式化输出到屏幕 * 支持形如%d %ld %c %s %-7s %7s的格式 * @param[in] fmt 格式字符串 * @param[in] utf8 输入是否为UTF-8编码 * @param[in] ap 参数列表 */ static void screen_vprintf(const char *fmt, bool utf8, va_list ap) { const char *ptr = fmt; while (*fmt != '\0') { if (*fmt == '%') { _put_string(ptr, fmt, utf8); bool left_adjust = false, long_ = false; size_t width = 0; ++fmt; switch (*fmt) { case '-': left_adjust = true; ++fmt; break; case 'l': long_ = true; ++fmt; break; } while (isdigit(*fmt)) { width *= 10; width += *fmt - '0'; ++fmt; } switch (*fmt) { case 's': { const char *ptr = va_arg(ap, const char *); _print_string(ptr, width, utf8, left_adjust); break; } case 'd': { int64_t n; if (long_) { n = va_arg(ap, int64_t); } else { n = va_arg(ap, int); } char buf[24]; snprintf(buf, sizeof(buf), "%ld", n); _print_string(buf, width, true, left_adjust); break; } case 'c': { int i = va_arg(ap, int); screen_putc(i); break; } case '\0': return; default: if (utf8) screen_putc(*fmt); else screen_put_gbk(*fmt); break; } ptr = ++fmt; } else { ++fmt;
int _doprnt(const char* formatString, va_list args, FuncT func, FargT farg) { const char *cp = formatString; FormatT format = { NULL, 0,0,0,0,0, "", "", "", ModFlag_None, kNone, 0, false, false, false, false, false }; int outsize=0; format.args = args; while (*cp != '\0') { if (*cp != '%') { (*func)(farg, *cp++); outsize+=1; } else { cp++; cp = _parse_format(cp, &format); switch (format.fcode) { case 'd': case 'u': case 'i': outsize+=_print_fixed(&format, 5, func, farg); break; case 'o': outsize+=_print_fixed(&format, 4, func, farg); break; case 'p': case 'X': case 'x': outsize+=_print_fixed(&format, 8, func, farg); break; #if defined(__FIXED_POINT_ALLOWED) case 'r': case 'R': #if !defined(__FX_NO_ACCUM) case 'k': case 'K': #endif /* __FX_NO_ACCUM */ #ifdef _ADI_FX_LIBIO outsize+=print_fx(&format, func, farg); #else format.precision = -1; outsize+=_print_fixed(&format, 8, func, farg); #endif /* _ADI_FX_LIBIO */ break; #endif /* __FIXED_POINT_ALLOWED */ case 'A': case 'a': outsize+=_print_a_float(&format, func, farg); break; case 'G': case 'g': case 'e': case 'E': case 'f': case 'F': outsize+=_print_float(&format, func, farg); break; case 'c': { char ch = FETCH((&format), int); if ( format.width>0 ) { char chbuf[2]; chbuf[0] = ch; chbuf[1] = '\0'; format.buffer = chbuf; outsize += _do_output(&format,func,farg); } else { (*func)(farg, ch); outsize+=1; } } break; case 'n': { void* ptr; ptr = FETCH((&format), void*); if (format.modFlag == ModFlag_l) { *((long *) ptr) = outsize; } else #if _LONG_LONG && !defined(__LIBIO_LITE) if (format.modFlag == ModFlag_ll) { *((long long *) ptr) = outsize; } else #endif if (format.modFlag == ModFlag_h) { *((short *) ptr) = outsize; } else { *((int *) ptr) = outsize; } } break; case 's': { char* s; s = FETCH((&format), char*); if (s == NULL) s = "(null)"; format.buffer=s; if ((format.width==0) && (format.precision<0)) { /* Faster route for "%s" */ format.precision = strlen(s); _put_string( func,farg,s,format.precision ); outsize+=format.precision; } else { /* Standard route for * "%[flags][width].[precision]s" */ outsize+=_do_output( &format,func,farg ); } } break; case '\0': /* Premature end of format string */ cp--; break; default: /* case '%': */ (*func)(farg, format.fcode); outsize+=1; break; } } } return outsize; }