2
******************************************************************************
4
* Copyright (C) 2000-2001, International Business Machines
5
* Corporation and others. All Rights Reserved.
7
******************************************************************************
11
* Modification History:
13
* Date Name Description
14
* 02/08/00 george Creation. Copied from uprntf_p.c
15
******************************************************************************
21
/* flag characters for uprintf */
22
#define FLAG_MINUS 0x002D
23
#define FLAG_PLUS 0x002B
24
#define FLAG_SPACE 0x0020
25
#define FLAG_POUND 0x0023
26
#define FLAG_ZERO 0x0030
27
#define FLAG_PAREN 0x0028
29
#define ISFLAG(s) (s) == FLAG_MINUS || \
31
(s) == FLAG_SPACE || \
32
(s) == FLAG_POUND || \
36
/* special characters for uprintf */
37
#define SPEC_ASTERISK 0x002A
38
#define SPEC_DOLLARSIGN 0x0024
39
#define SPEC_PERIOD 0x002E
40
#define SPEC_PERCENT 0x0025
43
#define DIGIT_ZERO 0x0030
44
#define DIGIT_ONE 0x0031
45
#define DIGIT_TWO 0x0032
46
#define DIGIT_THREE 0x0033
47
#define DIGIT_FOUR 0x0034
48
#define DIGIT_FIVE 0x0035
49
#define DIGIT_SIX 0x0036
50
#define DIGIT_SEVEN 0x0037
51
#define DIGIT_EIGHT 0x0038
52
#define DIGIT_NINE 0x0039
54
#define ISDIGIT(s) (s) == DIGIT_ZERO || \
57
(s) == DIGIT_THREE || \
58
(s) == DIGIT_FOUR || \
59
(s) == DIGIT_FIVE || \
61
(s) == DIGIT_SEVEN || \
62
(s) == DIGIT_EIGHT || \
65
/* u_printf modifiers */
67
#define MOD_LOWERL 0x006C
70
#define ISMOD(s) (s) == MOD_H || \
71
(s) == MOD_LOWERL || \
74
/* We parse the argument list in Unicode */
76
u_sprintf_parse_spec (const UChar *fmt,
81
u_sprintf_spec_info *info = &(spec->fInfo);
83
/* initialize spec to default values */
85
spec->fPrecisionPos = -1;
88
info->fPrecision = -1;
91
info->fPadChar = 0x0020;
95
info->fShowSign = FALSE;
97
info->fIsLongDouble = FALSE;
98
info->fIsShort = FALSE;
99
info->fIsLong = FALSE;
100
info->fIsLongLong = FALSE;
102
/* skip over the initial '%' */
105
/* Check for positional argument */
108
/* Save the current position */
111
/* handle positional parameters */
113
spec->fArgPos = (int) (*s++ - DIGIT_ZERO);
117
spec->fArgPos += (int) (*s++ - DIGIT_ZERO);
121
/* if there is no '$', don't read anything */
122
if(*s != SPEC_DOLLARSIGN) {
131
/* Get any format flags */
140
/* always show sign */
142
info->fShowSign = TRUE;
145
/* use space if no sign present */
147
info->fShowSign = TRUE;
151
/* use alternate form */
156
/* pad with leading zeroes */
159
info->fPadChar = 0x0030;
162
/* pad character specified */
165
/* first four characters are hex values for pad char */
166
info->fPadChar = (UChar)ufmt_digitvalue(*s++);
167
info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*s++));
168
info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*s++));
169
info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*s++));
171
/* final character is ignored */
180
/* width is specified out of line */
181
if(*s == SPEC_ASTERISK) {
188
/* Save the current position */
191
/* handle positional parameters */
193
spec->fWidthPos = (int) (*s++ - DIGIT_ZERO);
196
spec->fWidthPos *= 10;
197
spec->fWidthPos += (int) (*s++ - DIGIT_ZERO);
201
/* if there is no '$', don't read anything */
202
if(*s != SPEC_DOLLARSIGN) {
203
spec->fWidthPos = -1;
210
/* read the width, if present */
211
else if(ISDIGIT(*s)){
212
info->fWidth = (int) (*s++ - DIGIT_ZERO);
216
info->fWidth += (int) (*s++ - DIGIT_ZERO);
220
/* Get the precision */
222
if(*s == SPEC_PERIOD) {
227
/* precision is specified out of line */
228
if(*s == SPEC_ASTERISK) {
230
info->fPrecision = -2;
235
/* save the current position */
238
/* handle positional parameters */
240
spec->fPrecisionPos = (int) (*s++ - DIGIT_ZERO);
243
spec->fPrecisionPos *= 10;
244
spec->fPrecisionPos += (int) (*s++ - DIGIT_ZERO);
247
/* if there is no '$', don't read anything */
248
if(*s != SPEC_DOLLARSIGN) {
249
spec->fPrecisionPos = -1;
258
/* read the precision */
259
else if(ISDIGIT(*s)){
260
info->fPrecision = (int) (*s++ - DIGIT_ZERO);
263
info->fPrecision *= 10;
264
info->fPrecision += (int) (*s++ - DIGIT_ZERO);
269
/* Get any modifiers */
275
info->fIsShort = TRUE;
278
/* long or long long */
280
if(*s == MOD_LOWERL) {
281
info->fIsLongLong = TRUE;
282
/* skip over the next 'l' */
286
info->fIsLong = TRUE;
291
info->fIsLongDouble = TRUE;
296
/* finally, get the specifier letter */
299
/* return # of characters in this specifier */