Esempio n. 1
0
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);
			}
Esempio n. 2
0
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);
			}
Esempio n. 3
0
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);
			}
Esempio n. 4
0
/*
** 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);
   }
Esempio n. 6
0
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);
            }
Esempio n. 7
0
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);
			}
Esempio n. 8
0
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);
            }
Esempio n. 9
0
/**
 * 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;
}
Esempio n. 10
0
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);
	}
	
}
Esempio n. 11
0
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);
}
Esempio n. 12
0
/**
 * 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);
			}
Esempio n. 13
0
/**
 * 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);
			}
Esempio n. 15
0
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);
            }
Esempio n. 16
0
// 下面函数是送格式化输出到字符串中。
// 为了能在内核中使用格式化的输出,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);
	    }
Esempio n. 17
0
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);
	    }
Esempio n. 18
0
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);
			}
Esempio n. 19
0
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;
}
Esempio n. 20
0
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);
                    }
Esempio n. 21
0
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);
  }
Esempio n. 22
0
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;
}
Esempio n. 24
0
/** %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);
            }
Esempio n. 25
0
/**
* 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);
			}
Esempio n. 26
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;
        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 {
Esempio n. 27
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;
	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 {
Esempio n. 28
0
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);
            }
Esempio n. 29
0
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);
            }
Esempio n. 30
0
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);
			}