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

📄 vfprintf.c

📁 KPIT GNU Tools is a set of GNU development tools for Renesas microcontrollers.
💻 C
📖 第 1 页 / 共 4 页
字号:
		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,   FLAG,  /* 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,   SPEC,    SPEC,    SPEC,    OTHER,   SPEC,   /* 48-4f */  OTHER,   OTHER,   OTHER,   OTHER,   MODFR,   OTHER,   OTHER,   SPEC,   /* 50-57 */  OTHER,   OTHER,   OTHER,   SPEC,    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,    MODFR,   OTHER,   MODFR,   OTHER,   OTHER,   SPEC,   /* 70-77 */  SPEC,    MODFR,   OTHER,   SPEC,    MODFR,   SPEC,    OTHER,   OTHER,  /* 78-7f */  SPEC,    OTHER,   MODFR,   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 *_DEFUN(get_arg, (data, n, fmt, ap, numargs_p, args, arg_type, last_fmt),       struct _reent *data _AND       int n               _AND       char *fmt           _AND       va_list *ap         _AND       int *numargs_p      _AND       union arg_val *args _AND       int *arg_type       _AND       char **last_fmt){  int ch;  int number, flags;  int spec_type;  int numargs = *numargs_p;  CH_CLASS chtype;  STATE state, next_state;  ACTION action;  int pos, last_arg;  int max_pos_arg = n;  enum types { INT, LONG_INT, SHORT_INT, CHAR_INT, QUAD_INT, CHAR, CHAR_PTR, DOUBLE, LONG_DOUBLE, WIDE_CHAR };#ifdef _MB_CAPABLE  wchar_t wc;  mbstate_t wc_state;  int nbytes; #endif      /* if this isn't the first call, pick up where we left off last time */  if (*last_fmt != NULL)    fmt = *last_fmt;#ifdef _MB_CAPABLE  memset (&wc_state, '\0', sizeof (wc_state));#endif  /* 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)    {#ifdef _MB_CAPABLE      while ((nbytes = _mbtowc_r (data, &wc, fmt, MB_CUR_MAX, &wc_state)) > 0) 	{	  fmt += nbytes;	  if (wc == '%') 	    break;	}      if (nbytes <= 0)	break;#else      while (*fmt != '\0' && *fmt != '%')	fmt += 1;      if (*fmt == '\0')	break;#endif      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':		  if (*fmt == 'h')		    {		      flags |= CHARINT;		      ++fmt;		    }		  else		    flags |= SHORTINT;		  break;		case 'L':		  flags |= LONGDBL;		  break;		case 'q':		  flags |= QUADINT;		  break;		case 'j':		  if (sizeof (intmax_t) == sizeof (long))		    flags |= LONGINT;		  else		    flags |= QUADINT;		  break;		case 'z':		  if (sizeof (size_t) < sizeof (int))		    /* POSIX states size_t is 16 or more bits, as is short.  */		    flags |= SHORTINT;		  else if (sizeof (size_t) == sizeof (int))		    /* no flag needed */;		  else if (sizeof (size_t) <= sizeof (long))		    flags |= LONGINT;		  else		    /* POSIX states that at least one programming		       environment must support size_t no wider than		       long, but that means other environments can		       have size_t as wide as long long.  */		    flags |= QUADINT;		  break;		case 't':		  if (sizeof (ptrdiff_t) < sizeof (int))		    /* POSIX states ptrdiff_t is 16 or more bits, as		       is short.  */		    flags |= SHORTINT;		  else if (sizeof (ptrdiff_t) == sizeof (int))		    /* no flag needed */;		  else if (sizeof (ptrdiff_t) <= sizeof (long))		    flags |= LONGINT;		  else		    /* POSIX states that at least one programming		       environment must support ptrdiff_t no wider than		       long, but that means other environments can		       have ptrdiff_t as wide as long long.  */		    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;		    else if (flags & CHARINT)		      spec_type = CHAR_INT;#ifndef _NO_LONGLONG		    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 'S':		  case 'p':		    spec_type = CHAR_PTR;		    break;		  case 'c':		    spec_type = CHAR;		    break;		  case 'C':		    spec_type = WIDE_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 WIDE_CHAR:			args[numargs++].val_wint_t = va_arg (*ap, wint_t);			break;		      case CHAR:		      case CHAR_INT:		      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 WIDE_CHAR:	  args[numargs++].val_wint_t = va_arg (*ap, wint_t);	  break;	case INT:	case CHAR_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 + -