]>
git.saurik.com Git - apple/icu.git/blob - icuSources/extra/ustdio/uprntf_p.c
2 *******************************************************************************
4 * Copyright (C) 1998-1999, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
11 * Modification History:
13 * Date Name Description
14 * 11/23/98 stephen Creation.
15 * 03/12/99 stephen Modified for new C API.
16 *******************************************************************************
19 #include "unicode/utypes.h"
21 #if !UCONFIG_NO_FORMATTING
26 /* flag characters for uprintf */
27 #define FLAG_MINUS 0x002D
28 #define FLAG_PLUS 0x002B
29 #define FLAG_SPACE 0x0020
30 #define FLAG_POUND 0x0023
31 #define FLAG_ZERO 0x0030
32 #define FLAG_PAREN 0x0028
34 #define ISFLAG(s) (s) == FLAG_MINUS || \
36 (s) == FLAG_SPACE || \
37 (s) == FLAG_POUND || \
41 /* special characters for uprintf */
42 #define SPEC_ASTERISK 0x002A
43 #define SPEC_DOLLARSIGN 0x0024
44 #define SPEC_PERIOD 0x002E
45 #define SPEC_PERCENT 0x0025
48 #define DIGIT_ZERO 0x0030
49 #define DIGIT_ONE 0x0031
50 #define DIGIT_TWO 0x0032
51 #define DIGIT_THREE 0x0033
52 #define DIGIT_FOUR 0x0034
53 #define DIGIT_FIVE 0x0035
54 #define DIGIT_SIX 0x0036
55 #define DIGIT_SEVEN 0x0037
56 #define DIGIT_EIGHT 0x0038
57 #define DIGIT_NINE 0x0039
59 #define ISDIGIT(s) (s) == DIGIT_ZERO || \
62 (s) == DIGIT_THREE || \
63 (s) == DIGIT_FOUR || \
64 (s) == DIGIT_FIVE || \
66 (s) == DIGIT_SEVEN || \
67 (s) == DIGIT_EIGHT || \
70 /* u_printf modifiers */
72 #define MOD_LOWERL 0x006C
75 #define ISMOD(s) (s) == MOD_H || \
76 (s) == MOD_LOWERL || \
79 /* We parse the argument list in Unicode */
81 u_printf_parse_spec (const UChar
*fmt
,
86 u_printf_spec_info
*info
= &(spec
->fInfo
);
88 /* initialize spec to default values */
90 spec
->fPrecisionPos
= -1;
93 info
->fPrecision
= -1;
96 info
->fPadChar
= 0x0020;
100 info
->fShowSign
= FALSE
;
102 info
->fIsLongDouble
= FALSE
;
103 info
->fIsShort
= FALSE
;
104 info
->fIsLong
= FALSE
;
105 info
->fIsLongLong
= FALSE
;
107 /* skip over the initial '%' */
110 /* Check for positional argument */
113 /* Save the current position */
116 /* handle positional parameters */
118 spec
->fArgPos
= (int) (*s
++ - DIGIT_ZERO
);
122 spec
->fArgPos
+= (int) (*s
++ - DIGIT_ZERO
);
126 /* if there is no '$', don't read anything */
127 if(*s
!= SPEC_DOLLARSIGN
) {
136 /* Get any format flags */
145 /* always show sign */
147 info
->fShowSign
= TRUE
;
150 /* use space if no sign present */
152 info
->fShowSign
= TRUE
;
156 /* use alternate form */
161 /* pad with leading zeroes */
164 info
->fPadChar
= 0x0030;
167 /* pad character specified */
170 /* first four characters are hex values for pad char */
171 info
->fPadChar
= (UChar
)ufmt_digitvalue(*s
++);
172 info
->fPadChar
= (UChar
)((info
->fPadChar
* 16) + ufmt_digitvalue(*s
++));
173 info
->fPadChar
= (UChar
)((info
->fPadChar
* 16) + ufmt_digitvalue(*s
++));
174 info
->fPadChar
= (UChar
)((info
->fPadChar
* 16) + ufmt_digitvalue(*s
++));
176 /* final character is ignored */
185 /* width is specified out of line */
186 if(*s
== SPEC_ASTERISK
) {
193 /* Save the current position */
196 /* handle positional parameters */
198 spec
->fWidthPos
= (int) (*s
++ - DIGIT_ZERO
);
201 spec
->fWidthPos
*= 10;
202 spec
->fWidthPos
+= (int) (*s
++ - DIGIT_ZERO
);
206 /* if there is no '$', don't read anything */
207 if(*s
!= SPEC_DOLLARSIGN
) {
208 spec
->fWidthPos
= -1;
215 /* read the width, if present */
216 else if(ISDIGIT(*s
)){
217 info
->fWidth
= (int) (*s
++ - DIGIT_ZERO
);
221 info
->fWidth
+= (int) (*s
++ - DIGIT_ZERO
);
225 /* Get the precision */
227 if(*s
== SPEC_PERIOD
) {
232 /* precision is specified out of line */
233 if(*s
== SPEC_ASTERISK
) {
235 info
->fPrecision
= -2;
240 /* save the current position */
243 /* handle positional parameters */
245 spec
->fPrecisionPos
= (int) (*s
++ - DIGIT_ZERO
);
248 spec
->fPrecisionPos
*= 10;
249 spec
->fPrecisionPos
+= (int) (*s
++ - DIGIT_ZERO
);
252 /* if there is no '$', don't read anything */
253 if(*s
!= SPEC_DOLLARSIGN
) {
254 spec
->fPrecisionPos
= -1;
263 /* read the precision */
264 else if(ISDIGIT(*s
)){
265 info
->fPrecision
= (int) (*s
++ - DIGIT_ZERO
);
268 info
->fPrecision
*= 10;
269 info
->fPrecision
+= (int) (*s
++ - DIGIT_ZERO
);
274 /* Get any modifiers */
280 info
->fIsShort
= TRUE
;
283 /* long or long long */
285 if(*s
== MOD_LOWERL
) {
286 info
->fIsLongLong
= TRUE
;
287 /* skip over the next 'l' */
291 info
->fIsLong
= TRUE
;
296 info
->fIsLongDouble
= TRUE
;
301 /* finally, get the specifier letter */
304 /* return # of characters in this specifier */
305 return (int32_t)(s
- fmt
);
308 #endif /* #if !UCONFIG_NO_FORMATTING */