00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "uprntf_p.h"
00020 #include "ufmt_cmn.h"
00021
00022
00023 #define FLAG_MINUS 0x002D
00024 #define FLAG_PLUS 0x002B
00025 #define FLAG_SPACE 0x0020
00026 #define FLAG_POUND 0x0023
00027 #define FLAG_ZERO 0x0030
00028 #define FLAG_PAREN 0x0028
00029
00030 #define ISFLAG(s) (s) == FLAG_MINUS || \
00031 (s) == FLAG_PLUS || \
00032 (s) == FLAG_SPACE || \
00033 (s) == FLAG_POUND || \
00034 (s) == FLAG_ZERO || \
00035 (s) == FLAG_PAREN
00036
00037
00038 #define SPEC_ASTERISK 0x002A
00039 #define SPEC_DOLLARSIGN 0x0024
00040 #define SPEC_PERIOD 0x002E
00041 #define SPEC_PERCENT 0x0025
00042
00043
00044 #define DIGIT_ZERO 0x0030
00045 #define DIGIT_ONE 0x0031
00046 #define DIGIT_TWO 0x0032
00047 #define DIGIT_THREE 0x0033
00048 #define DIGIT_FOUR 0x0034
00049 #define DIGIT_FIVE 0x0035
00050 #define DIGIT_SIX 0x0036
00051 #define DIGIT_SEVEN 0x0037
00052 #define DIGIT_EIGHT 0x0038
00053 #define DIGIT_NINE 0x0039
00054
00055 #define ISDIGIT(s) (s) == DIGIT_ZERO || \
00056 (s) == DIGIT_ONE || \
00057 (s) == DIGIT_TWO || \
00058 (s) == DIGIT_THREE || \
00059 (s) == DIGIT_FOUR || \
00060 (s) == DIGIT_FIVE || \
00061 (s) == DIGIT_SIX || \
00062 (s) == DIGIT_SEVEN || \
00063 (s) == DIGIT_EIGHT || \
00064 (s) == DIGIT_NINE
00065
00066
00067 #define MOD_H 0x0068
00068 #define MOD_LOWERL 0x006C
00069 #define MOD_L 0x004C
00070
00071 #define ISMOD(s) (s) == MOD_H || \
00072 (s) == MOD_LOWERL || \
00073 (s) == MOD_L
00074
00075
00076 int32_t
00077 u_printf_parse_spec (const UChar *fmt,
00078 u_printf_spec *spec)
00079 {
00080 const UChar *s = fmt;
00081 const UChar *backup;
00082 u_printf_spec_info *info = &(spec->fInfo);
00083
00084
00085 spec->fWidthPos = -1;
00086 spec->fPrecisionPos = -1;
00087 spec->fArgPos = -1;
00088
00089 info->fPrecision = -1;
00090 info->fWidth = -1;
00091 info->fSpec = 0x0000;
00092 info->fPadChar = 0x0020;
00093 info->fAlt = FALSE;
00094 info->fSpace = FALSE;
00095 info->fLeft = FALSE;
00096 info->fShowSign = FALSE;
00097 info->fZero = FALSE;
00098 info->fIsLongDouble = FALSE;
00099 info->fIsShort = FALSE;
00100 info->fIsLong = FALSE;
00101 info->fIsLongLong = FALSE;
00102
00103
00104 s++;
00105
00106
00107 if(ISDIGIT(*s)) {
00108
00109
00110 backup = s;
00111
00112
00113 if(ISDIGIT(*s)) {
00114 spec->fArgPos = (int) (*s++ - DIGIT_ZERO);
00115
00116 while(ISDIGIT(*s)) {
00117 spec->fArgPos *= 10;
00118 spec->fArgPos += (int) (*s++ - DIGIT_ZERO);
00119 }
00120 }
00121
00122
00123 if(*s != SPEC_DOLLARSIGN) {
00124 spec->fArgPos = -1;
00125 s = backup;
00126 }
00127
00128 else
00129 s++;
00130 }
00131
00132
00133 while(ISFLAG(*s)) {
00134 switch(*s++) {
00135
00136
00137 case FLAG_MINUS:
00138 info->fLeft = TRUE;
00139 break;
00140
00141
00142 case FLAG_PLUS:
00143 info->fShowSign = TRUE;
00144 break;
00145
00146
00147 case FLAG_SPACE:
00148 info->fSpace = TRUE;
00149 break;
00150
00151
00152 case FLAG_POUND:
00153 info->fAlt = TRUE;
00154 break;
00155
00156
00157 case FLAG_ZERO:
00158 info->fZero = TRUE;
00159 info->fPadChar = 0x0030;
00160 break;
00161
00162
00163 case FLAG_PAREN:
00164
00165
00166 info->fPadChar = (UChar)ufmt_digitvalue(*s++);
00167 info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*s++));
00168 info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*s++));
00169 info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*s++));
00170
00171
00172 s++;
00173
00174 break;
00175 }
00176 }
00177
00178
00179
00180
00181 if(*s == SPEC_ASTERISK) {
00182
00183 info->fWidth = -2;
00184
00185
00186 s++;
00187
00188
00189 backup = s;
00190
00191
00192 if(ISDIGIT(*s)) {
00193 spec->fWidthPos = (int) (*s++ - DIGIT_ZERO);
00194
00195 while(ISDIGIT(*s)) {
00196 spec->fWidthPos *= 10;
00197 spec->fWidthPos += (int) (*s++ - DIGIT_ZERO);
00198 }
00199 }
00200
00201
00202 if(*s != SPEC_DOLLARSIGN) {
00203 spec->fWidthPos = -1;
00204 s = backup;
00205 }
00206
00207 else
00208 s++;
00209 }
00210
00211 else if(ISDIGIT(*s)){
00212 info->fWidth = (int) (*s++ - DIGIT_ZERO);
00213
00214 while(ISDIGIT(*s)) {
00215 info->fWidth *= 10;
00216 info->fWidth += (int) (*s++ - DIGIT_ZERO);
00217 }
00218 }
00219
00220
00221
00222 if(*s == SPEC_PERIOD) {
00223
00224
00225 s++;
00226
00227
00228 if(*s == SPEC_ASTERISK) {
00229
00230 info->fPrecision = -2;
00231
00232
00233 s++;
00234
00235
00236 backup = s;
00237
00238
00239 if(ISDIGIT(*s)) {
00240 spec->fPrecisionPos = (int) (*s++ - DIGIT_ZERO);
00241
00242 while(ISDIGIT(*s)) {
00243 spec->fPrecisionPos *= 10;
00244 spec->fPrecisionPos += (int) (*s++ - DIGIT_ZERO);
00245 }
00246
00247
00248 if(*s != SPEC_DOLLARSIGN) {
00249 spec->fPrecisionPos = -1;
00250 s = backup;
00251 }
00252 else {
00253
00254 s++;
00255 }
00256 }
00257 }
00258
00259 else if(ISDIGIT(*s)){
00260 info->fPrecision = (int) (*s++ - DIGIT_ZERO);
00261
00262 while(ISDIGIT(*s)) {
00263 info->fPrecision *= 10;
00264 info->fPrecision += (int) (*s++ - DIGIT_ZERO);
00265 }
00266 }
00267 }
00268
00269
00270 if(ISMOD(*s)) {
00271 switch(*s++) {
00272
00273
00274 case MOD_H:
00275 info->fIsShort = TRUE;
00276 break;
00277
00278
00279 case MOD_LOWERL:
00280 if(*s == MOD_LOWERL) {
00281 info->fIsLongLong = TRUE;
00282
00283 s++;
00284 }
00285 else
00286 info->fIsLong = TRUE;
00287 break;
00288
00289
00290 case MOD_L:
00291 info->fIsLongDouble = TRUE;
00292 break;
00293 }
00294 }
00295
00296
00297 info->fSpec = *s++;
00298
00299
00300 return (s - fmt);
00301 }