⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vsprintf.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
字号:
/* *  linux/lib/vsprintf.c * *  Copyright (C) 1991, 1992  Linus Torvalds *//* vsprintf.c -- Lars Wirzenius & Linus Torvalds. *//* * Wirzenius wrote this portably, Torvalds fucked it up :-) */#include <sys/types.h>#define MACH_INCLUDE#include <stdarg.h>#include <linux/types.h>#include <linux/string.h>#include <linux/ctype.h>unsigned long simple_strtoul (const char *cp, char **endp, unsigned int base){  unsigned long result = 0, value;  if (!base)    {      base = 10;      if (*cp == '0')	{	  base = 8;	  cp++;	  if ((*cp == 'x') && isxdigit (cp[1]))	    {	      cp++;	      base = 16;	    }	}    }  while (isxdigit (*cp)	 && (value = isdigit (*cp) ? *cp - '0'	     : (islower (*cp) ? toupper (*cp) : *cp) - 'A' + 10) < base)    {      result = result * base + value;      cp++;    }  if (endp)    *endp = (char *) cp;  return result;}/* we use this so that we can do without the ctype library */#define is_digit(c)	((c) >= '0' && (c) <= '9')static intskip_atoi (const char **s){  int i = 0;  while (is_digit (**s))    i = i * 10 + *((*s)++) - '0';  return i;}#define ZEROPAD	1		/* pad with zero */#define SIGN	2		/* unsigned/signed long */#define PLUS	4		/* show plus */#define SPACE	8		/* space if plus */#define LEFT	16		/* left justified */#define SPECIAL	32		/* 0x */#define LARGE	64		/* use 'ABCDEF' instead of 'abcdef' */#define do_div(n,base) ({ \int __res; \__res = ((unsigned long) n) % (unsigned) base; \n = ((unsigned long) n) / (unsigned) base; \__res; })static char *number (char *str, long num, int base, int size, int precision, int type){  char c, sign, tmp[66];  const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";  int i;  if (type & LARGE)    digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";  if (type & LEFT)    type &= ~ZEROPAD;  if (base < 2 || base > 36)    return 0;  c = (type & ZEROPAD) ? '0' : ' ';  sign = 0;  if (type & SIGN)    {      if (num < 0)	{	  sign = '-';	  num = -num;	  size--;	}      else if (type & PLUS)	{	  sign = '+';	  size--;	}      else if (type & SPACE)	{	  sign = ' ';	  size--;	}    }  if (type & SPECIAL)    {      if (base == 16)	size -= 2;      else if (base == 8)	size--;    }  i = 0;  if (num == 0)    tmp[i++] = '0';  else    while (num != 0)      tmp[i++] = digits[do_div (num, base)];  if (i > precision)    precision = i;  size -= precision;  if (!(type & (ZEROPAD + LEFT)))    while (size-- > 0)      *str++ = ' ';  if (sign)    *str++ = sign;  if (type & SPECIAL)    {      if (base == 8)	{	  *str++ = '0';	}      else if (base == 16)	{	  *str++ = '0';	  *str++ = digits[33];	}    }  if (!(type & LEFT))    while (size-- > 0)      *str++ = c;  while (i < precision--)    *str++ = '0';  while (i-- > 0)    *str++ = tmp[i];  while (size-- > 0)    *str++ = ' ';  return str;}intlinux_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;	}      /* 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);	    }	  if (precision < 0)	    precision = 0;	}      /* get the conversion qualifier */      qualifier = -1;      if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L')	{	  qualifier = *fmt;	  ++fmt;	}      /* default base */      base = 10;      switch (*fmt)	{	case 'c':	  if (!(flags & LEFT))	    while (--field_width > 0)	      *str++ = ' ';	  *str++ = (unsigned char) va_arg (args, int);	  while (--field_width > 0)	    *str++ = ' ';	  continue;	case 's':	  s = va_arg (args, char *);	  if (!s)	    s = "<NULL>";	  len = strnlen (s, precision);	  if (!(flags & LEFT))	    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 *);	      flags |= ZEROPAD;	    }	  str = number (str,			(unsigned long) va_arg (args, void *), 16,			field_width, precision, flags);	  continue;	case 'n':	  if (qualifier == 'l')	    {	      long *ip = va_arg (args, long *);	      *ip = (str - buf);	    }	  else	    {	      int *ip = va_arg (args, int *);	      *ip = (str - buf);	    }	  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 (*fmt != '%')	    *str++ = '%';	  if (*fmt)	    *str++ = *fmt;	  else	    --fmt;	  continue;	}      if (qualifier == 'l')	num = va_arg (args, unsigned long);      else if (qualifier == 'h')	if (flags & SIGN)	  num = va_arg (args, short);	else	  num = va_arg (args, unsigned short);      else if (flags & SIGN)	num = va_arg (args, int);      else	num = va_arg (args, unsigned int);      str = number (str, num, base, field_width, precision, flags);    }  *str = '\0';  return str - buf;}intlinux_sprintf (char *buf, const char *fmt,...){  va_list args;  int i;  va_start (args, fmt);  i = linux_vsprintf (buf, fmt, args);  va_end (args);  return i;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -