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

📄 vfscanf.c

📁 Newlib 嵌入式 C库 标准实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		    if (__srefill (fp))#endif		      goto input_failure;		}	    } 	}      else /* save to counter-act changes made to flags when processing */	orig_flags = flags;      /*       * Do the conversion.       */      switch (type)	{	case CT_CHAR:	  /* scan arbitrary characters (sets NOSKIP) */	  if (width == 0)	    width = 1;	  if (flags & SUPPRESS)	    {	      size_t sum = 0;	      for (;;)		{		  if ((n = fp->_r) < (int)width)		    {		      sum += n;		      width -= n;		      fp->_p += n;#ifndef CYGNUS_NEC		      if (__srefill (fp))			{#endif			  if (sum == 0)			    goto input_failure;			  break;#ifndef CYGNUS_NEC			}#endif		    }		  else		    {		      sum += width;		      fp->_r -= width;		      fp->_p += width;		      break;		    }		}	      nread += sum;	    }	  else	    {	      int n = width;	      if (!looped)		{		  if (flags & VECTOR)		    ch_dest = vec_buf.c;		  else		    ch_dest = va_arg (ap, char *);		}#ifdef CYGNUS_NEC	      /* Kludge city for the moment */	      if (fp->_r == 0)		goto input_failure;	      while (n && fp->_r)		{		  *ch_dest++ = *(fp->_p++);		  n--;		  fp->_r--;		  nread++;		}#else	      size_t r = fread (ch_dest, 1, width, fp);	      if (r == 0)		goto input_failure;	      nread += r;	      ch_dest += r;#endif	      if (!(flags & VECTOR))		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 = ~0;	  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:	  {	  unsigned int_width_left = 0;	  int skips = 0;	  int_width = width;#ifdef hardway	  if (int_width == 0 || int_width > sizeof (buf) - 1)#else	  /* size_t is unsigned, hence this optimisation */	  if (int_width - 1 > sizeof (buf) - 2)#endif	    {	      int_width_left = width - (sizeof (buf) - 1);	      int_width = sizeof (buf) - 1;	    }	  flags |= SIGNOK | NDIGITS | NZDIGITS | NNZDIGITS;	  for (p = buf; int_width; int_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 (int_width_left)		    {		      int_width_left--;		      int_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#ifndef CYGNUS_NEC	      if (__srefill (fp))#endif		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) && !(flags & VECTOR))		*(va_arg (ap, _PTR *)) = (_PTR) (unsigned _POINTER_INT) res;	      else if (flags & SHORT)		{		  if (!(flags & VECTOR))		    sp = va_arg (ap, short *);		  else if (!looped)		    sp = vec_buf.h;		  *sp++ = res;		}	      else if (flags & LONG)		{		  if (!(flags & VECTOR))		    lp = va_arg (ap, long *);		  else if (!looped)		    lp = vec_buf.l;		  *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		{		  if (!(flags & VECTOR))		    {		      ip = va_arg (ap, int *);		      *ip++ = res;		    }		  else		    {		      if (!looped)			ch_dest = vec_buf.c;		      *ch_dest++ = (char)res;		    }		}	      if (!(flags & VECTOR))		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 fl_width = width;	  unsigned width_left = 0;#ifdef hardway	  if (fl_width == 0 || fl_width > sizeof (buf) - 1)#else	  /* size_t is unsigned, hence this optimisation */	  if (fl_width - 1 > sizeof (buf) - 2)#endif	    {	      width_left = fl_width - (sizeof (buf) - 1);	      fl_width = sizeof (buf) - 1;	    }	  flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;	  zeroes = 0;	  exp_adjust = 0;	  for (p = buf; fl_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--;			  fl_width++;			}		      goto fskip;		    }		  /* Fall through.  */		case '1':		case '2':		case '3':		case '4':		case '5':		case '6':		case '7':		case '8':		case '9':		  flags &= ~(SIGNOK | NDIGITS);		  goto fok;		case '+':		case '-':		  if (flags & SIGNOK)		    {		      flags &= ~SIGNOK;		      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:	      fl_width--;              ++nread;	      if (--fp->_r > 0)		fp->_p++;	      else#ifndef CYGNUS_NEC	      if (__srefill (fp))#endif		break;		/* EOF */	    }	  if (zeroes)	    flags &= ~NDIGITS;	  /*	   * 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)	    {#ifdef _NO_LONGDBL	      double res;#else  /* !_NO_LONG_DBL */	      long double res;#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);		}#ifdef __SPE__	      if (flags & FIXEDPOINT)		{		  __uint64_t ufix64;		  if (flags & SIGNED)		    ufix64 = (__uint64_t)_strtosfix64_r (rptr, buf, NULL);                  else		    ufix64 = _strtoufix64_r (rptr, buf, NULL);		  if (flags & SHORT)		    {		      __uint16_t *sp = va_arg (ap, __uint16_t *);		      *sp = (__uint16_t)(ufix64 >> 48);		    }		  else if (flags & LONG)		    {		      __uint64_t *llp = va_arg (ap, __uint64_t *);		      *llp = ufix64;		    }		  else		    {		      __uint32_t *lp = va_arg (ap, __uint32_t *);		      *lp = (__uint32_t)(ufix64 >> 32);		    }		  nassigned++;		  break;		}	      #endif /* __SPE__ */#ifdef _NO_LONGDBL	      res = _strtod_r (rptr, buf, NULL);#else  /* !_NO_LONGDBL */	      res = _strtold (buf, NULL);#endif /* !_NO_LONGDBL */	      if (flags & LONG)		{		  dp = va_arg (ap, double *);		  *dp = res;		}	      else if (flags & LONGDBL)		{		  ldp = va_arg (ap, _LONG_DOUBLE *);		  *ldp = res;		}	      else		{		  if (!(flags & VECTOR))		    flp = va_arg (ap, float *);		  else if (!looped)		    flp = vec_buf.f;		  *flp++ = res;		}	      if (!(flags & VECTOR))		nassigned++;	    }	  break;	}#endif /* FLOATING_POINT */	}      if (vec_read_count-- > 1)	{	  looped = 1;	  goto process;	}      if (flags & VECTOR)	{	  int i;	  unsigned long *vp = va_arg (ap, unsigned long *);	  for (i = 0; i < 4; ++i)	    *vp++ = vec_buf.l[i];	  nassigned++;	}    }input_failure:  return nassigned ? nassigned : -1;match_failure:  return nassigned;}

⌨️ 快捷键说明

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