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

📄 vfprintf.c

📁 绝对正真的stdio.h的实现
💻 C
📖 第 1 页 / 共 5 页
字号:
					.left = left,			      \					.showsign = showsign,		      \					.group = group,			      \					.pad = pad,			      \					.extra = 0,			      \					.i18n = use_outdigits,		      \					.wide = sizeof (CHAR_T) != 1 };	      \									      \	    if (is_long_double)						      \	      the_arg.pa_long_double = va_arg (ap, long double);	      \	    else							      \	      the_arg.pa_double = va_arg (ap, double);			      \	    ptr = (const void *) &the_arg;				      \									      \	    function_done = __printf_fp (s, &info, &ptr);		      \	  }								      \	else								      \	  {								      \	    ptr = (const void *) &args_value[fspec->data_arg];		      \									      \	    function_done = __printf_fp (s, &fspec->info, &ptr);	      \	  }								      \									      \	if (function_done < 0)						      \	  {								      \	    /* Error in print handler.  */				      \	    done = -1;							      \	    goto all_done;						      \	  }								      \									      \	done += function_done;						      \      }									      \      break;								      \									      \    LABEL (form_floathex):						      \      {									      \        /* Floating point number printed as hexadecimal number.  */	      \	const void *ptr;						      \	int function_done;						      \									      \	if (fspec == NULL)						      \	  {								      \	    struct printf_info info = { .prec = prec,			      \					.width = width,			      \					.spec = spec,			      \					.is_long_double = is_long_double,     \					.is_short = is_short,		      \					.is_long = is_long,		      \					.alt = alt,			      \					.space = space,			      \					.left = left,			      \					.showsign = showsign,		      \					.group = group,			      \					.pad = pad,			      \					.extra = 0,			      \					.wide = sizeof (CHAR_T) != 1 };	      \									      \	    if (is_long_double)						      \	      the_arg.pa_long_double = va_arg (ap, long double);	      \	    else							      \	      the_arg.pa_double = va_arg (ap, double);			      \	    ptr = (const void *) &the_arg;				      \									      \	    function_done = __printf_fphex (s, &info, &ptr);		      \	  }								      \	else								      \	  {								      \	    ptr = (const void *) &args_value[fspec->data_arg];		      \									      \	    function_done = __printf_fphex (s, &fspec->info, &ptr);	      \	  }								      \									      \	if (function_done < 0)						      \	  {								      \	    /* Error in print handler.  */				      \	    done = -1;							      \	    goto all_done;						      \	  }								      \									      \	done += function_done;						      \      }									      \      break;								      \									      \    LABEL (form_pointer):						      \      /* Generic pointer.  */						      \      {									      \	const void *ptr;						      \	if (fspec == NULL)						      \	  ptr = va_arg (ap, void *);					      \	else								      \	  ptr = args_value[fspec->data_arg].pa_pointer;			      \	if (ptr != NULL)						      \	  {								      \	    /* If the pointer is not NULL, write it as a %#x spec.  */	      \	    base = 16;							      \	    number.word = (unsigned long int) ptr;			      \	    is_negative = 0;						      \	    alt = 1;							      \	    group = 0;							      \	    spec = L_('x');						      \	    goto LABEL (number);					      \	  }								      \	else								      \	  {								      \	    /* Write "(nil)" for a nil pointer.  */			      \	    string = (CHAR_T *) L_("(nil)");				      \	    /* Make sure the full string "(nil)" is printed.  */	      \	    if (prec < 5)						      \	      prec = 5;							      \	    is_long = 0;	/* This is no wide-char string.  */	      \	    goto LABEL (print_string);					      \	  }								      \      }									      \      /* NOTREACHED */							      \									      \    LABEL (form_number):						      \      if (s->_flags2 & _IO_FLAGS2_FORTIFY)				      \	{								      \	  if (! readonly_format)					      \	    {								      \	      extern int __readonly_area (const void *, size_t)		      \		attribute_hidden;					      \	      readonly_format						      \		= __readonly_area (format, ((STR_LEN (format) + 1)	      \					    * sizeof (CHAR_T)));	      \	    }								      \	  if (readonly_format < 0)					      \	    __libc_fatal ("*** %n in writable segment detected ***\n");	      \	}								      \      /* Answer the count of characters written.  */			      \      if (fspec == NULL)						      \	{								      \	  if (is_longlong)						      \	    *(long long int *) va_arg (ap, void *) = done;		      \	  else if (is_long_num)						      \	    *(long int *) va_arg (ap, void *) = done;			      \	  else if (is_char)						      \	    *(char *) va_arg (ap, void *) = done;			      \	  else if (!is_short)						      \	    *(int *) va_arg (ap, void *) = done;			      \	  else								      \	    *(short int *) va_arg (ap, void *) = done;			      \	}								      \      else								      \	if (is_longlong)						      \	  *(long long int *) args_value[fspec->data_arg].pa_pointer = done;   \	else if (is_long_num)						      \	  *(long int *) args_value[fspec->data_arg].pa_pointer = done;	      \	else if (is_char)						      \	  *(char *) args_value[fspec->data_arg].pa_pointer = done;	      \	else if (!is_short)						      \	  *(int *) args_value[fspec->data_arg].pa_pointer = done;	      \	else								      \	  *(short int *) args_value[fspec->data_arg].pa_pointer = done;	      \      break;								      \									      \    LABEL (form_strerror):						      \      /* Print description of error ERRNO.  */				      \      string =								      \	(CHAR_T *) __strerror_r (save_errno, (char *) work_buffer,	      \				 sizeof work_buffer);			      \      is_long = 0;		/* This is no wide-char string.  */	      \      goto LABEL (print_string)#ifdef COMPILE_WPRINTF# define process_string_arg(fspec) \    LABEL (form_character):						      \      /* Character.  */							      \      if (is_long)							      \	goto LABEL (form_wcharacter);					      \      --width;	/* Account for the character itself.  */		      \      if (!left)							      \	PAD (L' ');							      \      if (fspec == NULL)						      \	outchar (__btowc ((unsigned char) va_arg (ap, int))); /* Promoted. */ \      else								      \	outchar (__btowc ((unsigned char)				      \			  args_value[fspec->data_arg].pa_int));		      \      if (left)								      \	PAD (L' ');							      \      break;								      \									      \    LABEL (form_wcharacter):						      \      {									      \	/* Wide character.  */						      \	--width;							      \	if (!left)							      \	  PAD (L' ');							      \        if (fspec == NULL)						      \	  outchar (va_arg (ap, wchar_t));				      \	else								      \	  outchar (args_value[fspec->data_arg].pa_wchar);		      \	if (left)							      \	  PAD (L' ');							      \      }									      \      break;								      \									      \    LABEL (form_string):						      \      {									      \	size_t len;							      \	int string_malloced;						      \									      \	/* The string argument could in fact be `char *' or `wchar_t *'.      \	   But this should not make a difference here.  */		      \	if (fspec == NULL)						      \	  string = (CHAR_T *) va_arg (ap, const wchar_t *);		      \	else								      \	  string = (CHAR_T *) args_value[fspec->data_arg].pa_wstring;	      \									      \	/* Entry point for printing other strings.  */			      \      LABEL (print_string):						      \									      \	string_malloced = 0;						      \	if (string == NULL)						      \	  {								      \	    /* Write "(null)" if there's space.  */			      \	    if (prec == -1						      \		|| prec >= (int) (sizeof (null) / sizeof (null[0])) - 1)      \	      {								      \		string = (CHAR_T *) null;				      \		len = (sizeof (null) / sizeof (null[0])) - 1;		      \	      }								      \	    else							      \	      {								      \		string = (CHAR_T *) L"";				      \		len = 0;						      \	      }								      \	  }								      \	else if (!is_long && spec != L_('S'))				      \	  {								      \	    /* This is complicated.  We have to transform the multibyte	      \	       string into a wide character string.  */			      \	    const char *mbs = (const char *) string;			      \	    mbstate_t mbstate;						      \									      \	    len = prec != -1 ? (size_t) prec : strlen (mbs);		      \									      \	    /* Allocate dynamically an array which definitely is long	      \	       enough for the wide character version.  */		      \	    if (__libc_use_alloca (len * sizeof (wchar_t)))		      \	      string = (CHAR_T *) alloca (len * sizeof (wchar_t));	      \	    else if ((string = (CHAR_T *) malloc (len * sizeof (wchar_t)))    \		     == NULL)						      \	      {								      \		done = -1;						      \		goto all_done;						      \	      }								      \	    else							      \	      string_malloced = 1;					      \									      \	    memset (&mbstate, '\0', sizeof (mbstate_t));		      \	    len = __mbsrtowcs (string, &mbs, len, &mbstate);		      \	    if (len == (size_t) -1)					      \	      {								      \		/* Illegal multibyte character.  */			      \		done = -1;						      \		goto all_done;						      \	      }								      \	  }								      \	else								      \	  {								      \	    if (prec != -1)						      \	      /* Search for the end of the string, but don't search past      \		 the length specified by the precision.  */		      \	      len = __wcsnlen (string, prec);				      \	    else							      \	      len = __wcslen (string);					      \	  }								      \									      \	if ((width -= len) < 0)						      \	  {								      \	    outstring (string, len);					      \	    break;							      \	  }								      \									      \	if (!left)							      \	  PAD (L' ');							      \	outstring (string, len);					      \	if (left)							      \	  PAD (L' ');							      \	if (__builtin_expect (string_malloced, 0))			      \	  free (string);						      \      }									      \      break;#else# define process_string_arg(fspec) \    LABEL (form_character):						      \      /* Character.  */							      \      if (is_long)							      \	goto LABEL (form_wcharacter);					      \      --width;	/* Account for the character itself.  */		      \      if (!left)							      \	PAD (' ');							      \      if (fspec == NULL)						      \	outchar ((unsigned char) va_arg (ap, int)); /* Promoted.  */	      \      else								      \	outchar ((unsigned char) args_value[fspec->data_arg].pa_int);	      \      if (left)								      \	PAD (' ');							      \      break;								      \									      \    LABEL (form_wcharacter):						      \      {									      \	/* Wide character.  */						      \	char buf[MB_CUR_MAX];						      \	mbstate_t mbstate;						      \	size_t len;							      \									      \	memset (&mbstate, '\0', sizeof (mbstate_t));			      \	len = __wcrtomb (buf, (fspec == NULL ? va_arg (ap, wchar_t)	      \			       : args_value[fspec->data_arg].pa_wchar),	      \			 &mbstate);					      \	if (len == (size_t) -1)						      \	  {								      \	    /* Something went wron gduring the conversion.  Bail out.  */     \	    done = -1;							      \	    goto all_done;						      \	  }								      \	width -= len;							      \	if (!left)							      \	  PAD (' ');							      \	outstring (buf, len);						      \	if (left)							      \	  PAD (' ');							      \      }									      \      break;								      \									      \    LABEL (form_string):						      \      {									      \	size_t len;							      \	int string_malloced;						      \									      \	/* The string argument could in fact be `char *' or `wchar_t *'.      \	   But this should not make a difference here.  */		      \	if (fspec == NULL)						      \	  string = (char *) va_arg (ap, const char *);			      \	else								      \	  string = (char *) args_value[fspec->data_arg].pa_string;	      \									      \	/* Entry point for printing other strings.  */			      \      LABEL (print_string):						      \									      \	string_malloced = 0;						      \	if (string == NULL)						      \	  {								      \	    /* Write "(null)" if there's space.  */			      \	    if (prec == -1 || prec >= (int) sizeof (null) - 1)		      \	      {								      \		string = (char *) null;					      \		len = sizeof (null) - 1;				      \	      }								      \	    else							      \	      {								      \		string = (char *) "";					      \		len = 0;						      \	      }								      \	  }								      \	else if (!is_long && spec != L_('S'))				      \	  {								      \	    if (prec != -1)						      \	      {								      \		/* Search for the end of the string, but don't search past    \		   the length (in bytes) specified by the precision.  Also    \		   don't use incomplete characters.  */			      \		if (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MB_CUR_MAX) == 1)   \		  len = __strnlen (string, prec);			      \		else							      \		  {							      \		    /* In case we have a multibyte character set the	      \		       situation is more compilcated.  We must not copy	      \		       bytes at the end which form an incomplete character. */\		    wchar_t ignore[prec];				      \		    const char *str2 = string;				      \		    mbstate_t ps;					      \									      \		    memset (&ps, '\0', sizeof (ps));			      \		    if (__mbsnrtowcs (ignore, &str2, prec, prec, &ps)	      \			== (size_t) -1)					      \		      {							      \			done = -1;					      \			goto all_done;					      \		      }							      \		    if (str2 == NULL)					      \		      len = strlen (string);				      \

⌨️ 快捷键说明

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