TestScanf.cpp 107 KB

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