int vtxprintf(void (*tx_byte)(unsigned char byte, void *data), const char *fmt, va_list args, void *data) { int len; unsigned long long num; int i, base; const char *s; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'H', 'l', or 'L' for integer fields */ int count; for (count = 0; *fmt ; ++fmt) { if (*fmt != '%') { call_tx(*fmt), count++; continue; } /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } /* get field width */ field_width = -1; if (is_digit(*fmt)) { field_width = skip_atoi(&fmt); } else if (*fmt == '*') { ++fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (is_digit(*fmt)) { precision = skip_atoi(&fmt); } else if (*fmt == '*') { ++fmt; /* it's the next argument */ precision = va_arg(args, int); }
int vsprintf(char* buf, const char* fmt, va_list args) { int len; long num; int i; int base; char* str; const char* s; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', or 'q' for integer fields */ for (str = buf; *fmt; ++fmt) { if (*fmt != '%') { *str++ = *fmt; continue; } /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } /* get field width */ field_width = -1; if (is_digit(*fmt)) { field_width = skip_atoi(&fmt); } else if (*fmt == '*') { ++fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (is_digit(*fmt)) { precision = skip_atoi(&fmt); } else if (*fmt == '*') { ++fmt; /* it's the next argument */ precision = va_arg(args, int); }
static int vsprintf(char *buff, const char *format, va_list args) { int len; int i; char *str; char *s; int *ip; int flags; // flags to number() int field_width; // width of output field int precision; // min. # of digits for integers; max number of chars for from string for (str = buff ; *format ; ++format) { if (*format != '%') { *str++ = *format; continue; } flags = 0; repeat: ++format; // this also skips first '%' switch (*format) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } // get field width field_width = -1; if (is_digit(*format)) { field_width = skip_atoi(&format); } else if (*format == '*') { // it's the next argument field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } // get the precision precision = -1; if (*format == '.') { ++format; if (is_digit(*format)) { precision = skip_atoi(&format); } else if (*format == '*') { // it's the next argument precision = va_arg(args, int); }
/* ** This vsnprintf() emulation does not implement the conversions: ** %e, %E, %g, %G, %wc, %ws ** The %f implementation is limited. */ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) { int len; unsigned long num; int i, base; char *str; const char *s; int flags; int dotflag; int field_width; int precision; int qualifier; size--; for(str = buf; *fmt && size; ++fmt) { if(*fmt != '%') { *str++ = *fmt; size--; continue; } flags = 0; dotflag = 0; repeat: ++fmt; switch(*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } field_width = -1; if(isdigit(*fmt)) field_width = skip_atoi(&fmt); else if(*fmt == '*') { ++fmt; field_width = va_arg(args,int); if(field_width < 0) { field_width = - field_width; flags |= LEFT; } } precision = -1; if(*fmt == '.') { dotflag++; ++fmt; if(isdigit(*fmt)) precision = skip_atoi(&fmt); else if(*fmt == '*') { ++fmt; precision = va_arg(args,int); }
int vsprintf(char *buf, const char *fmt, va_list args) { int len; unsigned long num; int i, base; char *str; char *s; int flags; // Flags to number() int field_width; // Width of output field int precision; // Min. # of digits for integers; max number of chars for from string int qualifier; // 'l', or 'L' for integer fields for (str = buf; *fmt; fmt++) { if (*fmt != '%') { *str++ = *fmt; continue; } // Process flags flags = 0; repeat: fmt++; // This also skips first '%' switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } // Get field width field_width = -1; if (is_digit(*fmt)) { field_width = skip_atoi(&fmt); } else if (*fmt == '*') { fmt++; field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } // Get the precision precision = -1; if (*fmt == '.') { ++fmt; if (is_digit(*fmt)) { precision = skip_atoi(&fmt); } else if (*fmt == '*') { ++fmt; precision = va_arg(args, int); }
static int vsprintf(char *buff, const char *format, va_list args) { int len; int i; char *str; char *s; int *ip; int flags; int field_width; int precision; for (str = buff; *format; ++format) { if (*format != '%') { *str ++ = *format; continue; } flags = 0; repeat: ++format; switch (*format) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } // get field width field_width = -1; if (is_digit(*format)) { field_width = skip_atoi(&format); } else if (*format == '*') { // it's the next arguments field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } // get the precision precision = -1; if (*format == '.') { ++ format; if (is_digit(*format)) { precision = skip_atoi(&format); } else if (*format == '*') { // it's the next arguments precision = va_arg(args, int); }
int sprintf(char *buf, const char *fmt, va_list args) { char *str; // for keeping track of output location in buf int flags; // for keeping track of formatting flags int field_width;// width of output field int precision; // min number of digits for integers; for strings, // max number of chars int qualifier; // 'h', 'l' or 'L' for integers char *s; // if there's a string argument, this is it int len; // this is its length int i; // index variable int *ip; // ptr for 'n' format for (str = buf; *fmt; ++fmt) { // loop til end of format string if (*fmt != '%') { // detect speshul placeholders *str++ = *fmt; // twas a regular char so stick it in continue; } flags = 0; repeat: // an elegant use of goto if I've ever seen one ++fmt; // look at next char, or skip first '%' switch(*fmt) { // look at it! case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } // flags done, now field width field_width = -1; if (is_digit(*fmt)) { field_width = skip_atoi(&fmt); } else if (*fmt == '*') { // width in next arg field_width = va_arg(args, int); if (field_width < 0) { // negative width means left-align field_width = -field_width; flags |= LEFT; } } // width done, get precision precision = -1; if (*fmt == '.') { // precision coming up ++fmt; if (is_digit(*fmt)) { precision = skip_atoi(&fmt); } else if (*fmt == '*') { // precision is next argument precision = va_arg(args, int); }
static int vsprintf(char *buf, const char *fmt, va_list args) { int len; unsigned long num; int i, base; char * str; const char *s; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ for (str = buf; *fmt; ++fmt) { if (*fmt != '%') { *str++ = *fmt; continue; } flags = 0; repeat: ++fmt; switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE;goto repeat; case '#': flags |= SPECIAL;goto repeat; case '0': flags |= ZEROPAD;goto repeat; } field_width = -1; if (is_digit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++ fmt; field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } precision = -1; if (*fmt == '.') { ++fmt; if (is_digit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; precision = va_arg(args, int); }
/** * parse_printf_fmt() - Parse printf/printk conversion spec. * fmt points to the '%' in a printk conversion specification. Advance * fmt past any flags, width and/or precision specifiers, and qualifiers * such as 'l' and 'L'. Return a pointer to the conversion character. * Stores the qualifier character (or -1, if there is none) at *pqualifier. * *wp is set to flags indicating whether the width and/or precision are '*'. * For example, given * %*.2lx * *pqualifier is set to 'l', *wp is set to 0x1, and a pointer to the 'x' * is returned. * * Note: This function is derived from vsnprintf() (see * lib/vsprintf.c), * and should be kept in sync with that function. * * @fmt - points to '%' in conversion spec * @pqualifier - *pqualifier is set to conversion spec's qualifier, or -1. * @wp - Bits in *wp are set if the width or/and precision are '*'. */ const char * parse_printf_fmt(const char *fmt, int *pqualifier, int *wp) { int qualifier = -1; *wp = 0; /* process flags */ repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': case '+': case ' ': case '#': case '0': goto repeat; } /* get field width */ if (isdigit(*fmt)) skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ *wp |= 0x1; } /* get the precision */ if (*fmt == '.') { ++fmt; if (isdigit(*fmt)) skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ *wp |= 0x2; } } /* get the conversion qualifier */ if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { qualifier = *fmt; ++fmt; if (qualifier == 'l' && *fmt == 'l') { qualifier = 'L'; ++fmt; } } *pqualifier = qualifier; return fmt; }
static int do_gpio(int argc, const char* argv[]) { char *tmp = argv[2]; int gpio = skip_atoi(&tmp); if (strcmp(argv[1], "in") == 0) { GPIO_DIS_OUTPUT(gpio); console_printf("GP%d==%d\n", gpio, GPIO_INPUT_GET(gpio)); } else if (strcmp(argv[1], "out") == 0) { if (argc < 4) return; tmp = argv[3]; int v = skip_atoi(&tmp); GPIO_OUTPUT_SET(gpio, v); } }
static int do_listen(int argc, const char* argv[]) { int port = skip_atoi(&argv[1]); console_printf("Listening (TCP) on port %d\n", port); esp_conn.type = ESPCONN_TCP; esp_conn.state = ESPCONN_NONE; esp_conn.proto.tcp = &esptcp; esp_conn.proto.tcp->local_port = port; espconn_regist_connectcb(&esp_conn, webserver_listen); espconn_accept(&esp_conn); linebuffer = os_malloc(LINEBUFFER_SIZE); lineptr = 0; console_lock(1); }
/** * vsnprintf - Format a string and place it in a buffer * @buf: The buffer to place the result into * @size: The size of the buffer, including the trailing null space * @fmt: The format string to use * @args: Arguments for the format string * * The return value is the number of characters which would * be generated for the given input, excluding the trailing * '\0', as per ISO C99. If you want to have the exact * number of characters written into @buf as return value * (not including the trailing '\0'), use vscnprintf. If the * return is greater than or equal to @size, the resulting * string is truncated. * * Call this function if you are already dealing with a va_list. * You probably want snprintf instead. */ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) { int len; unsigned long long num; int i, base; char *str, *end, c; const char *s; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ /* 'z' support added 23/7/1999 S.H. */ /* 'z' changed to 'Z' --davidm 1/25/99 */ /* 't' added for ptrdiff_t */ DECLARE_MAC_BUF(mac); /* Reject out-of-range values early. Large positive sizes are used for unknown buffer sizes. */ if (unlikely((int) size < 0)) { /* There can be only one.. */ static int warn = 1; WARN_ON(warn); warn = 0; return 0; } str = buf; end = buf + size; /* Make sure end is always >= buf */ if (end < buf) { end = ((void *)-1); size = end - buf; } for (; *fmt ; ++fmt) { if (*fmt != '%') { if (str < end) *str = *fmt; ++str; continue; } /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } /* get field width */ field_width = -1; if (isdigit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (isdigit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ precision = va_arg(args, int); }
/** * bvsnprintf - BIRD's vsnprintf() * @buf: destination buffer * @size: size of the buffer * @fmt: format string * @args: a list of arguments to be formatted * * This functions acts like ordinary sprintf() except that it checks * available space to avoid buffer overflows and it allows some more * format specifiers: |%I| for formatting of IP addresses (any non-zero * width is automatically replaced by standard IP address width which * depends on whether we use IPv4 or IPv6; |%#I| gives hexadecimal format), * |%R| for Router / Network ID (u32 value printed as IPv4 address) * and |%m| resp. |%M| for error messages (uses strerror() to translate @errno code to * message text). On the other hand, it doesn't support floating * point numbers. * * Result: number of characters of the output string or -1 if * the buffer space was insufficient. */ int bvsnprintf(char *buf, int size, const char *fmt, va_list args) { int len; unsigned long num; int i, base; u32 x; char *str, *start; const char *s; char ipbuf[STD_ADDRESS_P_LENGTH+1]; struct iface *iface; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ for (start=str=buf ; *fmt ; ++fmt, size-=(str-start), start=str) { if (*fmt != '%') { if (!size) return -1; *str++ = *fmt; continue; } /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } /* get field width */ field_width = -1; if (is_digit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (is_digit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ precision = va_arg(args, int); }
int vsnprintf(char *buffer, size_t bufferSize, const char *format, va_list args) { uint64 num; int base; int flags; /* flags to number() */ int fieldWidth; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ Buffer outBuffer(buffer, bufferSize); for (; format[0]; format++) { if (format[0] != '%') { outBuffer.PutCharacter(format[0]); continue; } /* process flags */ flags = 0; repeat: format++; /* this also skips first '%' */ switch (format[0]) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; case '%': outBuffer.PutCharacter(format[0]); continue; } /* get field width */ fieldWidth = -1; if (isdigit(*format)) fieldWidth = skip_atoi(&format); else if (format[0] == '*') { format++; /* it's the next argument */ fieldWidth = va_arg(args, int); if (fieldWidth < 0) { fieldWidth = -fieldWidth; flags |= LEFT; } } /* get the precision */ precision = -1; if (format[0] == '.') { format++; if (isdigit(*format)) precision = skip_atoi(&format); else if (format[0] == '*') { format++; /* it's the next argument */ precision = va_arg(args, int); }
rt_int32_t rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args) { #ifdef RT_PRINTF_LONGLONG unsigned long long num; #else rt_uint32_t num; #endif int i, len; char *str, *end, c; const char *s; rt_uint8_t base; /* the base of number */ rt_uint8_t flags; /* flags to print number */ rt_uint8_t qualifier; /* 'h', 'l', or 'L' for integer fields */ rt_int32_t field_width; /* width of output field */ #ifdef RT_PRINTF_PRECISION int precision; /* min. # of digits for integers and max for a string */ #endif str = buf; end = buf + size - 1; /* Make sure end is always >= buf */ if (end < buf) { end = ((char *)-1); size = end - buf; } for (; *fmt ; ++fmt) { if (*fmt != '%') { if (str <= end) *str = *fmt; ++ str; continue; } /* process flags */ flags = 0; while (1) { /* skips the first '%' also */ ++ fmt; if (*fmt == '-') flags |= LEFT; else if (*fmt == '+') flags |= PLUS; else if (*fmt == ' ') flags |= SPACE; else if (*fmt == '#') flags |= SPECIAL; else if (*fmt == '0') flags |= ZEROPAD; else break; } /* get field width */ field_width = -1; if (isdigit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++ fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } #ifdef RT_PRINTF_PRECISION /* get the precision */ precision = -1; if (*fmt == '.') { ++ fmt; if (isdigit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { ++ fmt; /* it's the next argument */ precision = va_arg(args, int); }
// 下面函数是送格式化输出到字符串中。 // 为了能在内核中使用格式化的输出,Linus 在内核实现了该C 标准函数。 // 其中参数fmt 是格式字符串;args 是个数变化的值;buf 是输出字符串缓冲区。 // 请参见本代码列表后的有关格式转换字符的介绍。 int vsprintf (char *buf, const char *fmt, va_list args) { int len; int i; char *str; // 用于存放转换过程中的字符串。 char *s; int *ip; int flags; /* flags to number() */ /* number()函数使用的标志 */ int field_width; /* width of output field */ /* 输出字段宽度*/ int precision; /* min. # of digits for integers; max number of chars for from string */ /* min. 整数数字个数;max. 字符串中字符个数 */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ /* 'h', 'l',或'L'用于整数字段 */ // 首先将字符指针指向buf,然后扫描格式字符串,对各个格式转换指示进行相应的处理。 for (str = buf; *fmt; ++fmt) { // 格式转换指示字符串均以'%'开始,这里从fmt 格式字符串中扫描'%',寻找格式转换字符串的开始。 // 不是格式指示的一般字符均被依次存入str。 if (*fmt != '%') { *str++ = *fmt; continue; } // 下面取得格式指示字符串中的标志域,并将标志常量放入flags 变量中。 /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= LEFT; goto repeat; // 左靠齐调整。 case '+': flags |= PLUS; goto repeat; // 放加号。 case ' ': flags |= SPACE; goto repeat; // 放空格。 case '#': flags |= SPECIAL; goto repeat; // 是特殊转换。 case '0': flags |= ZEROPAD; goto repeat; // 要填零(即'0')。 } // 取当前参数字段宽度域值,放入field_width 变量中。如果宽度域中是数值则直接取其为宽度值。 // 如果宽度域中是字符'*',表示下一个参数指定宽度。因此调用va_arg 取宽度值。若此时宽度值 // 小于0,则该负数表示其带有标志域'-'标志(左靠齐),因此还需在标志变量中添入该标志,并 // 将字段宽度值取为其绝对值。 /* get field width */ field_width = -1; if (is_digit (*fmt)) field_width = skip_atoi (&fmt); else if (*fmt == '*') { /* it's the next argument */ field_width = va_arg (args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } // 下面这段代码,取格式转换串的精度域,并放入precision 变量中。精度域开始的标志是'.'。 // 其处理过程与上面宽度域的类似。如果精度域中是数值则直接取其为精度值。如果精度域中是 // 字符'*',表示下一个参数指定精度。因此调用va_arg 取精度值。若此时宽度值小于0,则 // 将字段精度值取为其绝对值。 /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (is_digit (*fmt)) precision = skip_atoi (&fmt); else if (*fmt == '*') { /* it's the next argument */ precision = va_arg (args, int); }
int vcprintf(const char *fmt, va_list args) { int len, DynamicColourFlag = 0, ColourCount; unsigned long num; int i, base; char *s; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max * number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ for (; *fmt; ++fmt) { ColourCount = 0; if (*fmt != '%') { if (*fmt == 1) { if (*(fmt + 1) == '%') { DynamicColourFlag = 1; /* * Tricky stuff... */ } else { DynamicColourFlag = 0; ColourChar(*(++fmt)); } } else bing(*fmt); continue; } /* * process flags */ flags = 0; repeat: ++fmt; /* * this also skips first '%' */ switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } /* * get field width */ field_width = -1; if (is_digit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* * it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } /* * get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (is_digit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* * it's the next argument */ precision = va_arg(args, int); }
int vsnprintf(int size, char *buf, const char *fmt, va_list args) { int len; int i; char *str; char *newstr; char *s; int *ip; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ int used_size=1; /* for null character */ if(size == 0) return 0; *buf = 0; if(size == 1) return 1; for (str=buf ; *fmt ; ++fmt) { if (*fmt != '%') { if(used_size >= size) break; *str++ = *fmt; used_size++; continue; } /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } /* get field width */ field_width = -1; if (is_digit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (is_digit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { /* it's the next argument */ precision = va_arg(args, int); }
static u16 vsprintf(char *buf, const char *fmt, va_list args) { char tmp_buffer[12]; s16 i; s16 len; s16 *ip; u16 num; char *s; char *hexchars; char *str; s16 left_align; s16 plus_sign; s16 zero_pad; s16 space_sign; s16 field_width; s16 precision; for (str=buf ; *fmt ; ++fmt) { if (*fmt != '%') { *str++ = *fmt; continue; } space_sign = zero_pad = plus_sign = left_align = 0; // Process the flags repeat: ++fmt; // this also skips first '%' switch (*fmt) { case '-': left_align = 1; goto repeat; case '+': plus_sign = 1; goto repeat; case ' ': if (!plus_sign) space_sign = 1; goto repeat; case '0': zero_pad = 1; goto repeat; } // Process field width and precision field_width = precision = -1; if (isdigit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; // it's the next argument field_width = va_arg(args, s16); if (field_width < 0) { field_width = -field_width; left_align = 1; } } if (*fmt == '.') { ++fmt; if (isdigit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; // it's the next argument precision = va_arg(args, s16); } if (precision < 0) precision = 0; } if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { ++fmt; } if (left_align) zero_pad = 0; switch (*fmt) { case 'c': if (!left_align) while (--field_width > 0) *str++ = ' '; *str++ = (unsigned char) va_arg(args, s16); while (--field_width > 0) *str++ = ' '; continue; case 's': s = va_arg(args, char *); if (!s) s = "<NULL>"; len = strnlen(s, precision); if (!left_align) while (len < field_width--) *str++ = ' '; for (i = 0; i < len; ++i) *str++ = *s++; while (len < field_width--) *str++ = ' '; continue; case 'p': if (field_width == -1) { field_width = 2*sizeof(void *); zero_pad = 1; } hexchars = (char *)uppercase_hexchars; goto hexa_conv; case 'x': hexchars = (char *)lowercase_hexchars; goto hexa_conv; case 'X': hexchars = (char *)uppercase_hexchars; hexa_conv: s = &tmp_buffer[12]; *--s = 0; num = va_arg(args, u16); if (!num) *--s = '0'; while(num) { *--s = hexchars[num&0xF]; num >>= 4; } num = plus_sign = 0; break; case 'n': ip = va_arg(args, s16 *); *ip = (str - buf); continue; case 'u': s = &tmp_buffer[12]; *--s = 0; num = va_arg(args, u16); if (!num) *--s = '0'; while(num) { *--s = (num%10) + 0x30; num /= 10; } num = plus_sign = 0; break; case 'd': case 'i': s = &tmp_buffer[12]; *--s = 0; i = va_arg(args, s16); if (!i) *--s = '0'; if (i < 0) { num = 1; while(i) { *--s = 0x30 - (i%10); i /= 10; } } else { num = 0; while(i) { *--s = (i%10) + 0x30; i /= 10; } } break; default: continue; } len = strnlen(s, precision); if (num) { *str++ = '-'; field_width--; } else if (plus_sign) { *str++ = '+'; field_width--; } else if (space_sign) { *str++ = ' '; field_width--; } if (!left_align) { if (zero_pad) { while (len < field_width--) *str++ = '0'; } else { while (len < field_width--) *str++ = ' '; } } for (i = 0; i < len; ++i) *str++ = *s++; while (len < field_width--) *str++ = ' '; } *str = '\0'; return str - buf; }
static int _stp_vsnprintf(char *buf, size_t size, const char *fmt, va_list args) { int len; uint64_t num; int i, base; char *str, *end, c; const char *s; enum print_flag flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ /* Reject out-of-range values early */ if (unlikely((int) size < 0)) return 0; /* * buf will be NULL when this function is called from _stp_printf. * This branch calculates the exact size print buffer required for * the string and allocates it with _stp_reserve_bytes. A change * to this branch requires a corresponding change to the same * section of code below. */ if (buf == NULL) { const char* fmt_copy = fmt; int num_bytes = 0; va_list args_copy; va_copy(args_copy, args); for (; *fmt_copy ; ++fmt_copy) { if (*fmt_copy != '%') { num_bytes++; continue; } /* process flags */ flags = 0; repeat_copy: ++fmt_copy; /* this also skips first '%' */ switch (*fmt_copy) { case '-': flags |= STP_LEFT; goto repeat_copy; case '+': flags |= STP_PLUS; goto repeat_copy; case ' ': flags |= STP_SPACE; goto repeat_copy; case '#': flags |= STP_SPECIAL; goto repeat_copy; case '0': flags |= STP_ZEROPAD; goto repeat_copy; } /* get field width */ field_width = -1; if (isdigit(*fmt_copy)) field_width = clamp(skip_atoi(&fmt_copy), 0, STP_BUFFER_SIZE); else if (*fmt_copy == '*') { ++fmt_copy; /* it's the next argument */ field_width = va_arg(args_copy, int); if (field_width < 0) { field_width = -field_width; flags |= STP_LEFT; } field_width = clamp(field_width, 0, STP_BUFFER_SIZE); } /* get the precision */ precision = -1; if (*fmt_copy == '.') { ++fmt_copy; if (isdigit(*fmt_copy)) precision = skip_atoi(&fmt_copy); else if (*fmt_copy == '*') { ++fmt_copy; /* it's the next argument */ precision = va_arg(args_copy, int); } precision = clamp(precision, 0, STP_BUFFER_SIZE); }
void nprintf(unsigned char *buf, uint32_t size, const char *fmt, va_list args) { int32_t num; // int i, len; unsigned char *str, *end;//, c; // const char *s; uint8_t base; /* the base of number */ uint8_t flags; /* flags to print number */ uint8_t qualifier; /* 'h', 'l', or 'L' for integer fields */ int32_t field_width; /* width of output field */ str = buf; end = buf + size - 1; /* Make sure end is always >= buf */ if (end < buf) { end = ((unsigned char *)-1); size = end - buf; } for (; *fmt ; ++fmt) { if (*fmt != '%') { if (str <= end) *str = *fmt; ++str; continue; } /* process flags */ flags = 0; while(1) { /* skips the first '%' also */ ++fmt; if (*fmt == '-') flags |= LEFT; else if (*fmt == '+') flags |= PLUS; else if (*fmt == ' ') flags |= SPACE; else if (*fmt == '#') flags |= SPECIAL; else if (*fmt == '0') flags |= ZEROPAD; else break; } /* get field width */ field_width = -1; if (isdigit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } /* get the conversion qualifier */ qualifier = 0; if (*fmt == 'h' || *fmt == 'l') { qualifier = *fmt; ++fmt; } /* the default base */ base = 10; switch (*fmt) { case '%': if (str <= end) *str = '%'; ++str; continue; /* integer number formats - set up the flags and "break" */ case 'o': base = 8; break; case 'X': flags |= LARGE; case 'x': base = 16; break; case 'd': case 'i': flags |= SIGN; case 'u': break; default: if (str <= end) *str = '%'; ++str; if (*fmt) { if (str <= end) *str = *fmt; ++str; } else { --fmt; } continue; } if (qualifier == 'h') { num = (uint16_t) va_arg(args, int32_t); if (flags & SIGN) num = (int16_t) num; } else { num = va_arg(args, uint32_t); if (flags & SIGN) num = (int32_t) num; } str = print_number(str, end, num, base, field_width, flags); }
int vsprintf(char *buf, const char *fmt, va_list args) { char *str = buf; for (; *fmt; fmt++) { if (*fmt != '%') { *str++ = *fmt; continue; } int loop = 1; int flags = 0; while (loop) { switch (*(++fmt)) { case '-': flags |= V_LEFT; break; case '+': flags |= V_PLUS; break; case ' ': flags |= V_SPACE; break; case '#': flags |= V_SPECIAL; break; case '0': flags |= V_ZEROPAD; break; default: loop = 0; break; } } int field_width = -1; if (is_digit(*fmt)) { field_width = skip_atoi(&fmt); } else { if (*fmt == '*') { field_width = va_arg(args, int); if (field_width < 0) { flags |= V_LEFT; field_width = -field_width; } } } int precision = -1; if (*fmt == '.') { fmt++; if (is_digit(*fmt)) { precision = skip_atoi(&fmt); } else { if (*fmt == '*') precision = va_arg(args, int); } if (precision < 0) precision = 0; }
/** * vsscanf - Unformat a buffer into a list of arguments * @buf: input buffer * @fmt: format of buffer * @args: arguments */ int vsscanf(const char *buf, const char *fmt, va_list args) { const char *str = buf; char *next; char digit; int num = 0; u8 qualifier; unsigned int base; union { long long s; unsigned long long u; } val; s16 field_width; bool is_sign; while (*fmt) { /* skip any white space in format */ /* white space in format matchs any amount of * white space, including none, in the input. */ if (isspace(*fmt)) { fmt = skip_spaces(++fmt); str = skip_spaces(str); } /* anything that is not a conversion must match exactly */ if (*fmt != '%' && *fmt) { if (*fmt++ != *str++) break; continue; } if (!*fmt) break; ++fmt; /* skip this conversion. * advance both strings to next white space */ if (*fmt == '*') { if (!*str) break; while (!isspace(*fmt) && *fmt != '%' && *fmt) fmt++; while (!isspace(*str) && *str) str++; continue; } /* get field width */ field_width = -1; if (isdigit(*fmt)) { field_width = skip_atoi(&fmt); if (field_width <= 0) break; } /* get conversion qualifier */ qualifier = -1; if (*fmt == 'h' || _tolower(*fmt) == 'l' || _tolower(*fmt) == 'z') { qualifier = *fmt++; if (unlikely(qualifier == *fmt)) { if (qualifier == 'h') { qualifier = 'H'; fmt++; } else if (qualifier == 'l') { qualifier = 'L'; fmt++; } } } if (!*fmt) break; if (*fmt == 'n') { /* return number of characters read so far */ *va_arg(args, int *) = str - buf; ++fmt; continue; } if (!*str) break; base = 10; is_sign = false; switch (*fmt++) { case 'c': { char *s = (char *)va_arg(args, char*); if (field_width == -1) field_width = 1; do { *s++ = *str++; } while (--field_width > 0 && *str); num++; } continue; case 's': { char *s = (char *)va_arg(args, char *); if (field_width == -1) field_width = SHRT_MAX; /* first, skip leading white space in buffer */ str = skip_spaces(str); /* now copy until next white space */ while (*str && !isspace(*str) && field_width--) *s++ = *str++; *s = '\0'; num++; } continue; case 'o': base = 8; break; case 'x': case 'X': base = 16; break; case 'i': base = 0; case 'd': is_sign = true; case 'u': break; case '%': /* looking for '%' in str */ if (*str++ != '%') return num; continue; default: /* invalid format; stop here */ return num; } /* have some sort of integer conversion. * first, skip white space in buffer. */ str = skip_spaces(str); digit = *str; if (is_sign && digit == '-') digit = *(str + 1); if (!digit || (base == 16 && !isxdigit(digit)) || (base == 10 && !isdigit(digit)) || (base == 8 && (!isdigit(digit) || digit > '7')) || (base == 0 && !isdigit(digit))) break; if (is_sign) val.s = qualifier != 'L' ? strtol(str, &next, base) : strtoll(str, &next, base); else val.u = qualifier != 'L' ? strtoul(str, &next, base) : strtoull(str, &next, base); if (field_width > 0 && next - str > field_width) { if (base == 0) _parse_integer_fixup_radix(str, &base); while (next - str > field_width) { if (is_sign) val.s = sdiv64(val.s, base); else val.u = udiv64(val.u, base); --next; } } switch (qualifier) { case 'H': /* that's 'hh' in format */ if (is_sign) *va_arg(args, signed char *) = val.s; else *va_arg(args, unsigned char *) = val.u; break; case 'h': if (is_sign) *va_arg(args, short *) = val.s; else *va_arg(args, unsigned short *) = val.u; break; case 'l': if (is_sign) *va_arg(args, long *) = val.s; else *va_arg(args, unsigned long *) = val.u; break; case 'L': if (is_sign) *va_arg(args, long long *) = val.s; else *va_arg(args, unsigned long long *) = val.u; break; case 'Z': case 'z': *va_arg(args, size_t *) = val.u; break; default: if (is_sign) *va_arg(args, int *) = val.s; else *va_arg(args, unsigned int *) = val.u; break; } num++; if (!next) break; str = next; } return num; }
/** %e, %f, %g are not implemented */ int _v_printf(int (*_write)(void*, const void *, ssize_t ), void* arg, const char *fmt, va_list args) { int len; unsigned long long num; int i, base; char* str = 0; const char *s; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ int err; off_t out_len = 0; int pos = 0; char buf[ 1024 ]; #define WRITE(C) do { buf[pos++] = (C); \ if(pos == 1024 ) { \ err = _write(arg, buf, 1024 );\ if(err < 0) { if(str) free(str); return err; }\ out_len += pos; \ pos = 0; \ } } while(0) #define ALLOC_STR(MAX) (char *)malloc(((precision > field_width) ? ((precision > (MAX) ) ? precision : (MAX) ) : (field_width > (MAX) ) ? field_width : (MAX) )*sizeof(char)); /* Loop through each character of the format*/ for (; *fmt ; ++fmt) { /* Copy over non-format chars */ if (*fmt != '%') { WRITE( *fmt ); continue; } /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } /* get field width */ field_width = -1; if (isdigit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (isdigit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ precision = va_arg(args, int); }
/** * vsnprintf - Format a string and place it in a buffer * @buf: The buffer to place the result into * @size: The size of the buffer, including the trailing null space * @fmt: The format string to use * @args: Arguments for the format string * * Call this function if you are already dealing with a va_list. * You probably want snprintf instead. */ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) { int len; unsigned long long num; int i, base; char *str, *end, c; const char *s; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ /* 'z' support added 23/7/1999 S.H. */ /* 'z' changed to 'Z' --davidm 1/25/99 */ #warning size check removed #if 0 /* Reject out-of-range values early */ if (unlikely((int) size < 0)) { /* There can be only one.. */ static int warn = 1; if (warn) { printk("improper call of vsnprintf!\n"); dump_stack(); warn = 0; } return 0; } #endif str = buf; end = buf + size - 1; if (end < buf - 1) { end = ((void *) -1); size = end - buf + 1; } for (; *fmt ; ++fmt) { if (*fmt != '%') { if (str <= end) *str = *fmt; ++str; continue; } /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } /* get field width */ field_width = -1; if (isdigit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (isdigit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ precision = va_arg(args, int); }
/** * vsscanf - Unformat a buffer into a list of arguments * @buf: input buffer * @fmt: format of buffer * @args: arguments */ int vsscanf(const char * buf, const char * fmt, va_list args) { const char *str = buf; char *next; char digit; int num = 0; int qualifier; int base; int field_width; int is_sign = 0; int in_skip = 0; int dummy_buffer[0x100]; //¿ÕµÄ»º´æ while(*fmt && *str) { /* skip any white space in format */ /* white space in format matchs any amount of * white space, including none, in the input. */ if (isspace(*fmt)) { while (isspace(*fmt)) ++fmt; while (isspace(*str)) ++str; } /* anything that is not a conversion must match exactly */ if (*fmt != '%' && *fmt) { if (*fmt++ != *str++) break; continue; } if (!*fmt) break; ++fmt; /* skip this conversion. * advance both strings to next white space */ if (*fmt == '*') { in_skip = 1; fmt++; } else{ in_skip = 0; } /* get field width */ field_width = -1; if (isdigit(*fmt)) field_width = skip_atoi(&fmt); /* get conversion qualifier */ qualifier = -1; if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'Z' || *fmt == 'z') { qualifier = *fmt++; if (unlikely(qualifier == *fmt)) { if (qualifier == 'h') { qualifier = 'H'; fmt++; } else if (qualifier == 'l') { qualifier = 'L'; fmt++; } } } base = 10; is_sign = 0; if (!*fmt || !*str) break; switch(*fmt++) { case 'c': { char *s = (char *) internal_va_arg(args,char*); if (field_width == -1) field_width = 1; do { *s++ = *str++; } while (--field_width > 0 && *str); num++; } continue; case 's': { char *s = (char *) internal_va_arg(args, char *); if(field_width == -1) field_width = INT_MAX; /* first, skip leading white space in buffer */ while (isspace(*str)) str++; /* now copy until next white space */ while (*str && !isspace(*str) && field_width--) { *s++ = *str++; } *s = '\0'; num++; } continue; case 'n': /* return number of characters read so far */ { int *i = (int *)internal_va_arg(args,int*); *i = str - buf; } continue; case 'o': base = 8; break; case 'x': case 'X': base = 16; break; case 'i': base = 0; case 'd': is_sign = 1; case 'u': break; case '%': /* looking for '%' in str */ if (*str++ != '%') return num; continue; case '[': { char *s = (char *) internal_va_arg(args, char *); if(field_width == -1) field_width = INT_MAX; /* first, skip leading white space in buffer */ while (isspace(*str)) str++; if( *fmt == '^' ) { while (*str) { const char * chkchar = fmt+1; while( *chkchar ) { if( chkchar[1] == '-' ) { char rang_s = chkchar[0]; char rang_d = chkchar[2]; chkchar += 3; if( *str >= rang_s && *str <= rang_d ) goto _get_char_nor; } else { if( *str == *chkchar ) goto _get_char_nor; chkchar ++; } if( *chkchar == ']' ) break; } *s++ = *str++; continue; _get_char_nor: break; } } else { while (*str) { const char * chkchar = fmt; while( *chkchar != ']' ) { if( chkchar[1] == '-' ) { char rang_s = chkchar[0]; char rang_d = chkchar[2]; chkchar += 3; if( *str >= rang_s && *str <= rang_d ) goto _get_char_or; } else { if( *str == *chkchar ) goto _get_char_or; chkchar ++; } } break; _get_char_or: *s++ = *str++; } } *s = '\0'; num++; fmt = (const char *)strchr( fmt, ']' )+1; } continue; default: /* invalid format; stop here */ return num; } /* have some sort of integer conversion. * first, skip white space in buffer. */ while (isspace(*str)) str++; digit = *str; if (is_sign && digit == '-') digit = *(str + 1); if (!digit || (base == 16 && !isxdigit(digit)) || (base == 10 && !isdigit(digit)) || (base == 8 && (!isdigit(digit) || digit > '7')) || (base == 0 && !isdigit(digit))) break; switch(qualifier) { case 'H': /* that's 'hh' in format */ if (is_sign) { signed char *s = (signed char *) internal_va_arg(args,signed char *); *s = (signed char) simple_strtol(str,&next,base); } else { unsigned char *s = (unsigned char *) internal_va_arg(args, unsigned char *); *s = (unsigned char) simple_strtoul(str, &next, base); } break; case 'h': if (is_sign) { short *s = (short *) internal_va_arg(args,short *); *s = (short) simple_strtol(str,&next,base); } else { unsigned short *s = (unsigned short *) internal_va_arg(args, unsigned short *); *s = (unsigned short) simple_strtoul(str, &next, base); } break; case 'l': if (is_sign) { long *l = (long *) internal_va_arg(args,long *); *l = simple_strtol(str,&next,base); } else {
/** * vsscanf - Unformat a buffer into a list of arguments * @buf: input buffer * @fmt: format of buffer * @args: arguments */ int vsscanf(const char * buf, const char * fmt, va_list args) { const char *str = buf; char *next; int num = 0; int qualifier; int base; int field_width = -1; int is_sign = 0; while(*fmt && *str) { /* skip any white space in format */ /* white space in format matchs any amount of * white space, including none, in the input. */ if (isspace(*fmt)) { while (isspace(*fmt)) ++fmt; while (isspace(*str)) ++str; } /* anything that is not a conversion must match exactly */ if (*fmt != '%' && *fmt) { if (*fmt++ != *str++) break; continue; } if (!*fmt) break; ++fmt; /* skip this conversion. * advance both strings to next white space */ if (*fmt == '*') { while (!isspace(*fmt) && *fmt) fmt++; while (!isspace(*str) && *str) str++; continue; } /* get field width */ if (isdigit(*fmt)) field_width = skip_atoi(&fmt); /* get conversion qualifier */ qualifier = -1; if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'Z') { qualifier = *fmt; fmt++; } base = 10; is_sign = 0; if (!*fmt || !*str) break; switch(*fmt++) { case 'c': { char *s = (char *) va_arg(args,char*); if (field_width == -1) field_width = 1; do { *s++ = *str++; } while(field_width-- > 0 && *str); num++; } continue; case 's': { char *s = (char *) va_arg(args, char *); if(field_width == -1) field_width = INT_MAX; /* first, skip leading white space in buffer */ while (isspace(*str)) str++; /* now copy until next white space */ while (*str && !isspace(*str) && field_width--) { *s++ = *str++; } *s = '\0'; num++; } continue; case 'n': /* return number of characters read so far */ { int *i = (int *)va_arg(args,int*); *i = str - buf; } continue; case 'o': base = 8; break; case 'x': case 'X': base = 16; break; case 'd': case 'i': is_sign = 1; case 'u': break; case '%': /* looking for '%' in str */ if (*str++ != '%') return num; continue; default: /* invalid format; stop here */ return num; } /* have some sort of integer conversion. * first, skip white space in buffer. */ while (isspace(*str)) str++; if (!*str || !isdigit(*str)) break; switch(qualifier) { case 'h': if (is_sign) { short *s = (short *) va_arg(args,short *); *s = (short) simple_strtol(str,&next,base); } else { unsigned short *s = (unsigned short *) va_arg(args, unsigned short *); *s = (unsigned short) simple_strtoul(str, &next, base); } break; case 'l': if (is_sign) { long *l = (long *) va_arg(args,long *); *l = simple_strtol(str,&next,base); } else { unsigned long *l = (unsigned long*) va_arg(args,unsigned long*); *l = simple_strtoul(str,&next,base); } break; case 'L': if (is_sign) { long long *l = (long long*) va_arg(args,long long *); *l = simple_strtoll(str,&next,base); } else {
int MYRTLEXP _VSNprintf( char *buf, size_t cnt, const char *fmt, va_list args ) { int len; unsigned MAXSIZE_INT num; int i, base; size_t nstr; const char *s; #if defined(HAS_UNICODE) const wchar_t *sw; #endif int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', 'L', 'I' or 'w' for integer fields */ if ( !buf && cnt ) return 0; if ( buf && cnt == 1 ) { buf[0] = 0; return 1; } for (nstr=0; *fmt ; ++fmt) { if (*fmt != '%') { STR( *fmt ); continue; } /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } /* get field width */ field_width = -1; if (isdigit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (isdigit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ precision = va_arg(args, int); }
int _kc_vsnprintf(char *buf, size_t size, const char *fmt, va_list args) { int len; unsigned long long num; int i, base; char *str, *end, c; const char *s; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ /* 'z' support added 23/7/1999 S.H. */ /* 'z' changed to 'Z' --davidm 1/25/99 */ str = buf; end = buf + size - 1; if (end < buf - 1) { end = ((void *)-1); size = end - buf + 1; } for (; *fmt; ++fmt) { if (*fmt != '%') { if (str <= end) *str = *fmt; ++str; continue; } /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= _kc_LEFT; goto repeat; case '+': flags |= _kc_PLUS; goto repeat; case ' ': flags |= _kc_SPACE; goto repeat; case '#': flags |= _kc_SPECIAL; goto repeat; case '0': flags |= _kc_ZEROPAD; goto repeat; } /* get field width */ field_width = -1; if (isdigit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= _kc_LEFT; } } /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if (isdigit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ precision = va_arg(args, int); }
int vsprintf(char *buf, const char *fmt, va_list args) { int len; unsigned long long num; int i, base; char * str; const char *s; int flags; /* flags to number() */ int field_width; /* width of output field */ int precision; /* min. # of digits for integers; max number of chars for from string */ int qualifier; /* 'h', 'l', or 'L' for integer fields */ /* 'z' support added 23/7/1999 S.H. */ /* 'z' changed to 'Z' --davidm 1/25/99 */ for (str=buf ; *fmt ; ++fmt) { if (*fmt != '%') { *str++ = *fmt; continue; } /* process flags */ flags = 0; repeat: ++fmt; /* this also skips first '%' */ switch (*fmt) { case '-': flags |= LEFT; goto repeat; case '+': flags |= PLUS; goto repeat; case ' ': flags |= SPACE; goto repeat; case '#': flags |= SPECIAL; goto repeat; case '0': flags |= ZEROPAD; goto repeat; } /* get field width */ field_width = -1; if ('0' <= *fmt && *fmt <= '9') field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ field_width = va_arg(args, int); if (field_width < 0) { field_width = -field_width; flags |= LEFT; } } /* get the precision */ precision = -1; if (*fmt == '.') { ++fmt; if ('0' <= *fmt && *fmt <= '9') precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; /* it's the next argument */ precision = va_arg(args, int); }