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

📄 vasnprintf.c

📁 一个扑克牌游戏集合的源码,包含了很多基本c-c++语言应用
💻 C
📖 第 1 页 / 共 2 页
字号:
/* vsprintf with automatic memory allocation.   Copyright (C) 1999, 2002-2005 Free Software Foundation, Inc.   This program is free software; you can redistribute it and/or modify it   under the terms of the GNU Library General Public License as published   by the Free Software Foundation; either version 2, or (at your option)   any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   Library General Public License for more details.   You should have received a copy of the GNU Library General Public   License along with this program; if not, write to the Free Software   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,   USA.  *//* Tell glibc's <stdio.h> to provide a prototype for snprintf().   This must come before <config.h> because <config.h> may include   <features.h>, and once <features.h> has been included, it's too late.  */#ifndef _GNU_SOURCE# define _GNU_SOURCE    1#endif#ifdef HAVE_CONFIG_H# include <config.h>#endif#ifndef IN_LIBINTL# include <alloca.h>#endif/* Specification.  */#if WIDE_CHAR_VERSION# include "vasnwprintf.h"#else# include "vasnprintf.h"#endif#include <stdio.h>	/* snprintf(), sprintf() */#include <stdlib.h>	/* abort(), malloc(), realloc(), free() */#include <string.h>	/* memcpy(), strlen() */#include <errno.h>	/* errno */#include <limits.h>	/* CHAR_BIT, INT_MAX */#include <float.h>	/* DBL_MAX_EXP, LDBL_MAX_EXP */#if WIDE_CHAR_VERSION# include "wprintf-parse.h"#else# include "printf-parse.h"#endif/* Checked size_t computations.  */#include "xsize.h"/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW.  */#ifndef EOVERFLOW# define EOVERFLOW E2BIG#endif#ifdef HAVE_WCHAR_T# ifdef HAVE_WCSLEN#  define local_wcslen wcslen# else   /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid      a dependency towards this library, here is a local substitute.      Define this substitute only once, even if this file is included      twice in the same compilation unit.  */#  ifndef local_wcslen_defined#   define local_wcslen_defined 1static size_tlocal_wcslen (const wchar_t *s){  const wchar_t *ptr;  for (ptr = s; *ptr != (wchar_t) 0; ptr++)    ;  return ptr - s;}#  endif# endif#endif#if WIDE_CHAR_VERSION# define VASNPRINTF vasnwprintf# define CHAR_T wchar_t# define DIRECTIVE wchar_t_directive# define DIRECTIVES wchar_t_directives# define PRINTF_PARSE wprintf_parse# define USE_SNPRINTF 1# if HAVE_DECL__SNWPRINTF   /* On Windows, the function swprintf() has a different signature than      on Unix; we use the _snwprintf() function instead.  */#  define SNPRINTF _snwprintf# else   /* Unix.  */#  define SNPRINTF swprintf# endif#else# define VASNPRINTF vasnprintf# define CHAR_T char# define DIRECTIVE char_directive# define DIRECTIVES char_directives# define PRINTF_PARSE printf_parse# define USE_SNPRINTF (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF)# if HAVE_DECL__SNPRINTF   /* Windows.  */#  define SNPRINTF _snprintf# else   /* Unix.  */#  define SNPRINTF snprintf# endif#endifCHAR_T *VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list args){  DIRECTIVES d;  arguments a;  if (PRINTF_PARSE (format, &d, &a) < 0)    {      errno = EINVAL;      return NULL;    }#define CLEANUP() \  free (d.dir);								\  if (a.arg)								\    free (a.arg);  if (printf_fetchargs (args, &a) < 0)    {      CLEANUP ();      errno = EINVAL;      return NULL;    }  {    size_t buf_neededlength;    CHAR_T *buf;    CHAR_T *buf_malloced;    const CHAR_T *cp;    size_t i;    DIRECTIVE *dp;    /* Output string accumulator.  */    CHAR_T *result;    size_t allocated;    size_t length;    /* Allocate a small buffer that will hold a directive passed to       sprintf or snprintf.  */    buf_neededlength =      xsum4 (7, d.max_width_length, d.max_precision_length, 6);#if HAVE_ALLOCA    if (buf_neededlength < 4000 / sizeof (CHAR_T))      {	buf = (CHAR_T *) alloca (buf_neededlength * sizeof (CHAR_T));	buf_malloced = NULL;      }    else#endif      {	size_t buf_memsize = xtimes (buf_neededlength, sizeof (CHAR_T));	if (size_overflow_p (buf_memsize))	  goto out_of_memory_1;	buf = (CHAR_T *) malloc (buf_memsize);	if (buf == NULL)	  goto out_of_memory_1;	buf_malloced = buf;      }    if (resultbuf != NULL)      {	result = resultbuf;	allocated = *lengthp;      }    else      {	result = NULL;	allocated = 0;      }    length = 0;    /* Invariants:       result is either == resultbuf or == NULL or malloc-allocated.       If length > 0, then result != NULL.  */    /* Ensures that allocated >= needed.  Aborts through a jump to       out_of_memory if needed is SIZE_MAX or otherwise too big.  */#define ENSURE_ALLOCATION(needed) \    if ((needed) > allocated)						     \      {									     \	size_t memory_size;						     \	CHAR_T *memory;							     \									     \	allocated = (allocated > 0 ? xtimes (allocated, 2) : 12);	     \	if ((needed) > allocated)					     \	  allocated = (needed);						     \	memory_size = xtimes (allocated, sizeof (CHAR_T));		     \	if (size_overflow_p (memory_size))				     \	  goto out_of_memory;						     \	if (result == resultbuf || result == NULL)			     \	  memory = (CHAR_T *) malloc (memory_size);			     \	else								     \	  memory = (CHAR_T *) realloc (result, memory_size);		     \	if (memory == NULL)						     \	  goto out_of_memory;						     \	if (result == resultbuf && length > 0)				     \	  memcpy (memory, result, length * sizeof (CHAR_T));		     \	result = memory;						     \      }    for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)      {	if (cp != dp->dir_start)	  {	    size_t n = dp->dir_start - cp;	    size_t augmented_length = xsum (length, n);	    ENSURE_ALLOCATION (augmented_length);	    memcpy (result + length, cp, n * sizeof (CHAR_T));	    length = augmented_length;	  }	if (i == d.count)	  break;	/* Execute a single directive.  */	if (dp->conversion == '%')	  {	    size_t augmented_length;	    if (!(dp->arg_index == ARG_NONE))	      abort ();	    augmented_length = xsum (length, 1);	    ENSURE_ALLOCATION (augmented_length);	    result[length] = '%';	    length = augmented_length;	  }	else	  {	    if (!(dp->arg_index != ARG_NONE))	      abort ();	    if (dp->conversion == 'n')	      {		switch (a.arg[dp->arg_index].type)		  {		  case TYPE_COUNT_SCHAR_POINTER:		    *a.arg[dp->arg_index].a.a_count_schar_pointer = length;		    break;		  case TYPE_COUNT_SHORT_POINTER:		    *a.arg[dp->arg_index].a.a_count_short_pointer = length;		    break;		  case TYPE_COUNT_INT_POINTER:		    *a.arg[dp->arg_index].a.a_count_int_pointer = length;		    break;		  case TYPE_COUNT_LONGINT_POINTER:		    *a.arg[dp->arg_index].a.a_count_longint_pointer = length;		    break;#ifdef HAVE_LONG_LONG		  case TYPE_COUNT_LONGLONGINT_POINTER:		    *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;		    break;#endif		  default:		    abort ();		  }	      }	    else	      {		arg_type type = a.arg[dp->arg_index].type;		CHAR_T *p;		unsigned int prefix_count;		int prefixes[2];#if !USE_SNPRINTF		size_t tmp_length;		CHAR_T tmpbuf[700];		CHAR_T *tmp;		/* Allocate a temporary buffer of sufficient size for calling		   sprintf.  */		{		  size_t width;		  size_t precision;		  width = 0;		  if (dp->width_start != dp->width_end)		    {		      if (dp->width_arg_index != ARG_NONE)			{			  int arg;			  if (!(a.arg[dp->width_arg_index].type == TYPE_INT))			    abort ();			  arg = a.arg[dp->width_arg_index].a.a_int;			  width = (arg < 0 ? (unsigned int) (-arg) : arg);			}		      else			{			  const CHAR_T *digitp = dp->width_start;			  do			    width = xsum (xtimes (width, 10), *digitp++ - '0');			  while (digitp != dp->width_end);			}		    }		  precision = 6;		  if (dp->precision_start != dp->precision_end)		    {		      if (dp->precision_arg_index != ARG_NONE)			{			  int arg;			  if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))			    abort ();			  arg = a.arg[dp->precision_arg_index].a.a_int;			  precision = (arg < 0 ? 0 : arg);			}		      else			{			  const CHAR_T *digitp = dp->precision_start + 1;			  precision = 0;			  while (digitp != dp->precision_end)			    precision = xsum (xtimes (precision, 10), *digitp++ - '0');			}		    }		  switch (dp->conversion)		    {		    case 'd': case 'i': case 'u':# ifdef HAVE_LONG_LONG		      if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)			tmp_length =			  (unsigned int) (sizeof (unsigned long long) * CHAR_BIT					  * 0.30103 /* binary -> decimal */					  * 2 /* estimate for FLAG_GROUP */					 )			  + 1 /* turn floor into ceil */			  + 1; /* account for leading sign */		      else# endif		      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)			tmp_length =			  (unsigned int) (sizeof (unsigned long) * CHAR_BIT					  * 0.30103 /* binary -> decimal */					  * 2 /* estimate for FLAG_GROUP */					 )			  + 1 /* turn floor into ceil */			  + 1; /* account for leading sign */		      else			tmp_length =			  (unsigned int) (sizeof (unsigned int) * CHAR_BIT					  * 0.30103 /* binary -> decimal */					  * 2 /* estimate for FLAG_GROUP */					 )			  + 1 /* turn floor into ceil */			  + 1; /* account for leading sign */		      break;		    case 'o':# ifdef HAVE_LONG_LONG		      if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)			tmp_length =			  (unsigned int) (sizeof (unsigned long long) * CHAR_BIT					  * 0.333334 /* binary -> octal */					 )			  + 1 /* turn floor into ceil */			  + 1; /* account for leading sign */		      else# endif		      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)			tmp_length =			  (unsigned int) (sizeof (unsigned long) * CHAR_BIT					  * 0.333334 /* binary -> octal */					 )			  + 1 /* turn floor into ceil */			  + 1; /* account for leading sign */		      else			tmp_length =			  (unsigned int) (sizeof (unsigned int) * CHAR_BIT					  * 0.333334 /* binary -> octal */					 )			  + 1 /* turn floor into ceil */			  + 1; /* account for leading sign */		      break;		    case 'x': case 'X':# ifdef HAVE_LONG_LONG		      if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)			tmp_length =			  (unsigned int) (sizeof (unsigned long long) * CHAR_BIT					  * 0.25 /* binary -> hexadecimal */					 )			  + 1 /* turn floor into ceil */			  + 2; /* account for leading sign or alternate form */		      else# endif		      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)			tmp_length =			  (unsigned int) (sizeof (unsigned long) * CHAR_BIT					  * 0.25 /* binary -> hexadecimal */					 )			  + 1 /* turn floor into ceil */			  + 2; /* account for leading sign or alternate form */		      else			tmp_length =			  (unsigned int) (sizeof (unsigned int) * CHAR_BIT					  * 0.25 /* binary -> hexadecimal */					 )			  + 1 /* turn floor into ceil */			  + 2; /* account for leading sign or alternate form */		      break;		    case 'f': case 'F':# ifdef HAVE_LONG_DOUBLE		      if (type == TYPE_LONGDOUBLE)			tmp_length =			  (unsigned int) (LDBL_MAX_EXP					  * 0.30103 /* binary -> decimal */					  * 2 /* estimate for FLAG_GROUP */					 )			  + 1 /* turn floor into ceil */			  + 10; /* sign, decimal point etc. */		      else# endif			tmp_length =			  (unsigned int) (DBL_MAX_EXP					  * 0.30103 /* binary -> decimal */					  * 2 /* estimate for FLAG_GROUP */					 )			  + 1 /* turn floor into ceil */			  + 10; /* sign, decimal point etc. */		      tmp_length = xsum (tmp_length, precision);		      break;		    case 'e': case 'E': case 'g': case 'G':		    case 'a': case 'A':		      tmp_length =			12; /* sign, decimal point, exponent etc. */		      tmp_length = xsum (tmp_length, precision);		      break;		    case 'c':# if defined HAVE_WINT_T && !WIDE_CHAR_VERSION		      if (type == TYPE_WIDE_CHAR)			tmp_length = MB_CUR_MAX;		      else# endif			tmp_length = 1;		      break;

⌨️ 快捷键说明

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