output.c

来自「C语言库函数的原型,有用的拿去」· C语言 代码 · 共 1,893 行 · 第 1/5 页

C
1,893
字号
#if defined (_SAFECRT_IMPL)
 /* 'a' */  0x70,       // Disable %a format
#else  /* defined (_SAFECRT_IMPL) */
 /* 'a' */  0x78,
#endif  /* defined (_SAFECRT_IMPL) */
 /* 'b' */  0x70,
 /* 'c' */  0x78,
 /* 'd' */  0x78,
 /* 'e' */  0x78,
 /* 'f' */  0x78,
 /* 'g' */  0x08,
 /* 'h' */  0x07,
 /* 'i' */  0x08,
 /* 'j' */  0x00,
 /* 'k' */  0x00,
 /* 'l' */  0x07,
 /* 'm' */  0x00,
#if defined (_SAFECRT_IMPL)
 /* 'n' */  0x00,       // Disable %n format
#else  /* defined (_SAFECRT_IMPL) */
 /* 'n' */  0x08,
#endif  /* defined (_SAFECRT_IMPL) */
 /* 'o' */  0x08,
 /* 'p' */  0x08,
 /* 'q' */  0x00,
 /* 'r' */  0x00,
 /* 's' */  0x08,
 /* 't' */  0x00,
 /* 'u' */  0x08,
 /* 'v' */  0x00,
 /* 'w' */  0x07,
 /* 'x' */  0x08
};

#endif  /* defined (_UNICODE) || defined (CPRFLAG) */

#else  /* FORMAT_VALIDATIONS */

#if defined (_UNICODE) || defined (CPRFLAG) || defined (POSITIONAL_PARAMETERS)
extern const unsigned char __lookuptable_s[];
#else  /* defined (_UNICODE) || defined (CPRFLAG) || defined (POSITIONAL_PARAMETERS) */
extern const unsigned char __lookuptable_s[] = {
 /* ' ' */  0x06,
 /* '!' */  0x80,
 /* '"' */  0x80,
 /* '#' */  0x86,
 /* '$' */  0x80,
 /* '%' */  0x81,
 /* '&' */  0x80,
 /* ''' */  0x00,
 /* '(' */  0x00,
 /* ')' */  0x10,
 /* '*' */  0x03,
 /* '+' */  0x86,
 /* ',' */  0x80,
 /* '-' */  0x86,
 /* '.' */  0x82,
 /* '/' */  0x80,
 /* '0' */  0x14,
 /* '1' */  0x05,
 /* '2' */  0x05,
 /* '3' */  0x45,
 /* '4' */  0x45,
 /* '5' */  0x45,
 /* '6' */  0x85,
 /* '7' */  0x85,
 /* '8' */  0x85,
 /* '9' */  0x05,
 /* ':' */  0x00,
 /* ';' */  0x00,
 /* '<' */  0x30,
 /* '=' */  0x30,
 /* '>' */  0x80,
 /* '?' */  0x50,
 /* '@' */  0x80,
#if defined (_SAFECRT_IMPL)
 /* 'A' */  0x80,       // Disable %A format
#else  /* defined (_SAFECRT_IMPL) */
 /* 'A' */  0x88,
#endif  /* defined (_SAFECRT_IMPL) */
 /* 'B' */  0x00,
 /* 'C' */  0x08,
 /* 'D' */  0x00,
 /* 'E' */  0x28,
 /* 'F' */  0x27,
 /* 'G' */  0x38,
 /* 'H' */  0x50,
 /* 'I' */  0x57,
 /* 'J' */  0x80,
 /* 'K' */  0x00,
 /* 'L' */  0x07,
 /* 'M' */  0x00,
 /* 'N' */  0x37,
 /* 'O' */  0x30,
 /* 'P' */  0x30,
 /* 'Q' */  0x50,
 /* 'R' */  0x50,
 /* 'S' */  0x88,
 /* 'T' */  0x00,
 /* 'U' */  0x00,
 /* 'V' */  0x00,
 /* 'W' */  0x20,
 /* 'X' */  0x28,
 /* 'Y' */  0x80,
 /* 'Z' */  0x88,
 /* '[' */  0x80,
 /* '\' */  0x80,
 /* ']' */  0x00,
 /* '^' */  0x00,
 /* '_' */  0x00,
 /* '`' */  0x60,
#if defined (_SAFECRT_IMPL)
 /* 'a' */  0x60,       // Disable %a format
#else  /* defined (_SAFECRT_IMPL) */
 /* 'a' */  0x68,
#endif  /* defined (_SAFECRT_IMPL) */
 /* 'b' */  0x60,
 /* 'c' */  0x68,
 /* 'd' */  0x68,
 /* 'e' */  0x68,
 /* 'f' */  0x08,
 /* 'g' */  0x08,
 /* 'h' */  0x07,
 /* 'i' */  0x78,
 /* 'j' */  0x70,
 /* 'k' */  0x70,
 /* 'l' */  0x77,
 /* 'm' */  0x70,
 /* 'n' */  0x70,
 /* 'o' */  0x08,
 /* 'p' */  0x08,
 /* 'q' */  0x00,
 /* 'r' */  0x00,
 /* 's' */  0x08,
 /* 't' */  0x00,
 /* 'u' */  0x08,
 /* 'v' */  0x00,
 /* 'w' */  0x07,
 /* 'x' */  0x08
};
#endif  /* defined (_UNICODE) || defined (CPRFLAG) || defined (POSITIONAL_PARAMETERS) */

#endif  /* FORMAT_VALIDATIONS */

#ifdef POSITIONAL_PARAMETERS

#define POSITION_CHAR _T('$')

#define FORMAT_POSSCAN_PASS 0
#define FORMAT_OUTPUT_PASS 1

#define FMT_TYPE_NOTSET -1
#define FMT_TYPE_NONPOSITIONAL 0
#define FMT_TYPE_POSITIONAL 1

enum ARG_TYPE{
eblank,
e_int_arg,
#ifndef _UNICODE
e_short_arg,
#endif  /* _UNICODE */
e_ptr_arg,
e_int64_arg,
e_long_long_arg,
e_long_arg,
e_longdouble_arg,
e_double_arg
};

struct positional_param
{
    enum ARG_TYPE arg_type;
    va_list arg_ptr;
    TCHAR type;
    int flags;
};



#ifndef _UNICODE
#define _IS_FMTTYPE_WIDE(fl) ((fl & (FL_LONG|FL_WIDECHAR)) != 0)
#else  /* _UNICODE */
#define _IS_FMTTYPE_WIDE(fl) ((fl & FL_SHORT) == 0)
#endif  /* _UNICODE */

#define _IS_FMTTYPE_PTRSIZE(fl) ((fl & FL_PTRSIZE) != 0)
#define _IS_FMTTYPE_SHORT(fl) ((fl & FL_SHORT) != 0)

#define _IS_FMTTYPE_POINTER(type) (type == _T('p'))
#define _IS_FMTTYPE_STRING(type) ( (type == _T('s')) || (type == _T('S')) )
#define _IS_FMTTYPE_NUMERIC(type) ( (type == _T('d')) || (type == _T('i')) || (type == _T('o')) || \
                              (type == _T('u')) || (type == _T('x')) || (type == _T('X')) )

#ifdef _UNICODE
#define _tvalidate_param_reuse _validate_param_reuseW
#else  /* _UNICODE */
#define _tvalidate_param_reuse _validate_param_reuseA
#endif  /* _UNICODE */


/***
*int _tvalidate_param_reuse(struct positional_param * pos, enum ARG_TYPE get_fn_type, TCHAR cur_type, int cur_flags)
*
*Purpose:
*   Validates if the reused positional parameter is doesn't breaking any rules.
*   a) %p - shouldn't be mixed with other format types.
*   b) Wide & Ansi strings shouldn't be mixed
*   c) Numeric types shouldn't mix if their sizes are different
*   d) %I (without I32 or I64) shouldn't mix with other numeric types
*
*Entry:
*   struct positional_param * pos
*   enum ARG_TYPE get_fn_type
*   TCHAR cur_type
*   int cur_flags
*
*Exit:
*   Returns 0 if any non-allowed reuse is happening otherwise 1
*
*******************************************************************************/

#ifndef CPRFLAG
int _tvalidate_param_reuse(struct positional_param * pos, enum ARG_TYPE get_fn_type, TCHAR cur_type, int cur_flags)
{
    int stored_value = 0 ;
    int new_value = 0 ;

    if(_IS_FMTTYPE_POINTER(pos->type) || _IS_FMTTYPE_POINTER(cur_type))
    {
        /* %p param shouldn't be mixed with other types. If both are %p,
        then we don't need to do any more validations */
        return (pos->type == cur_type) ;
    }

    stored_value = _IS_FMTTYPE_STRING(pos->type);
    new_value = _IS_FMTTYPE_STRING(cur_type);

    if(stored_value || new_value)
    {
        /* If one type is a string, then the other also should be a string. Also
           Wide & Ansi String parameters shouldn't be interchangebly used.
           If these conditions are met, we don't need to do any more validations.
        */
        return ( (stored_value == new_value) && (_IS_FMTTYPE_WIDE(pos->flags) == _IS_FMTTYPE_WIDE(cur_flags)) );
    }

    if( _IS_FMTTYPE_NUMERIC(pos->type) || _IS_FMTTYPE_NUMERIC(cur_type))
    {
        /* If one type is numeric, then the other should also be numeric. */
        if (_IS_FMTTYPE_NUMERIC(pos->type) != _IS_FMTTYPE_NUMERIC(cur_type))
            return 0;

        /* For Numeric Types, we should allow mixing only if the size is the
        same. Also, we shouldn't allow %I (without 32/64) which is platform
        dependent to mix with other fixed numeric types */
        if( (_IS_FMTTYPE_PTRSIZE(pos->flags) != _IS_FMTTYPE_PTRSIZE(cur_flags)) ||
            (_IS_FMTTYPE_SHORT(pos->flags) != _IS_FMTTYPE_SHORT(cur_flags)) )
        {
            return 0;
        }
    }

    return (pos->arg_type == get_fn_type);
}
#else  /* CPRFLAG */
int _tvalidate_param_reuse(struct positional_param * pos, enum ARG_TYPE get_fn_type, TCHAR cur_type, int cur_flags);
#endif  /* CPRFLAG */

#define STORE_ARGPTR(pos_struct, get_fn_type, pos, cur_type, cur_flags) \
        if(pos_struct[pos].arg_type == eblank) \
        { \
            pos_struct[pos].arg_type = get_fn_type; \
            pos_struct[pos].type = cur_type; \
            pos_struct[pos].flags = cur_flags; \
        } \
        else \
        { \
            _VALIDATE_RETURN(_tvalidate_param_reuse(&pos_struct[pos], get_fn_type, cur_type, cur_flags), EINVAL, -1); \
        }


#define GET_ARG(get_fn_type, arg_ptr, lhs, type) { va_list lst = arg_ptr ;lhs = type get_fn_type(&lst);}

#endif  /* POSITIONAL_PARAMETERS */

#define FIND_CHAR_CLASS(lookuptbl, c)      \
        ((c) < _T(' ') || (c) > _T('x') ? \
            CH_OTHER            \
            :               \
        (enum CHARTYPE)(lookuptbl[(c)-_T(' ')] & 0xF))

#define FIND_NEXT_STATE(lookuptbl, class, state)   \
        (enum STATE)(lookuptbl[(class) * NUMSTATES + (state)] >> 4)

/*
 * Note: CPRFLAG and _UNICODE cases are currently mutually exclusive.
 */

/* prototypes */

#ifdef CPRFLAG

#define WRITE_CHAR(ch, pnw)         write_char(ch, pnw)
#define WRITE_MULTI_CHAR(ch, num, pnw)  write_multi_char(ch, num, pnw)
#define WRITE_STRING(s, len, pnw)   write_string(s, len, pnw)
#define WRITE_WSTRING(s, len, pnw)  write_wstring(s, len, pnw)

LOCAL(void) write_char(_TCHAR ch, int *pnumwritten);
LOCAL(void) write_multi_char(_TCHAR ch, int num, int *pnumwritten);
LOCAL(void) write_string(_TCHAR *string, int len, int *numwritten);
LOCAL(void) write_wstring(wchar_t *string, int len, int *numwritten);

#else  /* CPRFLAG */

#define WRITE_CHAR(ch, pnw)         write_char(ch, stream, pnw)
#define WRITE_MULTI_CHAR(ch, num, pnw)  write_multi_char(ch, num, stream, pnw)
#define WRITE_STRING(s, len, pnw)   write_string(s, len, stream, pnw)
#define WRITE_WSTRING(s, len, pnw)  write_wstring(s, len, stream, pnw)

LOCAL(void) write_char(_TCHAR ch, FILE *f, int *pnumwritten);
LOCAL(void) write_multi_char(_TCHAR ch, int num, FILE *f, int *pnumwritten);
LOCAL(void) write_string(_TCHAR *string, int len, FILE *f, int *numwritten);
LOCAL(void) write_wstring(wchar_t *string, int len, FILE *f, int *numwritten);

#endif  /* CPRFLAG */

__inline int __cdecl get_int_arg(va_list *pargptr);

#ifndef _UNICODE
#if !SHORT_IS_INT
__inline short __cdecl get_short_arg(va_list *pargptr);
#endif  /* !SHORT_IS_INT */
#endif  /* _UNICODE */

#if !LONG_IS_INT
__inline long __cdecl get_long_arg(va_list *pargptr);
#endif  /* !LONG_IS_INT */

#if !LONGLONG_IS_INT64
__inline long long __cdecl get_long_long_arg(va_list *pargptr);
#endif  /* !LONGLONG_IS_INT64 */

__inline __int64 __cdecl get_int64_arg(va_list *pargptr);

#ifdef POSITIONAL_PARAMETERS
#if !LONGDOUBLE_IS_DOUBLE
__inline _LONGDOUBLE __cdecl get_longdouble_arg(va_list *pargptr);
#else  /* !LONGDOUBLE_IS_DOUBLE */
__inline _CRT_DOUBLE __cdecl get_crtdouble_arg(va_list *pargptr);
#endif  /* !LONGDOUBLE_IS_DOUBLE */
#endif  /* POSITIONAL_PARAMETERS */

#ifdef CPRFLAG
LOCAL(int) output(const _TCHAR *, _locale_t , va_list);
_CRTIMP int __cdecl _vtcprintf_l (const _TCHAR *, _locale_t, va_list);
_CRTIMP int __cdecl _vtcprintf_s_l (const _TCHAR *, _locale_t, va_list);
_CRTIMP int __cdecl _vtcprintf_p_l (const _TCHAR *, _locale_t, va_list);


/***
*int _cprintf(format, arglist) - write formatted output directly to console
*
*Purpose:
*   Writes formatted data like printf, but uses console I/O functions.
*
*Entry:
*   char *format - format string to determine data formats
*   arglist - list of POINTERS to where to put data
*
*Exit:
*   returns number of characters written
*
*Exceptions:
*
*******************************************************************************/
#ifndef FORMAT_VALIDATIONS
_CRTIMP int __cdecl _tcprintf_l (
        const _TCHAR * format,
        _locale_t plocinfo,

⌨️ 快捷键说明

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