📄 wsprintf.c
字号:
/*------------------------------------------------------------------------*/
static char fld[_ARSIZE];
char *f_start = (char *)fld;
char *f_end = f_start + pfield->fwidth;
char *a_end = f_start + _ARSIZE -1;
char *a_it = a_end;
char *where;
int minus_flag = 0;
int plus_flag = 0;
/*------------------------------------------------------------------------*/
/* Clear the temporary string. Then, since we are working from right to */
/* left, begin with the NULL character. */
/*------------------------------------------------------------------------*/
memset(fld, ' ', _ARSIZE);
*(a_it--) = '\0';
/*------------------------------------------------------------------------*/
/* Call the appropriate processing function. */
/*------------------------------------------------------------------------*/
switch (pfield->conv)
{
case 'd' :
case 'i' :
case 'o' :
case 'u' :
case 'x' :
case 'X' :
case 'p' : _pproc_diouxp(pfield, &minus_flag, &a_it, _ap);
break;
#ifndef NOFLOAT
case 'g' :
case 'G' :
case 'e' :
case 'E' :
case 'f' : _pproc_fge(pfield, &minus_flag, &a_it, _ap);
break;
#endif
case 'c' : *(a_it--) = va_arg(*_ap, int);
_UNSET(pfield, _PFPLUS);
break;
case '%' : strcpy(f_start, "%"); return((char *)fld);
}
plus_flag = (_STCHK(pfield, _PFPLUS) && SIGNED_CONV);
/*------------------------------------------------------------------------*/
/* If the number was negative, or the '+' flag was used, insert the sign. */
/* Make sure unsigned conversions don't get a '+' sign. */
/*------------------------------------------------------------------------*/
if (minus_flag) *(a_it--) = '-';
else if (plus_flag) *(a_it--) = '+';
/*------------------------------------------------------------------------*/
/* If the number was positive, the '+' flag was not used, and the ' ' */
/* flag was used, insert a space. */
/*------------------------------------------------------------------------*/
if (! minus_flag && ! plus_flag && _STCHK(pfield, _PFSPACE)) *(a_it--) = ' ';
/*------------------------------------------------------------------------*/
/* If the '-' flag was used or the resulting string is larger than the */
/* field, left justify the result in the array. Otherwise right-justify */
/* it. */
/*------------------------------------------------------------------------*/
where = (_STCHK(pfield, _PFMINUS) ||
((a_end - a_it) > pfield->fwidth)) ? f_start :
(f_end - (a_end - a_it)+1);
a_it = (char *)memccpy(where, a_it+1, '\0', _ARSIZE);
/*------------------------------------------------------------------------*/
/* If a resulting left-justified string is smaller than the field width, */
/* move the terminating NULL character to the end of the field. */
/*------------------------------------------------------------------------*/
if (a_it <= f_end)
{
*(a_it-1) = ' ';
*f_end = '\0';
}
/*------------------------------------------------------------------------*/
/* If the '0' flag was used, and the resulting string is right-justified, */
/* fill in the leading zeros. */
/*------------------------------------------------------------------------*/
if (_STCHK(pfield, _PFZERO))
{
memset(f_start, '0', (where - f_start));
/*---------------------------------------------------------------------*/
/* Make sure any sign or leading space is moved to the left side of */
/* any leading zeros. */
/*---------------------------------------------------------------------*/
if ((minus_flag || plus_flag || _STCHK(pfield, _PFSPACE)) &&
where != f_start)
{
*f_start = *where;
*where = '0';
}
}
/*------------------------------------------------------------------------*/
/* Return the result string. */
/*------------------------------------------------------------------------*/
return((char *)fld);
}
/*****************************************************************************/
/* _OUTC - Put a character in a wstring */
/*****************************************************************************/
static int _outc(char c, unsigned short *_op)
{
//strncat((char *)_op, &c, 1);
while (*_op++);
*(_op-1) = c;
*_op = 0;
return(c);
}
/*****************************************************************************/
/* _OUTS - Append a string to another wstring */
/*****************************************************************************/
static int _outs(char *s, unsigned short *_op)
{
//strcat((char *)_op, s);
while (*_op++);
expand2wstr(--_op, s);
return(strlen(s));
}
/*****************************************************************************/
/* _OUTWS - Append a wstring to another wstring */
/*****************************************************************************/
static int _outws(unsigned short *ws, unsigned short *_op)
{
//strcat((char *)_op, s);
wstrcat(_op, ws);
return(wstrlen(ws));
}
/*****************************************************************************/
/* _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. */
/* */
/*****************************************************************************/
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 *))
{
/*------------------------------------------------------------------------*/
/* 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;
/*------------------------------------------------------------------------*/
/* Iterate through the format string until the end of it is reached. */
/*------------------------------------------------------------------------*/
while (*_format < end)
{
/*---------------------------------------------------------------------*/
/* Initialize PFIELD. */
/*---------------------------------------------------------------------*/
memset(&pfield, '\0', sizeof(_PFIELD));
pfield.precision = -1;
/*---------------------------------------------------------------------*/
/* 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. */
/*---------------------------------------------------------------------*/
if (**_format == 'h' || **_format == 'l' || **_format == 'L')
{
_SET(&pfield, (**_format == 'h') ? _MFH : (**_format == 'l') ?
_MFL : _MFLD);
(*_format)++;
}
/*---------------------------------------------------------------------*/
/* 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 & (_MFL | _MFH))
{
/* 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, _outws);
else
{
/*------------------------------------------------------------------*/
/* Append the converted string to the result string, and reposition */
/* its iterator, it2. */
/*------------------------------------------------------------------*/
count += _outs(_setfield(&pfield, &_ap), _op);
}
}
return(count);
}
/*****************************************************************************/
/* WSPRINTF - Copy formatted output to a string */
/* */
/* This function passes a the format string and an argument list to */
/* _PRINTFI, and writes the result string to the string _STRING. */
/* */
/*****************************************************************************/
int wsprintf(unsigned short *_wstring, const char *_format, ...)
{
va_list _ap;
int rval;
char *fptr = (char *)_format;
*_wstring = 0;
va_start(_ap, _format);
rval = _printfi(&fptr, _ap, _wstring, _outc, _outs, _outws);
va_end(_ap);
return(rval);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -