TestScanf.cpp 106 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) Electronic Arts Inc. All rights reserved.
  3. ///////////////////////////////////////////////////////////////////////////////
  4. #include <EAStdC/EAScanf.h>
  5. #include <EAStdC/EAString.h>
  6. #include <EAStdC/EAMathHelp.h>
  7. #include <EAStdC/Int128_t.h>
  8. #include <EAStdC/internal/Config.h>
  9. #include <EAStdCTest/EAStdCTest.h>
  10. #include <EATest/EATest.h>
  11. #include <EAAssert/eaassert.h>
  12. #include <limits.h>
  13. #include <float.h>
  14. #include <string.h>
  15. #if !defined(LLONG_MAX) // Some C++ standard libraries don't define LLONG_MAX, etc.
  16. #if defined(__LONG_LONG_MAX__) // GCC
  17. #define LLONG_MIN (-LLONG_MAX-1)
  18. #define LLONG_MAX __LONG_LONG_MAX__
  19. #define ULLONG_MIN 0
  20. #define ULLONG_MAX (LLONG_MAX * 2ULL + 1)
  21. #else
  22. #define LLONG_MIN INT64_MIN
  23. #define LLONG_MAX INT64_MAX
  24. #define ULLONG_MIN 0
  25. #define ULLONG_MAX UINT64_MAX
  26. #endif
  27. #endif
  28. #ifdef EA_ASSERT_ENABLED
  29. #define VERIFY_ASSERTCOUNT(count) EATEST_VERIFY(v.assertCount_ == count)
  30. #else
  31. #define VERIFY_ASSERTCOUNT(count)
  32. #endif
  33. struct Values
  34. {
  35. // char_ is defined explicitly as 'signed char' rather than 'char' (which is determined signed/unsigned by the compiler) on purpose.
  36. // If char were interpreted as unsigned char then there will be no type promotion for negative values which our tests assume (we want 0xFF to be promoted to 0xFFFFFFFF).
  37. // Why work around the unsigned/signed char issue? There would be little gain duplicating test code per platform+compiler, particularly when a user
  38. // can force the signedness to be one way or the other regardless. Additionally, we already test our suite for explicit signed and unsigned char types.
  39. signed char char_[8];
  40. signed char schar_[8];
  41. unsigned char uchar_[8];
  42. wchar_t wchar_[8];
  43. short short_[8];
  44. unsigned short ushort_[8];
  45. int int_[8];
  46. unsigned int uint_[8];
  47. long long_[8];
  48. unsigned long ulong_[8];
  49. long long longlong_[8];
  50. unsigned long long ulonglong_[8];
  51. int8_t int8_[8];
  52. uint8_t uint8_[8];
  53. int16_t int16_[8];
  54. uint16_t uint16_[8];
  55. int32_t int32_[8];
  56. uint32_t uint32_[8];
  57. int64_t int64_[8];
  58. uint64_t uint64_[8];
  59. //EA::StdC::int128_t int128_[8]; // int128_t has constructors and so is not a POD and cannot be part of the Values union.
  60. //EA::StdC::uint128_t uint128_[8];
  61. char char8_[8];
  62. char16_t char16_[8];
  63. char32_t char32_[8];
  64. char str8_[8][64];
  65. char16_t str16_[8][64];
  66. char32_t str32_[8][64];
  67. wchar_t strw_[8][64];
  68. float float_[8];
  69. double double_[8];
  70. size_t size_[8];
  71. ptrdiff_t ptrdiff_[8];
  72. intptr_t intptr_[8];
  73. uintptr_t uintptr_[8];
  74. intmax_t intmax_[8];
  75. uintmax_t uintmax_[8];
  76. void* voidptr_[8];
  77. static uint32_t assertCount_; //Static to allow for use from lambda with empty capture set. Implicitly not thread safe.
  78. int Clear()
  79. {
  80. memset(this, 0xff, sizeof(*this));
  81. assertCount_ = 0;
  82. return 0;
  83. }
  84. };
  85. uint32_t Values::assertCount_ = 0;
  86. static int TestCRTVsscanf(const char* pBuffer, const char* pFormat, ...)
  87. {
  88. va_list vList;
  89. va_start(vList, pFormat);
  90. int n = EA::StdC::Vsscanf(pBuffer, pFormat, vList);
  91. va_end(vList);
  92. return n;
  93. }
  94. static int TestCRTVsscanf(const char16_t* pBuffer, const char16_t* pFormat, ...)
  95. {
  96. va_list vList;
  97. va_start(vList, pFormat);
  98. int n = EA::StdC::Vsscanf(pBuffer, pFormat, vList);
  99. va_end(vList);
  100. return n;
  101. }
  102. static int TestCRTVsscanf(const char32_t* pBuffer, const char32_t* pFormat, ...)
  103. {
  104. va_list vList;
  105. va_start(vList, pFormat);
  106. int n = EA::StdC::Vsscanf(pBuffer, pFormat, vList);
  107. va_end(vList);
  108. return n;
  109. }
  110. ///////////////////////////////////////////////////////////////////////////////
  111. // TestScanfLimits
  112. //
  113. static int TestScanfLimits()
  114. {
  115. using namespace EA::StdC;
  116. int nErrorCount = 0;
  117. // Until our custom hand-implemented scanf is some day completed, we don't
  118. // have a portable version of the scanf family of functions. In the meantime
  119. // we can only support it on Microsoft platforms as opposed to GCC.
  120. int n;
  121. Values v;
  122. { // Test limits
  123. // char
  124. v.Clear();
  125. n = Sscanf("-128 127", "%hhd %hhd", &v.schar_[0], &v.schar_[1]);
  126. EATEST_VERIFY(n == 2);
  127. EATEST_VERIFY(v.schar_[0] == SCHAR_MIN);
  128. EATEST_VERIFY(v.schar_[1] == SCHAR_MAX);
  129. v.Clear();
  130. n = Sscanf("0x80 0x7f", "%hhx %hhx", &v.schar_[0], &v.schar_[1]);
  131. EATEST_VERIFY(n == 2);
  132. EATEST_VERIFY(v.schar_[0] == SCHAR_MIN);
  133. EATEST_VERIFY(v.schar_[1] == SCHAR_MAX);
  134. // unsigned char
  135. v.Clear();
  136. n = Sscanf("-0 255", "%hhu %hhu", &v.uchar_[0], &v.uchar_[1]);
  137. EATEST_VERIFY(n == 2);
  138. EATEST_VERIFY(v.uchar_[0] == 0);
  139. EATEST_VERIFY(v.uchar_[1] == UCHAR_MAX);
  140. v.Clear();
  141. n = Sscanf("0 0xff", "%hhx %hhx", &v.uchar_[0], &v.uchar_[1]);
  142. EATEST_VERIFY(n == 2);
  143. EATEST_VERIFY(v.uchar_[0] == 0);
  144. EATEST_VERIFY(v.uchar_[1] == UCHAR_MAX);
  145. // short
  146. v.Clear();
  147. n = Sscanf("-32768 32767", "%hd %hd", &v.short_[0], &v.short_[1]);
  148. EATEST_VERIFY(n == 2);
  149. EATEST_VERIFY(v.short_[0] == SHRT_MIN);
  150. EATEST_VERIFY(v.short_[1] == SHRT_MAX);
  151. v.Clear();
  152. n = Sscanf("0x8000 0x7fff", "%hx %hx", &v.short_[0], &v.short_[1]);
  153. EATEST_VERIFY(n == 2);
  154. EATEST_VERIFY(v.short_[0] == SHRT_MIN);
  155. EATEST_VERIFY(v.short_[1] == SHRT_MAX);
  156. // unsigned short
  157. v.Clear();
  158. n = Sscanf("-0 65535", "%hu %hu", &v.ushort_[0], &v.ushort_[1]);
  159. EATEST_VERIFY(n == 2);
  160. EATEST_VERIFY(v.ushort_[0] == 0);
  161. EATEST_VERIFY(v.ushort_[1] == USHRT_MAX);
  162. v.Clear();
  163. n = Sscanf("0 0xffff", "%hx %hx", &v.ushort_[0], &v.ushort_[1]);
  164. EATEST_VERIFY(n == 2);
  165. EATEST_VERIFY(v.ushort_[0] == 0);
  166. EATEST_VERIFY(v.ushort_[1] == USHRT_MAX);
  167. // int
  168. v.Clear();
  169. n = Sscanf("-0 +0 -2147483648 +2147483647", "%d %d %d %d", &v.int_[0], &v.int_[1], &v.int_[2], &v.int_[3]);
  170. EATEST_VERIFY(n == 4);
  171. EATEST_VERIFY(v.int_[0] == 0);
  172. EATEST_VERIFY(v.int_[1] == 0);
  173. EATEST_VERIFY(v.int_[2] == INT32_MIN);
  174. EATEST_VERIFY(v.int_[3] == INT32_MAX);
  175. v.Clear();
  176. n = Sscanf("-0 +0 0x80000000 0x7fffffff", "%x %x %x %x", &v.int_[0], &v.int_[1], &v.int_[2], &v.int_[3]);
  177. EATEST_VERIFY(n == 4);
  178. EATEST_VERIFY(v.int_[0] == 0);
  179. EATEST_VERIFY(v.int_[1] == 0);
  180. EATEST_VERIFY(v.int_[2] == INT32_MIN);
  181. EATEST_VERIFY(v.int_[3] == INT32_MAX);
  182. // unsigned int
  183. v.Clear();
  184. n = Sscanf("0 4294967295", "%u %u", &v.uint_[0], &v.uint_[1]);
  185. EATEST_VERIFY(n == 2);
  186. EATEST_VERIFY(v.uint_[0] == 0);
  187. EATEST_VERIFY(v.uint_[1] == UINT32_MAX);
  188. v.Clear();
  189. n = Sscanf("0000000 0xffffffff", "%x %x", &v.uint_[0], &v.uint_[1]);
  190. EATEST_VERIFY(n == 2);
  191. EATEST_VERIFY(v.uint_[0] == 0);
  192. EATEST_VERIFY(v.uint_[1] == UINT32_MAX);
  193. // long
  194. #if LONG_MAX == INT32_MAX
  195. v.Clear();
  196. n = Sscanf("-2147483648 +2147483647", "%ld %ld", &v.long_[0], &v.long_[1]);
  197. #elif LONG_MAX == INT64_MAX
  198. v.Clear();
  199. n = Sscanf("-9223372036854775808 9223372036854775807", "%ld %ld", &v.long_[0], &v.long_[1]);
  200. #endif
  201. EATEST_VERIFY(n == 2);
  202. EATEST_VERIFY(v.long_[0] == LONG_MIN);
  203. EATEST_VERIFY(v.long_[1] == LONG_MAX);
  204. #if LONG_MAX == INT32_MAX
  205. v.Clear();
  206. n = Sscanf("0x80000000 0x7fffffff", "%lx %lx", &v.long_[0], &v.long_[1]);
  207. #elif LONG_MAX == INT64_MAX
  208. v.Clear();
  209. n = Sscanf("0x8000000000000000 0x7fffffffffffffff", "%lx %lx", &v.long_[0], &v.long_[1]);
  210. #endif
  211. EATEST_VERIFY(n == 2);
  212. EATEST_VERIFY(v.long_[0] == LONG_MIN);
  213. EATEST_VERIFY(v.long_[1] == LONG_MAX);
  214. // ulong
  215. #if ULONG_MAX == UINT_MAX
  216. v.Clear();
  217. n = Sscanf("-0 4294967295", "%ld %ld", &v.ulong_[0], &v.ulong_[1]);
  218. #elif ULONG_MAX > UINT_MAX
  219. v.Clear();
  220. n = Sscanf("-0 18446744073709551615", "%ld %ld", &v.ulong_[0], &v.ulong_[1]);
  221. #endif
  222. EATEST_VERIFY(n == 2);
  223. EATEST_VERIFY(v.ulong_[0] == 0);
  224. EATEST_VERIFY(v.ulong_[1] == ULONG_MAX);
  225. #if ULONG_MAX == UINT_MAX
  226. v.Clear();
  227. n = Sscanf("0 0xffffffff", "%lx %lx", &v.ulong_[0], &v.ulong_[1]);
  228. #elif ULONG_MAX > UINT_MAX
  229. v.Clear();
  230. n = Sscanf("-0 0xffffffffffffffff", "%lx %lx", &v.ulong_[0], &v.ulong_[1]);
  231. #endif
  232. EATEST_VERIFY(n == 2);
  233. EATEST_VERIFY(v.ulong_[0] == 0);
  234. EATEST_VERIFY(v.ulong_[1] == ULONG_MAX);
  235. // long long
  236. #if LLONG_MAX == INT64_MAX
  237. v.Clear();
  238. n = Sscanf("-9223372036854775808 9223372036854775807", "%lld %lld", &v.longlong_[0], &v.longlong_[1]);
  239. #else
  240. v.Clear();
  241. n = Sscanf("-170141183460469231731687303715884105728 170141183460469231731687303715884105727", "%lld %lld", &v.longlong_[0], &v.longlong_[1]);
  242. #endif
  243. EATEST_VERIFY(n == 2);
  244. EATEST_VERIFY(v.longlong_[0] == LLONG_MIN);
  245. EATEST_VERIFY(v.longlong_[1] == LLONG_MAX);
  246. #if LLONG_MAX == INT64_MAX
  247. v.Clear();
  248. n = Sscanf("0x8000000000000000 0x7fffffffffffffff", "%llx %llx", &v.longlong_[0], &v.longlong_[1]);
  249. #else
  250. v.Clear();
  251. n = Sscanf("0x80000000000000000000000000000000 0x7fffffffffffffffffffffffffffffff", "%llx %llx", &v.longlong_[0], &v.longlong_[1]);
  252. #endif
  253. EATEST_VERIFY(n == 2);
  254. EATEST_VERIFY(v.longlong_[0] == LLONG_MIN);
  255. EATEST_VERIFY(v.longlong_[1] == LLONG_MAX);
  256. // unsigned long long
  257. #if ULLONG_MAX == UINT64_MAX
  258. v.Clear();
  259. n = Sscanf("0 18446744073709551615", "%lld %lld", &v.ulonglong_[0], &v.ulonglong_[1]);
  260. #else
  261. v.Clear();
  262. n = Sscanf("0 170141183460469231731687303715884105727", "%lld %lld", &v.ulonglong_[0], &v.ulonglong_[1]);
  263. #endif
  264. EATEST_VERIFY(n == 2);
  265. EATEST_VERIFY(v.ulonglong_[0] == 0);
  266. EATEST_VERIFY(v.ulonglong_[1] == ULLONG_MAX);
  267. #if ULLONG_MAX == UINT64_MAX
  268. v.Clear();
  269. n = Sscanf("0x0000000000000000 0xffffffffffffffff", "%llx %llx", &v.ulonglong_[0], &v.ulonglong_[1]);
  270. #else
  271. v.Clear();
  272. n = Sscanf("0x00000000000000000000000000000000 0xffffffffffffffffffffffffffffffff", "%llx %llx", &v.ulonglong_[0], &v.ulonglong_[1]);
  273. #endif
  274. EATEST_VERIFY(n == 2);
  275. EATEST_VERIFY(v.ulonglong_[0] == 0);
  276. EATEST_VERIFY(v.ulonglong_[1] == ULLONG_MAX);
  277. // float
  278. v.Clear();
  279. n = Sscanf("1.175494351e-38 3.402823466e+38", "%f %f", &v.float_[0], &v.float_[1]);
  280. EATEST_VERIFY(n == 2);
  281. EATEST_VERIFY(FloatEqual(v.float_[0], 1.1754944e-38f)); // This is actually not a good enough test.
  282. EATEST_VERIFY(FloatEqual(v.float_[1], 3.4028234e+38f));
  283. // double
  284. v.Clear();
  285. n = Sscanf("2.2250738585072014e-308 1.7976931348623158e+308", "%lf %lf", &v.double_[0], &v.double_[1]);
  286. EATEST_VERIFY(n == 2);
  287. EATEST_VERIFY(DoubleEqual(v.double_[0], 2.2250738585072014e-308)); // This is actually not a good enough test.
  288. #if defined(EA_PLATFORM_WIN32)
  289. EATEST_VERIFY(DoubleEqual(v.double_[1], 1.7976931348623158e+308));
  290. #endif
  291. }
  292. // Regression of a user-reported bug:
  293. {
  294. float f;
  295. Sscanf("0.0001100f", "%f", &f);
  296. EATEST_VERIFY(FloatEqual(f, 0.0001100f));
  297. if(!FloatEqual(f, 0.0001100f))
  298. EA::UnitTest::Report("%f\n", f);
  299. }
  300. // Test fractions
  301. {
  302. const int nErrorCountSaved = nErrorCount; // We use this to exit the loop below upon the first found error.
  303. char buffer[10] = { '0', '.', '0', '0', '0', '0', '0', '0' };
  304. for(int i = 0; (i < 1000000) && (nErrorCount == nErrorCountSaved); i += 23)
  305. {
  306. buffer[2] = (char)('0' + (i / 100000 % 10));
  307. buffer[3] = (char)('0' + (i / 10000 % 10));
  308. buffer[4] = (char)('0' + (i / 1000 % 10));
  309. buffer[5] = (char)('0' + (i / 100 % 10));
  310. buffer[6] = (char)('0' + (i / 10 % 10));
  311. buffer[7] = (char)('0' + (i / 1 % 10));
  312. n = Sscanf(buffer, "%f", &v.float_[0]);
  313. EATEST_VERIFY(n == 1);
  314. EATEST_VERIFY(FloatEqual(v.float_[0], (float)i / 1000000));
  315. if(!FloatEqual(v.float_[0], (float)i / 1000000))
  316. EA::UnitTest::Report("%f %f\n", v.float_[0], (float)i / 1000000);
  317. char buffer2[32];
  318. sprintf(buffer2, "%f", v.float_[0]);
  319. EATEST_VERIFY(Strcmp(buffer2, buffer) == 0);
  320. if(Strcmp(buffer2, buffer) != 0)
  321. EA::UnitTest::Report("%s %s\n", buffer2, buffer);
  322. }
  323. }
  324. return nErrorCount;
  325. }
  326. ///////////////////////////////////////////////////////////////////////////////
  327. // TestScanfMisc
  328. //
  329. static int TestScanfMisc()
  330. {
  331. using namespace EA::StdC;
  332. int nErrorCount = 0;
  333. int n;
  334. Values v;
  335. { // Test of sscanf calls culled from some EA code.
  336. {
  337. v.Clear();
  338. n = Sscanf("", "");
  339. EATEST_VERIFY(n == 0);
  340. v.Clear();
  341. n = Sscanf(EA_CHAR16(""), EA_CHAR16(""));
  342. EATEST_VERIFY(n == 0);
  343. v.Clear();
  344. n = Sscanf(EA_CHAR32(""), EA_CHAR32(""));
  345. EATEST_VERIFY(n == 0);
  346. }
  347. {
  348. v.Clear();
  349. n = Sscanf("a", "%s", v.str8_[0]);
  350. EATEST_VERIFY(n == 1);
  351. EATEST_VERIFY(Strcmp(v.str8_[0], "a") == 0);
  352. v.Clear();
  353. n = Sscanf(EA_CHAR16("a"), EA_CHAR16("%s"), v.strw_[0]);
  354. EATEST_VERIFY(n == 1);
  355. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("a")) == 0);
  356. v.Clear();
  357. n = Sscanf(EA_CHAR32("a"), EA_CHAR32("%s"), v.strw_[0]);
  358. EATEST_VERIFY(n == 1);
  359. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("a")) == 0);
  360. }
  361. { // String tests
  362. // We accept %hc, %c, %lc, %I8c, %I16c, %I32c (regular, regular, wide, char, char16_t, char32_t)
  363. // We accept %hC, %C, %lC, %I8C, %I16C, %I32C (regular, wide, wide, char, char16_t, char32_t)
  364. // We accept %hs, %s, %ls, %I8s, %I16s, %I32s (regular, regular, wide, char, char16_t, char32_t)
  365. // We accept %hS, %S, %lS, %I8s, %I16s, %I32s (regular, wide, wide, char, char16_t, char32_t)
  366. { // char
  367. v.Clear();
  368. n = Sscanf("a b c d e f", "%hc %c %lc %I8c %I16c %I32c", &v.char_[0], &v.char_[1], &v.wchar_[0], &v.char8_[0], &v.char16_[0], &v.char32_[0]);
  369. EATEST_VERIFY(n == 6);
  370. EATEST_VERIFY((v.char_[0] == 'a') && (v.char_[1] == 'b') && (v.wchar_[0] == 'c') && (v.char8_[0] == 'd') && (v.char16_[0] == 'e') && (v.char32_[0] == 'f'));
  371. v.Clear();
  372. n = Sscanf("a b c d e f", "%hC %C %lC %I8C %I16C %I32C", &v.char_[0], &v.wchar_[0], &v.wchar_[1], &v.char8_[0], &v.char16_[0], &v.char32_[0]);
  373. EATEST_VERIFY(n == 6);
  374. EATEST_VERIFY((v.char_[0] == 'a') && (v.wchar_[0] == 'b') && (v.wchar_[1] == 'c') && (v.char8_[0] == 'd') && (v.char16_[0] == 'e') && (v.char32_[0] == 'f'));
  375. v.Clear();
  376. n = Sscanf("a b c d e f", "%hs %s %ls %I8s %I16s %I32s", &v.str8_[0], &v.str8_[1], &v.strw_[0], &v.str8_[2], &v.str16_[0], &v.str32_[0]);
  377. EATEST_VERIFY(n == 6);
  378. EATEST_VERIFY(Strcmp(v.str8_[0], "a") == 0);
  379. EATEST_VERIFY(Strcmp(v.str8_[1], "b") == 0);
  380. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("c")) == 0);
  381. EATEST_VERIFY(Strcmp(v.str8_[2], "d") == 0);
  382. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("e")) == 0);
  383. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("f")) == 0);
  384. v.Clear();
  385. n = Sscanf("a b c d e f", "%hS %S %lS %I8S %I16S %I32S", &v.str8_[0], &v.strw_[0], &v.strw_[1], &v.str8_[2], &v.str16_[0], &v.str32_[0]);
  386. EATEST_VERIFY(n == 6);
  387. EATEST_VERIFY(Strcmp(v.str8_[0], "a") == 0);
  388. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("b")) == 0);
  389. EATEST_VERIFY(Strcmp(v.strw_[1], EA_WCHAR("c")) == 0);
  390. EATEST_VERIFY(Strcmp(v.str8_[2], "d") == 0);
  391. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("e")) == 0);
  392. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("f")) == 0);
  393. }
  394. { // char16_t
  395. v.Clear();
  396. #if EASCANF_MS_STYLE_S_FORMAT // Microsoft style means that the meanings of S/C and s/c are reversed for non-char Sprintf.
  397. n = Sscanf(EA_CHAR16("a b c d e f"), EA_CHAR16("%hc %c %lc %I8c %I16c %I32c"), &v.char_[0], &v.wchar_[0], &v.wchar_[1], &v.char8_[0], &v.char16_[0], &v.char32_[0]);
  398. EATEST_VERIFY(n == 6);
  399. EATEST_VERIFY((v.char_[0] == 'a') && (v.wchar_[0] == 'b') && (v.wchar_[1] == 'c') && (v.char8_[0] == 'd') && (v.char16_[0] == 'e') && (v.char32_[0] == 'f'));
  400. #else
  401. n = Sscanf(EA_CHAR16("a b c d e f"), EA_CHAR16("%hc %c %lc %I8c %I16c %I32c"), &v.char_[0], &v.char_[1], &v.wchar_[1], &v.char8_[0], &v.char16_[0], &v.char32_[0]);
  402. EATEST_VERIFY(n == 6);
  403. EATEST_VERIFY((v.char_[0] == 'a') && (v.char_[1] == 'b') && (v.wchar_[1] == 'c') && (v.char8_[0] == 'd') && (v.char16_[0] == 'e') && (v.char32_[0] == 'f'));
  404. #endif
  405. v.Clear();
  406. #if EASCANF_MS_STYLE_S_FORMAT
  407. n = Sscanf(EA_CHAR16("a b c d e f"), EA_CHAR16("%hC %C %lC %I8C %I16C %I32C"), &v.char_[0], &v.char_[1], &v.wchar_[1], &v.char8_[0], &v.char16_[0], &v.char32_[0]);
  408. EATEST_VERIFY(n == 6);
  409. EATEST_VERIFY((v.char_[0] == 'a') && (v.char_[1] == 'b') && (v.wchar_[1] == 'c') && (v.char8_[0] == 'd') && (v.char16_[0] == 'e') && (v.char32_[0] == 'f'));
  410. #else
  411. n = Sscanf(EA_CHAR16("a b c d e f"), EA_CHAR16("%hC %C %lC %I8C %I16C %I32C"), &v.char_[0], &v.wchar_[0], &v.wchar_[1], &v.char8_[0], &v.char16_[0], &v.char32_[0]);
  412. EATEST_VERIFY(n == 6);
  413. EATEST_VERIFY((v.char_[0] == 'a') && (v.wchar_[0] == 'b') && (v.wchar_[1] == 'c') && (v.char8_[0] == 'd') && (v.char16_[0] == 'e') && (v.char32_[0] == 'f'));
  414. #endif
  415. v.Clear();
  416. #if EASCANF_MS_STYLE_S_FORMAT
  417. n = Sscanf(EA_CHAR16("a b c d e f"), EA_CHAR16("%hs %s %ls %I8s %I16s %I32s"), &v.str8_[0], &v.strw_[0], &v.strw_[1], &v.str8_[2], &v.str16_[0], &v.str32_[0]);
  418. EATEST_VERIFY(n == 6);
  419. EATEST_VERIFY(Strcmp(v.str8_[0], "a") == 0);
  420. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("b")) == 0);
  421. EATEST_VERIFY(Strcmp(v.strw_[1], EA_WCHAR("c")) == 0);
  422. EATEST_VERIFY(Strcmp(v.str8_[2], "d") == 0);
  423. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("e")) == 0);
  424. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("f")) == 0);
  425. #else
  426. n = Sscanf(EA_CHAR16("a b c d e f"), EA_CHAR16("%hs %s %ls %I8s %I16s %I32s"), &v.str8_[0], &v.str8_[1], &v.strw_[0], &v.str8_[2], &v.str16_[0], &v.str32_[0]);
  427. EATEST_VERIFY(n == 6);
  428. EATEST_VERIFY(Strcmp(v.str8_[0], "a") == 0);
  429. EATEST_VERIFY(Strcmp(v.str8_[1], "b") == 0);
  430. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("c")) == 0);
  431. EATEST_VERIFY(Strcmp(v.str8_[2], "d") == 0);
  432. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("e")) == 0);
  433. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("f")) == 0);
  434. #endif
  435. v.Clear();
  436. #if EASCANF_MS_STYLE_S_FORMAT
  437. n = Sscanf(EA_CHAR16("a b c d e f"), EA_CHAR16("%hS %S %lS %I8S %I16S %I32S"), &v.str8_[0], &v.str8_[1], &v.strw_[0], &v.str8_[2], &v.str16_[0], &v.str32_[0]);
  438. EATEST_VERIFY(n == 6);
  439. EATEST_VERIFY(Strcmp(v.str8_[0], "a") == 0);
  440. EATEST_VERIFY(Strcmp(v.str8_[1], "b") == 0);
  441. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("c")) == 0);
  442. EATEST_VERIFY(Strcmp(v.str8_[2], "d") == 0);
  443. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("e")) == 0);
  444. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("f")) == 0);
  445. #else
  446. n = Sscanf(EA_CHAR16("a b c d e f"), EA_CHAR16("%hS %S %lS %I8S %I16S %I32S"), &v.str8_[0], &v.strw_[0], &v.strw_[1], &v.str8_[2], &v.str16_[0], &v.str32_[0]);
  447. EATEST_VERIFY(n == 6);
  448. EATEST_VERIFY(Strcmp(v.str8_[0], "a") == 0);
  449. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("b")) == 0);
  450. EATEST_VERIFY(Strcmp(v.strw_[1], EA_WCHAR("c")) == 0);
  451. EATEST_VERIFY(Strcmp(v.str8_[2], "d") == 0);
  452. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("e")) == 0);
  453. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("f")) == 0);
  454. #endif
  455. }
  456. { // char32_t
  457. v.Clear();
  458. #if EASCANF_MS_STYLE_S_FORMAT // Microsoft style means that the meanings of S/C and s/c are reversed for non-char Sprintf.
  459. n = Sscanf(EA_CHAR32("a b c d e f"), EA_CHAR32("%hc %c %lc %I8c %I16c %I32c"), &v.char_[0], &v.wchar_[0], &v.wchar_[1], &v.char8_[0], &v.char16_[0], &v.char32_[0]);
  460. EATEST_VERIFY(n == 6);
  461. EATEST_VERIFY((v.char_[0] == 'a') && (v.wchar_[0] == 'b') && (v.wchar_[1] == 'c') && (v.char8_[0] == 'd') && (v.char16_[0] == 'e') && (v.char32_[0] == 'f'));
  462. #else
  463. n = Sscanf(EA_CHAR32("a b c d e f"), EA_CHAR32("%hc %c %lc %I8c %I16c %I32c"), &v.char_[0], &v.char_[1], &v.wchar_[1], &v.char8_[0], &v.char16_[0], &v.char32_[0]);
  464. EATEST_VERIFY(n == 6);
  465. EATEST_VERIFY((v.char_[0] == 'a') && (v.char_[1] == 'b') && (v.wchar_[1] == 'c') && (v.char8_[0] == 'd') && (v.char16_[0] == 'e') && (v.char32_[0] == 'f'));
  466. #endif
  467. v.Clear();
  468. #if EASCANF_MS_STYLE_S_FORMAT
  469. n = Sscanf(EA_CHAR32("a b c d e f"), EA_CHAR32("%hC %C %lC %I8C %I16C %I32C"), &v.char_[0], &v.char_[1], &v.wchar_[1], &v.char8_[0], &v.char16_[0], &v.char32_[0]);
  470. EATEST_VERIFY(n == 6);
  471. EATEST_VERIFY((v.char_[0] == 'a') && (v.char_[1] == 'b') && (v.wchar_[1] == 'c') && (v.char8_[0] == 'd') && (v.char16_[0] == 'e') && (v.char32_[0] == 'f'));
  472. #else
  473. n = Sscanf(EA_CHAR32("a b c d e f"), EA_CHAR32("%hC %C %lC %I8C %I16C %I32C"), &v.char_[0], &v.wchar_[0], &v.wchar_[1], &v.char8_[0], &v.char16_[0], &v.char32_[0]);
  474. EATEST_VERIFY(n == 6);
  475. EATEST_VERIFY((v.char_[0] == 'a') && (v.wchar_[0] == 'b') && (v.wchar_[1] == 'c') && (v.char8_[0] == 'd') && (v.char16_[0] == 'e') && (v.char32_[0] == 'f'));
  476. #endif
  477. v.Clear();
  478. #if EASCANF_MS_STYLE_S_FORMAT
  479. n = Sscanf(EA_CHAR32("a b c d e f"), EA_CHAR32("%hs %s %ls %I8s %I16s %I32s"), &v.str8_[0], &v.strw_[0], &v.strw_[1], &v.str8_[2], &v.str16_[0], &v.str32_[0]);
  480. EATEST_VERIFY(n == 6);
  481. EATEST_VERIFY(Strcmp(v.str8_[0], "a") == 0);
  482. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("b")) == 0);
  483. EATEST_VERIFY(Strcmp(v.strw_[1], EA_WCHAR("c")) == 0);
  484. EATEST_VERIFY(Strcmp(v.str8_[2], "d") == 0);
  485. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("e")) == 0);
  486. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("f")) == 0);
  487. #else
  488. n = Sscanf(EA_CHAR32("a b c d e f"), EA_CHAR32("%hs %s %ls %I8s %I16s %I32s"), &v.str8_[0], &v.str8_[1], &v.strw_[0], &v.str8_[2], &v.str16_[0], &v.str32_[0]);
  489. EATEST_VERIFY(n == 6);
  490. EATEST_VERIFY(Strcmp(v.str8_[0], "a") == 0);
  491. EATEST_VERIFY(Strcmp(v.str8_[1], "b") == 0);
  492. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("c")) == 0);
  493. EATEST_VERIFY(Strcmp(v.str8_[2], "d") == 0);
  494. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("e")) == 0);
  495. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("f")) == 0);
  496. #endif
  497. v.Clear();
  498. #if EASCANF_MS_STYLE_S_FORMAT
  499. n = Sscanf(EA_CHAR32("a b c d e f"), EA_CHAR32("%hS %S %lS %I8S %I16S %I32S"), &v.str8_[0], &v.str8_[1], &v.strw_[0], &v.str8_[2], &v.str16_[0], &v.str32_[0]);
  500. EATEST_VERIFY(n == 6);
  501. EATEST_VERIFY(Strcmp(v.str8_[0], "a") == 0);
  502. EATEST_VERIFY(Strcmp(v.str8_[1], "b") == 0);
  503. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("c")) == 0);
  504. EATEST_VERIFY(Strcmp(v.str8_[2], "d") == 0);
  505. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("e")) == 0);
  506. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("f")) == 0);
  507. #else
  508. n = Sscanf(EA_CHAR32("a b c d e f"), EA_CHAR32("%hS %S %lS %I8S %I16S %I32S"), &v.str8_[0], &v.strw_[0], &v.strw_[1], &v.str8_[2], &v.str16_[0], &v.str32_[0]);
  509. EATEST_VERIFY(n == 6);
  510. EATEST_VERIFY(Strcmp(v.str8_[0], "a") == 0);
  511. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("b")) == 0);
  512. EATEST_VERIFY(Strcmp(v.strw_[1], EA_WCHAR("c")) == 0);
  513. EATEST_VERIFY(Strcmp(v.str8_[2], "d") == 0);
  514. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("e")) == 0);
  515. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("f")) == 0);
  516. #endif
  517. }
  518. }
  519. {
  520. v.Clear();
  521. n = Sscanf("abc 123", "%I8s\t%i", v.str8_[0], &v.int_[0]);
  522. EATEST_VERIFY(n == 2);
  523. EATEST_VERIFY(Strcmp(v.str8_[0], "abc") == 0);
  524. EATEST_VERIFY(v.int_[0] == 123);
  525. v.Clear();
  526. n = Sscanf(EA_CHAR16("abc 123"), EA_CHAR16("%I16s\t%i"), v.str16_[0], &v.int_[0]);
  527. EATEST_VERIFY(n == 2);
  528. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("abc")) == 0);
  529. EATEST_VERIFY(v.int_[0] == 123);
  530. v.Clear();
  531. n = Sscanf(EA_CHAR32("abc 123"), EA_CHAR32("%I32s\t%i"), v.str32_[0], &v.int_[0]);
  532. EATEST_VERIFY(n == 2);
  533. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("abc")) == 0);
  534. EATEST_VERIFY(v.int_[0] == 123);
  535. }
  536. {
  537. v.Clear();
  538. n = Sscanf("0", "%lf", &v.double_[0]);
  539. EATEST_VERIFY(n == 1);
  540. EATEST_VERIFY(v.double_[0] == 0);
  541. v.Clear();
  542. n = Sscanf(EA_CHAR16("0"), EA_CHAR16("%lf"), &v.double_[0]);
  543. EATEST_VERIFY(n == 1);
  544. EATEST_VERIFY(v.double_[0] == 0);
  545. v.Clear();
  546. n = Sscanf(EA_CHAR32("0"), EA_CHAR32("%lf"), &v.double_[0]);
  547. EATEST_VERIFY(n == 1);
  548. EATEST_VERIFY(v.double_[0] == 0);
  549. }
  550. {
  551. v.Clear();
  552. n = Sscanf("-123.456", "%f", &v.float_[0]);
  553. EATEST_VERIFY(n == 1);
  554. EATEST_VERIFY(FloatEqual(v.float_[0], -123.456f));
  555. v.Clear();
  556. n = Sscanf(EA_CHAR16("-123.456"), EA_CHAR16("%f"), &v.float_[0]);
  557. EATEST_VERIFY(n == 1);
  558. EATEST_VERIFY(FloatEqual(v.float_[0], -123.456f));
  559. v.Clear();
  560. n = Sscanf(EA_CHAR32("-123.456"), EA_CHAR32("%f"), &v.float_[0]);
  561. EATEST_VERIFY(n == 1);
  562. EATEST_VERIFY(FloatEqual(v.float_[0], -123.456f));
  563. }
  564. {
  565. v.Clear();
  566. n = Sscanf("-123.456", "%lf", &v.double_[0]);
  567. EATEST_VERIFY(n == 1);
  568. EATEST_VERIFY(DoubleEqual(v.double_[0], -123.456));
  569. v.Clear();
  570. n = Sscanf(EA_CHAR16("-123.456"), EA_CHAR16("%lf"), &v.double_[0]);
  571. EATEST_VERIFY(n == 1);
  572. EATEST_VERIFY(DoubleEqual(v.double_[0], -123.456));
  573. v.Clear();
  574. n = Sscanf(EA_CHAR32("-123.456"), EA_CHAR32("%lf"), &v.double_[0]);
  575. EATEST_VERIFY(n == 1);
  576. EATEST_VERIFY(DoubleEqual(v.double_[0], -123.456));
  577. }
  578. {
  579. v.Clear();
  580. n = Sscanf("-123.456e4", "%lf", &v.double_[0]);
  581. EATEST_VERIFY(n == 1);
  582. EATEST_VERIFY(v.double_[0] == -123.456e4);
  583. v.Clear();
  584. n = Sscanf(EA_CHAR16("-123.456e4"), EA_CHAR16("%lf"), &v.double_[0]);
  585. EATEST_VERIFY(n == 1);
  586. EATEST_VERIFY(v.double_[0] == -123.456e4);
  587. v.Clear();
  588. n = Sscanf(EA_CHAR32("-123.456e4"), EA_CHAR32("%lf"), &v.double_[0]);
  589. EATEST_VERIFY(n == 1);
  590. EATEST_VERIFY(v.double_[0] == -123.456e4);
  591. }
  592. {
  593. v.Clear();
  594. n = Sscanf("12 abcdef", "%4u%n", &v.uint_[0], &v.int_[0]);
  595. EATEST_VERIFY(n == 1);
  596. EATEST_VERIFY(v.uint_[0] == 12);
  597. EATEST_VERIFY(v.int_[0] == 2);
  598. v.Clear();
  599. n = Sscanf(EA_CHAR16("12 abcdef"), EA_CHAR16("%4u%n"), &v.uint_[0], &v.int_[0]);
  600. EATEST_VERIFY(n == 1);
  601. EATEST_VERIFY(v.uint_[0] == 12);
  602. EATEST_VERIFY(v.int_[0] == 2);
  603. v.Clear();
  604. n = Sscanf(EA_CHAR32("12 abcdef"), EA_CHAR32("%4u%n"), &v.uint_[0], &v.int_[0]);
  605. EATEST_VERIFY(n == 1);
  606. EATEST_VERIFY(v.uint_[0] == 12);
  607. EATEST_VERIFY(v.int_[0] == 2);
  608. }
  609. {
  610. v.Clear();
  611. n = Sscanf("Test, more text -999 1.345e22 0x12345678", "%s %s %*s %i %lf 0x%08x", v.str8_[0], v.str8_[1], &v.int_[0], &v.double_[0], &v.uint_[1]);
  612. EATEST_VERIFY(n == 5);
  613. EATEST_VERIFY(!Strcmp("Test,", v.str8_[0]));
  614. EATEST_VERIFY(!Strcmp("more", v.str8_[1]));
  615. EATEST_VERIFY(v.int_[0] == -999);
  616. EATEST_VERIFY(DoubleEqual(v.double_[0], 1.345e22));
  617. EATEST_VERIFY(v.uint_[1] == 0x12345678);
  618. v.Clear();
  619. n = Sscanf(EA_CHAR16("Test, more text -999 1.345e22 0x12345678"), EA_CHAR16("%I16s %I16s %*s %i %lf 0x%08x"), v.str16_[0], v.str16_[1], &v.int_[0], &v.double_[0], &v.uint_[1]);
  620. EATEST_VERIFY(n == 5);
  621. EATEST_VERIFY(!Strcmp(EA_CHAR16("Test,"), v.str16_[0]));
  622. EATEST_VERIFY(!Strcmp(EA_CHAR16("more"), v.str16_[1]));
  623. EATEST_VERIFY(v.int_[0] == -999);
  624. EATEST_VERIFY(DoubleEqual(v.double_[0], 1.345e22));
  625. EATEST_VERIFY(v.uint_[1] == 0x12345678);
  626. v.Clear();
  627. n = Sscanf(EA_CHAR32("Test, more text -999 1.345e22 0x12345678"), EA_CHAR32("%I32s %I32s %*s %i %lf 0x%08x"), v.str32_[0], v.str32_[1], &v.int_[0], &v.double_[0], &v.uint_[1]);
  628. EATEST_VERIFY(n == 5);
  629. EATEST_VERIFY(!Strcmp(EA_CHAR32("Test,"), v.str32_[0]));
  630. EATEST_VERIFY(!Strcmp(EA_CHAR32("more"), v.str32_[1]));
  631. EATEST_VERIFY(v.int_[0] == -999);
  632. EATEST_VERIFY(DoubleEqual(v.double_[0], 1.345e22));
  633. EATEST_VERIFY(v.uint_[1] == 0x12345678);
  634. }
  635. #if (EA_PLATFORM_PTR_SIZE == 8)
  636. {
  637. v.Clear();
  638. n = Sscanf("1234567843434343", "%p", &v.voidptr_[0]);
  639. EATEST_VERIFY(n == 1);
  640. EATEST_VERIFY((uintptr_t)v.voidptr_[0] == UINT64_C(0x1234567843434343));
  641. v.Clear();
  642. n = Sscanf("ffffffffffffffff", "%p", &v.voidptr_[0]);
  643. EATEST_VERIFY(n == 1);
  644. EATEST_VERIFY((uintptr_t)v.voidptr_[0] == UINT64_C(0xffffffffffffffff));
  645. v.Clear();
  646. n = Sscanf("0xffffffffffffffff", "%p", &v.voidptr_[0]);
  647. EATEST_VERIFY(n == 1);
  648. EATEST_VERIFY((uintptr_t)v.voidptr_[0] == UINT64_C(0xffffffffffffffff));
  649. }
  650. #else
  651. {
  652. v.Clear();
  653. n = Sscanf("12345678", "%p", &v.voidptr_[0]);
  654. EATEST_VERIFY(n == 1);
  655. EATEST_VERIFY((uintptr_t)v.voidptr_[0] == 0x12345678);
  656. v.Clear();
  657. n = Sscanf("ffffffff", "%p", &v.voidptr_[0]);
  658. EATEST_VERIFY(n == 1);
  659. EATEST_VERIFY((uintptr_t)v.voidptr_[0] == 0xffffffff);
  660. v.Clear();
  661. n = Sscanf("0xffffffff", "%p", &v.voidptr_[0]);
  662. EATEST_VERIFY(n == 1);
  663. EATEST_VERIFY((uintptr_t)v.voidptr_[0] == 0xffffffff);
  664. }
  665. #endif
  666. }
  667. // UTF8 / UCS2 conversions
  668. {
  669. {
  670. v.Clear();
  671. n = Sscanf("a " "\xC2" "\xA9" "\xE2" "\x89" "\xA0", "%ls %ls", v.strw_[0], v.strw_[1]); // U+00A9 => 0xC2 0xA9. U+2260 => 0xE2 0x89 0xA0
  672. EATEST_VERIFY(n == 2);
  673. EATEST_VERIFY(v.strw_[0][0] == 'a');
  674. EATEST_VERIFY(v.strw_[0][1] == 0);
  675. EATEST_VERIFY(v.strw_[1][0] == 0x00A9);
  676. EATEST_VERIFY(v.strw_[1][1] == 0x2260);
  677. EATEST_VERIFY(v.strw_[1][2] == 0);
  678. v.Clear();
  679. n = Sscanf("a " "\xC2" "\xA9" "\xE2" "\x89" "\xA0", "%I16s %I16s", v.str16_[0], v.str16_[1]); // U+00A9 => 0xC2 0xA9. U+2260 => 0xE2 0x89 0xA0
  680. EATEST_VERIFY(n == 2);
  681. EATEST_VERIFY(v.str16_[0][0] == 'a');
  682. EATEST_VERIFY(v.str16_[0][1] == 0);
  683. EATEST_VERIFY(v.str16_[1][0] == 0x00A9);
  684. EATEST_VERIFY(v.str16_[1][1] == 0x2260);
  685. EATEST_VERIFY(v.str16_[1][2] == 0);
  686. v.Clear();
  687. n = Sscanf("a " "\xC2" "\xA9" "\xE2" "\x89" "\xA0", "%I32s %I32s", v.str32_[0], v.str32_[1]); // U+00A9 => 0xC2 0xA9. U+2260 => 0xE2 0x89 0xA0
  688. EATEST_VERIFY(n == 2);
  689. EATEST_VERIFY(v.str32_[0][0] == 'a');
  690. EATEST_VERIFY(v.str32_[0][1] == 0);
  691. EATEST_VERIFY(v.str32_[1][0] == 0x00A9);
  692. EATEST_VERIFY(v.str32_[1][1] == 0x2260);
  693. EATEST_VERIFY(v.str32_[1][2] == 0);
  694. }
  695. {
  696. v.Clear();
  697. n = Sscanf(EA_CHAR16("a \x00A9\x2260"), EA_CHAR16("%hs %hs"), v.str8_[0], v.str8_[1]);
  698. EATEST_VERIFY(n == 2);
  699. EATEST_VERIFY((uint8_t)v.str8_[0][0] == 'a');
  700. EATEST_VERIFY((uint8_t)v.str8_[0][1] == 0);
  701. EATEST_VERIFY((uint8_t)v.str8_[1][0] == 0xC2);
  702. EATEST_VERIFY((uint8_t)v.str8_[1][1] == 0xA9);
  703. EATEST_VERIFY((uint8_t)v.str8_[1][2] == 0xE2);
  704. EATEST_VERIFY((uint8_t)v.str8_[1][3] == 0x89);
  705. EATEST_VERIFY((uint8_t)v.str8_[1][4] == 0xA0);
  706. EATEST_VERIFY((uint8_t)v.str8_[1][5] == 0);
  707. v.Clear();
  708. n = Sscanf(EA_CHAR32("a \x00A9\x2260"), EA_CHAR32("%hs %hs"), v.str8_[0], v.str8_[1]);
  709. EATEST_VERIFY(n == 2);
  710. EATEST_VERIFY((uint8_t)v.str8_[0][0] == 'a');
  711. EATEST_VERIFY((uint8_t)v.str8_[0][1] == 0);
  712. EATEST_VERIFY((uint8_t)v.str8_[1][0] == 0xC2);
  713. EATEST_VERIFY((uint8_t)v.str8_[1][1] == 0xA9);
  714. EATEST_VERIFY((uint8_t)v.str8_[1][2] == 0xE2);
  715. EATEST_VERIFY((uint8_t)v.str8_[1][3] == 0x89);
  716. EATEST_VERIFY((uint8_t)v.str8_[1][4] == 0xA0);
  717. EATEST_VERIFY((uint8_t)v.str8_[1][5] == 0);
  718. }
  719. }
  720. // The following are examples taken from some EA code.
  721. {
  722. {
  723. v.Clear();
  724. n = Sscanf("12a", "%ld%c", &v.long_[0], &v.char_[0]);
  725. EATEST_VERIFY(n == 2);
  726. EATEST_VERIFY(v.long_[0] == 12);
  727. EATEST_VERIFY(v.char_[0] == 'a');
  728. v.Clear();
  729. n = Sscanf(EA_CHAR16("12a"), EA_CHAR16("%ld%c"), &v.long_[0], &v.wchar_[0]);
  730. EATEST_VERIFY(n == 2);
  731. EATEST_VERIFY(v.long_[0] == 12);
  732. EATEST_VERIFY(v.wchar_[0] == 'a');
  733. v.Clear();
  734. n = Sscanf(EA_CHAR32("12a"), EA_CHAR32("%ld%c"), &v.long_[0], &v.wchar_[0]);
  735. EATEST_VERIFY(n == 2);
  736. EATEST_VERIFY(v.long_[0] == 12);
  737. EATEST_VERIFY(v.wchar_[0] == 'a');
  738. }
  739. {
  740. v.Clear();
  741. n = Sscanf("#define width 640 #define height 480", "#define %*s %d #define %*s %d", &v.int_[0], &v.int_[1]);
  742. EATEST_VERIFY(n == 2);
  743. EATEST_VERIFY(v.int_[0] == 640);
  744. EATEST_VERIFY(v.int_[1] == 480);
  745. v.Clear();
  746. n = Sscanf(EA_CHAR16("#define width 640 #define height 480"), EA_CHAR16("#define %*s %d #define %*s %d"), &v.int_[0], &v.int_[1]);
  747. EATEST_VERIFY(n == 2);
  748. EATEST_VERIFY(v.int_[0] == 640);
  749. EATEST_VERIFY(v.int_[1] == 480);
  750. v.Clear();
  751. n = Sscanf(EA_CHAR32("#define width 640 #define height 480"), EA_CHAR32("#define %*s %d #define %*s %d"), &v.int_[0], &v.int_[1]);
  752. EATEST_VERIFY(n == 2);
  753. EATEST_VERIFY(v.int_[0] == 640);
  754. EATEST_VERIFY(v.int_[1] == 480);
  755. }
  756. {
  757. v.Clear();
  758. n = Sscanf("00010101", "%04d%02d%02d", &v.int_[0], &v.int_[1], &v.int_[2]);
  759. EATEST_VERIFY(n == 3);
  760. EATEST_VERIFY(v.int_[0] == 1);
  761. EATEST_VERIFY(v.int_[1] == 1);
  762. EATEST_VERIFY(v.int_[2] == 1);
  763. v.Clear();
  764. n = Sscanf(EA_CHAR16("00010101"), EA_CHAR16("%04d%02d%02d"), &v.int_[0], &v.int_[1], &v.int_[2]);
  765. EATEST_VERIFY(n == 3);
  766. EATEST_VERIFY(v.int_[0] == 1);
  767. EATEST_VERIFY(v.int_[1] == 1);
  768. EATEST_VERIFY(v.int_[2] == 1);
  769. v.Clear();
  770. n = Sscanf(EA_CHAR32("00010101"), EA_CHAR32("%04d%02d%02d"), &v.int_[0], &v.int_[1], &v.int_[2]);
  771. EATEST_VERIFY(n == 3);
  772. EATEST_VERIFY(v.int_[0] == 1);
  773. EATEST_VERIFY(v.int_[1] == 1);
  774. EATEST_VERIFY(v.int_[2] == 1);
  775. }
  776. {
  777. v.Clear();
  778. n = Sscanf("0xfafbfcfd", "%lx", &v.long_[0]);
  779. EATEST_VERIFY(n == 1);
  780. EATEST_VERIFY((uint32_t)v.long_[0] == 0xfafbfcfd);
  781. v.Clear();
  782. n = Sscanf(EA_CHAR16("0xfafbfcfd"), EA_CHAR16("%lx"), &v.long_[0]);
  783. EATEST_VERIFY(n == 1);
  784. EATEST_VERIFY((uint32_t)v.long_[0] == 0xfafbfcfd);
  785. v.Clear();
  786. n = Sscanf(EA_CHAR32("0xfafbfcfd"), EA_CHAR32("%lx"), &v.long_[0]);
  787. EATEST_VERIFY(n == 1);
  788. EATEST_VERIFY((uint32_t)v.long_[0] == 0xfafbfcfd);
  789. }
  790. {
  791. v.Clear();
  792. n = Sscanf("127.255.3.0", "%u.%u.%u.%u", &v.uint_[0], &v.uint_[1], &v.uint_[2], &v.uint_[3]);
  793. EATEST_VERIFY(n == 4);
  794. EATEST_VERIFY(v.uint_[0] == 127);
  795. EATEST_VERIFY(v.uint_[1] == 255);
  796. EATEST_VERIFY(v.uint_[2] == 3);
  797. EATEST_VERIFY(v.uint_[3] == 0);
  798. v.Clear();
  799. n = Sscanf(EA_CHAR16("127.255.3.0"), EA_CHAR16("%u.%u.%u.%u"), &v.uint_[0], &v.uint_[1], &v.uint_[2], &v.uint_[3]);
  800. EATEST_VERIFY(n == 4);
  801. EATEST_VERIFY(v.uint_[0] == 127);
  802. EATEST_VERIFY(v.uint_[1] == 255);
  803. EATEST_VERIFY(v.uint_[2] == 3);
  804. EATEST_VERIFY(v.uint_[3] == 0);
  805. v.Clear();
  806. n = Sscanf(EA_CHAR32("127.255.3.0"), EA_CHAR32("%u.%u.%u.%u"), &v.uint_[0], &v.uint_[1], &v.uint_[2], &v.uint_[3]);
  807. EATEST_VERIFY(n == 4);
  808. EATEST_VERIFY(v.uint_[0] == 127);
  809. EATEST_VERIFY(v.uint_[1] == 255);
  810. EATEST_VERIFY(v.uint_[2] == 3);
  811. EATEST_VERIFY(v.uint_[3] == 0);
  812. }
  813. {
  814. v.Clear();
  815. n = Sscanf("0.255.3.127", "%d.%d.%d.%d", &v.int_[0], &v.int_[1], &v.int_[2], &v.int_[3]);
  816. EATEST_VERIFY(n == 4);
  817. EATEST_VERIFY(v.int_[0] == 0);
  818. EATEST_VERIFY(v.int_[1] == 255);
  819. EATEST_VERIFY(v.int_[2] == 3);
  820. EATEST_VERIFY(v.int_[3] == 127);
  821. v.Clear();
  822. n = Sscanf(EA_CHAR16("0.255.3.127"), EA_CHAR16("%d.%d.%d.%d"), &v.int_[0], &v.int_[1], &v.int_[2], &v.int_[3]);
  823. EATEST_VERIFY(n == 4);
  824. EATEST_VERIFY(v.int_[0] == 0);
  825. EATEST_VERIFY(v.int_[1] == 255);
  826. EATEST_VERIFY(v.int_[2] == 3);
  827. EATEST_VERIFY(v.int_[3] == 127);
  828. v.Clear();
  829. n = Sscanf(EA_CHAR32("0.255.3.127"), EA_CHAR32("%d.%d.%d.%d"), &v.int_[0], &v.int_[1], &v.int_[2], &v.int_[3]);
  830. EATEST_VERIFY(n == 4);
  831. EATEST_VERIFY(v.int_[0] == 0);
  832. EATEST_VERIFY(v.int_[1] == 255);
  833. EATEST_VERIFY(v.int_[2] == 3);
  834. EATEST_VERIFY(v.int_[3] == 127);
  835. }
  836. {
  837. v.Clear();
  838. n = Sscanf("ff12ee", "%2x%2x%2x", &v.int_[0], &v.int_[1], &v.int_[2]);
  839. EATEST_VERIFY(n == 3);
  840. EATEST_VERIFY(v.int_[0] == 0xff);
  841. EATEST_VERIFY(v.int_[1] == 0x12);
  842. EATEST_VERIFY(v.int_[2] == 0xee);
  843. v.Clear();
  844. n = Sscanf(EA_CHAR16("ff12ee"), EA_CHAR16("%2x%2x%2x"), &v.int_[0], &v.int_[1], &v.int_[2]);
  845. EATEST_VERIFY(n == 3);
  846. EATEST_VERIFY(v.int_[0] == 0xff);
  847. EATEST_VERIFY(v.int_[1] == 0x12);
  848. EATEST_VERIFY(v.int_[2] == 0xee);
  849. v.Clear();
  850. n = Sscanf(EA_CHAR32("ff12ee"), EA_CHAR32("%2x%2x%2x"), &v.int_[0], &v.int_[1], &v.int_[2]);
  851. EATEST_VERIFY(n == 3);
  852. EATEST_VERIFY(v.int_[0] == 0xff);
  853. EATEST_VERIFY(v.int_[1] == 0x12);
  854. EATEST_VERIFY(v.int_[2] == 0xee);
  855. }
  856. {
  857. v.Clear();
  858. n = Sscanf("f2e", "%1hhx%1hhx%1hhx", &v.uint8_[0], &v.uint8_[1], &v.uint8_[2]);
  859. EATEST_VERIFY(n == 3);
  860. EATEST_VERIFY(v.uint8_[0] == 0xf);
  861. EATEST_VERIFY(v.uint8_[1] == 0x2);
  862. EATEST_VERIFY(v.uint8_[2] == 0xe);
  863. v.Clear();
  864. n = Sscanf(EA_CHAR16("f2e"), EA_CHAR16("%1hhx%1hhx%1hhx"), &v.uint8_[0], &v.uint8_[1], &v.uint8_[2]);
  865. EATEST_VERIFY(n == 3);
  866. EATEST_VERIFY(v.uint8_[0] == 0xf);
  867. EATEST_VERIFY(v.uint8_[1] == 0x2);
  868. EATEST_VERIFY(v.uint8_[2] == 0xe);
  869. v.Clear();
  870. n = Sscanf(EA_CHAR32("f2e"), EA_CHAR32("%1hhx%1hhx%1hhx"), &v.uint8_[0], &v.uint8_[1], &v.uint8_[2]);
  871. EATEST_VERIFY(n == 3);
  872. EATEST_VERIFY(v.uint8_[0] == 0xf);
  873. EATEST_VERIFY(v.uint8_[1] == 0x2);
  874. EATEST_VERIFY(v.uint8_[2] == 0xe);
  875. }
  876. {
  877. v.Clear();
  878. n = Sscanf("Test/123.4 567", "%4s/%5f %3d", v.str8_[0], &v.float_[0], &v.int_[0]);
  879. EATEST_VERIFY(n == 3);
  880. EATEST_VERIFY(!Strcmp(v.str8_[0], "Test"));
  881. EATEST_VERIFY(FloatEqual(v.float_[0], 123.4f));
  882. EATEST_VERIFY(v.int_[0] == 567);
  883. v.Clear();
  884. n = Sscanf(EA_CHAR16("Test/123.4 567"), EA_CHAR16("%4I16s/%5f %3d"), v.str16_[0], &v.float_[0], &v.int_[0]);
  885. EATEST_VERIFY(n == 3);
  886. EATEST_VERIFY(!Strcmp(v.str16_[0], EA_CHAR16("Test")));
  887. EATEST_VERIFY(FloatEqual(v.float_[0], 123.4f));
  888. EATEST_VERIFY(v.int_[0] == 567);
  889. v.Clear();
  890. n = Sscanf(EA_CHAR32("Test/123.4 567"), EA_CHAR32("%4I32s/%5f %3d"), v.str32_[0], &v.float_[0], &v.int_[0]);
  891. EATEST_VERIFY(n == 3);
  892. EATEST_VERIFY(!Strcmp(v.str32_[0], EA_CHAR32("Test")));
  893. EATEST_VERIFY(FloatEqual(v.float_[0], 123.4f));
  894. EATEST_VERIFY(v.int_[0] == 567);
  895. }
  896. {
  897. v.Clear();
  898. n = Sscanf("abdefg-hijk-a-mnopqrstu\n", "%32[^-]-%32[^-]-%32[^-]-%32[^\n\r]", v.str8_[0], v.str8_[1], v.str8_[2], v.str8_[3]);
  899. EATEST_VERIFY(n == 4);
  900. EATEST_VERIFY(!Strcmp(v.str8_[0], "abdefg"));
  901. EATEST_VERIFY(!Strcmp(v.str8_[1], "hijk"));
  902. EATEST_VERIFY(!Strcmp(v.str8_[2], "a"));
  903. EATEST_VERIFY(!Strcmp(v.str8_[3], "mnopqrstu"));
  904. v.Clear();
  905. n = Sscanf(EA_CHAR16("abdefg-hijk-a-mnopqrstu\n"), EA_CHAR16("%32I16[^-]-%32I16[^-]-%32I16[^-]-%32I16[^\n\r]"), v.str16_[0], v.str16_[1], v.str16_[2], v.str16_[3]);
  906. EATEST_VERIFY(n == 4);
  907. EATEST_VERIFY(!Strcmp(v.str16_[0], EA_CHAR16("abdefg")));
  908. EATEST_VERIFY(!Strcmp(v.str16_[1], EA_CHAR16("hijk")));
  909. EATEST_VERIFY(!Strcmp(v.str16_[2], EA_CHAR16("a")));
  910. EATEST_VERIFY(!Strcmp(v.str16_[3], EA_CHAR16("mnopqrstu")));
  911. v.Clear();
  912. n = Sscanf(EA_CHAR32("abdefg-hijk-a-mnopqrstu\n"), EA_CHAR32("%32I32[^-]-%32I32[^-]-%32I32[^-]-%32I32[^\n\r]"), v.str32_[0], v.str32_[1], v.str32_[2], v.str32_[3]);
  913. EATEST_VERIFY(n == 4);
  914. EATEST_VERIFY(!Strcmp(v.str32_[0], EA_CHAR32("abdefg")));
  915. EATEST_VERIFY(!Strcmp(v.str32_[1], EA_CHAR32("hijk")));
  916. EATEST_VERIFY(!Strcmp(v.str32_[2], EA_CHAR32("a")));
  917. EATEST_VERIFY(!Strcmp(v.str32_[3], EA_CHAR32("mnopqrstu")));
  918. }
  919. {
  920. v.Clear();
  921. n = Sscanf("[17;-18R", "[%hu;%huR", &v.short_[0], &v.short_[1]);
  922. EATEST_VERIFY(n == 2);
  923. EATEST_VERIFY(v.short_[0] == 17);
  924. EATEST_VERIFY(v.short_[1] == -18);
  925. v.Clear();
  926. n = Sscanf(EA_CHAR16("[17;-18R"), EA_CHAR16("[%hu;%huR"), &v.short_[0], &v.short_[1]);
  927. EATEST_VERIFY(n == 2);
  928. EATEST_VERIFY(v.short_[0] == 17);
  929. EATEST_VERIFY(v.short_[1] == -18);
  930. v.Clear();
  931. n = Sscanf(EA_CHAR32("[17;-18R"), EA_CHAR32("[%hu;%huR"), &v.short_[0], &v.short_[1]);
  932. EATEST_VERIFY(n == 2);
  933. EATEST_VERIFY(v.short_[0] == 17);
  934. EATEST_VERIFY(v.short_[1] == -18);
  935. }
  936. {
  937. v.Clear();
  938. n = Sscanf("0x01-0x02-0304", "%08x-%04x-%02x%02x", &v.int_[0], &v.int_[1], &v.int_[2], &v.int_[3]);
  939. EATEST_VERIFY(n == 4);
  940. EATEST_VERIFY(v.int_[0] == 0x01);
  941. EATEST_VERIFY(v.int_[1] == 0x02);
  942. EATEST_VERIFY(v.int_[2] == 0x03);
  943. EATEST_VERIFY(v.int_[3] == 0x04);
  944. v.Clear();
  945. n = Sscanf(EA_CHAR16("0x01-0x02-0304"), EA_CHAR16("%08x-%04x-%02x%02x"), &v.int_[0], &v.int_[1], &v.int_[2], &v.int_[3]);
  946. EATEST_VERIFY(n == 4);
  947. EATEST_VERIFY(v.int_[0] == 0x01);
  948. EATEST_VERIFY(v.int_[1] == 0x02);
  949. EATEST_VERIFY(v.int_[2] == 0x03);
  950. EATEST_VERIFY(v.int_[3] == 0x04);
  951. v.Clear();
  952. n = Sscanf(EA_CHAR32("0x01-0x02-0304"), EA_CHAR32("%08x-%04x-%02x%02x"), &v.int_[0], &v.int_[1], &v.int_[2], &v.int_[3]);
  953. EATEST_VERIFY(n == 4);
  954. EATEST_VERIFY(v.int_[0] == 0x01);
  955. EATEST_VERIFY(v.int_[1] == 0x02);
  956. EATEST_VERIFY(v.int_[2] == 0x03);
  957. EATEST_VERIFY(v.int_[3] == 0x04);
  958. }
  959. {
  960. v.Clear();
  961. n = Sscanf("-3.14 .2 48 1a", "%f %f %x %x", &v.float_[0], &v.float_[1], &v.int_[0], &v.int_[1]);
  962. EATEST_VERIFY(n == 4);
  963. EATEST_VERIFY(FloatEqual(v.float_[0], -3.14f));
  964. EATEST_VERIFY(FloatEqual(v.float_[1], .2f));
  965. EATEST_VERIFY(v.int_[0] == 0x48);
  966. EATEST_VERIFY(v.int_[1] == 0x1a);
  967. v.Clear();
  968. n = Sscanf(EA_CHAR16("-3.14 .2 48 1a"), EA_CHAR16("%f %f %x %x"), &v.float_[0], &v.float_[1], &v.int_[0], &v.int_[1]);
  969. EATEST_VERIFY(n == 4);
  970. EATEST_VERIFY(FloatEqual(v.float_[0], -3.14f));
  971. EATEST_VERIFY(FloatEqual(v.float_[1], .2f));
  972. EATEST_VERIFY(v.int_[0] == 0x48);
  973. EATEST_VERIFY(v.int_[1] == 0x1a);
  974. v.Clear();
  975. n = Sscanf(EA_CHAR32("-3.14 .2 48 1a"), EA_CHAR32("%f %f %x %x"), &v.float_[0], &v.float_[1], &v.int_[0], &v.int_[1]);
  976. EATEST_VERIFY(n == 4);
  977. EATEST_VERIFY(FloatEqual(v.float_[0], -3.14f));
  978. EATEST_VERIFY(FloatEqual(v.float_[1], .2f));
  979. EATEST_VERIFY(v.int_[0] == 0x48);
  980. EATEST_VERIFY(v.int_[1] == 0x1a);
  981. }
  982. { // Regression for %x '_' bug.
  983. {
  984. v.Clear();
  985. n = EA::StdC::Sscanf("_s", "%x_%c", &v.int_[0], &v.char_[1]);
  986. EATEST_VERIFY(n == 0);
  987. EATEST_VERIFY(v.int_[0] == -1);
  988. EATEST_VERIFY(v.char_[1] == -1);
  989. v.Clear();
  990. n = EA::StdC::Sscanf("1a01_", "%x_%c", &v.int_[0], &v.char_[1]); // EAStdC was mistakenly reading this as 0x1a018 instead of 0x1a01
  991. EATEST_VERIFY(n == 1);
  992. EATEST_VERIFY(v.int_[0] == 0x1a01);
  993. EATEST_VERIFY(v.char_[1] == -1);
  994. v.Clear();
  995. n = EA::StdC::Sscanf("1a01_s", "%x_%c", &v.int_[0], &v.char_[1]);
  996. EATEST_VERIFY(n == 2);
  997. EATEST_VERIFY(v.int_[0] == 0x1a01);
  998. EATEST_VERIFY(v.char_[1] == 's');
  999. }
  1000. {
  1001. v.Clear();
  1002. n = EA::StdC::Sscanf(EA_CHAR16("_s"), EA_CHAR16("%x_%I16c"), &v.int_[0], &v.char16_[1]);
  1003. EATEST_VERIFY(n == 0);
  1004. EATEST_VERIFY(v.int_[0] == -1);
  1005. EATEST_VERIFY((uint16_t)v.char16_[1] == 0xffff);
  1006. v.Clear();
  1007. n = EA::StdC::Sscanf(EA_CHAR16("1a01_"), EA_CHAR16("%x_%I16c"), &v.int_[0], &v.char16_[1]); // EAStdC was mistakenly reading this as 0x1a018 instead of 0x1a01
  1008. EATEST_VERIFY(n == 1);
  1009. EATEST_VERIFY(v.int_[0] == 0x1a01);
  1010. EATEST_VERIFY((uint16_t)v.char16_[1] == 0xffff);
  1011. v.Clear();
  1012. n = EA::StdC::Sscanf(EA_CHAR16("1a01_s"), EA_CHAR16("%x_%I16c"), &v.int_[0], &v.char16_[1]);
  1013. EATEST_VERIFY(n == 2);
  1014. EATEST_VERIFY(v.int_[0] == 0x1a01);
  1015. EATEST_VERIFY(v.char16_[1] == 's');
  1016. }
  1017. {
  1018. v.Clear();
  1019. n = EA::StdC::Sscanf(EA_CHAR32("_s"), EA_CHAR32("%x_%I32c"), &v.int_[0], &v.char32_[1]);
  1020. EATEST_VERIFY(n == 0);
  1021. EATEST_VERIFY(v.int_[0] == -1);
  1022. EATEST_VERIFY((uint32_t)v.char32_[1] == 0xffffffff);
  1023. v.Clear();
  1024. n = EA::StdC::Sscanf(EA_CHAR32("1a01_"), EA_CHAR32("%x_%I32c"), &v.int_[0], &v.char32_[1]); // EAStdC was mistakenly reading this as 0x1a018 instead of 0x1a01
  1025. EATEST_VERIFY(n == 1);
  1026. EATEST_VERIFY(v.int_[0] == 0x1a01);
  1027. EATEST_VERIFY((uint32_t)v.char32_[1] == 0xffffffff);
  1028. v.Clear();
  1029. n = EA::StdC::Sscanf(EA_CHAR32("1a01_s"), EA_CHAR32("%x_%I32c"), &v.int_[0], &v.char32_[1]);
  1030. EATEST_VERIFY(n == 2);
  1031. EATEST_VERIFY(v.int_[0] == 0x1a01);
  1032. EATEST_VERIFY(v.char32_[1] == 's');
  1033. }
  1034. }
  1035. {
  1036. v.Clear();
  1037. n = Sscanf(" for (int x = 0; x < 17; ++x)", " for %*[^(](%n%*[^)]%n%c\n", &v.int_[0], &v.int_[1], &v.char8_[0]);
  1038. EATEST_VERIFY(n == 1); // %n doesn't count towards the return value, so the expected result is 1 and not 3.
  1039. EATEST_VERIFY(v.int_[0] == 6);
  1040. EATEST_VERIFY(v.int_[1] == 28);
  1041. EATEST_VERIFY(v.char8_[0] == ')');
  1042. v.Clear();
  1043. n = Sscanf(EA_CHAR16(" for (int x = 0; x < 17; ++x)"), EA_CHAR16(" for %*[^(](%n%*[^)]%n%I16c\n"), &v.int_[0], &v.int_[1], &v.char16_[0]);
  1044. EATEST_VERIFY(n == 1); // %n doesn't count towards the return value, so the expected result is 1 and not 3.
  1045. EATEST_VERIFY(v.int_[0] == 6);
  1046. EATEST_VERIFY(v.int_[1] == 28);
  1047. EATEST_VERIFY(v.char16_[0] == ')');
  1048. v.Clear();
  1049. n = Sscanf(EA_CHAR32(" for (int x = 0; x < 17; ++x)"), EA_CHAR32(" for %*[^(](%n%*[^)]%n%I32c\n"), &v.int_[0], &v.int_[1], &v.char32_[0]);
  1050. EATEST_VERIFY(n == 1); // %n doesn't count towards the return value, so the expected result is 1 and not 3.
  1051. EATEST_VERIFY(v.int_[0] == 6);
  1052. EATEST_VERIFY(v.int_[1] == 28);
  1053. EATEST_VERIFY(v.char32_[0] == ')');
  1054. }
  1055. // To do: Implement some of these:
  1056. /*
  1057. v.Clear();
  1058. //n = Sscanf(mpStreamPosition, " %p %u %d", &pResult, &nSize, &nAllocationFlags);
  1059. v.Clear();
  1060. //n = Sscanf(line.c_str(), "IMADDI %[^,], %[^,], %[^,], %d", register1, register2, register3, &immediate1)
  1061. v.Clear();
  1062. //n = Sscanf(buffer, "%s %[A-Za-z0-9][%d][%d] %s %s", currentState->stateName,currentState->elementType, &currentState->numColumns, &currentState->numRows,currentState->uiType, currentState->globalStateType);
  1063. v.Clear();
  1064. //n = Sscanf(argv[i], "-i%x", &id);
  1065. v.Clear();
  1066. //n = Sscanf(argv[i], "-p%s", prefix);
  1067. v.Clear();
  1068. //n = Sscanf(argv[i], "-o%s", outputPath);
  1069. v.Clear();
  1070. //n = Sscanf(argv[i], "-h%s", stateFile);
  1071. v.Clear();
  1072. //n = Sscanf(argv[i], "-r%s", registerFile);
  1073. v.Clear();
  1074. //n = Sscanf(fp,"%128s",effectName)
  1075. v.Clear();
  1076. //n = Sscanf(linebuf.c_str(), "%x:%x %xH %*s %31s", &g.mSegment, &g.mOffset, &g.mLength, className))
  1077. v.Clear();
  1078. //n = Sscanf(linebuf.c_str(), "%x:%x %s %x %*c %s", &seg, &offset, symbolMangled, &rva, source))
  1079. v.Clear();
  1080. //n = Sscanf(&linebuf[9], " load address is %x", &address))
  1081. v.Clear();
  1082. //n = Sscanf(dfile,"%[^\n\r]", packageName);
  1083. v.Clear();
  1084. //n = Sscanf("127 -127 177 255 ff", "%"SCNd8 " %"SCNi8 " %"SCNo8 " %"SCNu8 " %"SCNx8, &d8, &i8, &o8, &u8, &x8);
  1085. v.Clear();
  1086. //n = Sscanf("32767 -32768 77777 65535 ffff", "%"SCNd16 " %"SCNi16 " %"SCNo16 " %"SCNu16 " %"SCNx16, &d16, &i16, &o16, &u16, &x16);
  1087. v.Clear();
  1088. //n = Sscanf("2147483647 -2147483648 17777777777 4294967295 ffffffff", "%"SCNd32 " %"SCNi32 " %"SCNo32 " %"SCNu32 " %"SCNx32, &d32, &i32, &o32, &u32, &x32);
  1089. v.Clear();
  1090. //n = Sscanf("9223372036854775807 -9223372036854775808 777777777777777777777 18446744073709551615 ffffffffffffffff", "%"SCNd64 " %"SCNi64 " %"SCNo64 " %"SCNu64 " %"SCNx64, &d64, &i64, &o64, &u64, &x64);
  1091. v.Clear();
  1092. //n = Sscanf("2147483647 -2147483648 17777777777 4294967295 ffffffff", "%"SCNdPTR " %"SCNiPTR " %"SCNoPTR " %"SCNuPTR " %"SCNxPTR, &dPtr, &iPtr, &oPtr, &uPtr, &xPtr);
  1093. v.Clear();
  1094. //n = Sscanf("2147483647 -2147483648 17777777777 18446744073709551615 ffffffffffffffff", "%"SCNdPTR " %"SCNiPTR " %"SCNoPTR " %"SCNuPTR " %"SCNxPTR, &dPtr, &iPtr, &oPtr, &uPtr, &xPtr);
  1095. v.Clear();
  1096. //n = Sscanf( sValue, EA_CHAR16( "%g,%g,%g,%g" ), &rf.mLeft, &rf.mTop, &rf.mRight, &rf.mBottom ) != 4)
  1097. v.Clear();
  1098. //n = Sscanf(sctheader+4,"%14lf%14lf%12lf%12lf",&faspectx,&faspecty,&fheight,&fwidth);
  1099. */
  1100. }
  1101. {
  1102. {
  1103. v.Clear();
  1104. n = Sscanf("%", "%%");
  1105. EATEST_VERIFY(n == 0);
  1106. v.Clear();
  1107. n = Sscanf(EA_CHAR16("%"), EA_CHAR16("%%"));
  1108. EATEST_VERIFY(n == 0);
  1109. v.Clear();
  1110. n = Sscanf(EA_CHAR32("%"), EA_CHAR32("%%"));
  1111. EATEST_VERIFY(n == 0);
  1112. }
  1113. {
  1114. v.Clear();
  1115. n = Sscanf("0 1 2 3 4 5 6 7 8 9 10 11 a 13 14", "%*d%*i%*o%*u%*x%*X%*e%*E%*f%*g%*G%*s%*[abc]%*c%*p");
  1116. EATEST_VERIFY(n == 0);
  1117. v.Clear();
  1118. n = Sscanf(EA_CHAR16("0 1 2 3 4 5 6 7 8 9 10 11 a 13 14"), EA_CHAR16("%*d%*i%*o%*u%*x%*X%*e%*E%*f%*g%*G%*s%*[abc]%*c%*p"));
  1119. EATEST_VERIFY(n == 0);
  1120. v.Clear();
  1121. n = Sscanf(EA_CHAR32("0 1 2 3 4 5 6 7 8 9 10 11 a 13 14"), EA_CHAR32("%*d%*i%*o%*u%*x%*X%*e%*E%*f%*g%*G%*s%*[abc]%*c%*p"));
  1122. EATEST_VERIFY(n == 0);
  1123. }
  1124. {
  1125. v.Clear();
  1126. n = Sscanf("123", "%0d", &v.int_[0]); // We should just ignore the field, as if it was %*d.
  1127. EATEST_VERIFY(n == 0);
  1128. v.Clear();
  1129. n = Sscanf(EA_CHAR16("123"), EA_CHAR16("%0d"), &v.int_[0]); // We should just ignore the field, as if it was %*d.
  1130. EATEST_VERIFY(n == 0);
  1131. v.Clear();
  1132. n = Sscanf(EA_CHAR32("123"), EA_CHAR32("%0d"), &v.int_[0]); // We should just ignore the field, as if it was %*d.
  1133. EATEST_VERIFY(n == 0);
  1134. }
  1135. {
  1136. v.Clear();
  1137. n = Sscanf("-0.0 -0.0 -0.0 -0.0 -0.0 -0.0 -0.0 -0.0", "%e %E %f %F %g %G %f %f", &v.float_[0], &v.float_[1], &v.float_[2], &v.float_[3], &v.float_[4], &v.float_[5], &v.float_[6], &v.float_[7]);
  1138. EATEST_VERIFY(n == 8);
  1139. EATEST_VERIFY(v.float_[0] == -0.f);
  1140. EATEST_VERIFY(v.float_[1] == -0.f);
  1141. EATEST_VERIFY(v.float_[2] == -0.f);
  1142. EATEST_VERIFY(v.float_[3] == -0.f);
  1143. EATEST_VERIFY(v.float_[4] == -0.f);
  1144. EATEST_VERIFY(v.float_[5] == -0.f);
  1145. EATEST_VERIFY(v.float_[6] == -0.f);
  1146. EATEST_VERIFY(v.float_[7] == -0.f);
  1147. v.Clear();
  1148. n = Sscanf(EA_CHAR16("-0.0 -0.0 -0.0 -0.0 -0.0 -0.0 -0.0 -0.0"), EA_CHAR16("%e %E %f %F %g %G %f %f"), &v.float_[0], &v.float_[1], &v.float_[2], &v.float_[3], &v.float_[4], &v.float_[5], &v.float_[6], &v.float_[7]);
  1149. EATEST_VERIFY(n == 8);
  1150. EATEST_VERIFY(v.float_[0] == -0.f);
  1151. EATEST_VERIFY(v.float_[1] == -0.f);
  1152. EATEST_VERIFY(v.float_[2] == -0.f);
  1153. EATEST_VERIFY(v.float_[3] == -0.f);
  1154. EATEST_VERIFY(v.float_[4] == -0.f);
  1155. EATEST_VERIFY(v.float_[5] == -0.f);
  1156. EATEST_VERIFY(v.float_[6] == -0.f);
  1157. EATEST_VERIFY(v.float_[7] == -0.f);
  1158. v.Clear();
  1159. n = Sscanf(EA_CHAR32("-0.0 -0.0 -0.0 -0.0 -0.0 -0.0 -0.0 -0.0"), EA_CHAR32("%e %E %f %F %g %G %f %f"), &v.float_[0], &v.float_[1], &v.float_[2], &v.float_[3], &v.float_[4], &v.float_[5], &v.float_[6], &v.float_[7]);
  1160. EATEST_VERIFY(n == 8);
  1161. EATEST_VERIFY(v.float_[0] == -0.f);
  1162. EATEST_VERIFY(v.float_[1] == -0.f);
  1163. EATEST_VERIFY(v.float_[2] == -0.f);
  1164. EATEST_VERIFY(v.float_[3] == -0.f);
  1165. EATEST_VERIFY(v.float_[4] == -0.f);
  1166. EATEST_VERIFY(v.float_[5] == -0.f);
  1167. EATEST_VERIFY(v.float_[6] == -0.f);
  1168. EATEST_VERIFY(v.float_[7] == -0.f);
  1169. }
  1170. {
  1171. v.Clear();
  1172. n = Sscanf("inF -inf nan -Nan INF -inf nan -NaN", "%e %E %f %F %g %G %f %f", &v.float_[0], &v.float_[1], &v.float_[2], &v.float_[3], &v.float_[4], &v.float_[5], &v.float_[6], &v.float_[7]);
  1173. EATEST_VERIFY(n == 8);
  1174. EATEST_VERIFY(IsInfinite(v.float_[0]));
  1175. EATEST_VERIFY(IsInfinite(v.float_[1]));
  1176. EATEST_VERIFY(IsNAN(v.float_[2]));
  1177. EATEST_VERIFY(IsNAN(v.float_[3]));
  1178. EATEST_VERIFY(IsInfinite(v.float_[4]));
  1179. EATEST_VERIFY(IsInfinite(v.float_[5]));
  1180. EATEST_VERIFY(IsNAN(v.float_[6]));
  1181. EATEST_VERIFY(IsNAN(v.float_[7]));
  1182. v.Clear();
  1183. n = Sscanf(EA_CHAR16("inF -inf nan -Nan INF -inf nan -NaN"), EA_CHAR16("%e %E %f %F %g %G %f %f"), &v.float_[0], &v.float_[1], &v.float_[2], &v.float_[3], &v.float_[4], &v.float_[5], &v.float_[6], &v.float_[7]);
  1184. EATEST_VERIFY(n == 8);
  1185. EATEST_VERIFY(IsInfinite(v.float_[0]));
  1186. EATEST_VERIFY(IsInfinite(v.float_[1]));
  1187. EATEST_VERIFY(IsNAN(v.float_[2]));
  1188. EATEST_VERIFY(IsNAN(v.float_[3]));
  1189. EATEST_VERIFY(IsInfinite(v.float_[4]));
  1190. EATEST_VERIFY(IsInfinite(v.float_[5]));
  1191. EATEST_VERIFY(IsNAN(v.float_[6]));
  1192. EATEST_VERIFY(IsNAN(v.float_[7]));
  1193. v.Clear();
  1194. n = Sscanf(EA_CHAR32("inF -inf nan -Nan INF -inf nan -NaN"), EA_CHAR32("%e %E %f %F %g %G %f %f"), &v.float_[0], &v.float_[1], &v.float_[2], &v.float_[3], &v.float_[4], &v.float_[5], &v.float_[6], &v.float_[7]);
  1195. EATEST_VERIFY(n == 8);
  1196. EATEST_VERIFY(IsInfinite(v.float_[0]));
  1197. EATEST_VERIFY(IsInfinite(v.float_[1]));
  1198. EATEST_VERIFY(IsNAN(v.float_[2]));
  1199. EATEST_VERIFY(IsNAN(v.float_[3]));
  1200. EATEST_VERIFY(IsInfinite(v.float_[4]));
  1201. EATEST_VERIFY(IsInfinite(v.float_[5]));
  1202. EATEST_VERIFY(IsNAN(v.float_[6]));
  1203. EATEST_VERIFY(IsNAN(v.float_[7]));
  1204. }
  1205. // To do: Implement some of these:
  1206. //n = Sscanf8_("%d", ip);
  1207. //n = Sscanf8_("%*d");
  1208. //n = Sscanf8_("%3d", ip);
  1209. //n = Sscanf8_("%hd", hp);
  1210. //n = Sscanf8_("%3ld", lp);
  1211. //n = Sscanf8_("%*3d");
  1212. //n = Sscanf8_("%d %ld", ip, lp);
  1213. //n = Sscanf8_("%d%i%o%u%x%X%a%A%e%E%f%F%g%G%s%[abc]%c%p%n%%", ip, ip, uip, uip, uip, uip, fp, fp, fp, fp, fp, fp, fp, fp, s, s, s, pp, n);
  1214. //n = Sscanf8_("%*d%*i%*o%*u%*x%*X%*e%*E%*f%*g%*G%*s%*[abc]%*c%*p");
  1215. //n = Sscanf8_("%*2d%*8s%*3c");
  1216. //n = Sscanf8_("%*n", n); // "suppress" "suppression of %n"
  1217. //n = Sscanf8_("%*hd"); // "together" "suppression with length"
  1218. //n = Sscanf8_("%le%lE%lf%lg%lG", dp, dp, dp, dp, dp);
  1219. //n = Sscanf8_("%Le%LE%Lf%Lg%LG", ldp, ldp, ldp, ldp, ldp);
  1220. //n = Sscanf8_("%d%i%o%u%x%X%e%E%f%g%G%s%[abc]%c%p%n%%", ip, ip, uip, uip, uip, uip, fp, fp, fp, fp, fp, s, s, s, pp, n);
  1221. //n = Sscanf8_("%2s%3s%4c%5c%6[abc]%7[abc]", ss, us, ss, us, ss, us);
  1222. //n = Sscanf8_("%[%d]%d", s, ip); // This is valid. It searches for % and d.
  1223. //n = Sscanf8_("%[^%d]%d", s, ip);
  1224. //n = Sscanf8_("%[]%d]%d", s, ip);
  1225. //n = Sscanf8_("%[^]%d]%d", s, ip);
  1226. //n = Sscanf8_("%hhd", hhp);
  1227. //n = Sscanf8_("%lld", llp);
  1228. //n = Sscanf8_("%jd", jp);
  1229. //n = Sscanf8_("%zu", zp);
  1230. //n = Sscanf8_("%td", tp);
  1231. //n = Sscanf8_("%F", fp);
  1232. //n = Sscanf8_("%a", fp);
  1233. //n = Sscanf8_("%A", fp);
  1234. //n = Sscanf8_("%lc%ls%l[abc]", ls, ls, ls);
  1235. //n = Sscanf8_("%*d%*i%*o%*u%*x%*X%*a%*A%*e%*E%*f%*F%*g%*G%*s%*[abc]%*c%*p");
  1236. //n = Sscanf8_("%*2d%*8s%*3c");
  1237. //n = Sscanf8_("%*n", n); // We should leave the n parameter as-is.
  1238. //n = Sscanf8_("%*hd"); // We should ignore the h.
  1239. //n = Sscanf8_("%2d%3i%4o%5u%6x%7X%8a%9A%10e%11E%12f%13F%14g%15G%16s%3[abc]%4c%5p", ip, ip, uip, uip, uip, uip, fp, fp, fp, fp, fp, fp, fp, fp, s, s, s, pp);
  1240. //n = Sscanf8_("%0d", ip); // We should just ignore the field, as if it was %*d.
  1241. //n = Sscanf8_("%3n", n); // We should just ignore the 3. Possibly assert about it.
  1242. // Modifiers
  1243. {
  1244. v.Clear();
  1245. n = Sscanf("0 1 012 55555 0x4ff 0x5FF x", "%hd%hi%ho%hu%hx%hX%hn", &v.short_[0], &v.short_[1], &v.short_[2], &v.ushort_[3], &v.short_[4], &v.short_[5], &v.short_[6]);
  1246. EATEST_VERIFY(n == 6);
  1247. EATEST_VERIFY(v.short_[0] == 0);
  1248. EATEST_VERIFY(v.short_[1] == 1);
  1249. EATEST_VERIFY(v.short_[2] == 012);
  1250. EATEST_VERIFY(v.ushort_[3] == 55555);
  1251. EATEST_VERIFY(v.short_[4] == 0x4ff);
  1252. EATEST_VERIFY(v.short_[5] == 0x5FF);
  1253. EATEST_VERIFY(v.short_[6] == 25);
  1254. v.Clear();
  1255. n = Sscanf(EA_CHAR16("0 1 012 55555 0x4ff 0x5FF x"), EA_CHAR16("%hd%hi%ho%hu%hx%hX%hn"), &v.short_[0], &v.short_[1], &v.short_[2], &v.ushort_[3], &v.short_[4], &v.short_[5], &v.short_[6]);
  1256. EATEST_VERIFY(n == 6);
  1257. EATEST_VERIFY(v.short_[0] == 0);
  1258. EATEST_VERIFY(v.short_[1] == 1);
  1259. EATEST_VERIFY(v.short_[2] == 012);
  1260. EATEST_VERIFY(v.ushort_[3] == 55555);
  1261. EATEST_VERIFY(v.short_[4] == 0x4ff);
  1262. EATEST_VERIFY(v.short_[5] == 0x5FF);
  1263. EATEST_VERIFY(v.short_[6] == 25);
  1264. v.Clear();
  1265. n = Sscanf(EA_CHAR32("0 1 012 55555 0x4ff 0x5FF x"), EA_CHAR32("%hd%hi%ho%hu%hx%hX%hn"), &v.short_[0], &v.short_[1], &v.short_[2], &v.ushort_[3], &v.short_[4], &v.short_[5], &v.short_[6]);
  1266. EATEST_VERIFY(n == 6);
  1267. EATEST_VERIFY(v.short_[0] == 0);
  1268. EATEST_VERIFY(v.short_[1] == 1);
  1269. EATEST_VERIFY(v.short_[2] == 012);
  1270. EATEST_VERIFY(v.ushort_[3] == 55555);
  1271. EATEST_VERIFY(v.short_[4] == 0x4ff);
  1272. EATEST_VERIFY(v.short_[5] == 0x5FF);
  1273. EATEST_VERIFY(v.short_[6] == 25);
  1274. }
  1275. {
  1276. v.Clear();
  1277. n = Sscanf("0 1 2 3 4 5 x", "%hhd%hhi%hho%hhu%hhx%hhX%hhn", &v.int8_[0], &v.int8_[1], &v.int8_[2], &v.int8_[3], &v.int8_[4], &v.int8_[5], &v.int8_[6]);
  1278. EATEST_VERIFY(n == 6);
  1279. EATEST_VERIFY(v.int8_[0] == 0);
  1280. EATEST_VERIFY(v.int8_[1] == 1);
  1281. EATEST_VERIFY(v.int8_[2] == 2);
  1282. EATEST_VERIFY(v.int8_[3] == 3);
  1283. EATEST_VERIFY(v.int8_[4] == 4);
  1284. EATEST_VERIFY(v.int8_[5] == 5);
  1285. EATEST_VERIFY(v.int8_[6] == 11);
  1286. v.Clear();
  1287. n = Sscanf(EA_CHAR16("0 1 2 3 4 5 x"), EA_CHAR16("%hhd%hhi%hho%hhu%hhx%hhX%hhn"), &v.int8_[0], &v.int8_[1], &v.int8_[2], &v.int8_[3], &v.int8_[4], &v.int8_[5], &v.int8_[6]);
  1288. EATEST_VERIFY(n == 6);
  1289. EATEST_VERIFY(v.int8_[0] == 0);
  1290. EATEST_VERIFY(v.int8_[1] == 1);
  1291. EATEST_VERIFY(v.int8_[2] == 2);
  1292. EATEST_VERIFY(v.int8_[3] == 3);
  1293. EATEST_VERIFY(v.int8_[4] == 4);
  1294. EATEST_VERIFY(v.int8_[5] == 5);
  1295. EATEST_VERIFY(v.int8_[6] == 11);
  1296. v.Clear();
  1297. n = Sscanf(EA_CHAR32("0 1 2 3 4 5 x"), EA_CHAR32("%hhd%hhi%hho%hhu%hhx%hhX%hhn"), &v.int8_[0], &v.int8_[1], &v.int8_[2], &v.int8_[3], &v.int8_[4], &v.int8_[5], &v.int8_[6]);
  1298. EATEST_VERIFY(n == 6);
  1299. EATEST_VERIFY(v.int8_[0] == 0);
  1300. EATEST_VERIFY(v.int8_[1] == 1);
  1301. EATEST_VERIFY(v.int8_[2] == 2);
  1302. EATEST_VERIFY(v.int8_[3] == 3);
  1303. EATEST_VERIFY(v.int8_[4] == 4);
  1304. EATEST_VERIFY(v.int8_[5] == 5);
  1305. EATEST_VERIFY(v.int8_[6] == 11);
  1306. }
  1307. {
  1308. v.Clear();
  1309. n = Sscanf("0 1 2 3 4 5 z", "%ld%li%lo%lu%lx%lX%ln", &v.long_[0], &v.long_[1], &v.long_[2], &v.long_[3], &v.long_[4], &v.long_[5], &v.long_[6]);
  1310. EATEST_VERIFY(n == 6);
  1311. EATEST_VERIFY(v.long_[0] == 0);
  1312. EATEST_VERIFY(v.long_[1] == 1);
  1313. EATEST_VERIFY(v.long_[2] == 2);
  1314. EATEST_VERIFY(v.long_[3] == 3);
  1315. EATEST_VERIFY(v.long_[4] == 4);
  1316. EATEST_VERIFY(v.long_[5] == 5);
  1317. EATEST_VERIFY(v.long_[6] == 11);
  1318. v.Clear();
  1319. n = Sscanf(EA_CHAR16("0 1 2 3 4 5 z"), EA_CHAR16("%ld%li%lo%lu%lx%lX%ln"), &v.long_[0], &v.long_[1], &v.long_[2], &v.long_[3], &v.long_[4], &v.long_[5], &v.long_[6]);
  1320. EATEST_VERIFY(n == 6);
  1321. EATEST_VERIFY(v.long_[0] == 0);
  1322. EATEST_VERIFY(v.long_[1] == 1);
  1323. EATEST_VERIFY(v.long_[2] == 2);
  1324. EATEST_VERIFY(v.long_[3] == 3);
  1325. EATEST_VERIFY(v.long_[4] == 4);
  1326. EATEST_VERIFY(v.long_[5] == 5);
  1327. EATEST_VERIFY(v.long_[6] == 11);
  1328. v.Clear();
  1329. n = Sscanf(EA_CHAR32("0 1 2 3 4 5 z"), EA_CHAR32("%ld%li%lo%lu%lx%lX%ln"), &v.long_[0], &v.long_[1], &v.long_[2], &v.long_[3], &v.long_[4], &v.long_[5], &v.long_[6]);
  1330. EATEST_VERIFY(n == 6);
  1331. EATEST_VERIFY(v.long_[0] == 0);
  1332. EATEST_VERIFY(v.long_[1] == 1);
  1333. EATEST_VERIFY(v.long_[2] == 2);
  1334. EATEST_VERIFY(v.long_[3] == 3);
  1335. EATEST_VERIFY(v.long_[4] == 4);
  1336. EATEST_VERIFY(v.long_[5] == 5);
  1337. EATEST_VERIFY(v.long_[6] == 11);
  1338. }
  1339. {
  1340. v.Clear();
  1341. n = Sscanf("1e-1\t 1e-2\t 123.456\t 234.567\t 123.456\t 234.567", "%le %lE %lf %lF %lg %lG", &v.double_[0], &v.double_[1], &v.double_[2], &v.double_[3], &v.double_[4], &v.double_[5]);
  1342. EATEST_VERIFY(n == 6);
  1343. EATEST_VERIFY(v.double_[0] == 1e-1);
  1344. EATEST_VERIFY(v.double_[1] == 1e-2);
  1345. EATEST_VERIFY(DoubleEqual(v.double_[2], 123.456));
  1346. EATEST_VERIFY(DoubleEqual(v.double_[3], 234.567));
  1347. EATEST_VERIFY(DoubleEqual(v.double_[4], 123.456));
  1348. EATEST_VERIFY(DoubleEqual(v.double_[5], 234.567));
  1349. v.Clear();
  1350. n = Sscanf(EA_CHAR16("1e-1\t 1e-2\t 123.456\t 234.567\t 123.456\t 234.567"), EA_CHAR16("%le %lE %lf %lF %lg %lG"), &v.double_[0], &v.double_[1], &v.double_[2], &v.double_[3], &v.double_[4], &v.double_[5]);
  1351. EATEST_VERIFY(n == 6);
  1352. EATEST_VERIFY(v.double_[0] == 1e-1);
  1353. EATEST_VERIFY(v.double_[1] == 1e-2);
  1354. EATEST_VERIFY(DoubleEqual(v.double_[2], 123.456));
  1355. EATEST_VERIFY(DoubleEqual(v.double_[3], 234.567));
  1356. EATEST_VERIFY(DoubleEqual(v.double_[4], 123.456));
  1357. EATEST_VERIFY(DoubleEqual(v.double_[5], 234.567));
  1358. v.Clear();
  1359. n = Sscanf(EA_CHAR32("1e-1\t 1e-2\t 123.456\t 234.567\t 123.456\t 234.567"), EA_CHAR32("%le %lE %lf %lF %lg %lG"), &v.double_[0], &v.double_[1], &v.double_[2], &v.double_[3], &v.double_[4], &v.double_[5]);
  1360. EATEST_VERIFY(n == 6);
  1361. EATEST_VERIFY(v.double_[0] == 1e-1);
  1362. EATEST_VERIFY(v.double_[1] == 1e-2);
  1363. EATEST_VERIFY(DoubleEqual(v.double_[2], 123.456));
  1364. EATEST_VERIFY(DoubleEqual(v.double_[3], 234.567));
  1365. EATEST_VERIFY(DoubleEqual(v.double_[4], 123.456));
  1366. EATEST_VERIFY(DoubleEqual(v.double_[5], 234.567));
  1367. }
  1368. {
  1369. // Test conversion of UTF8 sequences to wide strings.
  1370. // This works under the Standard C library scanf only if it supports UTF8 and you set it to UTF8.
  1371. v.Clear();
  1372. n = Sscanf("a\xed\x9f\xbf_ \xed\x9f\xbf", "%I16s %I32s", v.str16_[0], v.str32_[0]);
  1373. EATEST_VERIFY(n == 2);
  1374. EATEST_VERIFY(v.str16_[0][0] == 'a');
  1375. EATEST_VERIFY(v.str16_[0][1] == 0xd7ff);
  1376. EATEST_VERIFY(v.str16_[0][2] == '_');
  1377. EATEST_VERIFY(v.str16_[0][3] == 0);
  1378. EATEST_VERIFY(v.str32_[0][0] == 0xd7ff);
  1379. EATEST_VERIFY(v.str32_[0][1] == 0);
  1380. v.Clear();
  1381. n = Sscanf(EA_CHAR16("a\x1234_ \x5678"), EA_CHAR16("%I16s %I32s"), v.str16_[0], v.str32_[0]);
  1382. EATEST_VERIFY(n == 2);
  1383. EATEST_VERIFY(v.str16_[0][0] == 'a');
  1384. EATEST_VERIFY(v.str16_[0][1] == 0x1234);
  1385. EATEST_VERIFY(v.str16_[0][2] == '_');
  1386. EATEST_VERIFY(v.str16_[0][3] == 0);
  1387. EATEST_VERIFY(v.str32_[0][0] == 0x5678);
  1388. EATEST_VERIFY(v.str32_[0][1] == 0);
  1389. v.Clear();
  1390. n = Sscanf(EA_CHAR32("a\x1234_ \x5678"), EA_CHAR32("%I16s %I32s"), v.str16_[0], v.str32_[0]);
  1391. EATEST_VERIFY(n == 2);
  1392. EATEST_VERIFY(v.str16_[0][0] == 'a');
  1393. EATEST_VERIFY(v.str16_[0][1] == 0x1234);
  1394. EATEST_VERIFY(v.str16_[0][2] == '_');
  1395. EATEST_VERIFY(v.str16_[0][3] == 0);
  1396. EATEST_VERIFY(v.str32_[0][0] == 0x5678);
  1397. EATEST_VERIFY(v.str32_[0][1] == 0);
  1398. }
  1399. { // Test %[]
  1400. v.Clear();
  1401. n = Sscanf("abcdefghij", "%h[ab]%l[cd]%I16[ef]%I32[gh]", v.str8_[0], v.strw_[0], v.str16_[0], v.str32_[0]);
  1402. EATEST_VERIFY(n == 4);
  1403. EATEST_VERIFY(Strcmp(v.str8_[0], "ab") == 0);
  1404. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("cd")) == 0);
  1405. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("ef")) == 0);
  1406. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("gh")) == 0);
  1407. v.Clear();
  1408. n = Sscanf(EA_CHAR16("abcdefghij"), EA_CHAR16("%h[ab]%l[cd]%I16[ef]%I32[gh]"), v.str8_[0], v.strw_[0], v.str16_[0], v.str32_[0]);
  1409. EATEST_VERIFY(n == 4);
  1410. EATEST_VERIFY(Strcmp(v.str8_[0], "ab") == 0);
  1411. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("cd")) == 0);
  1412. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("ef")) == 0);
  1413. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("gh")) == 0);
  1414. v.Clear();
  1415. n = Sscanf(EA_CHAR32("abcdefghij"), EA_CHAR32("%h[ab]%l[cd]%I16[ef]%I32[gh]"), v.str8_[0], v.strw_[0], v.str16_[0], v.str32_[0]);
  1416. EATEST_VERIFY(n == 4);
  1417. EATEST_VERIFY(Strcmp(v.str8_[0], "ab") == 0);
  1418. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("cd")) == 0);
  1419. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("ef")) == 0);
  1420. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("gh")) == 0);
  1421. }
  1422. { // Test %[^]
  1423. v.Clear();
  1424. n = Sscanf("abcdefghij", "%h[^cd]%l[^ef]%I16[^gh]%I32[^ij]", v.str8_[0], v.strw_[0], v.str16_[0], v.str32_[0]);
  1425. EATEST_VERIFY(Strcmp(v.str8_[0], "ab") == 0);
  1426. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("cd")) == 0);
  1427. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("ef")) == 0);
  1428. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("gh")) == 0);
  1429. v.Clear();
  1430. n = Sscanf(EA_CHAR16("abcdefghij"), EA_CHAR16("%h[^cd]%l[^ef]%I16[^gh]%I32[^ij]"), v.str8_[0], v.strw_[0], v.str16_[0], v.str32_[0]);
  1431. EATEST_VERIFY(Strcmp(v.str8_[0], "ab") == 0);
  1432. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("cd")) == 0);
  1433. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("ef")) == 0);
  1434. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("gh")) == 0);
  1435. v.Clear();
  1436. n = Sscanf(EA_CHAR32("abcdefghij"), EA_CHAR32("%h[^cd]%l[^ef]%I16[^gh]%I32[^ij]"), v.str8_[0], v.strw_[0], v.str16_[0], v.str32_[0]);
  1437. EATEST_VERIFY(Strcmp(v.str8_[0], "ab") == 0);
  1438. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("cd")) == 0);
  1439. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("ef")) == 0);
  1440. EATEST_VERIFY(Strcmp(v.str32_[0], EA_CHAR32("gh")) == 0);
  1441. }
  1442. {
  1443. // Test conversion of UTF8 sequences to wide chars.
  1444. // This works under the Standard C library only if you set it to UTF8.
  1445. // As of this writing, we don't have support for this in our Scanf, and it is a 'to do' item.
  1446. //v.Clear();
  1447. //n = Sscanf("\xed\x9f\xbf\xed\x9f\xbf", "%I16c %I32c", &v.char16_[0], &v.char32_[0]);
  1448. //EATEST_VERIFY(n == 2);
  1449. //EATEST_VERIFY(v.char16_[0] == 0xd7ff);
  1450. //EATEST_VERIFY(v.char32_[0] == 0xd7ff);
  1451. //v.Clear();
  1452. //n = Sscanf(EA_CHAR16("\xed\x9f\xbf\xed\x9f\xbf"), EA_CHAR16("%I16c %I32c"), &v.char16_[0], &v.char32_[0]);
  1453. //EATEST_VERIFY(n == 2);
  1454. //EATEST_VERIFY(v.char16_[0] == 0xd7ff);
  1455. //EATEST_VERIFY(v.char32_[0] == 0xd7ff);
  1456. //v.Clear();
  1457. //n = Sscanf(EA_CHAR32("\xed\x9f\xbf\xed\x9f\xbf"), EA_CHAR32("%I16c %I32c"), &v.char16_[0], &v.char32_[0]);
  1458. //EATEST_VERIFY(n == 2);
  1459. //EATEST_VERIFY(v.char16_[0] == 0xd7ff);
  1460. //EATEST_VERIFY(v.char32_[0] == 0xd7ff);
  1461. }
  1462. {
  1463. v.Clear();
  1464. n = Sscanf("-0 -1 012 3 10 20", "%lld%lli%llo%llu%llx%llX%lln", &v.longlong_[0], &v.longlong_[1], &v.longlong_[2], &v.longlong_[3], &v.longlong_[4], &v.longlong_[5], &v.longlong_[6]);
  1465. EATEST_VERIFY(n == 6);
  1466. EATEST_VERIFY(v.longlong_[0] == -0);
  1467. EATEST_VERIFY(v.longlong_[1] == -1);
  1468. EATEST_VERIFY(v.longlong_[2] == 012);
  1469. EATEST_VERIFY(v.longlong_[3] == 3);
  1470. EATEST_VERIFY(v.longlong_[4] == 0x10);
  1471. EATEST_VERIFY(v.longlong_[5] == 0x20);
  1472. EATEST_VERIFY(v.longlong_[6] == 17);
  1473. v.Clear();
  1474. n = Sscanf(EA_CHAR16("-0 -1 012 3 10 20"), EA_CHAR16("%lld%lli%llo%llu%llx%llX%lln"), &v.longlong_[0], &v.longlong_[1], &v.longlong_[2], &v.longlong_[3], &v.longlong_[4], &v.longlong_[5], &v.longlong_[6]);
  1475. EATEST_VERIFY(n == 6);
  1476. EATEST_VERIFY(v.longlong_[0] == -0);
  1477. EATEST_VERIFY(v.longlong_[1] == -1);
  1478. EATEST_VERIFY(v.longlong_[2] == 012);
  1479. EATEST_VERIFY(v.longlong_[3] == 3);
  1480. EATEST_VERIFY(v.longlong_[4] == 0x10);
  1481. EATEST_VERIFY(v.longlong_[5] == 0x20);
  1482. EATEST_VERIFY(v.longlong_[6] == 17);
  1483. v.Clear();
  1484. n = Sscanf(EA_CHAR32("-0 -1 012 3 10 20"), EA_CHAR32("%lld%lli%llo%llu%llx%llX%lln"), &v.longlong_[0], &v.longlong_[1], &v.longlong_[2], &v.longlong_[3], &v.longlong_[4], &v.longlong_[5], &v.longlong_[6]);
  1485. EATEST_VERIFY(n == 6);
  1486. EATEST_VERIFY(v.longlong_[0] == -0);
  1487. EATEST_VERIFY(v.longlong_[1] == -1);
  1488. EATEST_VERIFY(v.longlong_[2] == 012);
  1489. EATEST_VERIFY(v.longlong_[3] == 3);
  1490. EATEST_VERIFY(v.longlong_[4] == 0x10);
  1491. EATEST_VERIFY(v.longlong_[5] == 0x20);
  1492. EATEST_VERIFY(v.longlong_[6] == 17);
  1493. }
  1494. {
  1495. v.Clear();
  1496. v.int_[0] = 0xdd;
  1497. n = Sscanf("", "%d", &v.int_[0]);
  1498. EATEST_VERIFY(n == 0);
  1499. EATEST_VERIFY(v.int_[0] == 0xdd);
  1500. v.Clear();
  1501. v.int_[0] = 0xdd;
  1502. n = Sscanf(EA_CHAR16(""), EA_CHAR16("%d"), &v.int_[0]);
  1503. EATEST_VERIFY(n == 0);
  1504. EATEST_VERIFY(v.int_[0] == 0xdd);
  1505. v.Clear();
  1506. v.int_[0] = 0xdd;
  1507. n = Sscanf(EA_CHAR32(""), EA_CHAR32("%d"), &v.int_[0]);
  1508. EATEST_VERIFY(n == 0);
  1509. EATEST_VERIFY(v.int_[0] == 0xdd);
  1510. }
  1511. {
  1512. v.Clear();
  1513. n = Sscanf("0x519", "%x", &v.int_[0]);
  1514. EATEST_VERIFY(n == 1);
  1515. EATEST_VERIFY(v.int_[0] == 0x519);
  1516. v.Clear();
  1517. n = Sscanf(EA_CHAR16("0x519"), EA_CHAR16("%x"), &v.int_[0]);
  1518. EATEST_VERIFY(n == 1);
  1519. EATEST_VERIFY(v.int_[0] == 0x519);
  1520. v.Clear();
  1521. n = Sscanf(EA_CHAR32("0x519"), EA_CHAR32("%x"), &v.int_[0]);
  1522. EATEST_VERIFY(n == 1);
  1523. EATEST_VERIFY(v.int_[0] == 0x519);
  1524. }
  1525. {
  1526. v.Clear();
  1527. n = Sscanf("0x51ag", "%x", &v.int_[0]);
  1528. EATEST_VERIFY(n == 1);
  1529. EATEST_VERIFY(v.int_[0] == 0x51a);
  1530. v.Clear();
  1531. n = Sscanf(EA_CHAR16("0x51ag"), EA_CHAR16("%x"), &v.int_[0]);
  1532. EATEST_VERIFY(n == 1);
  1533. EATEST_VERIFY(v.int_[0] == 0x51a);
  1534. v.Clear();
  1535. n = Sscanf(EA_CHAR32("0x51ag"), EA_CHAR32("%x"), &v.int_[0]);
  1536. EATEST_VERIFY(n == 1);
  1537. EATEST_VERIFY(v.int_[0] == 0x51a);
  1538. }
  1539. {
  1540. v.Clear();
  1541. n = Sscanf("-1", "%x", &v.int_[0]);
  1542. EATEST_VERIFY(n == 1);
  1543. EATEST_VERIFY(v.int_[0] == -1);
  1544. v.Clear();
  1545. n = Sscanf(EA_CHAR16("-1"), EA_CHAR16("%x"), &v.int_[0]);
  1546. EATEST_VERIFY(n == 1);
  1547. EATEST_VERIFY(v.int_[0] == -1);
  1548. v.Clear();
  1549. n = Sscanf(EA_CHAR32("-1"), EA_CHAR32("%x"), &v.int_[0]);
  1550. EATEST_VERIFY(n == 1);
  1551. EATEST_VERIFY(v.int_[0] == -1);
  1552. }
  1553. {
  1554. v.Clear();
  1555. n = Sscanf("\"%12@", "\"%%%d%%", &v.int_[0]);
  1556. EATEST_VERIFY(n == 1);
  1557. EATEST_VERIFY(v.int_[0] == 12);
  1558. v.Clear();
  1559. n = Sscanf(EA_CHAR16("\"%12@"), EA_CHAR16("\"%%%d%%"), &v.int_[0]);
  1560. EATEST_VERIFY(n == 1);
  1561. EATEST_VERIFY(v.int_[0] == 12);
  1562. v.Clear();
  1563. n = Sscanf(EA_CHAR32("\"%12@"), EA_CHAR32("\"%%%d%%"), &v.int_[0]);
  1564. EATEST_VERIFY(n == 1);
  1565. EATEST_VERIFY(v.int_[0] == 12);
  1566. }
  1567. {
  1568. v.Clear();
  1569. n = Sscanf("1.1\t2.2", "%f\t%f", &v.float_[0], &v.float_[1]);
  1570. EATEST_VERIFY(n == 2);
  1571. EATEST_VERIFY(FloatEqual(v.float_[0], 1.1f));
  1572. EATEST_VERIFY(FloatEqual(v.float_[1], 2.2f));
  1573. v.Clear();
  1574. n = Sscanf(EA_CHAR16("1.1\t2.2"), EA_CHAR16("%f\t%f"), &v.float_[0], &v.float_[1]);
  1575. EATEST_VERIFY(n == 2);
  1576. EATEST_VERIFY(FloatEqual(v.float_[0], 1.1f));
  1577. EATEST_VERIFY(FloatEqual(v.float_[1], 2.2f));
  1578. v.Clear();
  1579. n = Sscanf(EA_CHAR32("1.1\t2.2"), EA_CHAR32("%f\t%f"), &v.float_[0], &v.float_[1]);
  1580. EATEST_VERIFY(n == 2);
  1581. EATEST_VERIFY(FloatEqual(v.float_[0], 1.1f));
  1582. EATEST_VERIFY(FloatEqual(v.float_[1], 2.2f));
  1583. }
  1584. {
  1585. v.Clear(); // Skip one char then read a string that ends with \n (don't write the \n).
  1586. n = Sscanf(" Hello World\n", "%*c%[^\n]", v.str8_[0]);
  1587. EATEST_VERIFY(n == 1);
  1588. EATEST_VERIFY(Strcmp(v.str8_[0], " Hello World") == 0);
  1589. v.Clear();
  1590. #if EASCANF_MS_STYLE_S_FORMAT
  1591. n = Sscanf(EA_CHAR16(" Hello World\n"), EA_CHAR16("%*c%[^\n]"), v.strw_[0]);
  1592. EATEST_VERIFY(n == 1);
  1593. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR(" Hello World")) == 0);
  1594. #else
  1595. n = Sscanf(EA_CHAR16(" Hello World\n"), EA_CHAR16("%*c%[^\n]"), v.str8_[0]);
  1596. EATEST_VERIFY(n == 1);
  1597. EATEST_VERIFY(Strcmp(v.str8_[0], " Hello World") == 0);
  1598. #endif
  1599. #if EASCANF_MS_STYLE_S_FORMAT
  1600. n = Sscanf(EA_CHAR32(" Hello World\n"), EA_CHAR32("%*c%[^\n]"), v.strw_[0]);
  1601. EATEST_VERIFY(n == 1);
  1602. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR(" Hello World")) == 0);
  1603. #else
  1604. n = Sscanf(EA_CHAR32(" Hello World\n"), EA_CHAR32("%*c%[^\n]"), v.str8_[0]);
  1605. EATEST_VERIFY(n == 1);
  1606. EATEST_VERIFY(Strcmp(v.str8_[0], " Hello World") == 0);
  1607. #endif
  1608. }
  1609. {
  1610. v.Clear(); // Skip all the chars in the [] range, then read one char.
  1611. n = Sscanf("abcefgdh", "%*[a-cb-g]%c", &v.char8_[0]);
  1612. EATEST_VERIFY(n == 1);
  1613. EATEST_VERIFY(v.char8_[0] == 'h');
  1614. v.Clear();
  1615. n = Sscanf(EA_CHAR16("abcefgdh"), EA_CHAR16("%*[a-cb-g]%I16c"), &v.char16_[0]);
  1616. EATEST_VERIFY(n == 1);
  1617. EATEST_VERIFY(v.char16_[0] == 'h');
  1618. v.Clear();
  1619. n = Sscanf(EA_CHAR32("abcefgdh"), EA_CHAR32("%*[a-cb-g]%I32c"), &v.char32_[0]);
  1620. EATEST_VERIFY(n == 1);
  1621. EATEST_VERIFY(v.char32_[0] == 'h');
  1622. }
  1623. {
  1624. v.Clear(); // Skip all the chars in the [] range (exercizing d-d), then read one char.
  1625. n = Sscanf("abcefgdh", "%*[a-cd-de-g]%c", &v.char8_[0]);
  1626. EATEST_VERIFY(n == 1);
  1627. EATEST_VERIFY(v.char8_[0] == 'h');
  1628. v.Clear();
  1629. n = Sscanf(EA_CHAR16("abcefgdh"), EA_CHAR16("%*[a-cd-de-g]%I16c"), &v.char16_[0]);
  1630. EATEST_VERIFY(n == 1);
  1631. EATEST_VERIFY(v.char16_[0] == 'h');
  1632. v.Clear();
  1633. n = Sscanf(EA_CHAR32("abcefgdh"), EA_CHAR32("%*[a-cd-de-g]%I32c"), &v.char32_[0]);
  1634. EATEST_VERIFY(n == 1);
  1635. EATEST_VERIFY(v.char32_[0] == 'h');
  1636. }
  1637. {
  1638. v.Clear();
  1639. n = Sscanf("3:5:7", "%d%n:%n", &v.int_[0], &v.int_[1], &v.int_[2]);
  1640. EATEST_VERIFY(n == 1);
  1641. EATEST_VERIFY(v.int_[0] == 3);
  1642. EATEST_VERIFY(v.int_[1] == 1);
  1643. EATEST_VERIFY(v.int_[2] == 2);
  1644. v.Clear();
  1645. n = Sscanf(EA_CHAR16("3:5:7"), EA_CHAR16("%d%n:%n"), &v.int_[0], &v.int_[1], &v.int_[2]);
  1646. EATEST_VERIFY(n == 1);
  1647. EATEST_VERIFY(v.int_[0] == 3);
  1648. EATEST_VERIFY(v.int_[1] == 1);
  1649. EATEST_VERIFY(v.int_[2] == 2);
  1650. v.Clear();
  1651. n = Sscanf(EA_CHAR32("3:5:7"), EA_CHAR32("%d%n:%n"), &v.int_[0], &v.int_[1], &v.int_[2]);
  1652. EATEST_VERIFY(n == 1);
  1653. EATEST_VERIFY(v.int_[0] == 3);
  1654. EATEST_VERIFY(v.int_[1] == 1);
  1655. EATEST_VERIFY(v.int_[2] == 2);
  1656. }
  1657. {
  1658. v.Clear(); // Skip a char, then report how many chars were read so far.
  1659. n = Sscanf("5:7", "%*c%n", &v.int_[0]);
  1660. EATEST_VERIFY(n == 0);
  1661. EATEST_VERIFY(v.int_[0] == 1);
  1662. v.Clear();
  1663. n = Sscanf(EA_CHAR16("5:7"), EA_CHAR16("%*c%n"), &v.int_[0]);
  1664. EATEST_VERIFY(n == 0);
  1665. EATEST_VERIFY(v.int_[0] == 1);
  1666. v.Clear();
  1667. n = Sscanf(EA_CHAR32("5:7"), EA_CHAR32("%*c%n"), &v.int_[0]);
  1668. EATEST_VERIFY(n == 0);
  1669. EATEST_VERIFY(v.int_[0] == 1);
  1670. }
  1671. {
  1672. v.Clear();
  1673. n = Sscanf("-1", "%i", &v.int_[0]);
  1674. EATEST_VERIFY(n == 1);
  1675. EATEST_VERIFY(v.int_[0] == -1);
  1676. v.Clear();
  1677. n = Sscanf(EA_CHAR16("-1"), EA_CHAR16("%i"), &v.int_[0]);
  1678. EATEST_VERIFY(n == 1);
  1679. EATEST_VERIFY(v.int_[0] == -1);
  1680. v.Clear();
  1681. n = Sscanf(EA_CHAR32("-1"), EA_CHAR32("%i"), &v.int_[0]);
  1682. EATEST_VERIFY(n == 1);
  1683. EATEST_VERIFY(v.int_[0] == -1);
  1684. }
  1685. {
  1686. v.Clear();
  1687. n = Sscanf("0xff", "%i", &v.int_[0]); // %i differs from %d in that it acts like strtol with a base of 0 (auto-detect) as opposed to a base of 10.
  1688. EATEST_VERIFY(n == 1);
  1689. EATEST_VERIFY(v.int_[0] == 255);
  1690. v.Clear();
  1691. n = Sscanf(EA_CHAR16("0xff"), EA_CHAR16("%i"), &v.int_[0]); // %i differs from %d in that it acts like strtol with a base of 0 (auto-detect) as opposed to a base of 10.
  1692. EATEST_VERIFY(n == 1);
  1693. EATEST_VERIFY(v.int_[0] == 255);
  1694. v.Clear();
  1695. n = Sscanf(EA_CHAR32("0xff"), EA_CHAR32("%i"), &v.int_[0]); // %i differs from %d in that it acts like strtol with a base of 0 (auto-detect) as opposed to a base of 10.
  1696. EATEST_VERIFY(n == 1);
  1697. EATEST_VERIFY(v.int_[0] == 255);
  1698. }
  1699. {
  1700. v.Clear();
  1701. n = Sscanf("017", "%i", &v.int_[0]);
  1702. EATEST_VERIFY(n == 1);
  1703. EATEST_VERIFY(v.int_[0] == 017); // See C99 7.20.1.4 p3 and p5, 6.4.4.1
  1704. v.Clear();
  1705. n = Sscanf(EA_CHAR16("017"), EA_CHAR16("%i"), &v.int_[0]);
  1706. EATEST_VERIFY(n == 1);
  1707. EATEST_VERIFY(v.int_[0] == 017); // See C99 7.20.1.4 p3 and p5, 6.4.4.1
  1708. v.Clear();
  1709. n = Sscanf(EA_CHAR32("017"), EA_CHAR32("%i"), &v.int_[0]);
  1710. EATEST_VERIFY(n == 1);
  1711. EATEST_VERIFY(v.int_[0] == 017); // See C99 7.20.1.4 p3 and p5, 6.4.4.1
  1712. }
  1713. {
  1714. v.Clear();
  1715. n = Sscanf("-1", "%d", &v.int_[0]);
  1716. EATEST_VERIFY(n == 1);
  1717. EATEST_VERIFY(v.int_[0] == -1);
  1718. v.Clear();
  1719. n = Sscanf(EA_CHAR16("-1"), EA_CHAR16("%d"), &v.int_[0]);
  1720. EATEST_VERIFY(n == 1);
  1721. EATEST_VERIFY(v.int_[0] == -1);
  1722. v.Clear();
  1723. n = Sscanf(EA_CHAR32("-1"), EA_CHAR32("%d"), &v.int_[0]);
  1724. EATEST_VERIFY(n == 1);
  1725. EATEST_VERIFY(v.int_[0] == -1);
  1726. }
  1727. {
  1728. v.Clear();
  1729. n = Sscanf("0xff", "%d", &v.int_[0]);
  1730. EATEST_VERIFY(n == 1);
  1731. EATEST_VERIFY(v.int_[0] == 0); // %d should not treat 0x sequences as hexidecimal.
  1732. v.Clear();
  1733. n = Sscanf(EA_CHAR16("0xff"), EA_CHAR16("%d"), &v.int_[0]);
  1734. EATEST_VERIFY(n == 1);
  1735. EATEST_VERIFY(v.int_[0] == 0); // %d should not treat 0x sequences as hexidecimal.
  1736. v.Clear();
  1737. n = Sscanf(EA_CHAR32("0xff"), EA_CHAR32("%d"), &v.int_[0]);
  1738. EATEST_VERIFY(n == 1);
  1739. EATEST_VERIFY(v.int_[0] == 0); // %d should not treat 0x sequences as hexidecimal.
  1740. }
  1741. {
  1742. v.Clear();
  1743. n = Sscanf("-1", "%o", &v.int_[0]);
  1744. EATEST_VERIFY(n == 1);
  1745. EATEST_VERIFY(v.int_[0] == -1);
  1746. v.Clear();
  1747. n = Sscanf(EA_CHAR16("-1"), EA_CHAR16("%o"), &v.int_[0]);
  1748. EATEST_VERIFY(n == 1);
  1749. EATEST_VERIFY(v.int_[0] == -1);
  1750. v.Clear();
  1751. n = Sscanf(EA_CHAR32("-1"), EA_CHAR32("%o"), &v.int_[0]);
  1752. EATEST_VERIFY(n == 1);
  1753. EATEST_VERIFY(v.int_[0] == -1);
  1754. }
  1755. {
  1756. v.Clear();
  1757. n = Sscanf("-1", "%u", &v.int_[0]);
  1758. EATEST_VERIFY(n == 1);
  1759. EATEST_VERIFY(v.int_[0] == -1);
  1760. v.Clear();
  1761. n = Sscanf(EA_CHAR16("-1"), EA_CHAR16("%u"), &v.int_[0]);
  1762. EATEST_VERIFY(n == 1);
  1763. EATEST_VERIFY(v.int_[0] == -1);
  1764. v.Clear();
  1765. n = Sscanf(EA_CHAR32("-1"), EA_CHAR32("%u"), &v.int_[0]);
  1766. EATEST_VERIFY(n == 1);
  1767. EATEST_VERIFY(v.int_[0] == -1);
  1768. }
  1769. {
  1770. v.Clear();
  1771. n = Sscanf("xyzwa", "%hc%lc%I16c%I32c", &v.char8_[0], &v.wchar_[0], &v.char16_[0], &v.char32_[0]);
  1772. EATEST_VERIFY(n == 4);
  1773. EATEST_VERIFY((v.char8_[0] == 'x') && (v.wchar_[0] == 'y') && (v.char16_[0] == 'z') && (v.char32_[0] == 'w'));
  1774. v.Clear();
  1775. n = Sscanf(EA_CHAR16("xyzwa"), EA_CHAR16("%hc%lc%I16c%I32c"), &v.char8_[0], &v.wchar_[0], &v.char16_[0], &v.char32_[0]);
  1776. EATEST_VERIFY(n == 4);
  1777. EATEST_VERIFY((v.char8_[0] == 'x') && (v.wchar_[0] == 'y') && (v.char16_[0] == 'z') && (v.char32_[0] == 'w'));
  1778. v.Clear();
  1779. n = Sscanf(EA_CHAR16("xyzwa"), EA_CHAR16("%hc%lc%I16c%I32c"), &v.char8_[0], &v.wchar_[0], &v.char16_[0], &v.char32_[0]);
  1780. EATEST_VERIFY(n == 4);
  1781. EATEST_VERIFY((v.char8_[0] == 'x') && (v.wchar_[0] == 'y') && (v.char16_[0] == 'z') && (v.char32_[0] == 'w'));
  1782. }
  1783. {
  1784. v.Clear();
  1785. n = Sscanf(" xyz", "%c", &v.char8_[0]);
  1786. EATEST_VERIFY(n == 1);
  1787. EATEST_VERIFY(v.char8_[0] == ' ');
  1788. v.Clear();
  1789. n = Sscanf(EA_CHAR16(" xyz"), EA_CHAR16("%I16c"), &v.char16_[0]);
  1790. EATEST_VERIFY(n == 1);
  1791. EATEST_VERIFY(v.char16_[0] == ' ');
  1792. v.Clear();
  1793. n = Sscanf(EA_CHAR32(" xyz"), EA_CHAR32("%I32c"), &v.char32_[0]);
  1794. EATEST_VERIFY(n == 1);
  1795. EATEST_VERIFY(v.char32_[0] == ' ');
  1796. }
  1797. {
  1798. v.Clear();
  1799. v.char8_[0] = (char)(uint8_t)0xdd;
  1800. n = Sscanf("10:11", "%d:%d%c", &v.int_[0], &v.int_[1], &v.char8_[0]);
  1801. EATEST_VERIFY(n == 2);
  1802. EATEST_VERIFY(v.int_[0] == 10);
  1803. EATEST_VERIFY(v.int_[1] == 11);
  1804. EATEST_VERIFY(v.char8_[0] == (char)(uint8_t)0xdd);
  1805. v.Clear();
  1806. #if EASCANF_MS_STYLE_S_FORMAT
  1807. v.wchar_[0] = 0xdd;
  1808. n = Sscanf(EA_CHAR16("10:11"), EA_CHAR16("%d:%d%c"), &v.int_[0], &v.int_[1], &v.wchar_[0]);
  1809. EATEST_VERIFY(v.wchar_[0] == 0xdd);
  1810. #else
  1811. v.char8_[0] = (char)(uint8_t)0xdd;
  1812. n = Sscanf(EA_CHAR16("10:11"), EA_CHAR16("%d:%d%c"), &v.int_[0], &v.int_[1], &v.char8_[0]);
  1813. EATEST_VERIFY(v.char8_[0] == (char)(uint8_t)0xdd);
  1814. #endif
  1815. EATEST_VERIFY(n == 2);
  1816. EATEST_VERIFY(v.int_[0] == 10);
  1817. EATEST_VERIFY(v.int_[1] == 11);
  1818. v.Clear();
  1819. #if EASCANF_MS_STYLE_S_FORMAT
  1820. v.wchar_[0] = 0xdd;
  1821. n = Sscanf(EA_CHAR32("10:11"), EA_CHAR32("%d:%d%c"), &v.int_[0], &v.int_[1], &v.wchar_[0]);
  1822. EATEST_VERIFY(v.wchar_[0] == 0xdd);
  1823. #else
  1824. v.char8_[0] = (char)(uint8_t)0xdd;
  1825. n = Sscanf(EA_CHAR32("10:11"), EA_CHAR32("%d:%d%c"), &v.int_[0], &v.int_[1], &v.char8_[0]);
  1826. EATEST_VERIFY(v.char8_[0] == (char)(uint8_t)0xdd);
  1827. #endif
  1828. EATEST_VERIFY(n == 2);
  1829. EATEST_VERIFY(v.int_[0] == 10);
  1830. EATEST_VERIFY(v.int_[1] == 11);
  1831. }
  1832. {
  1833. v.Clear();
  1834. n = Sscanf("abc def", "%s %n%s", v.str8_[0], &v.int_[0], v.str8_[1]);
  1835. EATEST_VERIFY(n == 2);
  1836. EATEST_VERIFY(Strcmp(v.str8_[0], "abc") == 0);
  1837. EATEST_VERIFY(v.int_[0] == 6);
  1838. EATEST_VERIFY(Strcmp(v.str8_[1], "def") == 0);
  1839. v.Clear();
  1840. n = Sscanf(EA_CHAR16("abc def"), EA_CHAR16("%I16s %n%I32s"), v.str16_[0], &v.int_[0], v.str32_[1]);
  1841. EATEST_VERIFY(n == 2);
  1842. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("abc")) == 0);
  1843. EATEST_VERIFY(v.int_[0] == 6);
  1844. EATEST_VERIFY(Strcmp(v.str32_[1], EA_CHAR32("def")) == 0);
  1845. v.Clear();
  1846. n = Sscanf(EA_CHAR32("abc def"), EA_CHAR32("%I16s %n%I32s"), v.str16_[0], &v.int_[0], v.str32_[1]);
  1847. EATEST_VERIFY(n == 2);
  1848. EATEST_VERIFY(Strcmp(v.str16_[0], EA_CHAR16("abc")) == 0);
  1849. EATEST_VERIFY(v.int_[0] == 6);
  1850. EATEST_VERIFY(Strcmp(v.str32_[1], EA_CHAR32("def")) == 0);
  1851. }
  1852. {
  1853. v.Clear();
  1854. n = Sscanf("1:23", "%d:%d%n", &v.int_[0], &v.int_[1], &v.int_[2]);
  1855. EATEST_VERIFY(n == 2);
  1856. EATEST_VERIFY(v.int_[0] == 1);
  1857. EATEST_VERIFY(v.int_[1] == 23);
  1858. EATEST_VERIFY(v.int_[2] == 4);
  1859. v.Clear();
  1860. n = Sscanf(EA_CHAR16("1:23"), EA_CHAR16("%d:%d%n"), &v.int_[0], &v.int_[1], &v.int_[2]);
  1861. EATEST_VERIFY(n == 2);
  1862. EATEST_VERIFY(v.int_[0] == 1);
  1863. EATEST_VERIFY(v.int_[1] == 23);
  1864. EATEST_VERIFY(v.int_[2] == 4);
  1865. v.Clear();
  1866. n = Sscanf(EA_CHAR32("1:23"), EA_CHAR32("%d:%d%n"), &v.int_[0], &v.int_[1], &v.int_[2]);
  1867. EATEST_VERIFY(n == 2);
  1868. EATEST_VERIFY(v.int_[0] == 1);
  1869. EATEST_VERIFY(v.int_[1] == 23);
  1870. EATEST_VERIFY(v.int_[2] == 4);
  1871. }
  1872. {
  1873. v.Clear();
  1874. n = Sscanf("_", "_%n%hn%hhn%ln%lln%I8n%I16n%I32n%I64n", &v.int_[0], &v.short_[0], &v.char_[0], &v.long_[0], &v.longlong_[0], &v.int8_[0], &v.int16_[0], &v.int32_[0], &v.int64_[0]);
  1875. EATEST_VERIFY(n == 0);
  1876. EATEST_VERIFY(v.int_[0] == 1);
  1877. EATEST_VERIFY(v.short_[0] == 1);
  1878. EATEST_VERIFY(v.char_[0] == 1);
  1879. EATEST_VERIFY(v.long_[0] == 1);
  1880. EATEST_VERIFY(v.longlong_[0] == 1);
  1881. EATEST_VERIFY(v.int8_[0] == 1);
  1882. EATEST_VERIFY(v.int32_[0] == 1);
  1883. EATEST_VERIFY(v.int64_[0] == 1);
  1884. v.Clear();
  1885. n = Sscanf(EA_CHAR16("_"), EA_CHAR16("_%n%hn%hhn%ln%lln%I8n%I16n%I32n%I64n"), &v.int_[0], &v.short_[0], &v.char_[0], &v.long_[0], &v.longlong_[0], &v.int8_[0], &v.int16_[0], &v.int32_[0], &v.int64_[0]);
  1886. EATEST_VERIFY(n == 0);
  1887. EATEST_VERIFY(v.int_[0] == 1);
  1888. EATEST_VERIFY(v.short_[0] == 1);
  1889. EATEST_VERIFY(v.char_[0] == 1);
  1890. EATEST_VERIFY(v.long_[0] == 1);
  1891. EATEST_VERIFY(v.longlong_[0] == 1);
  1892. EATEST_VERIFY(v.int8_[0] == 1);
  1893. EATEST_VERIFY(v.int32_[0] == 1);
  1894. EATEST_VERIFY(v.int64_[0] == 1);
  1895. v.Clear();
  1896. n = Sscanf(EA_CHAR32("_"), EA_CHAR32("_%n%hn%hhn%ln%lln%I8n%I32n%I32n%I64n"), &v.int_[0], &v.short_[0], &v.char_[0], &v.long_[0], &v.longlong_[0], &v.int8_[0], &v.int32_[0], &v.int32_[0], &v.int64_[0]);
  1897. EATEST_VERIFY(n == 0);
  1898. EATEST_VERIFY(v.int_[0] == 1);
  1899. EATEST_VERIFY(v.short_[0] == 1);
  1900. EATEST_VERIFY(v.char_[0] == 1);
  1901. EATEST_VERIFY(v.long_[0] == 1);
  1902. EATEST_VERIFY(v.longlong_[0] == 1);
  1903. EATEST_VERIFY(v.int8_[0] == 1);
  1904. EATEST_VERIFY(v.int32_[0] == 1);
  1905. EATEST_VERIFY(v.int64_[0] == 1);
  1906. }
  1907. }
  1908. {
  1909. // Bug report regression.
  1910. // What was special about this case was that it represented an exponent of
  1911. // the power -10 (wouldn't happen with -9 or -11), and the code was mistakenly
  1912. // doing a test for >10 where it needed to do >=10.
  1913. float a, b, c;
  1914. int count = EA::StdC::Sscanf("0.1797734499 0.1797734499 0.1797734499", "%f %f %f", &a, &b, &c);
  1915. EATEST_VERIFY((count == 3) && FloatEqual(a, 1.79773e-01f));
  1916. }
  1917. {
  1918. float a;
  1919. EA::StdC::Sscanf( ".750", "%f", &a);
  1920. EATEST_VERIFY(FloatEqual(a, .750f));
  1921. EA::StdC::Sscanf(EA_CHAR16(".750"), EA_CHAR16("%f"), &a);
  1922. EATEST_VERIFY(FloatEqual(a, .750f));
  1923. }
  1924. {
  1925. // Regresssion for Coverity report that mSigStr[-1] could occur (out of bounds). Actually, mSigStr[-1] was never read though a pointer to it was created.
  1926. float a = 1.f;
  1927. int count = EA::StdC::Sscanf(".", "%f", &a); // This input caused mSigStr to be negatively indexed.
  1928. EATEST_VERIFY((count == 0) && (a == 1.f)); // VC++ sscanf returns a count of -1 (EOF), whereas glibc sscanf returns 0. The C11 Standard, section 7.21.6.2, example 3, seems to indicate that 0 is the proper return value.
  1929. }
  1930. return nErrorCount;
  1931. }
  1932. ///////////////////////////////////////////////////////////////////////////////
  1933. // TestScanfUnusual
  1934. //
  1935. static int TestScanfUnusual()
  1936. {
  1937. using namespace EA::StdC;
  1938. int nErrorCount = 0;
  1939. { // Test unusual things
  1940. Values v;
  1941. int n;
  1942. {
  1943. n = TestCRTVsscanf("", "");
  1944. EATEST_VERIFY(n == 0);
  1945. n = TestCRTVsscanf(EA_CHAR16(""), EA_CHAR16(""));
  1946. EATEST_VERIFY(n == 0);
  1947. n = TestCRTVsscanf(EA_CHAR32(""), EA_CHAR32(""));
  1948. EATEST_VERIFY(n == 0);
  1949. }
  1950. {
  1951. // testing to see if the 'j' specifier
  1952. // The test below is OK for both 32 and 64 bit pointer platforms.
  1953. v.Clear();
  1954. n = Sscanf("1111", "%jx", &v.uintmax_[0]);
  1955. EATEST_VERIFY(n == 1);
  1956. EATEST_VERIFY(v.uintmax_[0] == 0x1111);
  1957. }
  1958. {
  1959. // testing to see if the 'z' specifier
  1960. // The test below is OK for both 32 and 64 bit pointer platforms.
  1961. v.Clear();
  1962. n = Sscanf("1111", "%zx", &v.size_[0]);
  1963. EATEST_VERIFY(n == 1);
  1964. EATEST_VERIFY(v.size_[0] == 0x1111);
  1965. }
  1966. {
  1967. // testing to see if the 't' specifier
  1968. // The test below is OK for both 32 and 64 bit pointer platforms.
  1969. v.Clear();
  1970. n = Sscanf("1111", "%tx", &v.ptrdiff_[0]);
  1971. EATEST_VERIFY(n == 1);
  1972. EATEST_VERIFY(v.ptrdiff_[0] == 0x1111);
  1973. }
  1974. { // We should ignore the 'l' in front of 'p'
  1975. // The test below is OK for both 32 and 64 bit pointer platforms.
  1976. v.Clear();
  1977. n = Sscanf("0xffffffff", "%lp", &v.voidptr_[0]);
  1978. EATEST_VERIFY(n == 1);
  1979. EATEST_VERIFY((uintptr_t)v.voidptr_[0] == 0xffffffff);
  1980. v.Clear();
  1981. n = Sscanf(EA_CHAR16("0xffffffff"), EA_CHAR16("%lp"), &v.voidptr_[0]);
  1982. EATEST_VERIFY(n == 1);
  1983. EATEST_VERIFY((uintptr_t)v.voidptr_[0] == 0xffffffff);
  1984. v.Clear();
  1985. n = Sscanf(EA_CHAR32("0xffffffff"), EA_CHAR32("%lp"), &v.voidptr_[0]);
  1986. EATEST_VERIFY(n == 1);
  1987. EATEST_VERIFY((uintptr_t)v.voidptr_[0] == 0xffffffff);
  1988. }
  1989. { // We should ignore the 'h' in front of 'p'
  1990. // The test below is OK for both 32 and 64 bit pointer platforms.
  1991. v.Clear();
  1992. n = Sscanf("0xffffffff", "%hp", &v.voidptr_[0]);
  1993. EATEST_VERIFY(n == 1);
  1994. EATEST_VERIFY((uintptr_t)v.voidptr_[0] == 0xffffffff);
  1995. v.Clear();
  1996. n = Sscanf(EA_CHAR16("0xffffffff"), EA_CHAR16("%hp"), &v.voidptr_[0]);
  1997. EATEST_VERIFY(n == 1);
  1998. EATEST_VERIFY((uintptr_t)v.voidptr_[0] == 0xffffffff);
  1999. v.Clear();
  2000. n = Sscanf(EA_CHAR32("0xffffffff"), EA_CHAR32("%hp"), &v.voidptr_[0]);
  2001. EATEST_VERIFY(n == 1);
  2002. EATEST_VERIFY((uintptr_t)v.voidptr_[0] == 0xffffffff);
  2003. }
  2004. { // Make sure we support explicit char strings.
  2005. v.Clear();
  2006. n = Sscanf("2.0", "%hs", v.str8_[0]);
  2007. EATEST_VERIFY(n == 1);
  2008. EATEST_VERIFY(Strcmp(v.str8_[0], "2.0") == 0);
  2009. v.Clear();
  2010. n = Sscanf(EA_CHAR16("2.0"), EA_CHAR16("%hs"), v.str8_[0]);
  2011. EATEST_VERIFY(n == 1);
  2012. EATEST_VERIFY(Strcmp(v.str8_[0], "2.0") == 0);
  2013. v.Clear();
  2014. n = Sscanf(EA_CHAR32("2.0"), EA_CHAR32("%hs"), v.str8_[0]);
  2015. EATEST_VERIFY(n == 1);
  2016. EATEST_VERIFY(Strcmp(v.str8_[0], "2.0") == 0);
  2017. }
  2018. { // Make sure we support explicit wchar_t strings.
  2019. v.Clear();
  2020. n = Sscanf("2.0", "%ls", v.strw_[0]);
  2021. EATEST_VERIFY(n == 1);
  2022. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("2.0")) == 0);
  2023. v.Clear();
  2024. n = Sscanf(EA_CHAR16("2.0"), EA_CHAR16("%ls"), v.strw_[0]);
  2025. EATEST_VERIFY(n == 1);
  2026. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("2.0")) == 0);
  2027. v.Clear();
  2028. n = Sscanf(EA_CHAR32("2.0"), EA_CHAR32("%ls"), v.strw_[0]);
  2029. EATEST_VERIFY(n == 1);
  2030. EATEST_VERIFY(Strcmp(v.strw_[0], EA_WCHAR("2.0")) == 0);
  2031. }
  2032. { // Make sure we support explicit char chars.
  2033. v.Clear();
  2034. n = Sscanf("2.0", "%hc", &v.char8_[0]);
  2035. EATEST_VERIFY(n == 1);
  2036. EATEST_VERIFY(v.char8_[0] == '2');
  2037. v.Clear();
  2038. n = Sscanf(EA_CHAR16("2.0"), EA_CHAR16("%hc"), &v.char8_[0]);
  2039. EATEST_VERIFY(n == 1);
  2040. EATEST_VERIFY(v.char8_[0] == '2');
  2041. v.Clear();
  2042. n = Sscanf(EA_CHAR32("2.0"), EA_CHAR32("%hc"), &v.char8_[0]);
  2043. EATEST_VERIFY(n == 1);
  2044. EATEST_VERIFY(v.char8_[0] == '2');
  2045. }
  2046. { // Make sure we support explicit char16_t chars.
  2047. v.Clear();
  2048. n = Sscanf("2.0", "%lc", &v.wchar_[0]);
  2049. EATEST_VERIFY(n == 1);
  2050. EATEST_VERIFY(v.wchar_[0] == '2');
  2051. v.Clear();
  2052. n = Sscanf(EA_CHAR16("2.0"), EA_CHAR16("%lc"), &v.wchar_[0]);
  2053. EATEST_VERIFY(n == 1);
  2054. EATEST_VERIFY(v.wchar_[0] == '2');
  2055. v.Clear();
  2056. n = Sscanf(EA_CHAR32("2.0"), EA_CHAR32("%lc"), &v.wchar_[0]);
  2057. EATEST_VERIFY(n == 1);
  2058. EATEST_VERIFY(v.wchar_[0] == '2');
  2059. }
  2060. EA::Assert::FailureCallback originalCallback = EA::Assert::GetFailureCallback();
  2061. EA::Assert::SetFailureCallback([](const char* expr, const char* filename, int line, const char* function, const char* msg, va_list args) -> bool { ++Values::assertCount_; return false; });
  2062. // The following are invalid formats. They will result in assertion failures in Sscanf.
  2063. {
  2064. v.Clear();
  2065. v.int_[0] = 0xdd;
  2066. n = Sscanf("%4", "%*%%d", &v.int_[0]);
  2067. EATEST_VERIFY(n == 0);
  2068. EATEST_VERIFY(v.int_[0] == 0xdd);
  2069. VERIFY_ASSERTCOUNT(1);
  2070. v.Clear();
  2071. v.int_[0] = 0xdd;
  2072. n = Sscanf(EA_CHAR16("%4"), EA_CHAR16("%*%%d"), &v.int_[0]);
  2073. EATEST_VERIFY(n == 0);
  2074. EATEST_VERIFY(v.int_[0] == 0xdd);
  2075. VERIFY_ASSERTCOUNT(1);
  2076. v.Clear();
  2077. v.int_[0] = 0xdd;
  2078. n = Sscanf(EA_CHAR32("%4"), EA_CHAR32("%*%%d"), &v.int_[0]);
  2079. EATEST_VERIFY(n == 0);
  2080. EATEST_VERIFY(v.int_[0] == 0xdd);
  2081. VERIFY_ASSERTCOUNT(1);
  2082. }
  2083. {
  2084. v.Clear();
  2085. v.int_[0] = 0xdd;
  2086. n = Sscanf("%4", "%2%%d", &v.int_[0]);
  2087. EATEST_VERIFY(n == 0);
  2088. EATEST_VERIFY(v.int_[0] == 0xdd);
  2089. VERIFY_ASSERTCOUNT(1);
  2090. v.Clear();
  2091. v.int_[0] = 0xdd;
  2092. n = Sscanf(EA_CHAR16("%4"), EA_CHAR16("%2%%d"), &v.int_[0]);
  2093. EATEST_VERIFY(n == 0);
  2094. EATEST_VERIFY(v.int_[0] == 0xdd);
  2095. VERIFY_ASSERTCOUNT(1);
  2096. v.Clear();
  2097. v.int_[0] = 0xdd;
  2098. n = Sscanf(EA_CHAR32("%4"), EA_CHAR32("%2%%d"), &v.int_[0]);
  2099. EATEST_VERIFY(n == 0);
  2100. EATEST_VERIFY(v.int_[0] == 0xdd);
  2101. VERIFY_ASSERTCOUNT(1);
  2102. }
  2103. {
  2104. v.Clear();
  2105. v.int_[0] = 0xdd;
  2106. n = Sscanf("%4", "%h%%d", &v.int_[0]);
  2107. EATEST_VERIFY(n == 0);
  2108. EATEST_VERIFY(v.int_[0] == 0xdd);
  2109. VERIFY_ASSERTCOUNT(1);
  2110. v.Clear();
  2111. v.int_[0] = 0xdd;
  2112. n = Sscanf(EA_CHAR16("%4"), EA_CHAR16("%h%%d"), &v.int_[0]);
  2113. EATEST_VERIFY(n == 0);
  2114. EATEST_VERIFY(v.int_[0] == 0xdd);
  2115. VERIFY_ASSERTCOUNT(1);
  2116. v.Clear();
  2117. v.int_[0] = 0xdd;
  2118. n = Sscanf(EA_CHAR32("%4"), EA_CHAR32("%h%%d"), &v.int_[0]);
  2119. EATEST_VERIFY(n == 0);
  2120. EATEST_VERIFY(v.int_[0] == 0xdd);
  2121. VERIFY_ASSERTCOUNT(1);
  2122. }
  2123. {
  2124. v.Clear();
  2125. Strcpy(v.str8_[0], "x");
  2126. n = Sscanf("abcd", "%[]abcd", v.str8_[0]);
  2127. EATEST_VERIFY(n == 0);
  2128. EATEST_VERIFY(Strcmp(v.str8_[0], "x") == 0);
  2129. VERIFY_ASSERTCOUNT(1);
  2130. v.Clear();
  2131. Strcpy(v.str8_[0], "x");
  2132. n = Sscanf(EA_CHAR16("abcd"), EA_CHAR16("%[]abcd"), v.str8_[0]);
  2133. EATEST_VERIFY(n == 0);
  2134. EATEST_VERIFY(Strcmp(v.str8_[0], "x") == 0);
  2135. VERIFY_ASSERTCOUNT(1);
  2136. v.Clear();
  2137. Strcpy(v.str8_[0], "x");
  2138. n = Sscanf(EA_CHAR32("abcd"), EA_CHAR32("%[]abcd"), v.str8_[0]);
  2139. EATEST_VERIFY(n == 0);
  2140. EATEST_VERIFY(Strcmp(v.str8_[0], "x") == 0);
  2141. VERIFY_ASSERTCOUNT(1);
  2142. }
  2143. {
  2144. v.Clear();
  2145. v.float_[0] = -1.f;
  2146. n = Sscanf("2.0", "%hf", &v.float_[0]);
  2147. EATEST_VERIFY(n == 0);
  2148. EATEST_VERIFY(v.float_[0] == -1.f);
  2149. VERIFY_ASSERTCOUNT(1);
  2150. v.Clear();
  2151. v.float_[0] = -1.f;
  2152. n = Sscanf(EA_CHAR16("2.0"), EA_CHAR16("%hf"), &v.float_[0]);
  2153. EATEST_VERIFY(n == 0);
  2154. EATEST_VERIFY(v.float_[0] == -1.f);
  2155. VERIFY_ASSERTCOUNT(1);
  2156. v.Clear();
  2157. v.float_[0] = -1.f;
  2158. n = Sscanf(EA_CHAR32("2.0"), EA_CHAR32("%hf"), &v.float_[0]);
  2159. EATEST_VERIFY(n == 0);
  2160. EATEST_VERIFY(v.float_[0] == -1.f);
  2161. VERIFY_ASSERTCOUNT(1);
  2162. }
  2163. /*{ Currently our Scanf supports %h in front of string formats, but it's not required to by the Standard. We should disable this support.
  2164. v.Clear();
  2165. Strcpy(v.str8_[0], "x");
  2166. n = Sscanf("2.0", "%h[2.]", v.str8_[0]);
  2167. EATEST_VERIFY(n == 0);
  2168. EATEST_VERIFY(Strcmp(v.str8_[0], "x") == 0);
  2169. v.Clear();
  2170. Strcpy(v.str8_[0], "x");
  2171. n = Sscanf(EA_CHAR16("2.0"), EA_CHAR16("%h[2.]"), v.str8_[0]);
  2172. EATEST_VERIFY(n == 0);
  2173. EATEST_VERIFY(Strcmp(v.str8_[0], "x") == 0);
  2174. v.Clear();
  2175. Strcpy(v.str8_[0], "x");
  2176. n = Sscanf(EA_CHAR32("2.0"), EA_CHAR32("%h[2.]"), v.str8_[0]);
  2177. EATEST_VERIFY(n == 0);
  2178. EATEST_VERIFY(Strcmp(v.str8_[0], "x") == 0);
  2179. } */
  2180. {
  2181. v.Clear();
  2182. v.uint64_[0] = 0xdd;
  2183. n = Sscanf("abcd", "%h", &v.uint64_[0]);
  2184. EATEST_VERIFY(n == 0);
  2185. EATEST_VERIFY(v.uint64_[0] == 0xdd);
  2186. VERIFY_ASSERTCOUNT(1);
  2187. v.Clear();
  2188. v.uint64_[0] = 0xdd;
  2189. n = Sscanf(EA_CHAR16("abcd"), EA_CHAR16("%h"), &v.uint64_[0]);
  2190. EATEST_VERIFY(n == 0);
  2191. EATEST_VERIFY(v.uint64_[0] == 0xdd);
  2192. VERIFY_ASSERTCOUNT(1);
  2193. v.Clear();
  2194. v.uint64_[0] = 0xdd;
  2195. n = Sscanf(EA_CHAR32("abcd"), EA_CHAR32("%h"), &v.uint64_[0]);
  2196. EATEST_VERIFY(n == 0);
  2197. EATEST_VERIFY(v.uint64_[0] == 0xdd);
  2198. VERIFY_ASSERTCOUNT(1);
  2199. }
  2200. {
  2201. v.Clear();
  2202. v.uint64_[0] = 0xdd;
  2203. n = Sscanf("abcd", "%l.", &v.uint64_[0]);
  2204. EATEST_VERIFY(n == 0);
  2205. EATEST_VERIFY(v.uint64_[0] == 0xdd);
  2206. VERIFY_ASSERTCOUNT(1);
  2207. v.Clear();
  2208. v.uint64_[0] = 0xdd;
  2209. n = Sscanf(EA_CHAR16("abcd"), EA_CHAR16("%l."), &v.uint64_[0]);
  2210. EATEST_VERIFY(n == 0);
  2211. EATEST_VERIFY(v.uint64_[0] == 0xdd);
  2212. VERIFY_ASSERTCOUNT(1);
  2213. v.Clear();
  2214. v.uint64_[0] = 0xdd;
  2215. n = Sscanf(EA_CHAR32("abcd"), EA_CHAR32("%l."), &v.uint64_[0]);
  2216. EATEST_VERIFY(n == 0);
  2217. EATEST_VERIFY(v.uint64_[0] == 0xdd);
  2218. VERIFY_ASSERTCOUNT(1);
  2219. }
  2220. {
  2221. v.Clear();
  2222. v.float_[0] = -1.f;
  2223. n = Sscanf("2.0", "%zf", &v.float_[0]);
  2224. EATEST_VERIFY(n == 0);
  2225. EATEST_VERIFY(v.float_[0] == -1.f);
  2226. VERIFY_ASSERTCOUNT(1);
  2227. v.Clear();
  2228. v.float_[0] = -1.f;
  2229. n = Sscanf("2.0", "%ze", &v.float_[0]); //Invalid use of 'z' modifier with 'f' field specifier
  2230. EATEST_VERIFY(n == 0);
  2231. EATEST_VERIFY(v.float_[0] == -1.f);
  2232. VERIFY_ASSERTCOUNT(1);
  2233. v.Clear();
  2234. v.float_[0] = -1.f;
  2235. n = Sscanf("2.0", "%zg", &v.float_[0]); //Invalid use of 'z' modifier with 'g' field specifier
  2236. EATEST_VERIFY(n == 0);
  2237. EATEST_VERIFY(v.float_[0] == -1.f);
  2238. VERIFY_ASSERTCOUNT(1);
  2239. v.Clear();
  2240. v.float_[0] = -1.f;
  2241. n = Sscanf("2.0", "%za", &v.float_[0]); //Invalid use of 'z' modifier with 'a' field specifier
  2242. EATEST_VERIFY(n == 0);
  2243. EATEST_VERIFY(v.float_[0] == -1.f);
  2244. VERIFY_ASSERTCOUNT(1);
  2245. v.Clear();
  2246. v.char_[0] = 'x';
  2247. n = Sscanf("y", "%zc", &v.char_[0]); //Invalid use of 'z' modifier with 'c' field specifier
  2248. EATEST_VERIFY(n == 0);
  2249. EATEST_VERIFY(v.char_[0] == 'x');
  2250. VERIFY_ASSERTCOUNT(1);
  2251. }
  2252. EA::Assert::SetFailureCallback(originalCallback);
  2253. }
  2254. return nErrorCount;
  2255. }
  2256. ///////////////////////////////////////////////////////////////////////////////
  2257. // TestScanfVariants
  2258. //
  2259. static int TestScanfVariants()
  2260. {
  2261. int nErrorCount = 0;
  2262. { // Test sscanf family variants.
  2263. // To do: Implement some of these:
  2264. /*
  2265. EASTDC_API int Cscanf(ReadFunction8 pReadFunction8, void* pContext, const char* pFormat, ...);
  2266. EASTDC_API int Fscanf(FILE* pFile, const char* pFormat, ...);
  2267. EASTDC_API int Scanf(const char* pFormat, ...);
  2268. EASTDC_API int Sscanf(const char* pTextBuffer, const char* pFormat, ...);
  2269. EASTDC_API int Cscanf(ReadFunction16 pReadFunction16, void* pContext, const char16_t* pFormat, ...);
  2270. EASTDC_API int Fscanf(FILE* pFile, const char16_t* pFormat, ...);
  2271. EASTDC_API int Scanf(const char16_t* pFormat, ...);
  2272. EASTDC_API int Sscanf(const char16_t* pTextBuffer, const char16_t* pFormat, ...);
  2273. EASTDC_API int Cscanf(ReadFunction32 pReadFunction32, void* pContext, const char32_t* pFormat, ...);
  2274. EASTDC_API int Fscanf(FILE* pFile, const char32_t* pFormat, ...);
  2275. EASTDC_API int Scanf(const char32_t* pFormat, ...);
  2276. EASTDC_API int Sscanf(const char32_t* pTextBuffer, const char32_t* pFormat, ...);
  2277. EASTDC_API int Vcscanf(ReadFunction8 pReadFunction8, void* pContext, const char* pFormat, va_list arguments);
  2278. EASTDC_API int Vfscanf(FILE* pFile, const char* pFormat, va_list arguments);
  2279. EASTDC_API int Vscanf(const char* pFormat, va_list arguments);
  2280. EASTDC_API int Vsscanf(const char* pTextBuffer, const char* pFormat, va_list arguments);
  2281. EASTDC_API int Vcscanf(ReadFunction16 pReadFunction16, void* pContext, const char16_t* pFormat, va_list arguments);
  2282. EASTDC_API int Vfscanf(FILE* pFile, const char16_t* pFormat, va_list arguments);
  2283. EASTDC_API int Vscanf(const char16_t* pFormat, va_list arguments);
  2284. EASTDC_API int Vsscanf(const char16_t* pTextBuffer, const char16_t* pFormat, va_list arguments);
  2285. EASTDC_API int Vcscanf(ReadFunction32 pReadFunction32, void* pContext, const char32_t* pFormat, va_list arguments);
  2286. EASTDC_API int Vfscanf(FILE* pFile, const char32_t* pFormat, va_list arguments);
  2287. EASTDC_API int Vscanf(const char32_t* pFormat, va_list arguments);
  2288. EASTDC_API int Vsscanf(const char32_t* pTextBuffer, const char32_t* pFormat, va_list arguments);
  2289. */
  2290. }
  2291. return nErrorCount;
  2292. }
  2293. ///////////////////////////////////////////////////////////////////////////////
  2294. // TestScanfExtensions
  2295. //
  2296. static int TestScanfExtensions()
  2297. {
  2298. int nErrorCount = 0;
  2299. { // Test sscanf extensions
  2300. using namespace EA::StdC;
  2301. int n;
  2302. Values v;
  2303. {
  2304. n = Sscanf("127 -128 255", "%I8d %I8i %I8u", &v.int8_[0], &v.int8_[1], &v.uint8_[2]);
  2305. EATEST_VERIFY(n == 3);
  2306. EATEST_VERIFY((v.int8_[0] == INT8_MAX) && (v.int8_[1] == INT8_MIN) && (v.uint8_[2] == UINT8_MAX));
  2307. n = Sscanf(EA_CHAR16("127 -128 255"), EA_CHAR16("%I8d %I8i %I8u"), &v.int8_[0], &v.int8_[1], &v.uint8_[2]);
  2308. EATEST_VERIFY(n == 3);
  2309. EATEST_VERIFY((v.int8_[0] == INT8_MAX) && (v.int8_[1] == INT8_MIN) && (v.uint8_[2] == UINT8_MAX));
  2310. n = Sscanf(EA_CHAR32("127 -128 255"), EA_CHAR32("%I8d %I8i %I8u"), &v.int8_[0], &v.int8_[1], &v.uint8_[2]);
  2311. EATEST_VERIFY(n == 3);
  2312. EATEST_VERIFY((v.int8_[0] == INT8_MAX) && (v.int8_[1] == INT8_MIN) && (v.uint8_[2] == UINT8_MAX));
  2313. }
  2314. {
  2315. n = Sscanf("32767 -32768 65535", "%I16d %I16i %I16u", &v.int16_[0], &v.int16_[1], &v.uint16_[2]);
  2316. EATEST_VERIFY(n == 3);
  2317. EATEST_VERIFY((v.int16_[0] == INT16_MAX));
  2318. EATEST_VERIFY((v.int16_[1] == INT16_MIN));
  2319. EATEST_VERIFY((v.uint16_[2] == UINT16_MAX));
  2320. // The three lines above were added to replace the line below. The comparisons are identical, but
  2321. // the line below fails on iPhone due to an apparent Clang compiler bug.
  2322. //EATEST_VERIFY((v.int16_[0] == INT16_MAX) && (v.int16_[1] == INT16_MIN) && (v.uint16_[2] == UINT16_MAX));
  2323. n = Sscanf(EA_CHAR16("32767 -32768 65535"), EA_CHAR16("%I16d %I16i %I16u"), &v.int16_[0], &v.int16_[1], &v.uint16_[2]);
  2324. EATEST_VERIFY(n == 3);
  2325. EATEST_VERIFY((v.int16_[0] == INT16_MAX));
  2326. EATEST_VERIFY((v.int16_[1] == INT16_MIN));
  2327. EATEST_VERIFY((v.uint16_[2] == UINT16_MAX));
  2328. // The three lines above were added to replace the line below. The comparisons are identical, but
  2329. // the line below fails on iPhone due to an apparent Clang compiler bug.
  2330. //EATEST_VERIFY((v.int16_[0] == INT16_MAX) && (v.int16_[1] == INT16_MIN) && (v.uint16_[2] == UINT16_MAX));
  2331. n = Sscanf(EA_CHAR32("32767 -32768 65535"), EA_CHAR32("%I16d %I16i %I16u"), &v.int16_[0], &v.int16_[1], &v.uint16_[2]);
  2332. EATEST_VERIFY(n == 3);
  2333. EATEST_VERIFY((v.int16_[0] == INT16_MAX));
  2334. EATEST_VERIFY((v.int16_[1] == INT16_MIN));
  2335. EATEST_VERIFY((v.uint16_[2] == UINT16_MAX));
  2336. // The three lines above were added to replace the line below. The comparisons are identical, but
  2337. // the line below fails on iPhone due to an apparent Clang compiler bug.
  2338. //EATEST_VERIFY((v.int16_[0] == INT16_MAX) && (v.int16_[1] == INT16_MIN) && (v.uint16_[2] == UINT16_MAX));
  2339. }
  2340. {
  2341. n = Sscanf("2147483647 -2147483648 4294967295", "%I32d %I32i %I32u", &v.int32_[0], &v.int32_[1], &v.uint32_[2]);
  2342. EATEST_VERIFY(n == 3);
  2343. EATEST_VERIFY((v.int32_[0] == INT32_MAX) && (v.int32_[1] == INT32_MIN) && (v.uint32_[2] == UINT32_MAX));
  2344. n = Sscanf(EA_CHAR16("2147483647 -2147483648 4294967295"), EA_CHAR16("%I32d %I32i %I32u"), &v.int32_[0], &v.int32_[1], &v.uint32_[2]);
  2345. EATEST_VERIFY(n == 3);
  2346. EATEST_VERIFY((v.int32_[0] == INT32_MAX) && (v.int32_[1] == INT32_MIN) && (v.uint32_[2] == UINT32_MAX));
  2347. n = Sscanf(EA_CHAR32("2147483647 -2147483648 4294967295"), EA_CHAR32("%I32d %I32i %I32u"), &v.int32_[0], &v.int32_[1], &v.uint32_[2]);
  2348. EATEST_VERIFY(n == 3);
  2349. EATEST_VERIFY((v.int32_[0] == INT32_MAX) && (v.int32_[1] == INT32_MIN) && (v.uint32_[2] == UINT32_MAX));
  2350. }
  2351. {
  2352. n = Sscanf("9223372036854775807 -9223372036854775808 18446744073709551615", "%I64d %I64i %I64u", &v.int64_[0], &v.int64_[1], &v.uint64_[2]);
  2353. EATEST_VERIFY(n == 3);
  2354. EATEST_VERIFY((v.int64_[0] == INT64_MAX) && (v.int64_[1] == INT64_MIN) && (v.uint64_[2] == UINT64_MAX));
  2355. n = Sscanf(EA_CHAR16("9223372036854775807 -9223372036854775808 18446744073709551615"), EA_CHAR16("%I64d %I64i %I64u"), &v.int64_[0], &v.int64_[1], &v.uint64_[2]);
  2356. EATEST_VERIFY(n == 3);
  2357. EATEST_VERIFY((v.int64_[0] == INT64_MAX) && (v.int64_[1] == INT64_MIN) && (v.uint64_[2] == UINT64_MAX));
  2358. n = Sscanf(EA_CHAR32("9223372036854775807 -9223372036854775808 18446744073709551615"), EA_CHAR32("%I64d %I64i %I64u"), &v.int64_[0], &v.int64_[1], &v.uint64_[2]);
  2359. EATEST_VERIFY(n == 3);
  2360. EATEST_VERIFY((v.int64_[0] == INT64_MAX) && (v.int64_[1] == INT64_MIN) && (v.uint64_[2] == UINT64_MAX));
  2361. }
  2362. // We don't currently support %I128, though it could be done if needed.
  2363. // If somebody actually asks for this then it can be implemented.
  2364. // Otherwise it probably would just bloat the library with something nobody wants.
  2365. //
  2366. // int128_t int128_[4]; // int128_t has constructors and so is not a POD and cannot be part of the Values union.
  2367. // uint128_t uint128_[4];
  2368. //
  2369. // n = Sscanf(EA_CHAR16("170141183460469231731687303715884105727 -170141183460469231731687303715884105728 340282366920938463463374607431768211455"), EA_CHAR16("%I128d %I128i %I128u"), &int128_[0], &int128_[1], &uint128_[2]);
  2370. // EATEST_VERIFY(n == 3);
  2371. // EATEST_VERIFY((int128_[0] == int128_t("170141183460469231731687303715884105727")) &&
  2372. // (int128_[1] == int128_t("-170141183460469231731687303715884105728")) &&
  2373. // (uint128_[2] == uint128_t("340282366920938463463374607431768211455")));
  2374. { // Test sized %s
  2375. // We could test %I8s, %I16s, %I32s, %I8c, %I16c, %I32c here, but we already
  2376. // test these a lot in the other code here.
  2377. }
  2378. { // Test %b (binary)
  2379. n = Sscanf("11010111 111011000101011 10110110111101100001110001100111 111010011101100000110100011111100111000011100111110011101110011", "%I8b %I16b %I32b %I64b", &v.uint8_[0], &v.uint16_[0], &v.uint32_[0], &v.uint64_[0]);
  2380. EATEST_VERIFY(n == 4);
  2381. EATEST_VERIFY((v.uint8_[0] == 0xd7) && (v.uint16_[0] == 0x762B) && (v.uint32_[0] == 0xB6F61C67) && (v.uint64_[0] == UINT64_C(0x74EC1A3F3873E773)));
  2382. n = Sscanf(EA_CHAR16("11010111 111011000101011 10110110111101100001110001100111 111010011101100000110100011111100111000011100111110011101110011"), EA_CHAR16("%I8b %I16b %I32b %I64b"), &v.uint8_[0], &v.uint16_[0], &v.uint32_[0], &v.uint64_[0]);
  2383. EATEST_VERIFY(n == 4);
  2384. EATEST_VERIFY((v.uint8_[0] == 0xd7) && (v.uint16_[0] == 0x762B) && (v.uint32_[0] == 0xB6F61C67) && (v.uint64_[0] == UINT64_C(0x74EC1A3F3873E773)));
  2385. n = Sscanf(EA_CHAR32("11010111 111011000101011 10110110111101100001110001100111 111010011101100000110100011111100111000011100111110011101110011"), EA_CHAR32("%I8b %I16b %I32b %I64b"), &v.uint8_[0], &v.uint16_[0], &v.uint32_[0], &v.uint64_[0]);
  2386. EATEST_VERIFY(n == 4);
  2387. EATEST_VERIFY((v.uint8_[0] == 0xd7) && (v.uint16_[0] == 0x762B) && (v.uint32_[0] == 0xB6F61C67) && (v.uint64_[0] == UINT64_C(0x74EC1A3F3873E773)));
  2388. }
  2389. { // Test %Ld (same as %lld)
  2390. // To do.
  2391. }
  2392. { // Test %S handling
  2393. // To do.
  2394. }
  2395. { // Test %C handling
  2396. // To do.
  2397. }
  2398. }
  2399. return nErrorCount;
  2400. }
  2401. ///////////////////////////////////////////////////////////////////////////////
  2402. // TestScanfErrors
  2403. //
  2404. static int TestScanfErrors()
  2405. {
  2406. int nErrorCount = 0;
  2407. { // Test sscanf error situations
  2408. // To do: Implement some of these:
  2409. /*
  2410. // Wrong number of arguments.
  2411. // Not possible to test at runtime.
  2412. // sscanf("%d%d", ip);
  2413. // sscanf("%d", ip, ip);
  2414. // Various tests of bad argument types. Some of these are only pedantic warnings.
  2415. sscanf("%d", lp); // "format" "bad argument types"
  2416. sscanf("%d", uip); // "format" "bad argument types"
  2417. sscanf("%d", pp); // "format" "bad argument types"
  2418. sscanf("%p", ppc); // "format" "bad argument types"
  2419. sscanf("%p", ppv); // "format" "bad argument types"
  2420. sscanf("%s", n); // "format" "bad argument types"
  2421. sscanf("%s", p); // "format" "bad argument types"
  2422. sscanf("%p", p); // "format" "bad argument types"
  2423. sscanf("%p", sp); // "format" "bad argument types"
  2424. // Tests for writing into constant values.
  2425. sscanf("%d", cip); // "constant" "%d writing into const"
  2426. sscanf("%n", cn); // "constant" "%n writing into const"
  2427. sscanf("%s", cs); // "constant" "%s writing into const"
  2428. sscanf("%p", pcp); // "constant" "%p writing into const"
  2429. sscanf(""); // "zero-length" "warning for empty format"
  2430. sscanf("\0"); // "embedded" "warning for embedded NUL"
  2431. sscanf("%d\0", ip); // "embedded" "warning for embedded NUL"
  2432. sscanf("%d\0%d", ip, ip); // "embedded|too many" "warning for embedded NUL"
  2433. sscanf(NULL); // "null" "null format string warning"
  2434. sscanf("%"); // "trailing" "trailing % warning"
  2435. sscanf("%d", (int *)0); // "null" "writing into NULL"
  2436. sscanf("%lla", fp); // "length" "bad use of %ll"
  2437. sscanf("%llA", fp); // "length" "bad use of %ll"
  2438. sscanf("%lle", fp); // "length" "bad use of %ll"
  2439. sscanf("%llE", fp); // "length" "bad use of %ll"
  2440. sscanf("%llf", fp); // "length" "bad use of %ll"
  2441. sscanf("%llF", fp); // "length" "bad use of %ll"
  2442. sscanf("%llg", fp); // "length" "bad use of %ll"
  2443. sscanf("%llG", fp); // "length" "bad use of %ll"
  2444. sscanf("%lls", s); // "length" "bad use of %ll"
  2445. sscanf("%ll[ac]", s); // "length" "bad use of %ll"
  2446. sscanf("%llc", s); // "length" "bad use of %ll"
  2447. sscanf("%llp", pp); // "length" "bad use of %ll"
  2448. sscanf("%jd%ji%jo%ju%jx%jX%jn", jp, jp, ujp, ujp, ujp, ujp, jn); /// "length" "bogus %j warning"
  2449. sscanf("%ja", fp); // "length" "bad use of %j"
  2450. sscanf("%jA", fp); // "length" "bad use of %j"
  2451. sscanf("%je", fp); // "length" "bad use of %j"
  2452. sscanf("%jE", fp); // "length" "bad use of %j"
  2453. sscanf("%jf", fp); // "length" "bad use of %j"
  2454. sscanf("%jF", fp); // "length" "bad use of %j"
  2455. sscanf("%jg", fp); // "length" "bad use of %j"
  2456. sscanf("%jG", fp); // "length" "bad use of %j"
  2457. sscanf("%js", s); // "length" "bad use of %j"
  2458. sscanf("%j[ac]", s); // "length" "bad use of %j"
  2459. sscanf("%jc", s); // "length" "bad use of %j"
  2460. sscanf("%jp", pp); // "length" "bad use of %j"
  2461. sscanf("%zd%zi%zo%zu%zx%zX%zn", szp, szp, zp, zp, zp, zp, zn);
  2462. sscanf("%za", fp); // "length" "bad use of %z"
  2463. sscanf("%zA", fp); // "length" "bad use of %z"
  2464. sscanf("%ze", fp); // "length" "bad use of %z"
  2465. sscanf("%zE", fp); // "length" "bad use of %z"
  2466. sscanf("%zf", fp); // "length" "bad use of %z"
  2467. sscanf("%zF", fp); // "length" "bad use of %z"
  2468. sscanf("%zg", fp); // "length" "bad use of %z"
  2469. sscanf("%zG", fp); // "length" "bad use of %z"
  2470. sscanf("%zs", s); // "length" "bad use of %z"
  2471. sscanf("%z[ac]", s); // "length" "bad use of %z"
  2472. sscanf("%zc", s); // "length" "bad use of %z"
  2473. sscanf("%zp", pp); // "length" "bad use of %z"
  2474. sscanf("%td%ti%to%tu%tx%tX%tn", tp, tp, utp, utp, utp, utp, tn);
  2475. sscanf("%ta", fp); // "length" "bad use of %t"
  2476. sscanf("%tA", fp); // "length" "bad use of %t"
  2477. sscanf("%te", fp); // "length" "bad use of %t"
  2478. sscanf("%tE", fp); // "length" "bad use of %t"
  2479. sscanf("%tf", fp); // "length" "bad use of %t"
  2480. sscanf("%tF", fp); // "length" "bad use of %t"
  2481. sscanf("%tg", fp); // "length" "bad use of %t"
  2482. sscanf("%tG", fp); // "length" "bad use of %t"
  2483. sscanf("%ts", s); // "length" "bad use of %t"
  2484. sscanf("%t[ac]", s); // "length" "bad use of %t"
  2485. sscanf("%tc", s); // "length" "bad use of %t"
  2486. sscanf("%tp", pp); // "length" "bad use of %t"
  2487. sscanf("%La%LA%Le%LE%Lf%LF%Lg%LG", ldp, ldp, ldp, ldp, ldp, ldp, ldp, ldp);
  2488. sscanf("%Ld", llp); // "does not support" "bad use of L"
  2489. sscanf("%Li", llp); // "does not support" "bad use of L"
  2490. sscanf("%Lo", ullp); // "does not support" "bad use of L"
  2491. sscanf("%Lu", ullp); // "does not support" "bad use of L"
  2492. sscanf("%Lx", ullp); // "does not support" "bad use of L"
  2493. sscanf("%LX", ullp); // "does not support" "bad use of L"
  2494. sscanf("%Ls", s); // "length" "bad use of L"
  2495. sscanf("%L[ac]", s); // "length" "bad use of L"
  2496. sscanf("%Lc", s); // "length" "bad use of L"
  2497. sscanf("%Lp", pp); // "length" "bad use of L"
  2498. sscanf("%Ln", n); // "length" "bad use of L"
  2499. sscanf("%ha", fp); // "length" "bad use of %h"
  2500. sscanf("%hA", fp); // "length" "bad use of %h"
  2501. sscanf("%he", fp); // "length" "bad use of %h"
  2502. sscanf("%hE", fp); // "length" "bad use of %h"
  2503. sscanf("%hf", fp); // "length" "bad use of %h"
  2504. sscanf("%hF", fp); // "length" "bad use of %h"
  2505. sscanf("%hg", fp); // "length" "bad use of %h"
  2506. sscanf("%hG", fp); // "length" "bad use of %h"
  2507. sscanf("%hs", s); // "length" "bad use of %h"
  2508. sscanf("%h[ac]", s); // "length" "bad use of %h"
  2509. sscanf("%hc", s); // "length" "bad use of %h"
  2510. sscanf("%hp", pp); // "length" "bad use of %h"
  2511. sscanf("%hha", fp); // "length" "bad use of %hh"
  2512. sscanf("%hhA", fp); // "length" "bad use of %hh"
  2513. sscanf("%hhe", fp); // "length" "bad use of %hh"
  2514. sscanf("%hhE", fp); // "length" "bad use of %hh"
  2515. sscanf("%hhf", fp); // "length" "bad use of %hh"
  2516. sscanf("%hhF", fp); // "length" "bad use of %hh"
  2517. sscanf("%hhg", fp); // "length" "bad use of %hh"
  2518. sscanf("%hhG", fp); // "length" "bad use of %hh"
  2519. sscanf("%hhs", s); // "length" "bad use of %hh"
  2520. sscanf("%hh[ac]", s); // "length" "bad use of %hh"
  2521. sscanf("%hhc", s); // "length" "bad use of %hh"
  2522. sscanf("%hhp", pp); // "length" "bad use of %hh"
  2523. sscanf("%lp", pp); // "length" "bad use of %l"
  2524. */
  2525. }
  2526. return nErrorCount;
  2527. }
  2528. ///////////////////////////////////////////////////////////////////////////////
  2529. // TestScanf
  2530. //
  2531. int TestScanf()
  2532. {
  2533. int nErrorCount = 0;
  2534. EA::UnitTest::Report("TestScanf\n");
  2535. nErrorCount += TestScanfLimits();
  2536. nErrorCount += TestScanfMisc();
  2537. nErrorCount += TestScanfUnusual();
  2538. nErrorCount += TestScanfVariants();
  2539. nErrorCount += TestScanfExtensions();
  2540. nErrorCount += TestScanfErrors();
  2541. return nErrorCount;
  2542. }