#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
#include "sscanf_p.h"
#include "ufmt_cmn.h"
#define FLAG_ASTERISK 0x002A
#define FLAG_PAREN 0x0028
#define ISFLAG(s) (s) == FLAG_ASTERISK || \
(s) == FLAG_PAREN
#define SPEC_DOLLARSIGN 0x0024
#define DIGIT_ZERO 0x0030
#define DIGIT_ONE 0x0031
#define DIGIT_TWO 0x0032
#define DIGIT_THREE 0x0033
#define DIGIT_FOUR 0x0034
#define DIGIT_FIVE 0x0035
#define DIGIT_SIX 0x0036
#define DIGIT_SEVEN 0x0037
#define DIGIT_EIGHT 0x0038
#define DIGIT_NINE 0x0039
#define ISDIGIT(s) (s) == DIGIT_ZERO || \
(s) == DIGIT_ONE || \
(s) == DIGIT_TWO || \
(s) == DIGIT_THREE || \
(s) == DIGIT_FOUR || \
(s) == DIGIT_FIVE || \
(s) == DIGIT_SIX || \
(s) == DIGIT_SEVEN || \
(s) == DIGIT_EIGHT || \
(s) == DIGIT_NINE
#define MOD_H 0x0068
#define MOD_LOWERL 0x006C
#define MOD_L 0x004C
#define ISMOD(s) (s) == MOD_H || \
(s) == MOD_LOWERL || \
(s) == MOD_L
int32_t
u_sscanf_parse_spec (const UChar *fmt,
u_sscanf_spec *spec)
{
const UChar *s = fmt;
const UChar *backup;
u_sscanf_spec_info *info = &(spec->fInfo);
spec->fArgPos = -1;
spec->fSkipArg = FALSE;
info->fSpec = 0x0000;
info->fWidth = -1;
info->fPadChar = 0x0020;
info->fIsLongDouble = FALSE;
info->fIsShort = FALSE;
info->fIsLong = FALSE;
info->fIsLongLong = FALSE;
s++;
if(ISDIGIT(*s)) {
backup = s;
if(ISDIGIT(*s)) {
spec->fArgPos = (int) (*s++ - DIGIT_ZERO);
while(ISDIGIT(*s)) {
spec->fArgPos *= 10;
spec->fArgPos += (int) (*s++ - DIGIT_ZERO);
}
}
if(*s != SPEC_DOLLARSIGN) {
spec->fArgPos = -1;
s = backup;
}
else
s++;
}
while(ISFLAG(*s)) {
switch(*s++) {
case FLAG_ASTERISK:
spec->fSkipArg = TRUE;
break;
case FLAG_PAREN:
info->fPadChar = (UChar)ufmt_digitvalue(*s++);
info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*s++));
info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*s++));
info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*s++));
s++;
break;
}
}
if(ISDIGIT(*s)){
info->fWidth = (int) (*s++ - DIGIT_ZERO);
while(ISDIGIT(*s)) {
info->fWidth *= 10;
info->fWidth += (int) (*s++ - DIGIT_ZERO);
}
}
if(ISMOD(*s)) {
switch(*s++) {
case MOD_H:
info->fIsShort = TRUE;
break;
case MOD_LOWERL:
if(*s == MOD_LOWERL) {
info->fIsLongLong = TRUE;
s++;
}
else
info->fIsLong = TRUE;
break;
case MOD_L:
info->fIsLongDouble = TRUE;
break;
}
}
info->fSpec = *s++;
return (int32_t)(s - fmt);
}
#endif