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

📄 _scanfi.c

📁 MMI层OBJ不能完全编译
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************/
/*  _SCANFI.C v2.54                                                          */
/*  Copyright (c) 1995-2004 Texas Instruments Incorporated                   */
/*****************************************************************************/

/*****************************************************************************/
/*    This file contains the main routines that all three variations of the  */
/*    scanf function use.  The main function in the file is _scanfi, and     */
/*    the other functions here are called by it.                             */
/*                                                                           */
/* FUNCTIONS:                                                                */
/*    _scanfi        -  The main scanf handling routine                      */
/*    _sget_conv     -  Read the format flags into the _SFIELD pointer sfield*/
/*    _sget_scanset  -  Read in the scanset from the format statement        */
/*    _sproc_int     -  Read an integer string into a temporary string       */
/*    _sproc_float   -  Read a float string into a temporary string          */
/*    _sproc_str     -  Copy a string from the input source to a temporary   */
/*                      string                                               */
/*    _sproc_lb      -  Process the %[ conversion                            */
/*    _sset_arg      -  Assign the converted value to the next argument      */
/*****************************************************************************/
#include <stdio.h>
#include "format.h"
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>

#ifdef LLONG_MAX
_CODE_ACCESS long long strtoll(const char *_st, char **_endptr, int _base);
_CODE_ACCESS unsigned long long strtoull(const char *_st, char **_endptr,
					 int _base);
#endif

_CODE_ACCESS long double strtold(const char *st, char **endptr);

static int _sget_conv(char **_format, _SFIELD *sfield);
static int _sget_scanset(_SFIELD *sfield, char **_format);
static int _sproc_int(int w_counter, int (*_inpchar)(void **inp),
                       void (*_uninpchar)(void **inp, char outchar),
                       char *tmpptr, char conv, void **inp, int *num_read);
static int _sproc_float(int w_counter, int (*_inpchar)(void **inp),
                         void (*_uninpchar)(void **inp, char outchar),
                         char *tmpptr, char conv, void **inp, int *num_read);
static int _sproc_str(int w_counter, int (*_inpchar)(void **inp),
                       void (*_uninpchar)(void **inp, char outchar),
                       char *tmpptr, char conv, void **inp, int *num_read);
static int _sproc_lb(int (*_inpchar)(void **inp),
                      void (*_uninpchar)(void **inp, char outchar),
                      char *tmpptr, _SFIELD *sfield, void **inp, int *num_read);
static void _sset_arg(_SFIELD *sfield, va_list *_ap, char *tmpbuf);

/*****************************************************************************/
/* _SCANFI  -  The main scanf handling routine                               */
/*                                                                           */
/*    This function parses all non-conversion characters in the format       */
/*    string, passes control to the appropriate function when a '%' is       */
/*    encountered, then calls _SSET_ARG, which assignes the result to the    */
/*    next argument.                                                         */
/*                                                                           */
/*****************************************************************************/
int _scanfi(void *inp, const char *_format, va_list _ap, 
            int (*_chkmbc)(void **inp, char **_format, int *num_read),
            int (*_inpchar)(void **inp), 
            void (*_uninpchar)(void **inp, char outchar))
{
#ifdef ENABLE_SCANF
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */
   /*------------------------------------------------------------------------*/
   _SFIELD  sfield;
   char     tmpbuf[256],
           *tmpptr,
           *f_ptr        = (char *)_format;
   int      num_assigned =  0,
            inchar,
            num_read     =  0,
            stat         =  0;

   /*------------------------------------------------------------------------*/
   /* If the first character in the format string is a white space character */
   /* parse the format string until a non-white space character is found.    */
   /* Do the same for the input, but put the first non-white space character */
   /* back onto the input stream when finished.                              */
   /*------------------------------------------------------------------------*/
   if (isspace(*f_ptr))
   {
      for(;isspace(*f_ptr);f_ptr++);

      inchar = _inpchar(&inp);
      if(inchar == EOF) return EOF;
      num_read++;

      for(;isspace(inchar); inchar = _inpchar(&inp), num_read++);

      _uninpchar(&inp, inchar);
      num_read--;

      if(inchar == EOF) return EOF;
   }

   while(1)
   {
      /*---------------------------------------------------------------------*/
      /* Initialize sfield                                                   */
      /*---------------------------------------------------------------------*/
      memset(&sfield, 0, sizeof(_SFIELD));
      sfield.fwidth = -1;

      /*---------------------------------------------------------------------*/
      /* Call _chkmbc to compare the format string to the input.  If a       */
      /* mismatch occurs, return an EOF, if the end of the format string     */
      /* is reached, return the number of arguments assigned.  Otherwise     */
      /* a '%' has been encountered, so call _sget_conv to process it.       */
      /*---------------------------------------------------------------------*/
      switch(_chkmbc(&inp, &f_ptr, &num_read))
      {
         case  EOF   : return (EOF);
   
         case  0     : return (num_assigned);
   
         case  1     :  _sget_conv(&f_ptr, &sfield);
   
      }
   
      tmpptr = tmpbuf;

      /*---------------------------------------------------------------------*/
      /* Unless the conversion specifier is a [, c, or n, skip to the next   */
      /* non-white space character in the input.                             */
      /*---------------------------------------------------------------------*/
      if (sfield.conv != '[' && sfield.conv != 'c' && sfield.conv != 'n')
      {
         inchar = _inpchar(&inp);
         num_read++;
    
         for(;isspace(inchar); inchar = _inpchar(&inp), num_read++);
    
         _uninpchar(&inp, inchar);
         num_read--;

         /*---------------------------------------------------------------*/
         /* If we've encountered the end of the stream AND we haven't     */
         /* matched anything yet, return EOF.                             */
         /*---------------------------------------------------------------*/
         if(inchar == EOF && num_read == 0) return EOF;
      }
      else
      {
         /*---------------------------------------------------------------*/
         /* If we've encountered the end of the stream AND we haven't     */
         /* matched anything yet, return EOF.                             */
         /*---------------------------------------------------------------*/
         inchar = _inpchar(&inp);
         _uninpchar(&inp, inchar);
         if(inchar == EOF && num_read == 0) return EOF;
      }

      /*---------------------------------------------------------------------*/
      /* The flags have been set in sfield, so process the conversion by     */
      /* calling the appropriate function.                                   */
      /*---------------------------------------------------------------------*/
      switch(sfield.conv)
      {
         case  'X'   :  sfield.conv = 'x';
         case  'i'   :
         case  'p'   :  
         case  'x'   :
         case  'u'   :
         case  'o'   :
         case  'd'   :  stat = _sproc_int(sfield.fwidth, _inpchar, _uninpchar, 
                                         tmpptr, sfield.conv, &inp, &num_read); 
                        break;
         case  'f'   :
         case  'e'   :
         case  'E'   :
         case  'g'   :
         case  'G'   :  stat = _sproc_float(sfield.fwidth, _inpchar, _uninpchar,
                                     tmpptr, sfield.conv, &inp, &num_read);
                        break;

         case  'c'   :  
         case  's'   : {
                          char *stptr = (sfield.flags & _SFSTAR) ?
                                         NULL : va_arg(_ap, char*);

                          stat = _sproc_str(sfield.fwidth, _inpchar, _uninpchar,
                                     stptr, sfield.conv, &inp, &num_read);
                       }
                       stat = (stat != EOF);
                       if (!(sfield.flags & _SFSTAR) && stat) num_assigned++;
                       break;

         case  '['   :  stat = _sproc_lb(_inpchar, _uninpchar, tmpptr, &sfield,
                                         &inp, &num_read);

      }

      stat = (stat != EOF);

      /*---------------------------------------------------------------------*/
      /* Now, call the function to handle the actual assignment, or if there */
      /* is no assignment to take place, process it here.                    */
      /*---------------------------------------------------------------------*/
      switch(sfield.conv)
      {
         case  'i'   :
         case  'd'   :  
         case  'x'   :
         case  'u'   :
         case  'o'   :  
         case  'p'   : 
         case  'e'   :
         case  'f'   :
         case  'g'   :
         case  'E'   :
         case  'G'   :  _sset_arg(&sfield, &_ap, tmpbuf);
                        if ((!(sfield.flags & _SFSTAR)) && stat) num_assigned++;
                        break;
 
         case  'n'   :  if (!(sfield.flags & _SFSTAR))
                           switch(sfield.flags & (_MFH | _MFL | _MFLL))
                           {
                              case  _MFH  :  *(va_arg(_ap, short int*)) =
                                             (short int)num_read;
                                             break;
 
                              case _MFL   :  *(va_arg(_ap, long int*)) =
                                             (long int)num_read;
                                             break;
#ifdef LLONG_MAX
                              case _MFLL  :  *(va_arg(_ap, long long int*)) =
                                             (long long int)num_read;
                                             break;
#endif
                              default     :  *(va_arg(_ap, int*)) =
                                             num_read;
                                             break;
                           }
                        break;

         case  '%'   :  inchar = _inpchar(&inp);
                        if (inchar != '%') return (EOF);
                        else num_read++;
                        break;
                              
         case  '['   :  if ((!(sfield.flags & _SFSTAR)) && stat)
                        {
                           strcpy(va_arg(_ap, char *), tmpbuf);
                           num_assigned++;
                        }
      }

⌨️ 快捷键说明

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