Exemplo n.º 1
0
/**
 * 格式化输出到屏幕
 * 支持形如%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;
Exemplo n.º 2
0
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;
}