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

📄 vfscanf.c

📁 KPIT GNU Tools is a set of GNU development tools for Renesas microcontrollers.
💻 C
📖 第 1 页 / 共 2 页
字号:
		      if (__srefill_r (rptr, fp))			{			  if (sum == 0)			    goto input_failure;			  break;			}		    }		  else		    {		      sum += width;		      fp->_r -= width;		      fp->_p += width;		      break;		    }		}	      nread += sum;	    }	  else	    {	      size_t r = fread ((_PTR) va_arg (ap, char *), 1, width, fp);	      if (r == 0)		goto input_failure;	      nread += r;	      nassigned++;	    }	  break;	case CT_CCL:	  /* scan a (nonempty) character class (sets NOSKIP) */	  if (width == 0)	    width = ~0;		/* `infinity' */	  /* take only those things in the class */	  if (flags & SUPPRESS)	    {	      n = 0;	      while (ccltab[*fp->_p])		{		  n++, fp->_r--, fp->_p++;		  if (--width == 0)		    break;		  if (BufferEmpty)		    {		      if (n == 0)			goto input_failure;		      break;		    }		}	      if (n == 0)		goto match_failure;	    }	  else	    {	      p0 = p = va_arg (ap, char *);	      while (ccltab[*fp->_p])		{		  fp->_r--;		  *p++ = *fp->_p++;		  if (--width == 0)		    break;		  if (BufferEmpty)		    {		      if (p == p0)			goto input_failure;		      break;		    }		}	      n = p - p0;	      if (n == 0)		goto match_failure;	      *p = 0;	      nassigned++;	    }	  nread += n;	  break;	case CT_STRING:	  /* like CCL, but zero-length string OK, & no NOSKIP */	  if (width == 0)            width = (size_t)~0;          if (flags & LONG)             {              /* Process %S and %ls placeholders */              if ((flags & SUPPRESS) == 0)                wcp = va_arg (ap, wchar_t *);              else                wcp = &wc;              n = 0;              while (!isspace (*fp->_p) && width != 0)                 {                  if (n == MB_CUR_MAX)                    goto input_failure;                  buf[n++] = *fp->_p;                  fp->_r -= 1;                  fp->_p += 1;                  memset ((_PTR)&state, '\0', sizeof (mbstate_t));                  if ((mbslen = _mbrtowc_r (rptr, wcp, buf, n, &state))                                                         == (size_t)-1)                    goto input_failure;                  if (mbslen == 0)                    *wcp = L'\0';                  if (mbslen != (size_t)-2) /* Incomplete sequence */                    {                      if (iswspace(*wcp))                         {                          while (n != 0)                            ungetc (buf[--n], fp);                          break;                        }                      nread += n;                      width -= 1;                      if ((flags & SUPPRESS) == 0)                        wcp += 1;                      n = 0;                    }                  if (BufferEmpty)                     {                      if (n != 0)                        goto input_failure;                      break;                    }                }              if (!(flags & SUPPRESS))                 {                  *wcp = L'\0';                  nassigned++;                }            }          else if (flags & SUPPRESS) 	    {	      n = 0;	      while (!isspace (*fp->_p))		{		  n++, fp->_r--, fp->_p++;		  if (--width == 0)		    break;		  if (BufferEmpty)		    break;		}	      nread += n;	    }	  else	    {	      p0 = p = va_arg (ap, char *);	      while (!isspace (*fp->_p))		{		  fp->_r--;		  *p++ = *fp->_p++;		  if (--width == 0)		    break;		  if (BufferEmpty)		    break;		}	      *p = 0;	      nread += p - p0;	      nassigned++;	    }	  continue;	case CT_INT:	{	  /* scan an integer as if by strtol/strtoul */	  unsigned width_left = 0;	  int skips = 0;#ifdef hardway	  if (width == 0 || width > sizeof (buf) - 1)#else	  /* size_t is unsigned, hence this optimisation */	  if (width - 1 > sizeof (buf) - 2)#endif	    {	      width_left = width - (sizeof (buf) - 1);	      width = sizeof (buf) - 1;	    }	  flags |= SIGNOK | NDIGITS | NZDIGITS | NNZDIGITS;	  for (p = buf; width; width--)	    {	      c = *fp->_p;	      /*	       * Switch on the character; `goto ok' if we	       * accept it as a part of number.	       */	      switch (c)		{		  /*		   * The digit 0 is always legal, but is special.		   * For %i conversions, if no digits (zero or nonzero)		   * have been scanned (only signs), we will have base==0.		   * In that case, we should set it to 8 and enable 0x		   * prefixing. Also, if we have not scanned zero digits		   * before this, do not turn off prefixing (someone else		   * will turn it off if we have scanned any nonzero digits).		   */		case '0':		  if (! (flags & NNZDIGITS))		    goto ok;		  if (base == 0)		    {		      base = 8;		      flags |= PFXOK;		    }		  if (flags & NZDIGITS)		    {		      flags &= ~(SIGNOK | NZDIGITS | NDIGITS);		      goto ok;		    }		  flags &= ~(SIGNOK | PFXOK | NDIGITS);		  if (width_left)		    {		      width_left--;		      width++;		    }		  ++skips;		  goto skip;		  /* 1 through 7 always legal */		case '1':		case '2':		case '3':		case '4':		case '5':		case '6':		case '7':		  base = basefix[base];		  flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);		  goto ok;		  /* digits 8 and 9 ok iff decimal or hex */		case '8':		case '9':		  base = basefix[base];		  if (base <= 8)		    break;	/* not legal here */		  flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);		  goto ok;		  /* letters ok iff hex */		case 'A':		case 'B':		case 'C':		case 'D':		case 'E':		case 'F':		case 'a':		case 'b':		case 'c':		case 'd':		case 'e':		case 'f':		  /* no need to fix base here */		  if (base <= 10)		    break;	/* not legal here */		  flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);		  goto ok;		  /* sign ok only as first character */		case '+':		case '-':		  if (flags & SIGNOK)		    {		      flags &= ~SIGNOK;		      goto ok;		    }		  break;		  /* x ok iff flag still set & 2nd char */		case 'x':		case 'X':		  if (flags & PFXOK && p == buf + 1)		    {		      base = 16;/* if %i */		      flags &= ~PFXOK;		      /* We must reset the NZDIGITS and NDIGITS		         flags that would have been unset by seeing			 the zero that preceded the X or x.  */		      flags |= NZDIGITS | NDIGITS;		      goto ok;		    }		  break;		}	      /*	       * If we got here, c is not a legal character	       * for a number.  Stop accumulating digits.	       */	      break;	    ok:	      /*	       * c is legal: store it and look at the next.	       */	      *p++ = c;	    skip:	      if (--fp->_r > 0)		fp->_p++;	      else	      if (__srefill_r (rptr, fp))		break;		/* EOF */	    }	  /*	   * If we had only a sign, it is no good; push back the sign.	   * If the number ends in `x', it was [sign] '0' 'x', so push back	   * the x and treat it as [sign] '0'.	   */	  if (flags & NDIGITS)	    {	      if (p > buf)		_CAST_VOID ungetc (*(u_char *)-- p, fp);	      goto match_failure;	    }	  c = ((u_char *) p)[-1];	  if (c == 'x' || c == 'X')	    {	      --p;	      /*(void)*/ ungetc (c, fp);	    }	  if ((flags & SUPPRESS) == 0)	    {	      u_long res;	      *p = 0;	      res = (*ccfn) (rptr, buf, (char **) NULL, base);	      if (flags & POINTER)		*(va_arg (ap, _PTR *)) = (_PTR) (unsigned _POINTER_INT) res;	      else if (flags & CHAR)		{		  cp = va_arg (ap, char *);		  *cp = res;		}	      else if (flags & SHORT)		{		  sp = va_arg (ap, short *);		  *sp = res;		}	      else if (flags & LONG)		{		  lp = va_arg (ap, long *);		  *lp = res;		}#ifndef _NO_LONGLONG	      else if (flags & LONGDBL)		{		  u_long_long resll;		  if (ccfn == _strtoul_r)		    resll = _strtoull_r (rptr, buf, (char **) NULL, base);		  else		    resll = _strtoll_r (rptr, buf, (char **) NULL, base);		  llp = va_arg (ap, long long*);		  *llp = resll;		}#endif	      else		{		  ip = va_arg (ap, int *);		  *ip = res;		}	      nassigned++;	    }	  nread += p - buf + skips;	  break;	}#ifdef FLOATING_POINT	case CT_FLOAT:	{	  /* scan a floating point number as if by strtod */	  /* This code used to assume that the number of digits is reasonable.	     However, ANSI / ISO C makes no such stipulation; we have to get	     exact results even when there is an unreasonable amount of	     leading zeroes.  */	  long leading_zeroes = 0;	  long zeroes, exp_adjust;	  char *exp_start = NULL;	  unsigned width_left = 0;	  int nancount = 0;#ifdef hardway	  if (width == 0 || width > sizeof (buf) - 1)#else	  /* size_t is unsigned, hence this optimisation */	  if (width - 1 > sizeof (buf) - 2)#endif	    {	      width_left = width - (sizeof (buf) - 1);	      width = sizeof (buf) - 1;	    }	  flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;	  zeroes = 0;	  exp_adjust = 0;	  for (p = buf; width; )	    {	      c = *fp->_p;	      /*	       * This code mimicks the integer conversion	       * code, but is much simpler.	       */	      switch (c)		{		case '0':		  if (flags & NDIGITS)		    {		      flags &= ~SIGNOK;		      zeroes++;		      if (width_left)			{			  width_left--;			  width++;			}		      goto fskip;		    }		  /* Fall through.  */		case '1':		case '2':		case '3':		case '4':		case '5':		case '6':		case '7':		case '8':		case '9':		  if (nancount == 0)		    {		      flags &= ~(SIGNOK | NDIGITS);		      goto fok;		    }		  break;		case '+':		case '-':		  if (flags & SIGNOK)		    {		      flags &= ~SIGNOK;		      goto fok;		    }		  break;		case 'n':		case 'N':	          if (nancount == 0		      && (flags & (SIGNOK | NDIGITS | DPTOK | EXPOK)) ==		      	          (SIGNOK | NDIGITS | DPTOK | EXPOK))		    {		      flags &= ~(SIGNOK | DPTOK | EXPOK | NDIGITS);		      nancount = 1;		      goto fok;		    }		  else if (nancount == 2)		    {		      nancount = 3;		      goto fok;		    }		  break;		case 'a':		case 'A':		  if (nancount == 1)		    {		      nancount = 2;		      goto fok;		    }		  break;		case '.':		  if (flags & DPTOK)		    {		      flags &= ~(SIGNOK | DPTOK);		      leading_zeroes = zeroes;		      goto fok;		    }		  break;		case 'e':		case 'E':		  /* no exponent without some digits */		  if ((flags & (NDIGITS | EXPOK)) == EXPOK		      || ((flags & EXPOK) && zeroes))		    {		      if (! (flags & DPTOK))			{			  exp_adjust = zeroes - leading_zeroes;			  exp_start = p;			}		      flags =			(flags & ~(EXPOK | DPTOK)) |			SIGNOK | NDIGITS;		      zeroes = 0;		      goto fok;		    }		  break;		}	      break;	    fok:	      *p++ = c;	    fskip:	      width--;              ++nread;	      if (--fp->_r > 0)		fp->_p++;	      else	      if (__srefill_r (rptr, fp))		break;		/* EOF */	    }	  if (zeroes)	    flags &= ~NDIGITS;          /* We may have a 'N' or possibly even a 'Na' as the start of 'NaN', 	     only to run out of chars before it was complete (or having 	     encountered a non- matching char).  So check here if we have an 	     outstanding nancount, and if so put back the chars we did 	     swallow and treat as a failed match. */          if (nancount && nancount != 3)            {              /* Ok... what are we supposed to do in the event that the              __srefill call above was triggered in the middle of the partial              'NaN' and so we can't put it all back? */              while (nancount-- && (p > buf))                {                  ungetc (*(u_char *)--p, fp);                  --nread;                }              goto match_failure;            }          /*	   * If no digits, might be missing exponent digits	   * (just give back the exponent) or might be missing	   * regular digits, but had sign and/or decimal point.	   */	  if (flags & NDIGITS)	    {	      if (flags & EXPOK)		{		  /* no digits at all */		  while (p > buf)                    {		      ungetc (*(u_char *)--p, fp);                      --nread;                    }		  goto match_failure;		}	      /* just a bad exponent (e and maybe sign) */	      c = *(u_char *)-- p;              --nread;	      if (c != 'e' && c != 'E')		{		  _CAST_VOID ungetc (c, fp);	/* sign */		  c = *(u_char *)-- p;                  --nread;		}	      _CAST_VOID ungetc (c, fp);	    }	  if ((flags & SUPPRESS) == 0)	    {	      double res = 0;#ifdef _NO_LONGDBL#define QUAD_RES res;#else  /* !_NO_LONG_DBL */	      long double qres = 0;#define QUAD_RES qres;#endif /* !_NO_LONG_DBL */	      long new_exp = 0;	      *p = 0;	      if ((flags & (DPTOK | EXPOK)) == EXPOK)		{		  exp_adjust = zeroes - leading_zeroes;		  new_exp = -exp_adjust;		  exp_start = p;		}	      else if (exp_adjust)                new_exp = _strtol_r (rptr, (exp_start + 1), NULL, 10) - exp_adjust;	      if (exp_adjust)		{		  /* If there might not be enough space for the new exponent,		     truncate some trailing digits to make room.  */		  if (exp_start >= buf + sizeof (buf) - MAX_LONG_LEN)		    exp_start = buf + sizeof (buf) - MAX_LONG_LEN - 1;                 sprintf (exp_start, "e%ld", new_exp);		}	      /* Current _strtold routine is markedly slower than 	         _strtod_r.  Only use it if we have a long double	         result.  */#ifndef _NO_LONGDBL /* !_NO_LONGDBL */	      if (flags & LONGDBL)	      	qres = _strtold (buf, NULL);	      else#endif	        res = _strtod_r (rptr, buf, NULL);	      if (flags & LONG)		{		  dp = va_arg (ap, double *);		  *dp = res;		}	      else if (flags & LONGDBL)		{		  ldp = va_arg (ap, _LONG_DOUBLE *);		  *ldp = QUAD_RES;		}	      else		{		  flp = va_arg (ap, float *);		  if (isnan (res))		    *flp = nanf (NULL);		  else		    *flp = res;		}	      nassigned++;	    }	  break;	}#endif /* FLOATING_POINT */	}    }input_failure:  _funlockfile (fp);  return nassigned ? nassigned : -1;match_failure:all_done:  _funlockfile (fp);  return nassigned;}

⌨️ 快捷键说明

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