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