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

📄 vfprintf.c

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 C
📖 第 1 页 / 共 3 页
字号:
					PRINT(".", 1);					PRINT(cp, ndig-expt);				}			} else {	/* 'e' or 'E' */				if (ndig > 1 || flags & ALT) {					ox[0] = *cp++;					ox[1] = '.';					PRINT(ox, 2);                                       if (_fpvalue) {						PRINT(cp, ndig-1);					} else	/* 0.[0..] */						/* __dtoa irregularity */						PAD(ndig - 1, zeroes);				} else	/* XeYYY */					PRINT(cp, 1);				PRINT(expstr, expsize);			}		}#else		PRINT(cp, size);#endif		/* left-adjusting padding (always blank) */		if (flags & LADJUST)			PAD(width - realsz, blanks);		/* finally, adjust ret */		ret += width > realsz ? width : realsz;		FLUSH();	/* copy out the I/O vectors */	}done:	FLUSH();error:	return (__sferror(fp) ? EOF : ret);	/* NOTREACHED */}#ifdef FLOATING_POINT#ifdef _NO_LONGDBLextern char *_dtoa_r _PARAMS((struct _reent *, double, int,			      int, int *, int *, char **));#elseextern char *_ldtoa_r _PARAMS((struct _reent *, _LONG_DOUBLE, int,			      int, int *, int *, char **));#undef word0#define word0(x) ldword0(x)#endifstatic char *cvt(data, value, ndigits, flags, sign, decpt, ch, length)	struct _reent *data;#ifdef _NO_LONGDBL	double value;#else	_LONG_DOUBLE value;#endif	int ndigits, flags, *decpt, ch, *length;	char *sign;{	int mode, dsgn;	char *digits, *bp, *rve;#ifdef _NO_LONGDBL        union double_union tmp;#else        struct ldieee *ldptr;#endif	if (ch == 'f') {		mode = 3;		/* ndigits after the decimal point */	} else {		/* To obtain ndigits after the decimal point for the 'e' 		 * and 'E' formats, round to ndigits + 1 significant 		 * figures.		 */		if (ch == 'e' || ch == 'E') {			ndigits++;		}		mode = 2;		/* ndigits significant digits */	}#ifdef _NO_LONGDBL        tmp.d = value;	if (word0(tmp) & Sign_bit) { /* this will check for < 0 and -0.0 */		value = -value;		*sign = '-';        } else		*sign = '\000';	digits = _dtoa_r(data, value, mode, ndigits, decpt, &dsgn, &rve);#else /* !_NO_LONGDBL */	ldptr = (struct ldieee *)&value;	if (ldptr->sign) { /* this will check for < 0 and -0.0 */		value = -value;		*sign = '-';        } else		*sign = '\000';	digits = _ldtoa_r(data, value, mode, ndigits, decpt, &dsgn, &rve);#endif /* !_NO_LONGDBL */	if ((ch != 'g' && ch != 'G') || flags & ALT) {	/* Print trailing zeros */		bp = digits + ndigits;		if (ch == 'f') {			if (*digits == '0' && value)				*decpt = -ndigits + 1;			bp += *decpt;		}		if (value == 0)	/* kludge for __dtoa irregularity */			rve = bp;		while (rve < bp)			*rve++ = '0';	}	*length = rve - digits;	return (digits);}static intexponent(p0, exp, fmtch)	char *p0;	int exp, fmtch;{	register char *p, *t;	char expbuf[40];	p = p0;	*p++ = fmtch;	if (exp < 0) {		exp = -exp;		*p++ = '-';	}	else		*p++ = '+';	t = expbuf + 40;	if (exp > 9) {		do {			*--t = to_char(exp % 10);		} while ((exp /= 10) > 9);		*--t = to_char(exp);		for (; t < expbuf + 40; *p++ = *t++);	}	else {		*p++ = '0';		*p++ = to_char(exp);	}	return (p - p0);}#endif /* FLOATING_POINT */#ifndef _NO_POS_ARGS/* Positional argument support.   Written by Jeff Johnston   Copyright (c) 2002 Red Hat Incorporated.   All rights reserved.   Redistribution and use in source and binary forms, with or without   modification, are permitted provided that the following conditions are met:      Redistributions of source code must retain the above copyright      notice, this list of conditions and the following disclaimer.      Redistributions in binary form must reproduce the above copyright      notice, this list of conditions and the following disclaimer in the      documentation and/or other materials provided with the distribution.            The name of Red Hat Incorporated may not be used to endorse      or promote products derived from this software without specific      prior written permission.   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE   DISCLAIMED.  IN NO EVENT SHALL RED HAT INCORPORATED BE LIABLE FOR ANY   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */typedef enum {  ZERO,   /* '0' */  DIGIT,  /* '1-9' */  DOLLAR, /* '$' */  MODFR,  /* spec modifier */  SPEC,   /* format specifier */  DOT,    /* '.' */  STAR,   /* '*' */  FLAG,   /* format flag */  OTHER,  /* all other chars */   MAX_CH_CLASS /* place-holder */} CH_CLASS;typedef enum {   START,  /* start */  SFLAG,  /* seen a flag */  WDIG,   /* seen digits in width area */  WIDTH,  /* processed width */  SMOD,   /* seen spec modifier */  SDOT,   /* seen dot */   VARW,   /* have variable width specifier */  VARP,   /* have variable precision specifier */  PREC,   /* processed precision */  VWDIG,  /* have digits in variable width specification */  VPDIG,  /* have digits in variable precision specification */  DONE,   /* done */     MAX_STATE, /* place-holder */ } STATE;typedef enum {  NOOP,  /* do nothing */  NUMBER, /* build a number from digits */  SKIPNUM, /* skip over digits */  GETMOD,  /* get and process format modifier */  GETARG,  /* get and process argument */  GETPW,   /* get variable precision or width */  GETPWB,  /* get variable precision or width and pushback fmt char */  GETPOS,  /* get positional parameter value */  PWPOS,   /* get positional parameter value for variable width or precision */} ACTION;const static CH_CLASS chclass[256] = {  /* 00-07 */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* 08-0f */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* 10-17 */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* 18-1f */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* 20-27 */  FLAG,    OTHER,   OTHER,   FLAG,    DOLLAR,  OTHER,   OTHER,   OTHER,  /* 28-2f */  OTHER,   OTHER,   STAR,    FLAG,    OTHER,   FLAG,    DOT,     OTHER,  /* 30-37 */  ZERO,    DIGIT,   DIGIT,   DIGIT,   DIGIT,   DIGIT,   DIGIT,   DIGIT,  /* 38-3f */  DIGIT,   DIGIT,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* 40-47 */  OTHER,   OTHER,   OTHER,   OTHER,   SPEC,    SPEC,    OTHER,   SPEC,   /* 48-4f */  OTHER,   OTHER,   OTHER,   OTHER,   MODFR,   OTHER,   OTHER,   SPEC,   /* 50-57 */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   SPEC,    OTHER,   SPEC,   /* 58-5f */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* 60-67 */  OTHER,   OTHER,   OTHER,   SPEC,    SPEC,    SPEC,    SPEC,    SPEC,   /* 68-6f */  MODFR,   SPEC,    OTHER,   OTHER,   MODFR,   OTHER,   OTHER,   SPEC,   /* 70-77 */  SPEC,    MODFR,   OTHER,   SPEC,    OTHER,   SPEC,    OTHER,   OTHER,  /* 78-7f */  SPEC,    OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* 80-87 */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* 88-8f */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* 90-97 */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* 98-9f */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* a0-a7 */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* a8-af */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* b0-b7 */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* b8-bf */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* c0-c7 */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* c8-cf */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* d0-d7 */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* d8-df */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* e0-e7 */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* e8-ef */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* f0-f7 */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,  /* f8-ff */  OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,   OTHER,};const static STATE state_table[MAX_STATE][MAX_CH_CLASS] = {  /*             '0'     '1-9'     '$'     MODFR    SPEC    '.'     '*'    FLAG    OTHER */   /* START */  { SFLAG,   WDIG,    DONE,   SMOD,    DONE,   SDOT,  VARW,   SFLAG,  DONE },  /* SFLAG */  { SFLAG,   WDIG,    DONE,   SMOD,    DONE,   SDOT,  VARW,   SFLAG,  DONE },  /* WDIG  */  { DONE,    DONE,    WIDTH,  SMOD,    DONE,   SDOT,  DONE,   DONE,   DONE },  /* WIDTH */  { DONE,    DONE,    DONE,   SMOD,    DONE,   SDOT,  DONE,   DONE,   DONE },  /* SMOD  */  { DONE,    DONE,    DONE,   DONE,    DONE,   DONE,  DONE,   DONE,   DONE },  /* SDOT  */  { SDOT,    PREC,    DONE,   SMOD,    DONE,   DONE,  VARP,   DONE,   DONE },  /* VARW  */  { DONE,    VWDIG,   DONE,   SMOD,    DONE,   SDOT,  DONE,   DONE,   DONE },  /* VARP  */  { DONE,    VPDIG,   DONE,   SMOD,    DONE,   DONE,  DONE,   DONE,   DONE },  /* PREC  */  { DONE,    DONE,    DONE,   SMOD,    DONE,   DONE,  DONE,   DONE,   DONE },  /* VWDIG */  { DONE,    DONE,    WIDTH,  DONE,    DONE,   DONE,  DONE,   DONE,   DONE },  /* VPDIG */  { DONE,    DONE,    PREC,   DONE,    DONE,   DONE,  DONE,   DONE,   DONE },};const static ACTION action_table[MAX_STATE][MAX_CH_CLASS] = {  /*             '0'     '1-9'     '$'     MODFR    SPEC    '.'     '*'    FLAG    OTHER */   /* START */  { NOOP,    NUMBER,  NOOP,   GETMOD,  GETARG, NOOP,  NOOP,   NOOP,   NOOP },  /* SFLAG */  { NOOP,    NUMBER,  NOOP,   GETMOD,  GETARG, NOOP,  NOOP,   NOOP,   NOOP },  /* WDIG  */  { NOOP,    NOOP,    GETPOS, GETMOD,  GETARG, NOOP,  NOOP,   NOOP,   NOOP },  /* WIDTH */  { NOOP,    NOOP,    NOOP,   GETMOD,  GETARG, NOOP,  NOOP,   NOOP,   NOOP },  /* SMOD  */  { NOOP,    NOOP,    NOOP,   NOOP,    GETARG, NOOP,  NOOP,   NOOP,   NOOP },  /* SDOT  */  { NOOP,    SKIPNUM, NOOP,   GETMOD,  GETARG, NOOP,  NOOP,   NOOP,   NOOP },  /* VARW  */  { NOOP,    NUMBER,  NOOP,   GETPW,   GETPWB, GETPW, NOOP,   NOOP,   NOOP },  /* VARP  */  { NOOP,    NUMBER,  NOOP,   GETPW,   GETPWB, NOOP,  NOOP,   NOOP,   NOOP },  /* PREC  */  { NOOP,    NOOP,    NOOP,   GETMOD,  GETARG, NOOP,  NOOP,   NOOP,   NOOP },  /* VWDIG */  { NOOP,    NOOP,    PWPOS,  NOOP,    NOOP,   NOOP,  NOOP,   NOOP,   NOOP },  /* VPDIG */  { NOOP,    NOOP,    PWPOS,  NOOP,    NOOP,   NOOP,  NOOP,   NOOP,   NOOP },};/* function to get positional parameter N where n = N - 1 */static union arg_val *get_arg (int n, char *fmt, va_list *ap, int *numargs_p, union arg_val *args, 	int *arg_type, char **last_fmt) {  int ch;  wchar_t wc;  int nbytes, number, flags;  int spec_type;  int numargs = *numargs_p;  CH_CLASS chtype;  STATE state, next_state;  ACTION action;  int pos, last_arg;  mbstate_t wc_state;  int max_pos_arg = n;  enum types { INT, LONG_INT, SHORT_INT, QUAD_INT, CHAR, CHAR_PTR, DOUBLE, LONG_DOUBLE };    /* if this isn't the first call, pick up where we left off last time */  if (*last_fmt != NULL)    fmt = *last_fmt;  memset (&wc_state, '\0', sizeof (wc_state));  /* we need to process either to end of fmt string or until we have actually     read the desired parameter from the vararg list. */  while (*fmt && n >= numargs)    {      while ((nbytes = _mbtowc_r(_REENT, &wc, fmt, MB_CUR_MAX, &wc_state)) > 0) 	{	  fmt += nbytes;	  if (wc == '%') 	    break;	}            if (nbytes <= 0)	break;      state = START;      flags = 0;      pos = -1;      number = 0;      spec_type = INT;      /* Use state/action table to process format specifiers.  We ignore invalid         formats and we are only interested in information that tells us how to         read the vararg list. */      while (state != DONE)	{	  ch = *fmt++;	  chtype = chclass[ch];	  next_state = state_table[state][chtype];	  action = action_table[state][chtype];	  state = next_state;	  	  switch (action)	    {	    case GETMOD:  /* we have format modifier */	      switch (ch)		{		case 'h':		  flags |= SHORTINT;		  break;		case 'L':		  flags |= LONGDBL;		  break;		case 'q':		  flags |= QUADINT;		  break;		case 'l':		default:		  if (*fmt == 'l')		    {		      flags |= QUADINT;		      ++fmt;		    }		  else		    flags |= LONGINT;		  break;		}	      break;	    case GETARG: /* we have format specifier */	      {		numargs &= (MAX_POS_ARGS - 1);		/* process the specifier and translate it to a type to fetch from varargs */		switch (ch)		  {		  case 'd':		  case 'i':		  case 'o':		  case 'x':		  case 'X':		  case 'u':		    if (flags & LONGINT)		      spec_type = LONG_INT;		    else if (flags & SHORTINT)		      spec_type = SHORT_INT;#ifndef _NO_LONG_LONG		    else if (flags & QUADINT)		      spec_type = QUAD_INT;#endif		    else		      spec_type = INT;		    break;		  case 'D':		  case 'U':		  case 'O':		    spec_type = LONG_INT;		    break;		  case 'f':		  case 'g':		  case 'G':		  case 'E':		  case 'e':#ifndef _NO_LONGDBL		    if (flags & LONGDBL)		      spec_type = LONG_DOUBLE;		    else#endif		      spec_type = DOUBLE;		    break;		  case 's':		  case 'p':		    spec_type = CHAR_PTR;		    break;		  case 'c':		    spec_type = CHAR;		    break;		  }		/* if we have a positional parameter, just store the type, otherwise		   fetch the parameter from the vararg list */		if (pos != -1)		  arg_type[pos] = spec_type;		else		  {		    switch (spec_type)		      {		      case LONG_INT:			args[numargs++].val_long = va_arg(*ap, long);			break;		      case QUAD_INT:			args[numargs++].val_quad_t = va_arg(*ap, quad_t);			break;		      case CHAR:		      case SHORT_INT:		      case INT:			args[numargs++].val_int = va_arg(*ap, int);			break;		      case CHAR_PTR:			args[numargs++].val_char_ptr_t = va_arg(*ap, char *);			break;		      case DOUBLE:			args[numargs++].val_double = va_arg(*ap, double);			break;		      case LONG_DOUBLE:			args[numargs++].val__LONG_DOUBLE = va_arg(*ap, _LONG_DOUBLE);			break;		      }		  }	      }	      break;	    case GETPOS: /* we have positional specifier */	      if (arg_type[0] == -1)		memset (arg_type, 0, sizeof(int) * MAX_POS_ARGS);	      pos = number - 1;	      max_pos_arg = (max_pos_arg > pos ? max_pos_arg : pos);	      break;	    case PWPOS:  /* we have positional specifier for width or precision */	      if (arg_type[0] == -1)		memset (arg_type, 0, sizeof(int) * MAX_POS_ARGS);	      number -= 1;	      arg_type[number] = INT;	      max_pos_arg = (max_pos_arg > number ? max_pos_arg : number);	      break;	    case GETPWB: /* we require format pushback */	      --fmt;	      /* fallthrough */	    case GETPW:  /* we have a variable precision or width to acquire */	      args[numargs++].val_int = va_arg(*ap, int);	      break;	    case NUMBER: /* we have a number to process */	      number = (ch - '0');	      while ((ch = *fmt) != '\0' && is_digit(ch))		{		  number = number * 10 + (ch - '0');		  ++fmt;		}	      break;	    case SKIPNUM: /* we have a number to skip */	      while ((ch = *fmt) != '\0' && is_digit(ch))		++fmt;	      break;	    case NOOP:	    default:	      break; /* do nothing */	    }	}    }  /* process all arguments up to at least the one we are looking for and if we     have seen the end of the string, then process up to the max argument needed */  if (*fmt == '\0')    last_arg = max_pos_arg;  else    last_arg = n;  while (numargs <= last_arg)    {      switch (arg_type[numargs])	{	case LONG_INT:	  args[numargs++].val_long = va_arg(*ap, long);	  break;	case QUAD_INT:	  args[numargs++].val_quad_t = va_arg(*ap, quad_t);	  break;	case CHAR_PTR:	  args[numargs++].val_char_ptr_t = va_arg(*ap, char *);	  break;	case DOUBLE:	  args[numargs++].val_double = va_arg(*ap, double);	  break;	case LONG_DOUBLE:	  args[numargs++].val__LONG_DOUBLE = va_arg(*ap, _LONG_DOUBLE);	  break;	case INT:	case SHORT_INT:	case CHAR:	default:	  args[numargs++].val_int = va_arg(*ap, int);	  break;	}    }  /* alter the global numargs value and keep a reference to the last bit of the fmt     string we processed here because the caller will continue processing where we started */  *numargs_p = numargs;  *last_fmt = fmt;  return &args[n];}#endif /* !_NO_POS_ARGS */

⌨️ 快捷键说明

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