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

📄 _printfi.c

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

/*****************************************************************************/
/*    This file contains the main routines that all six variations of the    */
/*    printf function use.  The main function in the file is _printfi,       */
/*    and the other functions here are called by it.                         */
/*                                                                           */
/* FUNCTIONS:                                                                */
/*    _printfi       -  Perform the main printf routine                      */
/*    _pproc_fflags  -  Process the format flags for a conversion            */
/*    _pproc_fwp     -  Convert field width and precision into numbers       */
/*    _pproc_str     -  Process the string (%s) conversion                   */
/*    _setfield      -  Performs conversions when the '%' is encountered     */
/*    _pproc_fge     -  Process the conversion for f, g, G, e, and E         */
/*    _pconv_f       -  Perform the %f conversion                            */
/*    _pconv_e       -  Perform the %e conversion                            */
/*    _pconv_g       -  Perform the %g conversion                            */
/*    _fcpy          -  Copy the fraction part of a float to a string        */
/*    _ecpy          -  Copy the "E+xx" part of a float to a string          */
/*    _mcpy          -  Copy the whole number part of a float to a string    */
/*    _pproc_diouxp  -  Process the conversion for d, i, o, u, x, and p      */
/*    _getarg_diouxp -  Get the argument for d, i, o, u, x, or p conversion  */
/*    _ltostr        -  Convert an integer to a string of up to base 16      */
/*    _div           -  Divide two integers                                  */
/*                                                                           */
/* Note:  If NOFLOAT is defined at compile time, this file will be compiled  */
/*        without floating point support.                                    */
/*****************************************************************************/

/*
 * 07/30/04 re-entrance of sprintf.
 * Change originally came from RTS1.22e modified on 02/27/01 re-entrance of sprintf.
 * _ARSIZE is the size of the fld array defined in local static in _setfied
 * in the original version of rts.src. Now this array is not static and is
 * defined in _printfi because the current stack may be corrupted if the fld
 * array is defined in _setfield. The size of the array is reduced to avoid
 * to use too much space in stack. The prototype of _setfield is modified to
 * use the fld array defined in _printfi.
 * The call to malloc in _pproc_str is removed and replaced with a local
 * array because malloc uses a global variable.
 */


#include <stdio.h>
#include <format.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <limits.h>
#include <math.h>
#include <_lock.h>

#define SIGNED_CONV (pfield->conv != 'u' && pfield->conv != 'o' && \
                     pfield->conv != 'x' && pfield->conv != 'X')

extern _CODE_ACCESS char *fcvt(long double value, register int ndigit, 
			       int *decpt, int *sign);
extern _CODE_ACCESS char *ecvt(long double value, register int ndigit, 
			       int *decpt, int *sign);
extern _CODE_ACCESS char *memccpy(char *dest, const char *src, int ch,
				  int count);

extern int _printfi(char **_format, va_list _ap, void *_op,
                    int (*_outc)(char, void *), int (*_outs)(char *, void *));

static void _pproc_fflags(_PFIELD *pfield, char **it);
static void _pproc_fwp(_PFIELD *pfield, char **it, va_list *_ap);
static void _pproc_str(_PFIELD *pfield, void *_op, va_list *_ap, int *count,
                       int (*_outs)(char *, void *));
static void _setfield(char *fld, _PFIELD *pfield, va_list *_ap);
static void _pproc_fge(_PFIELD *pfield, int *minus_flag, char **a_it,
                       va_list *_ap);
static void _pconv_f(long double cvt, _PFIELD *pfield, char **a_it);
static void _pconv_e(long double cvt, _PFIELD *pfield, char **a_it);
static void _pconv_g(long double cvt, _PFIELD *pfield, char **a_it);
static char *_fcpy(const char *tmpbuf, int dpt, int trail, int precision,
                   char **a_it);
static char *_ecpy(int exp, char letter, char **a_it);
static char *_mcpy(const char *tmpbuf, int dpt, int putdec, char **a_it);
static int _pproc_diouxp(_PFIELD *pfield, int *minus_flag, char **a_it,
                         va_list *_ap);
static uintmax_t _getarg_diouxp(_PFIELD *pfield, va_list *_ap);
static int _ltostr(uintmax_t cvt, int base, char conv, char **a_it);
static uintmax_t _div(uintmax_t cvt, int base);





/*****************************************************************************/
/* _PRINTFI -  Perform the main printf routine                               */
/*                                                                           */
/*    This function processes the format string.  It copies the format       */
/*    string into the result string until a '%' is encountered, where any    */
/*    flags, the field width, the precision, and the type of conversion are  */
/*    read in, stored in a structure called PFIELD, and passed to _SETFIELD, */
/*    where the actual conversion is processed.  This function returns       */
/*    the number of characters output.                                       */
/*                                                                           */
/*****************************************************************************/
int _printfi(char **_format, va_list _ap, void *_op, 
             int (*_outc)(char, void *), int (*_outs)(char *, void *))
{
   /*------------------------------------------------------------------------*/
   /* Local Variables                                                        */
   /*                                                                        */
   /*    *end     -  A pointer to the end of the format string               */
   /*    *pfield  -  A pointer to a structure _PFIELD, which stores all of   */
   /*                flags and parameters needed to perform a conversion.    */
   /*------------------------------------------------------------------------*/
   char     *end           =  *_format + strlen(*_format);
   int      count          =  0;
   _PFIELD  pfield;
   char     fld[_ARSIZE];

   /*------------------------------------------------------------------------*/
   /* Iterate through the format string until the end of it is reached.      */
   /*------------------------------------------------------------------------*/
   while(*_format < end)
   {
      /*---------------------------------------------------------------------*/
      /* Initialize PFIELD.                                                  */
      /*---------------------------------------------------------------------*/
      pfield.flags     = 0;
      pfield.fwidth    = 0;
      pfield.precision = -1;
      pfield.conv      = 0;

      /*---------------------------------------------------------------------*/
      /* Copy the format string directly to the target string until a '%'    */
      /* is encountered.                                                     */
      /*---------------------------------------------------------------------*/
      for(; **_format != '%' && **_format != '\0'; 
          _outc(*((*_format)++), _op), count++);

      /*---------------------------------------------------------------------*/
      /* If the end of the format string has been reached, break out of the  */
      /* while loop.                                                         */
      /*---------------------------------------------------------------------*/
      if(! (**_format)) break;

      (*_format)++;                   /* Skip to the character after the '%' */

      /*---------------------------------------------------------------------*/
      /* Process the flags immediately after the '%'.                        */
      /*---------------------------------------------------------------------*/
      _pproc_fflags(&pfield, _format);

      /*---------------------------------------------------------------------*/
      /* Convert the field width and precision into numbers.                 */
      /*---------------------------------------------------------------------*/
      _pproc_fwp(&pfield, _format, &_ap);
 
      /*---------------------------------------------------------------------*/
      /* If the h, l, or L flag was specified, set the corresponding flag    */
      /* in pfield.                                                          */
      /*---------------------------------------------------------------------*/
      switch (**_format)
      {
	  case 'L': _SET(&pfield, _MFLD); (*_format)++; break;
	  case 'h': _SET(&pfield, _MFH);  (*_format)++; break;
	  case 'l':
	  {
	      (*_format)++; 
	      if (**_format == 'l') { _SET(&pfield, _MFLL); (*_format)++; }
	      else _SET(&pfield, _MFL);
	  }
      }

      /*---------------------------------------------------------------------*/
      /* Set the conversion character in pfield.                             */
      /*---------------------------------------------------------------------*/
      pfield.conv = *((*_format)++);

      /*---------------------------------------------------------------------*/
      /* If 'n' is the conversion specifier, process it in this function,    */
      /* since it is the only one that makes no conversions.  It just stores */
      /* the number of characters printed so far into the next argument.     */
      /* Otherwise, call _SETFIELD which performs the conversion.            */
      /*---------------------------------------------------------------------*/
      if(pfield.conv == 'n')
         switch (pfield.flags & (_MFLL | _MFL | _MFH))
         {
#ifdef LLONG_MAX
                           /* The 'll' flag was specified */
            case _MFLL  :  *(va_arg(_ap, long long*)) = (long long)count;
                           break;
#endif
                           /* The 'l' flag was specified */
            case _MFL   :  *(va_arg(_ap, long*)) = (long)count;
                           break;

                           /* The 'h' flag was specified */
            case _MFH   :  *(va_arg(_ap, short*)) = (short)count;
                           break;

            default     :  *(va_arg(_ap, int*)) = (int)count;
                           break;

         }
      else if(pfield.conv == 's') 
         _pproc_str(&pfield, _op, &_ap, &count, _outs);   
      else
      {
         /*------------------------------------------------------------------*/
         /* Append the converted string to the result string, and reposition */
         /* its iterator, it2.                                               */
         /*------------------------------------------------------------------*/
	 /* Must hold the system lock to call _setfield() because it returns
	    a static buffer. */
	 _lock();
         _setfield(fld, &pfield, &_ap);
         count += _outs(fld, _op);
	 _unlock();
      }
   }

   return (count);
}


/*****************************************************************************/
/* _PPROC_FFLAGS   -  Process the format flags for a conversion              */
/*                                                                           */
/*    This function takes the flags directly after the '%' and stores them   */
/*    in the _PFIELD structure PFIELD for later reference.                   */
/*                                                                           */
/*****************************************************************************/
static void _pproc_fflags(_PFIELD *pfield, char **it)
{
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */
   /*------------------------------------------------------------------------*/
   int flags_done = 0;

   /*---------------------------------------------------------------------*/
   /* Read in all of the flags associated with this conversion, and set   */
   /* the corresponding flags in the PFIELD structure.                    */
   /*---------------------------------------------------------------------*/
   while(! flags_done)
      switch (**it)
      {
         case '-' :  _SET(pfield, _PFMINUS);
                     (*it)++;
                     break;   

         case '+' :  _SET(pfield, _PFPLUS);
                     (*it)++;
                     break;

         case ' ' :  _SET(pfield, _PFSPACE);
                     (*it)++;
                     break;

         case '#' :  _SET(pfield, _PFPOUND);
                     (*it)++;
                     break;

         case '0' :  _SET(pfield, _PFZERO);
                     (*it)++;
                     break;

         default  :  flags_done = 1;
      }

   return;
}


/*****************************************************************************/
/* _PPROC_FWP   -  Convert the field width and precision from the format     */
/*                 string into numbers.                                      */
/*                                                                           */
/*    This function reads the field and precision out of the format string   */
/*    and converts them into numbers that will be stored in the _PFIELD      */

⌨️ 快捷键说明

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