output.c
来自「C语言库函数的原型,有用的拿去」· C语言 代码 · 共 1,893 行 · 第 1/5 页
C
1,893 行
check the format_type to make sure that they don't get output
again in the 2nd pass */
break;
}
#endif /* POSITIONAL_PARAMETERS */
NORMAL_STATE:
/* normal state -- just write character */
#ifdef _UNICODE
bufferiswide = 1;
#else /* _UNICODE */
bufferiswide = 0;
#ifdef _SAFECRT_IMPL
if (isleadbyte((unsigned char)ch)) {
#else /* _SAFECRT_IMPL */
if (_isleadbyte_l((unsigned char)ch, _loc_update.GetLocaleT())) {
#endif /* _SAFECRT_IMPL */
WRITE_CHAR(ch, &charsout);
ch = *format++;
/* don't fall off format string */
_VALIDATE_RETURN( (ch != _T('\0')), EINVAL, -1);
}
#endif /* _UNICODE */
WRITE_CHAR(ch, &charsout);
break;
case ST_PERCENT:
/* set default value of conversion parameters */
prefixlen = fldwidth = no_output = capexp = 0;
flags = 0;
precision = -1;
bufferiswide = 0; /* default */
break;
case ST_FLAG:
/* set flag based on which flag character */
switch (ch) {
case _T('-'):
flags |= FL_LEFT; /* '-' => left justify */
break;
case _T('+'):
flags |= FL_SIGN; /* '+' => force sign indicator */
break;
case _T(' '):
flags |= FL_SIGNSP; /* ' ' => force sign or space */
break;
case _T('#'):
flags |= FL_ALTERNATE; /* '#' => alternate form */
break;
case _T('0'):
flags |= FL_LEADZERO; /* '0' => pad with leading zeros */
break;
}
break;
case ST_WIDTH:
/* update width value */
if (ch == _T('*')) {
/* get width from arg list */
#ifdef POSITIONAL_PARAMETERS
if(format_type == FMT_TYPE_NONPOSITIONAL)
{
#endif /* POSITIONAL_PARAMETERS */
fldwidth = get_int_arg(&argptr);
#ifdef POSITIONAL_PARAMETERS
}
else
{
width_pos = _tcstol(format, &end_pos, 10) - 1;
format = end_pos + 1;
if(pass == FORMAT_POSSCAN_PASS)
{
_VALIDATE_RETURN(((width_pos >= 0) && (*end_pos == POSITION_CHAR) && (type_pos < _ARGMAX)), EINVAL, -1);
/* Update max_pos with the current maximum pos argument */
max_pos = width_pos > max_pos ? width_pos : max_pos;
STORE_ARGPTR(pos_value, e_int_arg, width_pos, ch, flags)
break;
}
else
{
/* get width from arg list */
GET_ARG(get_int_arg,pos_value[width_pos].arg_ptr, fldwidth, )
}
}
#endif /* POSITIONAL_PARAMETERS */
if (fldwidth < 0) {
/* ANSI says neg fld width means '-' flag and pos width */
flags |= FL_LEFT;
fldwidth = -fldwidth;
}
}
else {
/* add digit to current field width */
fldwidth = fldwidth * 10 + (ch - _T('0'));
}
break;
case ST_DOT:
/* zero the precision, since dot with no number means 0
not default, according to ANSI */
precision = 0;
break;
case ST_PRECIS:
/* update precison value */
if (ch == _T('*')) {
/* get precision from arg list */
#ifdef POSITIONAL_PARAMETERS
if(format_type == FMT_TYPE_NONPOSITIONAL)
{
#endif /* POSITIONAL_PARAMETERS */
precision = get_int_arg(&argptr);
#ifdef POSITIONAL_PARAMETERS
}
else
{
precis_pos = _tcstol(format, &end_pos, 10) - 1;
format = end_pos + 1;
if(pass == FORMAT_POSSCAN_PASS)
{
_VALIDATE_RETURN(((precis_pos >= 0) && (*end_pos == POSITION_CHAR) && (type_pos < _ARGMAX)), EINVAL, -1);
/* Update max_pos with the current maximum pos argument */
max_pos = precis_pos > max_pos ? precis_pos : max_pos;
STORE_ARGPTR(pos_value, e_int_arg, precis_pos, ch, flags)
break;
}
else
{
/* get width from arg list */
GET_ARG(get_int_arg,pos_value[precis_pos].arg_ptr, precision, )
}
}
#endif /* POSITIONAL_PARAMETERS */
if (precision < 0)
precision = -1; /* neg precision means default */
}
else {
/* add digit to current precision */
precision = precision * 10 + (ch - _T('0'));
}
break;
case ST_SIZE:
/* just read a size specifier, set the flags based on it */
switch (ch) {
case _T('l'):
/*
* In order to handle the ll case, we depart from the
* simple deterministic state machine.
*/
if (*format == _T('l'))
{
++format;
flags |= FL_LONGLONG; /* 'll' => long long */
}
else
{
flags |= FL_LONG; /* 'l' => long int or wchar_t */
}
break;
case _T('I'):
/*
* In order to handle the I, I32, and I64 size modifiers, we
* depart from the simple deterministic state machine. The
* code below scans for characters following the 'I',
* and defaults to 64 bit on WIN64 and 32 bit on WIN32
*/
#if PTR_IS_INT64
flags |= FL_I64; /* 'I' => __int64 on WIN64 systems */
#endif /* PTR_IS_INT64 */
if ( (*format == _T('6')) && (*(format + 1) == _T('4')) )
{
format += 2;
flags |= FL_I64; /* I64 => __int64 */
}
else if ( (*format == _T('3')) && (*(format + 1) == _T('2')) )
{
format += 2;
flags &= ~FL_I64; /* I32 => __int32 */
}
else if ( (*format == _T('d')) ||
(*format == _T('i')) ||
(*format == _T('o')) ||
(*format == _T('u')) ||
(*format == _T('x')) ||
(*format == _T('X')) )
{
#ifdef POSITIONAL_PARAMETERS
/* %I without 32/64 is platform dependent. We set FL_PTRSIZE to indicate
this - this is used in the positional parameter reuse validation */
flags |= FL_PTRSIZE;
#else /* POSITIONAL_PARAMETERS */
/*
* Nothing further needed. %Id (et al) is
* handled just like %d, except that it defaults to 64 bits
* on WIN64. Fall through to the next iteration.
*/
#endif /* POSITIONAL_PARAMETERS */
}
else {
state = ST_NORMAL;
goto NORMAL_STATE;
}
break;
case _T('h'):
flags |= FL_SHORT; /* 'h' => short int or char */
break;
case _T('w'):
flags |= FL_WIDECHAR; /* 'w' => wide character */
break;
}
break;
case ST_TYPE:
/* we have finally read the actual type character, so we */
/* now format and "print" the output. We use a big switch */
/* statement that sets 'text' to point to the text that should */
/* be printed, and 'textlen' to the length of this text. */
/* Common code later on takes care of justifying it and */
/* other miscellaneous chores. Note that cases share code, */
/* in particular, all integer formatting is done in one place. */
/* Look at those funky goto statements! */
switch (ch) {
case _T('C'): /* ISO wide character */
if (!(flags & (FL_SHORT|FL_LONG|FL_WIDECHAR)))
#ifdef _UNICODE
flags |= FL_SHORT;
#else /* _UNICODE */
flags |= FL_WIDECHAR; /* ISO std. */
#endif /* _UNICODE */
/* fall into 'c' case */
case _T('c'): {
/* print a single character specified by int argument */
#ifdef _UNICODE
bufferiswide = 1;
#ifdef POSITIONAL_PARAMETERS
if(format_type == FMT_TYPE_NONPOSITIONAL)
{
#endif /* POSITIONAL_PARAMETERS */
wchar = (wchar_t) get_int_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_int_arg, type_pos, ch, flags)
break;
}
else
{
GET_ARG(get_int_arg,pos_value[type_pos].arg_ptr, wchar, (wchar_t))
}
}
#endif /* POSITIONAL_PARAMETERS */
if (flags & FL_SHORT) {
/* format multibyte character */
/* this is an extension of ANSI */
char tempchar[2];
{
tempchar[0] = (char)(wchar & 0x00ff);
tempchar[1] = '\0';
}
#ifdef _SAFECRT_IMPL
if (_MBTOWC(buffer.wz,tempchar, MB_CUR_MAX) < 0)
#else /* _SAFECRT_IMPL */
if (_mbtowc_l(buffer.wz,
tempchar,
_loc_update.GetLocaleT()->locinfo->mb_cur_max,
_loc_update.GetLocaleT()) < 0)
#endif /* _SAFECRT_IMPL */
{
/* ignore if conversion was unsuccessful */
no_output = 1;
}
} else {
buffer.wz[0] = wchar;
}
text.wz = buffer.wz;
textlen = 1; /* print just a single character */
#else /* _UNICODE */
if (flags & (FL_LONG|FL_WIDECHAR)) {
errno_t e = 0;
#ifdef POSITIONAL_PARAMETERS
if(format_type == FMT_TYPE_NONPOSITIONAL)
{
#endif /* POSITIONAL_PARAMETERS */
wchar = (wchar_t) get_short_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_short_arg, type_pos, ch, flags)
break;
}
else
{
GET_ARG(get_short_arg,pos_value[type_pos].arg_ptr, wchar, (wchar_t))
}
}
#endif /* POSITIONAL_PARAMETERS */
/* convert to multibyte character */
e = _WCTOMB_S(&textlen, buffer.sz, _countof(buffer.sz), wchar);
/* check that conversion was successful */
if (e != 0)
no_output = 1;
} else {
/* format multibyte character */
/* this is an extension of ANSI */
unsigned short temp;
#ifdef POSITIONAL_PARAMETERS
if(format_type == FMT_TYPE_NONPOSITIONAL)
{
#endif /* POSITIONAL_PARAMETERS */
temp = (unsigned short) get_int_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_int_arg, type_pos, ch, flags)
break;
}
else
{
GET_ARG(get_int_arg,pos_value[type_pos].arg_ptr, temp, (unsigned short))
}
}
#endif /* POSITIONAL_PARAMETERS */
{
buffer.sz[0] = (char) temp;
textlen = 1;
}
}
text.sz = buffer.sz;
#endif /* _UNICODE */
}
break;
case _T('Z'): {
/* print a Counted String
int i;
char *p; /* temps */
struct _count_string {
short Length;
short MaximumLength;
char *Buffer;
} *pstr;
#ifdef POSITIONAL_PARAMETERS
if(format_type == FMT_TYPE_NONPOSITIONAL)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?