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

📄 wsprintf.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
+-----------------------------------------------------------------------+
|                       Restricted Rights Legend                        |
| Copyright(c) 1999-2000 by Mobile Innovation, Inc.                               |
| This file is the property of the Mobile Innovation Inc. and it is               |
| protected by P.R.China Copyright laws, Internationals laws and        |
| treaties. It is there by forbidden for any unauthorized use,          |
| duplication, distribution or disclosure by any commercial industry    |
| (public or private), private individual, or by any Government agency  |
| without a explicit written consent of release from Synchronization.   |
|....................................................................   |
| PROJECT: Lithium                  $Workfile::   wsprintf.c           $|
| $Author: root $$Revision: 1.1.1.1 $|
| CREATED: 15 MAR 2001              $Modtime::   Mar 15 2001 14:45:34  $|
+-----------------------------------------------------------------------+

   PURPOSE  : For Unicode Extension
   TO DO    : Unicode sprintf function
*/

#include <stdio.h>
//#include <format.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>

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

extern char *fcvt(double value, register int ndigit, int *decpt, int *sign);
extern char *ecvt(double value, register int ndigit, int *decpt, int *sign);
static unsigned short *wmemccpy(char *dest, const char *src, int ch, int count);

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, unsigned short *_op, va_list *_ap, int *count,
                       int (*_outws)(unsigned short *, unsigned short *));
static char *_setfield(_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 unsigned long _getarg_diouxp(_PFIELD *pfield, va_list *_ap);
static int _ltostr(unsigned long cvt, int base, char conv, char **a_it);
static unsigned long _div(unsigned long cvt, int base);
static int _outc(char c, unsigned short *_op);
static int _outs(char *s, unsigned short *_op);
static int _outws(unsigned short *ws, unsigned short *_op);
static int _printfi(char **_format, va_list _ap, unsigned short *_op, int (*_outc)(char, unsigned short *), 
                    int (*_outs)(char *, unsigned short *), int (*_outws)(unsigned short *, unsigned short *));
extern char *memccpy(char *dest, const char *src, int ch, int 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      */
/*    structure pointed to by PFIELD.  They will be needed for future        */
/*    reference.                                                             */
/*                                                                           */
/*****************************************************************************/
static void _pproc_fwp(_PFIELD *pfield, char **it, va_list *_ap)
{
   char tmpstr[10];
   char *tmpptr;

   /*------------------------------------------------------------------------*/
   /* If a '*' was given for the field width, use the next argument as       */
   /* the field width for the conversion.  Otherwise, copy the following     */
   /* numerical characters into a temporary string, and convert that         */
   /* string into an integer, which will be used for the field width.        */
   /*------------------------------------------------------------------------*/
   if (**it == '*')
   {
      pfield->fwidth = va_arg(*_ap, int);

      /*---------------------------------------------------------------------*/
      /* If the argument given for the field width is negative, treat it as  */
      /* if the '-' flag was used, and the field width was positive.         */
      /*---------------------------------------------------------------------*/
      if (pfield->fwidth < 0)
      {
         pfield->fwidth = -(pfield->fwidth);
         _SET(pfield, _PFMINUS);
      }

      (*it)++;
   } else
   {
      /*---------------------------------------------------------------------*/
      /* Initialize the temporary string and iterator that will hold the     */
      /* field width temporarily.                                            */
      /*---------------------------------------------------------------------*/
      tmpptr = tmpstr;
      memset(tmpptr, '\0', 10);

      while ((**it >= '0') && (**it <= '9')) *(tmpptr++) = *((*it)++);

      if (*tmpstr != '\0') pfield->fwidth = atoi(tmpstr);
   }

   /*------------------------------------------------------------------------*/
   /* If a '.' appears as the next character, process the following          */
   /* characters as a precision.                                             */
   /*------------------------------------------------------------------------*/
   if (**it == '.')
   {
      (*it)++;

      /*---------------------------------------------------------------------*/
      /* Cancel any effects of the zero flag.                                */
      /*---------------------------------------------------------------------*/
      _UNSET(pfield, _PFZERO);

      /*---------------------------------------------------------------------*/
      /* If a '*' was given for the precision, use the next argument as      */
      /* the precision for the conversion.  Otherwise, copy the following    */
      /* numerical characters into a temporary string, and convert that      */
      /* string into an integer, which will be used for the precision.       */
      /*---------------------------------------------------------------------*/
      if (**it == '*')
      {
         pfield->precision = va_arg(*_ap, int);
         (*it)++;
      } else
      {
         /*------------------------------------------------------------------*/
         /* Initialize the temporary string and iterator that will hold      */
         /* the field width temporarily.                                     */
         /*------------------------------------------------------------------*/
         tmpptr = tmpstr;
         memset(tmpptr, '\0', 10);

         while ((**it >= '0') && (**it <= '9'))
            *(tmpptr++) = *((*it)++);

         if (*tmpstr != '\0') pfield->precision = atoi(tmpstr);
         else pfield->precision = 0;
      }
   }
   return;
}

/*****************************************************************************/
/* _PPROC_STR  -  Processes the string conversion (%s)                       */
/*                                                                           */
/*    This function places all or a portion of the input string into the     */
/*    the temporary string.  It returns a zero, unless the input string had  */
/*    a length of zero.  In this case, a one is returned.                    */
/*                                                                           */
/*****************************************************************************/
static void _pproc_str(_PFIELD *pfield, unsigned short *_op, va_list *_ap, int *count,
                       int (*_outws)(unsigned short *, unsigned short *))
{
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */
   /*------------------------------------------------------------------------*/
   unsigned short  *strbuf;
   unsigned short  *tmpstr;
   unsigned short  *tmpptr;
   int   len, buflen;

   /*------------------------------------------------------------------------*/
   /* Get the next argument.                                                 */
   /*------------------------------------------------------------------------*/
   strbuf = va_arg(*_ap, unsigned short*);

   /*------------------------------------------------------------------------*/
   /* Handle NULL strings.                                                   */
   /*------------------------------------------------------------------------*/
   if (strbuf == NULL)
   {
      _outs("(null)", _op);
      return;
   }

   buflen = (pfield->precision >= 0 && pfield->precision < wstrlen(strbuf)) ?
            pfield->precision : wstrlen(strbuf);
   len = (pfield->fwidth > buflen) ? pfield->fwidth : buflen;
   *count += len;

   if (!(tmpstr = (unsigned short *)malloc((len + 1)*sizeof(unsigned short)))) return;
   tmpptr = tmpstr;

   if (buflen < len && !_STCHK(pfield, _PFMINUS))
   {
      wmemset(tmpptr, ' ', (len - buflen));
      tmpptr += (len - buflen);  
   }

   wstrncpy(tmpptr, strbuf, buflen);
   tmpptr += buflen;

   if (buflen < len && _STCHK(pfield, _PFMINUS))
   {
      wmemset(tmpptr, ' ', (len - buflen));
      tmpptr += (len - buflen);
   }

   *(tmpstr + len) = '\0';

   _outws(tmpstr, _op);

   free(tmpstr);

   return;
}

/*****************************************************************************/
/* _PPROC_DIOUXP   -  Process the conversion for d, i, o, u, x, and p        */
/*                                                                           */
/*    This function takes the structure PFIELD, which contains all of the    */
/*    flags and parameters to process the conversion, and it does this       */
/*    conversion, and stores the result in the string pointed to by          */
/*    *A_IT.                                                                 */
/*                                                                           */
/*****************************************************************************/
static int _pproc_diouxp(_PFIELD *pfield, int *minus_flag, char **a_it, 
                         va_list *_ap)
{
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */

⌨️ 快捷键说明

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