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 + -
显示快捷键?