output.c
来自「C语言库函数的原型,有用的拿去」· C语言 代码 · 共 1,893 行 · 第 1/5 页
C
1,893 行
...
)
#else /* FORMAT_VALIDATIONS */
#ifdef POSITIONAL_PARAMETERS
_CRTIMP int __cdecl _tcprintf_p_l (
const _TCHAR * format,
_locale_t plocinfo,
...
)
#else /* POSITIONAL_PARAMETERS */
_CRTIMP int __cdecl _tcprintf_s_l (
const _TCHAR * format,
_locale_t plocinfo,
...
)
#endif /* POSITIONAL_PARAMETERS */
#endif /* FORMAT_VALIDATIONS */
{
va_list arglist;
va_start(arglist, plocinfo);
#ifndef FORMAT_VALIDATIONS
return _vtcprintf_l(format, plocinfo, arglist);
#else /* FORMAT_VALIDATIONS */
#ifdef POSITIONAL_PARAMETERS
return _vtcprintf_p_l(format, plocinfo, arglist);
#else /* POSITIONAL_PARAMETERS */
return _vtcprintf_s_l(format, plocinfo, arglist);
#endif /* POSITIONAL_PARAMETERS */
#endif /* FORMAT_VALIDATIONS */
}
#ifndef FORMAT_VALIDATIONS
_CRTIMP int __cdecl _tcprintf (
const _TCHAR * format,
...
)
#else /* FORMAT_VALIDATIONS */
#ifdef POSITIONAL_PARAMETERS
_CRTIMP int __cdecl _tcprintf_p (
const _TCHAR * format,
...
)
#else /* POSITIONAL_PARAMETERS */
_CRTIMP int __cdecl _tcprintf_s (
const _TCHAR * format,
...
)
#endif /* POSITIONAL_PARAMETERS */
#endif /* FORMAT_VALIDATIONS */
{
va_list arglist;
va_start(arglist, format);
#ifndef FORMAT_VALIDATIONS
return _vtcprintf_l(format, NULL, arglist);
#else /* FORMAT_VALIDATIONS */
#ifdef POSITIONAL_PARAMETERS
return _vtcprintf_p_l(format, NULL, arglist);
#else /* POSITIONAL_PARAMETERS */
return _vtcprintf_s_l(format, NULL, arglist);
#endif /* POSITIONAL_PARAMETERS */
#endif /* FORMAT_VALIDATIONS */
}
#endif /* CPRFLAG */
/***
*int _output(stream, format, argptr), static int output(format, argptr)
*
*Purpose:
* Output performs printf style output onto a stream. It is called by
* printf/fprintf/sprintf/vprintf/vfprintf/vsprintf to so the dirty
* work. In multi-thread situations, _output assumes that the given
* stream is already locked.
*
* Algorithm:
* The format string is parsed by using a finite state automaton
* based on the current state and the current character read from
* the format string. Thus, looping is on a per-character basis,
* not a per conversion specifier basis. Once the format specififying
* character is read, output is performed.
*
*Entry:
* FILE *stream - stream for output
* char *format - printf style format string
* va_list argptr - pointer to list of subsidiary arguments
*
*Exit:
* Returns the number of characters written, or -1 if an output error
* occurs.
*ifdef _UNICODE
* The wide-character flavour returns the number of wide-characters written.
*endif
*
*Exceptions:
*
*******************************************************************************/
#ifdef CPRFLAG
#ifndef FORMAT_VALIDATIONS
_CRTIMP int __cdecl _vtcprintf (
const _TCHAR *format,
va_list argptr
)
{
return _vtcprintf_l(format, NULL, argptr);
}
#else /* FORMAT_VALIDATIONS */
#ifdef POSITIONAL_PARAMETERS
_CRTIMP int __cdecl _vtcprintf_p (
const _TCHAR *format,
va_list argptr
)
{
return _vtcprintf_p_l(format, NULL, argptr);
}
#else /* POSITIONAL_PARAMETERS */
_CRTIMP int __cdecl _vtcprintf_s (
const _TCHAR *format,
va_list argptr
)
{
return _vtcprintf_s_l(format, NULL, argptr);
}
#endif /* POSITIONAL_PARAMETERS */
#endif /* FORMAT_VALIDATIONS */
#endif /* CPRFLAG */
#ifdef CPRFLAG
#ifndef FORMAT_VALIDATIONS
_CRTIMP int __cdecl _vtcprintf_l (
#else /* FORMAT_VALIDATIONS */
#ifdef POSITIONAL_PARAMETERS
_CRTIMP int __cdecl _vtcprintf_p_l (
#else /* POSITIONAL_PARAMETERS */
_CRTIMP int __cdecl _vtcprintf_s_l (
#endif /* POSITIONAL_PARAMETERS */
#endif /* FORMAT_VALIDATIONS */
#else /* CPRFLAG */
#ifdef _UNICODE
#ifndef FORMAT_VALIDATIONS
#ifdef _SAFECRT_IMPL
int __cdecl _woutput (
#else /* _SAFECRT_IMPL */
int __cdecl _woutput_l (
#endif /* _SAFECRT_IMPL */
FILE *stream,
#else /* FORMAT_VALIDATIONS */
#ifdef POSITIONAL_PARAMETERS
#ifdef _SAFECRT_IMPL
int __cdecl _woutput_p (
#else /* _SAFECRT_IMPL */
int __cdecl _woutput_p_l (
#endif /* _SAFECRT_IMPL */
FILE *stream,
#else /* POSITIONAL_PARAMETERS */
#ifdef _SAFECRT_IMPL
int __cdecl _woutput_s (
#else /* _SAFECRT_IMPL */
int __cdecl _woutput_s_l (
#endif /* _SAFECRT_IMPL */
FILE *stream,
#endif /* POSITIONAL_PARAMETERS */
#endif /* FORMAT_VALIDATIONS */
#else /* _UNICODE */
#ifndef FORMAT_VALIDATIONS
#ifdef _SAFECRT_IMPL
int __cdecl _output (
#else /* _SAFECRT_IMPL */
int __cdecl _output_l (
#endif /* _SAFECRT_IMPL */
FILE *stream,
#else /* FORMAT_VALIDATIONS */
#ifdef POSITIONAL_PARAMETERS
#ifdef _SAFECRT_IMPL
int __cdecl _output_p (
#else /* _SAFECRT_IMPL */
int __cdecl _output_p_l (
#endif /* _SAFECRT_IMPL */
FILE *stream,
#else /* POSITIONAL_PARAMETERS */
#ifdef _SAFECRT_IMPL
int __cdecl _output_s (
#else /* _SAFECRT_IMPL */
int __cdecl _output_s_l (
#endif /* _SAFECRT_IMPL */
FILE *stream,
#endif /* POSITIONAL_PARAMETERS */
#endif /* FORMAT_VALIDATIONS */
#endif /* _UNICODE */
#endif /* CPRFLAG */
const _TCHAR *format,
#ifndef _SAFECRT_IMPL
_locale_t plocinfo,
#endif /* _SAFECRT_IMPL */
va_list argptr
)
{
int hexadd=0; /* offset to add to number to get 'a'..'f' */
TCHAR ch; /* character just read */
int flags=0; /* flag word -- see #defines above for flag values */
enum STATE state; /* current state */
enum CHARTYPE chclass; /* class of current character */
int radix; /* current conversion radix */
int charsout; /* characters currently written so far, -1 = IO error */
int fldwidth = 0; /* selected field width -- 0 means default */
int precision = 0; /* selected precision -- -1 means default */
TCHAR prefix[2]; /* numeric prefix -- up to two characters */
int prefixlen=0; /* length of prefix -- 0 means no prefix */
int capexp; /* non-zero = 'E' exponent signifient, zero = 'e' */
int no_output=0; /* non-zero = prodcue no output for this specifier */
union {
char *sz; /* pointer text to be printed, not zero terminated */
wchar_t *wz;
} text;
int textlen; /* length of the text in bytes/wchars to be printed.
textlen is in multibyte or wide chars if _UNICODE */
union {
char sz[BUFFERSIZE];
#ifdef _UNICODE
wchar_t wz[BUFFERSIZE];
#endif /* _UNICODE */
} buffer;
wchar_t wchar; /* temp wchar_t */
int buffersize; /* size of text.sz (used only for the call to _cfltcvt) */
int bufferiswide=0; /* non-zero = buffer contains wide chars already */
#ifndef _SAFECRT_IMPL
_LocaleUpdate _loc_update(plocinfo);
#endif /* _SAFECRT_IMPL */
#ifdef POSITIONAL_PARAMETERS
/* Used for parsing the format */
const _TCHAR * saved_format = NULL;
_TCHAR * end_pos = NULL;
/* This is the structure which stores the values corresponding to
each positional param */
struct positional_param pos_value[_ARGMAX];
int pass = 0; /* Ctr for scanning the format string in diff passes */
int noofpasses = 0; /* Set to 2 for positional formats, otherwise 1 */
int max_pos = -1; /* Keeping track of the current max positional arg */
int type_pos = -1; /* position of an arg denoting a type */
int width_pos = -1; /* position of an arg denoting width */
int precis_pos = -1; /* position of an arg denoting precision */
int format_type = FMT_TYPE_NOTSET; /* type of format string */
#endif /* POSITIONAL_PARAMETERS */
char *heapbuf = NULL; /* non-zero = test.sz using heap buffer to be freed */
#ifndef CPRFLAG
_VALIDATE_RETURN( (stream != NULL), EINVAL, -1);
#ifndef _UNICODE
_VALIDATE_STREAM_ANSI_RETURN(stream, EINVAL, EOF);
#endif /* _UNICODE */
#endif /* CPRFLAG */
_VALIDATE_RETURN( (format != NULL), EINVAL, -1);
charsout = 0; /* no characters written yet */
#ifdef POSITIONAL_PARAMETERS
saved_format = format;
for(pass = 0 ; pass < 2; ++pass)
{
if((pass == FORMAT_OUTPUT_PASS) && (format_type == FMT_TYPE_NONPOSITIONAL))
{
/* If in pass2, we still have format_type isn't positional, it means
that we do not need a 2nd pass */
break;
}
#endif /* POSITIONAL_PARAMETERS */
textlen = 0; /* no text yet */
state = ST_NORMAL; /* starting state */
heapbuf = NULL; /* not using heap-allocated buffer */
buffersize = 0;
#ifdef POSITIONAL_PARAMETERS
max_pos = -1;
fldwidth = 0;
precision = 0;
format = saved_format;
type_pos = -1;
width_pos = -1;
precis_pos = -1;
/* All chars before the first format specifier get output in the first
pass itself. Hence we have to reset format_type to FMT_TYPE_NOTSET to ensure
that they do not get output again in the 2nd pass */
format_type = FMT_TYPE_NOTSET;
#endif /* POSITIONAL_PARAMETERS */
/* main loop -- loop while format character exist and no I/O errors */
while ((ch = *format++) != _T('\0') && charsout >= 0) {
#ifndef FORMAT_VALIDATIONS
chclass = FIND_CHAR_CLASS(__lookuptable, ch); /* find character class */
state = FIND_NEXT_STATE(__lookuptable, chclass, state); /* find next state */
#else /* FORMAT_VALIDATIONS */
chclass = FIND_CHAR_CLASS(__lookuptable_s, ch); /* find character class */
state = FIND_NEXT_STATE(__lookuptable_s, chclass, state); /* find next state */
#ifdef POSITIONAL_PARAMETERS
if((state == ST_PERCENT) && (*format != _T('%')))
{
if(format_type == FMT_TYPE_NOTSET)
{
/* We set the value of format_type when we hit the first type specifier */
if(_tcstol(format, &end_pos, 10) > 0 && (*end_pos == POSITION_CHAR))
{
if(pass == FORMAT_POSSCAN_PASS)
{
memset(pos_value,0,sizeof(pos_value));
}
format_type = FMT_TYPE_POSITIONAL;
}
else
{
format_type = FMT_TYPE_NONPOSITIONAL;
}
}
if(format_type == FMT_TYPE_POSITIONAL)
{
type_pos = _tcstol(format, &end_pos, 10) - 1;
format = end_pos + 1;
if(pass == FORMAT_POSSCAN_PASS)
{
/* We don't redo the validations in the 2nd pass */
_VALIDATE_RETURN(((type_pos >= 0) && (*end_pos == POSITION_CHAR) && (type_pos < _ARGMAX)), EINVAL, -1);
/* Update max_pos with the current maximum pos argument */
max_pos = type_pos > max_pos ? type_pos : max_pos;
}
}
}
else
{
/* If state is ST_INVALID, that means an invalid format specifier */
if (state == ST_INVALID)
_VALIDATE_RETURN(("Incorrect format specifier", 0), EINVAL, -1);
}
#else /* POSITIONAL_PARAMETERS */
if (state == ST_INVALID)
_VALIDATE_RETURN(("Incorrect format specifier", 0), EINVAL, -1);
#endif /* POSITIONAL_PARAMETERS */
#endif /* FORMAT_VALIDATIONS */
/* execute code for each state */
switch (state) {
case ST_NORMAL:
#ifdef POSITIONAL_PARAMETERS
if(((pass == FORMAT_POSSCAN_PASS) && (format_type == FMT_TYPE_POSITIONAL))
|| ((pass == FORMAT_OUTPUT_PASS) && (format_type == FMT_TYPE_NOTSET)))
{
/* Do not output in the 1st pass, if we have already come across
a positional format specifier. All chars before the first format
specifier get output in the first pass itself. Hence we need to
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?