1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*******************************************************************************
3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius*   Copyright (C) 1998-2011, International Business Machines
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Corporation and others.  All Rights Reserved.
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*******************************************************************************
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* File uscnnf_p.c
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Modification History:
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Date        Name        Description
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   12/02/98    stephen        Creation.
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   03/13/99    stephen     Modified for new C API.
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*******************************************************************************
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uchar.h"
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ustring.h"
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/unum.h"
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/udat.h"
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uset.h"
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uscanf.h"
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ufmt_cmn.h"
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ufile.h"
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "locbund.h"
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h"
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ustr_cnv.h"
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* flag characters for u_scanf */
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define FLAG_ASTERISK 0x002A
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define FLAG_PAREN 0x0028
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define ISFLAG(s)    (s) == FLAG_ASTERISK || \
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (s) == FLAG_PAREN
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* special characters for u_scanf */
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define SPEC_DOLLARSIGN 0x0024
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* unicode digits */
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_ZERO 0x0030
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_ONE 0x0031
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_TWO 0x0032
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_THREE 0x0033
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_FOUR 0x0034
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_FIVE 0x0035
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_SIX 0x0036
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_SEVEN 0x0037
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_EIGHT 0x0038
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DIGIT_NINE 0x0039
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define ISDIGIT(s)    (s) == DIGIT_ZERO || \
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (s) == DIGIT_ONE || \
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (s) == DIGIT_TWO || \
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (s) == DIGIT_THREE || \
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (s) == DIGIT_FOUR || \
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (s) == DIGIT_FIVE || \
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (s) == DIGIT_SIX || \
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (s) == DIGIT_SEVEN || \
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (s) == DIGIT_EIGHT || \
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (s) == DIGIT_NINE
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* u_scanf modifiers */
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MOD_H 0x0068
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MOD_LOWERL 0x006C
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MOD_L 0x004C
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define ISMOD(s)    (s) == MOD_H || \
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (s) == MOD_LOWERL || \
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            (s) == MOD_L
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Struct encapsulating a single uscanf format specification.
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef struct u_scanf_spec_info {
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t fWidth;         /* Width  */
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar   fSpec;          /* Format specification  */
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar   fPadChar;       /* Padding character  */
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool   fSkipArg;       /* TRUE if arg should be skipped */
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool   fIsLongDouble;  /* L flag  */
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool   fIsShort;       /* h flag  */
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool   fIsLong;        /* l flag  */
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool   fIsLongLong;    /* ll flag  */
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool   fIsString;      /* TRUE if this is a NULL-terminated string. */
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} u_scanf_spec_info;
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Struct encapsulating a single u_scanf format specification.
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef struct u_scanf_spec {
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    u_scanf_spec_info    fInfo;        /* Information on this spec */
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t        fArgPos;    /* Position of data in arg list */
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} u_scanf_spec;
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Parse a single u_scanf format specifier in Unicode.
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param fmt A pointer to a '%' character in a u_scanf format specification.
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param spec A pointer to a <TT>u_scanf_spec</TT> to receive the parsed
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * format specifier.
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return The number of characters contained in this specifier.
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_parse_spec (const UChar     *fmt,
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            u_scanf_spec    *spec)
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar *s = fmt;
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar *backup;
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    u_scanf_spec_info *info = &(spec->fInfo);
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* initialize spec to default values */
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    spec->fArgPos             = -1;
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    info->fWidth        = -1;
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    info->fSpec         = 0x0000;
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    info->fPadChar      = 0x0020;
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    info->fSkipArg      = FALSE;
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    info->fIsLongDouble = FALSE;
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    info->fIsShort      = FALSE;
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    info->fIsLong       = FALSE;
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    info->fIsLongLong   = FALSE;
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    info->fIsString     = TRUE;
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* skip over the initial '%' */
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    s++;
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Check for positional argument */
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(ISDIGIT(*s)) {
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* Save the current position */
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        backup = s;
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* handle positional parameters */
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(ISDIGIT(*s)) {
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            spec->fArgPos = (int) (*s++ - DIGIT_ZERO);
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            while(ISDIGIT(*s)) {
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                spec->fArgPos *= 10;
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                spec->fArgPos += (int) (*s++ - DIGIT_ZERO);
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* if there is no '$', don't read anything */
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(*s != SPEC_DOLLARSIGN) {
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            spec->fArgPos = -1;
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            s = backup;
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* munge the '$' */
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            s++;
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Get any format flags */
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while(ISFLAG(*s)) {
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        switch(*s++) {
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* skip argument */
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case FLAG_ASTERISK:
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            info->fSkipArg = TRUE;
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* pad character specified */
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case FLAG_PAREN:
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* first four characters are hex values for pad char */
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            info->fPadChar = (UChar)ufmt_digitvalue(*s++);
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*s++));
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*s++));
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            info->fPadChar = (UChar)((info->fPadChar * 16) + ufmt_digitvalue(*s++));
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* final character is ignored */
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            s++;
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Get the width */
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(ISDIGIT(*s)){
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        info->fWidth = (int) (*s++ - DIGIT_ZERO);
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while(ISDIGIT(*s)) {
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            info->fWidth *= 10;
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            info->fWidth += (int) (*s++ - DIGIT_ZERO);
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Get any modifiers */
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(ISMOD(*s)) {
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        switch(*s++) {
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* short */
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case MOD_H:
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            info->fIsShort = TRUE;
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* long or long long */
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case MOD_LOWERL:
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(*s == MOD_LOWERL) {
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                info->fIsLongLong = TRUE;
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* skip over the next 'l' */
212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                s++;
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                info->fIsLong = TRUE;
216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* long double */
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case MOD_L:
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            info->fIsLongDouble = TRUE;
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* finally, get the specifier letter */
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    info->fSpec = *s++;
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* return # of characters in this specifier */
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return (int32_t)(s - fmt);
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UP_PERCENT 0x0025
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* ANSI style formatting */
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Use US-ASCII characters only for formatting */
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* % */
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_SIMPLE_PERCENT {ufmt_simple_percent, u_scanf_simple_percent_handler}
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* s */
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_STRING         {ufmt_string, u_scanf_string_handler}
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* c */
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_CHAR           {ufmt_string, u_scanf_char_handler}
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* d, i */
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_INT            {ufmt_int, u_scanf_integer_handler}
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* u */
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_UINT           {ufmt_int, u_scanf_uinteger_handler}
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* o */
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_OCTAL          {ufmt_int, u_scanf_octal_handler}
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* x, X */
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_HEX            {ufmt_int, u_scanf_hex_handler}
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* f */
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_DOUBLE         {ufmt_double, u_scanf_double_handler}
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* e, E */
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_SCIENTIFIC     {ufmt_double, u_scanf_scientific_handler}
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* g, G */
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_SCIDBL         {ufmt_double, u_scanf_scidbl_handler}
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* n */
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_COUNT          {ufmt_count, u_scanf_count_handler}
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* [ */
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_SCANSET        {ufmt_string, u_scanf_scanset_handler}
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* non-ANSI extensions */
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Use US-ASCII characters only for formatting */
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* p */
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_POINTER        {ufmt_pointer, u_scanf_pointer_handler}
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* V */
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_SPELLOUT       {ufmt_double, u_scanf_spellout_handler}
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* P */
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_PERCENT        {ufmt_double, u_scanf_percent_handler}
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* C  K is old format */
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_UCHAR          {ufmt_uchar, u_scanf_uchar_handler}
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* S  U is old format */
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_USTRING        {ufmt_ustring, u_scanf_ustring_handler}
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UFMT_EMPTY {ufmt_empty, NULL}
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * A u_scanf handler function.
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * A u_scanf handler is responsible for handling a single u_scanf
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * format specification, for example 'd' or 's'.
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param stream The UFILE to which to write output.
285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param info A pointer to a <TT>u_scanf_spec_info</TT> struct containing
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * information on the format specification.
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param args A pointer to the argument data
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param fmt A pointer to the first character in the format string
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * following the spec.
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param fmtConsumed On output, set to the number of characters consumed
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * in <TT>fmt</TT>. Do nothing, if the argument isn't variable width.
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param argConverted The number of arguments converted and assigned, or -1 if an
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * error occurred.
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return The number of code points consumed during reading.
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef int32_t (*u_scanf_handler) (UFILE   *stream,
297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                   u_scanf_spec_info  *info,
298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                   ufmt_args                *args,
299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                   const UChar              *fmt,
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                   int32_t                  *fmtConsumed,
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                   int32_t                  *argConverted);
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef struct u_scanf_info {
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ufmt_type_info info;
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    u_scanf_handler handler;
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} u_scanf_info;
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define USCANF_NUM_FMT_HANDLERS 108
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define USCANF_SYMBOL_BUFFER_SIZE 8
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* We do not use handlers for 0-0x1f */
312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define USCANF_BASE_FMT_HANDLERS 0x20
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_skip_leading_ws(UFILE   *input,
317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        UChar   pad)
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar   c;
320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t count = 0;
321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool isNotEOF;
322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* skip all leading ws in the input */
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while( (isNotEOF = ufile_getch(input, &c)) && (c == pad || u_isWhitespace(c)) )
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        count++;
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* put the final character back on the input */
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(isNotEOF)
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        u_fungetc(c, input);
332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return count;
334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* TODO: Is always skipping the prefix symbol as a positive sign a good idea in all locales? */
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_skip_leading_positive_sign(UFILE   *input,
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UNumberFormat *format,
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UErrorCode *status)
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar   c;
343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t count = 0;
344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool isNotEOF;
345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar plusSymbol[USCANF_SYMBOL_BUFFER_SIZE];
346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t symbolLen;
347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode localStatus = U_ZERO_ERROR;
348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_SUCCESS(*status)) {
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        symbolLen = unum_getSymbol(format,
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UNUM_PLUS_SIGN_SYMBOL,
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            plusSymbol,
353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            sizeof(plusSymbol)/sizeof(*plusSymbol),
354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            &localStatus);
355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_SUCCESS(localStatus)) {
357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* skip all leading ws in the input */
358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            while( (isNotEOF = ufile_getch(input, &c)) && (count < symbolLen && c == plusSymbol[count]) )
359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            {
360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                count++;
361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* put the final character back on the input */
364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(isNotEOF) {
365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                u_fungetc(c, input);
366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return count;
371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_simple_percent_handler(UFILE        *input,
375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                               u_scanf_spec_info *info,
376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                               ufmt_args    *args,
377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                               const UChar  *fmt,
378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                               int32_t      *fmtConsumed,
379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                               int32_t      *argConverted)
380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* make sure the next character in the input is a percent */
382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *argConverted = 0;
383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(u_fgetc(input) != 0x0025) {
384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *argConverted = -1;
385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return 1;
387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_count_handler(UFILE         *input,
391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      u_scanf_spec_info *info,
392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      ufmt_args     *args,
393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      const UChar   *fmt,
394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      int32_t       *fmtConsumed,
395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      int32_t       *argConverted)
396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* in the special case of count, the u_scanf_spec_info's width */
398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* will contain the # of items converted thus far */
399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!info->fSkipArg) {
400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (info->fIsShort)
401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(int16_t*)(args[0].ptrValue) = (int16_t)(UINT16_MAX & info->fWidth);
402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (info->fIsLongLong)
403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(int64_t*)(args[0].ptrValue) = info->fWidth;
404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else
405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(int32_t*)(args[0].ptrValue) = (int32_t)(UINT32_MAX & info->fWidth);
406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *argConverted = 0;
408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* we converted 0 args */
410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return 0;
411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_double_handler(UFILE        *input,
415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       u_scanf_spec_info *info,
416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       ufmt_args    *args,
417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       const UChar  *fmt,
418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       int32_t      *fmtConsumed,
419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       int32_t      *argConverted)
420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         len;
422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    double          num;
423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UNumberFormat   *format;
424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         parsePos    = 0;
425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         skipped;
426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode      status      = U_ZERO_ERROR;
427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* skip all ws in the input */
430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    skipped = u_scanf_skip_leading_ws(input, info->fPadChar);
431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* fill the input's internal buffer */
433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ufile_fill_uchar_buffer(input);
434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* determine the size of the input's buffer */
436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    len = (int32_t)(input->str.fLimit - input->str.fPos);
437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* truncate to the width, if specified */
439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(info->fWidth != -1)
440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        len = ufmt_min(len, info->fWidth);
441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* get the formatter */
443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    format = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_DECIMAL);
444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* handle error */
446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(format == 0)
447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0;
448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */
450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    skipped += u_scanf_skip_leading_positive_sign(input, format, &status);
451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* parse the number */
453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    num = unum_parseDouble(format, input->str.fPos, len, &parsePos, &status);
454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!info->fSkipArg) {
456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (info->fIsLong)
457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(double*)(args[0].ptrValue) = num;
458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (info->fIsLongDouble)
459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(long double*)(args[0].ptrValue) = num;
460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else
461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(float*)(args[0].ptrValue) = (float)num;
462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* mask off any necessary bits */
465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*  if(! info->fIsLong_double)
466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    num &= DBL_MAX;*/
467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* update the input's position to reflect consumed data */
469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    input->str.fPos += parsePos;
470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* we converted 1 arg */
472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *argConverted = !info->fSkipArg;
473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return parsePos + skipped;
474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
47627f654740f2a26ad62a5c155af9199af9e69b889claireho#define UPRINTF_SYMBOL_BUFFER_SIZE 8
47727f654740f2a26ad62a5c155af9199af9e69b889claireho
478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_scientific_handler(UFILE        *input,
480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           u_scanf_spec_info *info,
481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           ufmt_args    *args,
482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           const UChar  *fmt,
483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           int32_t      *fmtConsumed,
484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           int32_t      *argConverted)
485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         len;
487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    double          num;
488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UNumberFormat   *format;
489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         parsePos    = 0;
490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         skipped;
491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode      status      = U_ZERO_ERROR;
49227f654740f2a26ad62a5c155af9199af9e69b889claireho    UChar srcExpBuf[UPRINTF_SYMBOL_BUFFER_SIZE];
49327f654740f2a26ad62a5c155af9199af9e69b889claireho    int32_t srcLen, expLen;
49427f654740f2a26ad62a5c155af9199af9e69b889claireho    UChar expBuf[UPRINTF_SYMBOL_BUFFER_SIZE];
495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* skip all ws in the input */
498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    skipped = u_scanf_skip_leading_ws(input, info->fPadChar);
499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* fill the input's internal buffer */
501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ufile_fill_uchar_buffer(input);
502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* determine the size of the input's buffer */
504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    len = (int32_t)(input->str.fLimit - input->str.fPos);
505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* truncate to the width, if specified */
507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(info->fWidth != -1)
508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        len = ufmt_min(len, info->fWidth);
509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* get the formatter */
511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    format = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_SCIENTIFIC);
512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* handle error */
514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(format == 0)
515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0;
516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
51727f654740f2a26ad62a5c155af9199af9e69b889claireho    /* set the appropriate flags on the formatter */
51827f654740f2a26ad62a5c155af9199af9e69b889claireho
51927f654740f2a26ad62a5c155af9199af9e69b889claireho    srcLen = unum_getSymbol(format,
52027f654740f2a26ad62a5c155af9199af9e69b889claireho        UNUM_EXPONENTIAL_SYMBOL,
52127f654740f2a26ad62a5c155af9199af9e69b889claireho        srcExpBuf,
52227f654740f2a26ad62a5c155af9199af9e69b889claireho        sizeof(srcExpBuf),
52327f654740f2a26ad62a5c155af9199af9e69b889claireho        &status);
52427f654740f2a26ad62a5c155af9199af9e69b889claireho
52527f654740f2a26ad62a5c155af9199af9e69b889claireho    /* Upper/lower case the e */
52627f654740f2a26ad62a5c155af9199af9e69b889claireho    if (info->fSpec == (UChar)0x65 /* e */) {
52727f654740f2a26ad62a5c155af9199af9e69b889claireho        expLen = u_strToLower(expBuf, (int32_t)sizeof(expBuf),
52827f654740f2a26ad62a5c155af9199af9e69b889claireho            srcExpBuf, srcLen,
52927f654740f2a26ad62a5c155af9199af9e69b889claireho            input->str.fBundle.fLocale,
53027f654740f2a26ad62a5c155af9199af9e69b889claireho            &status);
53127f654740f2a26ad62a5c155af9199af9e69b889claireho    }
53227f654740f2a26ad62a5c155af9199af9e69b889claireho    else {
53327f654740f2a26ad62a5c155af9199af9e69b889claireho        expLen = u_strToUpper(expBuf, (int32_t)sizeof(expBuf),
53427f654740f2a26ad62a5c155af9199af9e69b889claireho            srcExpBuf, srcLen,
53527f654740f2a26ad62a5c155af9199af9e69b889claireho            input->str.fBundle.fLocale,
53627f654740f2a26ad62a5c155af9199af9e69b889claireho            &status);
53727f654740f2a26ad62a5c155af9199af9e69b889claireho    }
53827f654740f2a26ad62a5c155af9199af9e69b889claireho
53927f654740f2a26ad62a5c155af9199af9e69b889claireho    unum_setSymbol(format,
54027f654740f2a26ad62a5c155af9199af9e69b889claireho        UNUM_EXPONENTIAL_SYMBOL,
54127f654740f2a26ad62a5c155af9199af9e69b889claireho        expBuf,
54227f654740f2a26ad62a5c155af9199af9e69b889claireho        expLen,
54327f654740f2a26ad62a5c155af9199af9e69b889claireho        &status);
54427f654740f2a26ad62a5c155af9199af9e69b889claireho
54527f654740f2a26ad62a5c155af9199af9e69b889claireho
54627f654740f2a26ad62a5c155af9199af9e69b889claireho
54727f654740f2a26ad62a5c155af9199af9e69b889claireho
548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */
549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    skipped += u_scanf_skip_leading_positive_sign(input, format, &status);
550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* parse the number */
552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    num = unum_parseDouble(format, input->str.fPos, len, &parsePos, &status);
553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!info->fSkipArg) {
555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (info->fIsLong)
556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(double*)(args[0].ptrValue) = num;
557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (info->fIsLongDouble)
558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(long double*)(args[0].ptrValue) = num;
559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else
560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(float*)(args[0].ptrValue) = (float)num;
561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* mask off any necessary bits */
564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*  if(! info->fIsLong_double)
565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    num &= DBL_MAX;*/
566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* update the input's position to reflect consumed data */
568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    input->str.fPos += parsePos;
569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* we converted 1 arg */
571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *argConverted = !info->fSkipArg;
572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return parsePos + skipped;
573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_scidbl_handler(UFILE        *input,
577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       u_scanf_spec_info *info,
578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       ufmt_args    *args,
579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       const UChar  *fmt,
580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       int32_t      *fmtConsumed,
581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       int32_t      *argConverted)
582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t       len;
584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    double        num;
585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UNumberFormat *scientificFormat, *genericFormat;
586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*int32_t       scientificResult, genericResult;*/
587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    double        scientificResult, genericResult;
588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t       scientificParsePos = 0, genericParsePos = 0, parsePos = 0;
589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t       skipped;
590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode    scientificStatus = U_ZERO_ERROR;
591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode    genericStatus = U_ZERO_ERROR;
592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* since we can't determine by scanning the characters whether */
595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* a number was formatted in the 'f' or 'g' styles, parse the */
596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* string with both formatters, and assume whichever one */
597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* parsed the most is the correct formatter to use */
598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* skip all ws in the input */
601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    skipped = u_scanf_skip_leading_ws(input, info->fPadChar);
602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* fill the input's internal buffer */
604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ufile_fill_uchar_buffer(input);
605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* determine the size of the input's buffer */
607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    len = (int32_t)(input->str.fLimit - input->str.fPos);
608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* truncate to the width, if specified */
610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(info->fWidth != -1)
611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        len = ufmt_min(len, info->fWidth);
612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* get the formatters */
614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    scientificFormat = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_SCIENTIFIC);
615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    genericFormat = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_DECIMAL);
616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* handle error */
618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(scientificFormat == 0 || genericFormat == 0)
619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0;
620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */
622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    skipped += u_scanf_skip_leading_positive_sign(input, genericFormat, &genericStatus);
623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* parse the number using each format*/
625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    scientificResult = unum_parseDouble(scientificFormat, input->str.fPos, len,
627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        &scientificParsePos, &scientificStatus);
628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    genericResult = unum_parseDouble(genericFormat, input->str.fPos, len,
630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        &genericParsePos, &genericStatus);
631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* determine which parse made it farther */
633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(scientificParsePos > genericParsePos) {
634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* stash the result in num */
635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        num = scientificResult;
636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* update the input's position to reflect consumed data */
637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        parsePos += scientificParsePos;
638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else {
640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* stash the result in num */
641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        num = genericResult;
642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* update the input's position to reflect consumed data */
643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        parsePos += genericParsePos;
644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    input->str.fPos += parsePos;
646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!info->fSkipArg) {
648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (info->fIsLong)
649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(double*)(args[0].ptrValue) = num;
650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (info->fIsLongDouble)
651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(long double*)(args[0].ptrValue) = num;
652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else
653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(float*)(args[0].ptrValue) = (float)num;
654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* mask off any necessary bits */
657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*  if(! info->fIsLong_double)
658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    num &= DBL_MAX;*/
659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* we converted 1 arg */
661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *argConverted = !info->fSkipArg;
662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return parsePos + skipped;
663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_integer_handler(UFILE       *input,
667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        u_scanf_spec_info *info,
668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        ufmt_args   *args,
669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        const UChar *fmt,
670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        int32_t     *fmtConsumed,
671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        int32_t     *argConverted)
672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         len;
674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void            *num        = (void*) (args[0].ptrValue);
675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UNumberFormat   *format;
676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         parsePos    = 0;
677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         skipped;
678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode      status      = U_ZERO_ERROR;
679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int64_t         result;
680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* skip all ws in the input */
683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    skipped = u_scanf_skip_leading_ws(input, info->fPadChar);
684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* fill the input's internal buffer */
686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ufile_fill_uchar_buffer(input);
687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* determine the size of the input's buffer */
689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    len = (int32_t)(input->str.fLimit - input->str.fPos);
690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* truncate to the width, if specified */
692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(info->fWidth != -1)
693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        len = ufmt_min(len, info->fWidth);
694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* get the formatter */
696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    format = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_DECIMAL);
697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* handle error */
699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(format == 0)
700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0;
701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */
703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    skipped += u_scanf_skip_leading_positive_sign(input, format, &status);
704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* parse the number */
706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    result = unum_parseInt64(format, input->str.fPos, len, &parsePos, &status);
707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* mask off any necessary bits */
709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!info->fSkipArg) {
710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (info->fIsShort)
711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(int16_t*)num = (int16_t)(UINT16_MAX & result);
712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (info->fIsLongLong)
713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(int64_t*)num = result;
714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else
715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(int32_t*)num = (int32_t)(UINT32_MAX & result);
716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* update the input's position to reflect consumed data */
719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    input->str.fPos += parsePos;
720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* we converted 1 arg */
722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *argConverted = !info->fSkipArg;
723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return parsePos + skipped;
724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_uinteger_handler(UFILE          *input,
728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                         u_scanf_spec_info *info,
729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                         ufmt_args      *args,
730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                         const UChar    *fmt,
731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                         int32_t        *fmtConsumed,
732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                         int32_t        *argConverted)
733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* TODO Fix this when Numberformat handles uint64_t */
735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return u_scanf_integer_handler(input, info, args, fmt, fmtConsumed, argConverted);
736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_percent_handler(UFILE       *input,
740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        u_scanf_spec_info *info,
741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        ufmt_args   *args,
742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        const UChar *fmt,
743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        int32_t     *fmtConsumed,
744ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        int32_t     *argConverted)
745ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
746ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         len;
747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    double          num;
748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UNumberFormat   *format;
749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         parsePos    = 0;
750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode      status      = U_ZERO_ERROR;
751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* skip all ws in the input */
75483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    u_scanf_skip_leading_ws(input, info->fPadChar);
755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
756ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* fill the input's internal buffer */
757ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ufile_fill_uchar_buffer(input);
758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
759ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* determine the size of the input's buffer */
760ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    len = (int32_t)(input->str.fLimit - input->str.fPos);
761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* truncate to the width, if specified */
763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(info->fWidth != -1)
764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        len = ufmt_min(len, info->fWidth);
765ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* get the formatter */
767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    format = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_PERCENT);
768ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* handle error */
770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(format == 0)
771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0;
772ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */
77483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    u_scanf_skip_leading_positive_sign(input, format, &status);
775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* parse the number */
777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    num = unum_parseDouble(format, input->str.fPos, len, &parsePos, &status);
778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!info->fSkipArg) {
780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *(double*)(args[0].ptrValue) = num;
781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* mask off any necessary bits */
784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*  if(! info->fIsLong_double)
785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    num &= DBL_MAX;*/
786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* update the input's position to reflect consumed data */
788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    input->str.fPos += parsePos;
789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* we converted 1 arg */
791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *argConverted = !info->fSkipArg;
792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return parsePos;
793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_string_handler(UFILE        *input,
797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       u_scanf_spec_info *info,
798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       ufmt_args    *args,
799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       const UChar  *fmt,
800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       int32_t      *fmtConsumed,
801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       int32_t      *argConverted)
802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar *source;
804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UConverter  *conv;
805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char        *arg    = (char*)(args[0].ptrValue);
806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char        *alias  = arg;
807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char        *limit;
808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode  status  = U_ZERO_ERROR;
809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     count;
810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     skipped = 0;
811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar       c;
812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool       isNotEOF = FALSE;
813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* skip all ws in the input */
815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (info->fIsString) {
816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        skipped = u_scanf_skip_leading_ws(input, info->fPadChar);
817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* get the string one character at a time, truncating to the width */
820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    count = 0;
821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* open the default converter */
823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    conv = u_getDefaultConverter(&status);
824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(U_FAILURE(status))
826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return -1;
827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while( (info->fWidth == -1 || count < info->fWidth)
829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        && (isNotEOF = ufile_getch(input, &c))
830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        && (!info->fIsString || (c != info->fPadChar && !u_isWhitespace(c))))
831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (!info->fSkipArg) {
834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* put the character from the input onto the target */
835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            source = &c;
836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* Since we do this one character at a time, do it this way. */
837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (info->fWidth > 0) {
838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                limit = alias + info->fWidth - count;
839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                limit = alias + ucnv_getMaxCharSize(conv);
842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
843ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* convert the character to the default codepage */
845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucnv_fromUnicode(conv, &alias, limit, &source, source + 1,
846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                NULL, TRUE, &status);
847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(U_FAILURE(status)) {
849ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* clean up */
850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                u_releaseDefaultConverter(conv);
851ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return -1;
852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* increment the count */
856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ++count;
857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* put the final character we read back on the input */
860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!info->fSkipArg) {
861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if ((info->fWidth == -1 || count < info->fWidth) && isNotEOF)
862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            u_fungetc(c, input);
863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* add the terminator */
865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (info->fIsString) {
866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *alias = 0x00;
867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* clean up */
871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    u_releaseDefaultConverter(conv);
872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* we converted 1 arg */
874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *argConverted = !info->fSkipArg;
875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return count + skipped;
876ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
877ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_char_handler(UFILE          *input,
880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     u_scanf_spec_info *info,
881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     ufmt_args      *args,
882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     const UChar    *fmt,
883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     int32_t        *fmtConsumed,
884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     int32_t        *argConverted)
885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (info->fWidth < 0) {
887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        info->fWidth = 1;
888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    info->fIsString = FALSE;
890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return u_scanf_string_handler(input, info, args, fmt, fmtConsumed, argConverted);
891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_ustring_handler(UFILE       *input,
895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        u_scanf_spec_info *info,
896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        ufmt_args   *args,
897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        const UChar *fmt,
898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        int32_t     *fmtConsumed,
899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        int32_t     *argConverted)
900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar   *arg     = (UChar*)(args[0].ptrValue);
902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar   *alias     = arg;
903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t count;
904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t skipped = 0;
905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar   c;
906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool   isNotEOF = FALSE;
907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* skip all ws in the input */
909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (info->fIsString) {
910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        skipped = u_scanf_skip_leading_ws(input, info->fPadChar);
911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* get the string one character at a time, truncating to the width */
914ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    count = 0;
915ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    while( (info->fWidth == -1 || count < info->fWidth)
917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        && (isNotEOF = ufile_getch(input, &c))
918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        && (!info->fIsString || (c != info->fPadChar && !u_isWhitespace(c))))
919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* put the character from the input onto the target */
922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (!info->fSkipArg) {
923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *alias++ = c;
924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* increment the count */
927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ++count;
928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* put the final character we read back on the input */
931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!info->fSkipArg) {
932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if((info->fWidth == -1 || count < info->fWidth) && isNotEOF) {
933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            u_fungetc(c, input);
934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* add the terminator */
937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (info->fIsString) {
938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *alias = 0x0000;
939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* we converted 1 arg */
943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *argConverted = !info->fSkipArg;
944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return count + skipped;
945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_uchar_handler(UFILE         *input,
949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      u_scanf_spec_info *info,
950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      ufmt_args     *args,
951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      const UChar   *fmt,
952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      int32_t       *fmtConsumed,
953ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      int32_t       *argConverted)
954ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (info->fWidth < 0) {
956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        info->fWidth = 1;
957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
958ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    info->fIsString = FALSE;
959ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return u_scanf_ustring_handler(input, info, args, fmt, fmtConsumed, argConverted);
960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
961ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
962ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
963ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_spellout_handler(UFILE          *input,
964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                         u_scanf_spec_info *info,
965ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                         ufmt_args      *args,
966ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                         const UChar    *fmt,
967ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                         int32_t        *fmtConsumed,
968ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                         int32_t        *argConverted)
969ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
970ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         len;
971ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    double          num;
972ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UNumberFormat   *format;
973ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         parsePos    = 0;
974ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         skipped;
975ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode      status      = U_ZERO_ERROR;
976ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
977ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
978ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* skip all ws in the input */
979ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    skipped = u_scanf_skip_leading_ws(input, info->fPadChar);
980ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
981ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* fill the input's internal buffer */
982ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ufile_fill_uchar_buffer(input);
983ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
984ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* determine the size of the input's buffer */
985ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    len = (int32_t)(input->str.fLimit - input->str.fPos);
986ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
987ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* truncate to the width, if specified */
988ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(info->fWidth != -1)
989ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        len = ufmt_min(len, info->fWidth);
990ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
991ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* get the formatter */
992ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    format = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_SPELLOUT);
993ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
994ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* handle error */
995ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(format == 0)
996ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0;
997ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
998ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */
999ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* This is not applicable to RBNF. */
1000ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*skipped += u_scanf_skip_leading_positive_sign(input, format, &status);*/
1001ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1002ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* parse the number */
1003ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    num = unum_parseDouble(format, input->str.fPos, len, &parsePos, &status);
1004ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!info->fSkipArg) {
1006ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *(double*)(args[0].ptrValue) = num;
1007ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1008ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1009ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* mask off any necessary bits */
1010ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*  if(! info->fIsLong_double)
1011ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    num &= DBL_MAX;*/
1012ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1013ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* update the input's position to reflect consumed data */
1014ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    input->str.fPos += parsePos;
1015ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1016ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* we converted 1 arg */
1017ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *argConverted = !info->fSkipArg;
1018ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return parsePos + skipped;
1019ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1020ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1021ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
1022ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_hex_handler(UFILE       *input,
1023ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    u_scanf_spec_info *info,
1024ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    ufmt_args   *args,
1025ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    const UChar *fmt,
1026ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    int32_t     *fmtConsumed,
1027ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    int32_t     *argConverted)
1028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     len;
1030ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     skipped;
1031ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void        *num    = (void*) (args[0].ptrValue);
1032ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int64_t     result;
1033ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1034ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* skip all ws in the input */
1035ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    skipped = u_scanf_skip_leading_ws(input, info->fPadChar);
1036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* fill the input's internal buffer */
1038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ufile_fill_uchar_buffer(input);
1039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1040ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* determine the size of the input's buffer */
1041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    len = (int32_t)(input->str.fLimit - input->str.fPos);
1042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* truncate to the width, if specified */
1044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(info->fWidth != -1)
1045ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        len = ufmt_min(len, info->fWidth);
1046ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1047ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* check for alternate form */
1048ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if( *(input->str.fPos) == 0x0030 &&
1049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        (*(input->str.fPos + 1) == 0x0078 || *(input->str.fPos + 1) == 0x0058) ) {
1050ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1051ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* skip the '0' and 'x' or 'X' if present */
1052ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        input->str.fPos += 2;
1053ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        len -= 2;
1054ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1055ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1056ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* parse the number */
1057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    result = ufmt_uto64(input->str.fPos, &len, 16);
1058ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1059ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* update the input's position to reflect consumed data */
1060ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    input->str.fPos += len;
1061ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1062ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* mask off any necessary bits */
1063ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!info->fSkipArg) {
1064ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (info->fIsShort)
1065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(int16_t*)num = (int16_t)(UINT16_MAX & result);
1066ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (info->fIsLongLong)
1067ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(int64_t*)num = result;
1068ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else
1069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(int32_t*)num = (int32_t)(UINT32_MAX & result);
1070ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1071ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1072ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* we converted 1 arg */
1073ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *argConverted = !info->fSkipArg;
1074ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return len + skipped;
1075ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1076ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1077ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
1078ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_octal_handler(UFILE         *input,
1079ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      u_scanf_spec_info *info,
1080ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      ufmt_args     *args,
1081ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      const UChar   *fmt,
1082ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      int32_t       *fmtConsumed,
1083ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      int32_t       *argConverted)
1084ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1085ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     len;
1086ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     skipped;
1087ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void        *num         = (void*) (args[0].ptrValue);
1088ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int64_t     result;
1089ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1090ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* skip all ws in the input */
1091ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    skipped = u_scanf_skip_leading_ws(input, info->fPadChar);
1092ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1093ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* fill the input's internal buffer */
1094ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ufile_fill_uchar_buffer(input);
1095ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1096ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* determine the size of the input's buffer */
1097ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    len = (int32_t)(input->str.fLimit - input->str.fPos);
1098ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1099ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* truncate to the width, if specified */
1100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(info->fWidth != -1)
1101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        len = ufmt_min(len, info->fWidth);
1102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* parse the number */
1104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    result = ufmt_uto64(input->str.fPos, &len, 8);
1105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* update the input's position to reflect consumed data */
1107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    input->str.fPos += len;
1108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* mask off any necessary bits */
1110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!info->fSkipArg) {
1111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (info->fIsShort)
1112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(int16_t*)num = (int16_t)(UINT16_MAX & result);
1113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else if (info->fIsLongLong)
1114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(int64_t*)num = result;
1115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else
1116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *(int32_t*)num = (int32_t)(UINT32_MAX & result);
1117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* we converted 1 arg */
1120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *argConverted = !info->fSkipArg;
1121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return len + skipped;
1122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
1125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_pointer_handler(UFILE       *input,
1126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        u_scanf_spec_info *info,
1127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        ufmt_args   *args,
1128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        const UChar *fmt,
1129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        int32_t     *fmtConsumed,
1130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        int32_t     *argConverted)
1131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t len;
1133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t skipped;
1134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void    *result;
1135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void    **p     = (void**)(args[0].ptrValue);
1136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* skip all ws in the input */
1139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    skipped = u_scanf_skip_leading_ws(input, info->fPadChar);
1140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* fill the input's internal buffer */
1142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ufile_fill_uchar_buffer(input);
1143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* determine the size of the input's buffer */
1145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    len = (int32_t)(input->str.fLimit - input->str.fPos);
1146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* truncate to the width, if specified */
1148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(info->fWidth != -1) {
1149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        len = ufmt_min(len, info->fWidth);
1150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Make sure that we don't consume too much */
1153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (len > (int32_t)(sizeof(void*)*2)) {
1154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        len = (int32_t)(sizeof(void*)*2);
1155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* parse the pointer - assign to temporary value */
1158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    result = ufmt_utop(input->str.fPos, &len);
1159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!info->fSkipArg) {
1161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *p = result;
1162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* update the input's position to reflect consumed data */
1165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    input->str.fPos += len;
1166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* we converted 1 arg */
1168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *argConverted = !info->fSkipArg;
1169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return len + skipped;
1170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t
1173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_scanset_handler(UFILE       *input,
1174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        u_scanf_spec_info *info,
1175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        ufmt_args   *args,
1176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        const UChar *fmt,
1177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        int32_t     *fmtConsumed,
1178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        int32_t     *argConverted)
1179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    USet        *scanset;
1181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode  status = U_ZERO_ERROR;
1182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     chLeft = INT32_MAX;
1183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar32     c;
1184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar       *alias = (UChar*) (args[0].ptrValue);
1185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool       isNotEOF = FALSE;
1186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool       readCharacter = FALSE;
1187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Create an empty set */
1189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    scanset = uset_open(0, -1);
1190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* Back up one to get the [ */
1192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fmt--;
1193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* truncate to the width, if specified and alias the target */
1195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(info->fWidth >= 0) {
1196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        chLeft = info->fWidth;
1197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* parse the scanset from the fmt string */
1200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *fmtConsumed = uset_applyPattern(scanset, fmt, -1, 0, &status);
1201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* verify that the parse was successful */
1203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_SUCCESS(status)) {
1204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        c=0;
1205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* grab characters one at a time and make sure they are in the scanset */
1207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while(chLeft > 0) {
1208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if ((isNotEOF = ufile_getch32(input, &c)) && uset_contains(scanset, c)) {
1209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                readCharacter = TRUE;
1210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (!info->fSkipArg) {
1211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    int32_t idx = 0;
1212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    UBool isError = FALSE;
1213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    U16_APPEND(alias, idx, chLeft, c, isError);
1215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if (isError) {
1216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        break;
1217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
1218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    alias += idx;
1219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
1220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                chLeft -= (1 + U_IS_SUPPLEMENTARY(c));
1221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
1223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* if the character's not in the scanset, break out */
1224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
1225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* put the final character we read back on the input */
1229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(isNotEOF && chLeft > 0) {
1230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            u_fungetc(c, input);
1231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uset_close(scanset);
1235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* if we didn't match at least 1 character, fail */
1237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(!readCharacter)
1238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return -1;
1239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* otherwise, add the terminator */
1240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else if (!info->fSkipArg) {
1241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *alias = 0x00;
1242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* we converted 1 arg */
1245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *argConverted = !info->fSkipArg;
1246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return (info->fWidth >= 0 ? info->fWidth : INT32_MAX) - chLeft;
1247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Use US-ASCII characters only for formatting. Most codepages have
1250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru characters 20-7F from Unicode. Using any other codepage specific
1251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru characters will make it very difficult to format the string on
1252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru non-Unicode machines */
1253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const u_scanf_info g_u_scanf_infos[USCANF_NUM_FMT_HANDLERS] = {
1254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 0x20 */
1255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,
1256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_SIMPLE_PERCENT,UFMT_EMPTY,         UFMT_EMPTY,
1257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,
1258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,
1259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 0x30 */
1261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,
1262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,
1263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,
1264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,
1265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 0x40 */
1267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,         UFMT_UCHAR,
1268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_SCIENTIFIC,    UFMT_EMPTY,         UFMT_SCIDBL,
1269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef U_USE_OBSOLETE_IO_FORMATTING
1270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,         UFMT_UCHAR/*deprecated*/,
1271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else
1272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,
1273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
1274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,
1275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 0x50 */
1277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_PERCENT,       UFMT_EMPTY,         UFMT_EMPTY,         UFMT_USTRING,
1278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef U_USE_OBSOLETE_IO_FORMATTING
1279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_USTRING/*deprecated*/,UFMT_SPELLOUT,      UFMT_EMPTY,
1280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else
1281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_SPELLOUT,      UFMT_EMPTY,
1282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
1283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_HEX,           UFMT_EMPTY,         UFMT_EMPTY,         UFMT_SCANSET,
1284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,
1285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 0x60 */
1287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,         UFMT_CHAR,
1288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_INT,           UFMT_SCIENTIFIC,    UFMT_DOUBLE,        UFMT_SCIDBL,
1289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_INT,           UFMT_EMPTY,         UFMT_EMPTY,
1290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_COUNT,         UFMT_OCTAL,
1291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 0x70 */
1293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_POINTER,       UFMT_EMPTY,         UFMT_EMPTY,         UFMT_STRING,
1294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_UINT,          UFMT_EMPTY,         UFMT_EMPTY,
1295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_HEX,           UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,
1296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,         UFMT_EMPTY,
1297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
1298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CFUNC int32_t
1300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruu_scanf_parse(UFILE     *f,
1301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            const UChar *patternSpecification,
1302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            va_list     ap)
1303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar     *alias;
1305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         count, converted, argConsumed, cpConsumed;
1306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint16_t        handlerNum;
1307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ufmt_args       args;
1309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    u_scanf_spec    spec;
1310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ufmt_type_info  info;
1311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    u_scanf_handler handler;
1312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* alias the pattern */
1314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    alias = patternSpecification;
1315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* haven't converted anything yet */
1317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    argConsumed = 0;
1318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    converted = 0;
1319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    cpConsumed = 0;
1320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* iterate through the pattern */
1322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for(;;) {
1323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* match any characters up to the next '%' */
1325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while(*alias != UP_PERCENT && *alias != 0x0000 && u_fgetc(f) == *alias) {
1326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            alias++;
1327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* if we aren't at a '%', or if we're at end of string, break*/
1330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(*alias != UP_PERCENT || *alias == 0x0000)
1331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
1332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* parse the specifier */
1334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        count = u_scanf_parse_spec(alias, &spec);
1335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* update the pointer in pattern */
1337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        alias += count;
1338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        handlerNum = (uint16_t)(spec.fInfo.fSpec - USCANF_BASE_FMT_HANDLERS);
1340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (handlerNum < USCANF_NUM_FMT_HANDLERS) {
1341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* skip the argument, if necessary */
1342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* query the info function for argument information */
1343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            info = g_u_scanf_infos[ handlerNum ].info;
1344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (info != ufmt_count && u_feof(f)) {
1345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
1346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else if(spec.fInfo.fSkipArg) {
1348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                args.ptrValue = NULL;
1349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
1351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                switch(info) {
1352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                case ufmt_count:
1353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    /* set the spec's width to the # of items converted */
1354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    spec.fInfo.fWidth = cpConsumed;
1355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    /* fall through to next case */
1356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                case ufmt_char:
1357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                case ufmt_uchar:
1358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                case ufmt_int:
1359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                case ufmt_string:
1360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                case ufmt_ustring:
1361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                case ufmt_pointer:
1362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                case ufmt_float:
1363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                case ufmt_double:
1364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    args.ptrValue = va_arg(ap, void*);
1365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    break;
1366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                default:
1368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    /* else args is ignored */
1369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    args.ptrValue = NULL;
1370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    break;
1371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
1372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* call the handler function */
1375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            handler = g_u_scanf_infos[ handlerNum ].handler;
1376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(handler != 0) {
1377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* reset count to 1 so that += for alias works. */
1379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                count = 1;
1380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                cpConsumed += (*handler)(f, &spec.fInfo, &args, alias, &count, &argConsumed);
1382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* if the handler encountered an error condition, break */
1384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if(argConsumed < 0) {
1385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    converted = -1;
1386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    break;
1387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
1388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* add to the # of items converted */
1390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                converted += argConsumed;
1391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                /* update the pointer in pattern */
1393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                alias += count-1;
1394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            /* else do nothing */
1396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* else do nothing */
1398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* just ignore unknown tags */
1400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* return # of items converted */
1403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return converted;
1404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */
1407