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