📄 wsprintf.c
字号:
/*
+-----------------------------------------------------------------------+
| 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 + -