hexadd; /* offset to add to number to get 'a'..'f' */ TCHAR ch; /* character just read */ int flags; /* 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; /* selected field width -- 0 means default */ int precision; /* selected precision -- -1 means default */ TCHAR prefix[2]; /* numeric prefix -- up to two characters */ int prefixlen; /* length of prefix -- 0 means no prefix */ int capexp; /* non-zero = 'E' exponent signifient, zero = 'e' */ int no_output; /* 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 WPRFLAG */ union { char sz[BUFFERSIZE]; #ifdef WPRFLAG wchar_t wz[BUFFERSIZE]; #endif } buffer; wchar_t wchar; /* temp wchar_t */ int bufferiswide; /* non-zero = buffer contains wide chars already */ charsout = 0; /* no characters written yet */ state = ST_NORMAL; /* starting state */ /* main loop -- loop while format character exist and no I/O errors */ while ((ch = *format++) != _T('\0') && charsout >= 0) { chclass = find_char_class(ch); /* find character class */ state = find_next_state(chclass, state); /* find next state */ /* execute code for each state */ switch (state) { case ST_NORMAL: /* normal state -- just write character */ #ifdef WPRFLAG bufferiswide = 1; #else bufferiswide = 0; if (isleadbyte((int)(unsigned char)ch)) { WRITE_CHAR(ch, &charsout); ch = *format++; assert (ch != _T('\0')); /* UNDONE: don't fall off format string */ } #endif /* !WPRFLAG */ 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 */ fldwidth = get_int_arg(&argptr); 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; br |