output.c

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

C
1,893
字号
#endif  /* POSITIONAL_PARAMETERS */
                pstr = (struct _count_string *)get_ptr_arg(&argptr);
#ifdef POSITIONAL_PARAMETERS
                }
                else
                {
                    _VALIDATE_RETURN(((type_pos>=0) && (type_pos<_ARGMAX)), EINVAL, -1);

                    if (pass == FORMAT_POSSCAN_PASS)
                    {
                        STORE_ARGPTR(pos_value, e_ptr_arg, type_pos, ch, flags)
                        break;
                    }
                    else
                    {
                        GET_ARG(get_ptr_arg,pos_value[type_pos].arg_ptr, pstr, (struct _count_string *) )
                    }
                }
#endif  /* POSITIONAL_PARAMETERS */
                if (pstr == NULL || pstr->Buffer == NULL) {
                    /* null ptr passed, use special string */
                    text.sz = __nullstring;
                    textlen = (int)strlen(text.sz);
                } else {
                    if (flags & FL_WIDECHAR) {
                        text.wz = (wchar_t *)pstr->Buffer;
                        textlen = pstr->Length / (int)sizeof(wchar_t);
                        bufferiswide = 1;
                    } else {
                        bufferiswide = 0;
                        text.sz = pstr->Buffer;
                        textlen = pstr->Length;
                    }
                }
            }
            break;

            case _T('S'):   /* ISO wide character string */
#ifndef _UNICODE
                if (!(flags & (FL_SHORT|FL_LONG|FL_WIDECHAR)))
                    flags |= FL_WIDECHAR;
#else  /* _UNICODE */
                if (!(flags & (FL_SHORT|FL_LONG|FL_WIDECHAR)))
                    flags |= FL_SHORT;
#endif  /* _UNICODE */

            case _T('s'): {
                /* print a string --                            */
                /* ANSI rules on how much of string to print:   */
                /*   all if precision is default,               */
                /*   min(precision, length) if precision given. */
                /* prints '(null)' if a null string is passed   */

                int i;
                char *p;       /* temps */
                wchar_t *pwch;

                /* At this point it is tempting to use strlen(), but */
                /* if a precision is specified, we're not allowed to */
                /* scan past there, because there might be no null   */
                /* at all.  Thus, we must do our own scan.           */

                i = (precision == -1) ? INT_MAX : precision;
#ifdef POSITIONAL_PARAMETERS
                if(format_type == FMT_TYPE_NONPOSITIONAL)
                {
#endif  /* POSITIONAL_PARAMETERS */
                text.sz = (char *)get_ptr_arg(&argptr);
#ifdef POSITIONAL_PARAMETERS
                }
                else
                {
                    _VALIDATE_RETURN(((type_pos>=0) && (type_pos<_ARGMAX)), EINVAL, -1);

                    if (pass == FORMAT_POSSCAN_PASS)
                    {
                        STORE_ARGPTR(pos_value, e_ptr_arg, type_pos, ch, flags)
                        break;
                    }
                    else
                    {
                        GET_ARG(get_ptr_arg,pos_value[type_pos].arg_ptr, text.sz,(char *))
                    }
                }
#endif  /* POSITIONAL_PARAMETERS */

                /* scan for null upto i characters */
#ifdef _UNICODE
                if (flags & FL_SHORT) {
                    if (text.sz == NULL) /* NULL passed, use special string */
                        text.sz = __nullstring;
                    p = text.sz;
                    for (textlen=0; textlen<i && *p; textlen++) {
#ifdef _SAFECRT_IMPL
                        if (isleadbyte((unsigned char)(*p)))
#else  /* _SAFECRT_IMPL */
                        if (_isleadbyte_l((unsigned char)(*p), _loc_update.GetLocaleT()))
#endif  /* _SAFECRT_IMPL */
                            ++p;
                        ++p;
                    }
                    /* textlen now contains length in multibyte chars */
                } else {
                    if (text.wz == NULL) /* NULL passed, use special string */
                        text.wz = __wnullstring;
                    bufferiswide = 1;
                    pwch = text.wz;
                    while (i-- && *pwch)
                        ++pwch;
                    textlen = (int)(pwch - text.wz);       /* in wchar_ts */
                    /* textlen now contains length in wide chars */
                }
#else  /* _UNICODE */
                if (flags & (FL_LONG|FL_WIDECHAR)) {
                    if (text.wz == NULL) /* NULL passed, use special string */
                        text.wz = __wnullstring;
                    bufferiswide = 1;
                    pwch = text.wz;
                    while ( i-- && *pwch )
                        ++pwch;
                    textlen = (int)(pwch - text.wz);
                    /* textlen now contains length in wide chars */
                } else {
                    if (text.sz == NULL) /* NULL passed, use special string */
                        text.sz = __nullstring;
                    p = text.sz;
                    while (i-- && *p)
                        ++p;
                    textlen = (int)(p - text.sz);    /* length of the string */
                }

#endif  /* _UNICODE */
            }
            break;


            case _T('n'): {
                /* write count of characters seen so far into */
                /* short/int/long thru ptr read from args */

                void *p;        /* temp */

#ifdef POSITIONAL_PARAMETERS
                if(format_type == FMT_TYPE_NONPOSITIONAL)
                {
#endif  /* POSITIONAL_PARAMETERS */
                p = get_ptr_arg(&argptr);
#ifdef POSITIONAL_PARAMETERS
                }
                else
                {
                    _VALIDATE_RETURN(((type_pos>=0) && (type_pos<_ARGMAX)), EINVAL, -1);

                    if (pass == FORMAT_POSSCAN_PASS)
                    {
                        STORE_ARGPTR(pos_value, e_ptr_arg, type_pos, ch, flags)
                        break;
                    }
                    else
                    {
                        GET_ARG(get_ptr_arg,pos_value[type_pos].arg_ptr,p,)
                    }
                }
#endif  /* POSITIONAL_PARAMETERS */

                /* if %n is disabled, we skip an arg and print 'n' */
                if ( !_get_printf_count_output() )
                {
                    _VALIDATE_RETURN(("'n' format specifier disabled", 0), EINVAL, -1);
                    break;
                }

                /* store chars out into short/long/int depending on flags */
#if !LONG_IS_INT
                if (flags & FL_LONG)
                    *(long *)p = charsout;
                else
#endif  /* !LONG_IS_INT */

#if !SHORT_IS_INT
                if (flags & FL_SHORT)
                    *(short *)p = (short) charsout;
                else
#endif  /* !SHORT_IS_INT */
                    *(int *)p = charsout;

                no_output = 1;              /* force no output */
            }
            break;

            case _T('E'):
            case _T('G'):
            case _T('A'):
                capexp = 1;                 /* capitalize exponent */
                ch += _T('a') - _T('A');    /* convert format char to lower */
                /* DROP THROUGH */
            case _T('e'):
            case _T('f'):
            case _T('g'):
            case _T('a'): {
                /* floating point conversion -- we call cfltcvt routines */
                /* to do the work for us.                                */
                flags |= FL_SIGNED;         /* floating point is signed conversion */
#ifdef POSITIONAL_PARAMETERS
                if((format_type == FMT_TYPE_POSITIONAL) && (pass == FORMAT_POSSCAN_PASS))
                {
                    _VALIDATE_RETURN(((type_pos>=0) && (type_pos<_ARGMAX)), EINVAL, -1);

#if !LONGDOUBLE_IS_DOUBLE

                    if (flags & FL_LONGDOUBLE)
                    {
                        STORE_ARGPTR(pos_value, e_longdouble_arg, type_pos, ch, flags)
                    }
                    else
#endif  /* !LONGDOUBLE_IS_DOUBLE */
                    {
                        STORE_ARGPTR(pos_value, e_double_arg, type_pos, ch, flags)
                    }

                    break;
                }
#endif  /* POSITIONAL_PARAMETERS */
                text.sz = buffer.sz;        /* put result in buffer */
                buffersize = BUFFERSIZE;

                /* compute the precision value */
                if (precision < 0)
                    precision = 6;          /* default precision: 6 */
                else if (precision == 0 && ch == _T('g'))
                    precision = 1;          /* ANSI specified */
                else if (precision > MAXPRECISION)
                    precision = MAXPRECISION;

                if (precision > BUFFERSIZE - _CVTBUFSIZE) {
                    /* conversion will potentially overflow local buffer */
                    /* so we need to use a heap-allocated buffer.        */
                    heapbuf = (char *)_malloc_crt(_CVTBUFSIZE + precision);
                    if (heapbuf != NULL)
                    {
                        text.sz = heapbuf;
                        buffersize = _CVTBUFSIZE + precision;
                    }
                    else
                        /* malloc failed, cap precision further */
                        precision = BUFFERSIZE - _CVTBUFSIZE;
                }

#ifdef _SAFECRT_IMPL
                /* for safecrt, we pass along the FL_ALTERNATE flag to _safecrt_cfltcvt */
                if (flags & FL_ALTERNATE)
                {
                    capexp |= FL_ALTERNATE;
                }
#endif  /* _SAFECRT_IMPL */

#if !LONGDOUBLE_IS_DOUBLE
                /* do the conversion */
                if (flags & FL_LONGDOUBLE) {
                    _LONGDOUBLE tmp;
#ifdef POSITIONAL_PARAMETERS
                    if(format_type == FMT_TYPE_NONPOSITIONAL)
                    {
#endif  /* POSITIONAL_PARAMETERS */
                    tmp=va_arg(argptr, _LONGDOUBLE);
#ifdef POSITIONAL_PARAMETERS
                    }
                    else
                    {
                        /* Will get here only for pass == FORMAT_OUTPUT_PASS because
                        pass == FORMAT_POSSCAN_PASS has a break Above */
                        va_list tmp_arg;
                        _ASSERTE(pass == FORMAT_OUTPUT_PASS);
                        tmp_arg = pos_value[type_pos].arg_ptr;
                        tmp=va_arg(tmp_arg, _LONGDOUBLE);
                    }
#endif  /* POSITIONAL_PARAMETERS */
                    /* Note: assumes ch is in ASCII range */
                    _CLDCVT(&tmp, text.sz, buffersize, (char)ch, precision, capexp);
                } else
#endif  /* !LONGDOUBLE_IS_DOUBLE */
                {
                    _CRT_DOUBLE tmp;
#ifdef POSITIONAL_PARAMETERS
                    if(format_type == FMT_TYPE_NONPOSITIONAL)
                    {
#endif  /* POSITIONAL_PARAMETERS */
                    tmp=va_arg(argptr, _CRT_DOUBLE);
#ifdef POSITIONAL_PARAMETERS
                    }
                    else
                    {
                        /* Will get here only for pass == FORMAT_OUTPUT_PASS because
                        pass == FORMAT_POSSCAN_PASS has a break Above */
                        va_list tmp_arg;

                        _VALIDATE_RETURN(((type_pos>=0) && (type_pos<_ARGMAX)), EINVAL, -1);

                                                _ASSERTE(pass == FORMAT_OUTPUT_PASS);
                        tmp_arg = pos_value[type_pos].arg_ptr;
                        tmp=va_arg(tmp_arg, _CRT_DOUBLE);
                    }
#endif  /* POSITIONAL_PARAMETERS */
                    /* Note: assumes ch is in ASCII range */
                    /* In safecrt, we provide a special version of _cfltcvt which internally calls printf (see safecrt_output_s.c) */
#ifndef _SAFECRT_IMPL
                    _cfltcvt_l(&tmp.x, text.sz, buffersize, (char)ch, precision, capexp, _loc_update.GetLocaleT());
#else  /* _SAFECRT_IMPL */
                    _CFLTCVT(&tmp, text.sz, buffersize, (char)ch, precision, capexp);
#endif  /* _SAFECRT_IMPL */
                }

#ifndef _SAFECRT_IMPL
                /* For safecrt, this is done already in _safecrt_cfltcvt */

                /* '#' and precision == 0 means force a decimal point */
                if ((flags & FL_ALTERNATE) && precision == 0)
                {
                    _forcdecpt_l(text.sz, _loc_update.GetLocaleT());
                }

                /* 'g' format means crop zero unless '#' given */
                if (ch == _T('g') && !(flags & FL_ALTERNATE))
                {
                    _cropzeros_l(text.sz, _loc_update.GetLocaleT());
                }
#endif  /* _SAFECRT_IMPL */

                /* check if result was negative, save '-' for later */
                /* and point to positive part (this is for '0' padding) */
                if (*text.sz == '-') {
                    flags |= FL_NEGATIVE;
                    ++text.sz;
                }

                textlen = (int)strlen(text.sz);     /* compute length of text */
            }
            break;

            case _T('d'):
            case _T('i'):
                /* signed decimal output */
                flags |= FL_SIGNED;
                radix = 10;
                goto COMMON_INT;

            case _T('u'):
                radix = 10;
                goto COMMON_INT;

            case _T('p'):
                /* write a pointer -- this is like an integer or long */
                /* except we force precision to pad with zeros and */
                /* output in big hex. */

                precision = 2 * sizeof(void *);     /* number of hex digits needed */
#if PTR_IS_INT64
                flags |= FL_I64;                    /* assume we're converting an int64 */
#elif !PTR_IS_INT
                flags |= FL_LONG;                   /* assume we're converting a long */
#endif  /* !PTR_IS_INT */
                /* DROP THROUGH to hex formatting */

            case _T('X'):
                /* unsigned upper hex output */
                hexadd = _T('A') - _T('9') - 1;     /* set hexadd for uppercase hex */
                goto COMMON_HEX;

            case _T('x'):
                /* unsigned lower hex output */
                hexadd = _T('a') - _T('9') - 1;     /* set hexadd for lowercase hex */
                /* DROP THROUGH TO COMMON_HEX */

            COMMON_HEX:
                radix = 16;
                if (flags & FL_ALTERNATE) {
                 

⌨️ 快捷键说明

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