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