| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784 |
- ///////////////////////////////////////////////////////////////////////////////
- // Copyright (c) Electronic Arts Inc. All rights reserved.
- ///////////////////////////////////////////////////////////////////////////////
- #include <EAStdC/EASprintf.h>
- #include <EAStdC/EASprintfOrdered.h>
- #include <EAStdC/EAString.h>
- #include <EAStdC/EADateTime.h>
- #include <EAStdCTest/EAStdCTest.h>
- #include <EASTL/string.h>
- #include <EASTL/unique_ptr.h>
- #include <EATest/EATest.h>
- #include <float.h>
- #include <string.h>
- #include <stdarg.h>
- static void TestCRTVsnprintf(char8_t* pDestination, size_t n, const char8_t* pFormat, ...)
- {
- va_list vList;
- va_start(vList, pFormat);
- EA::StdC::Vsnprintf(pDestination, n, pFormat, vList);
- va_end(vList);
- }
- static void TestCRTVsnprintf(char16_t* pDestination, size_t n, const char16_t* pFormat, ...)
- {
- va_list vList;
- va_start(vList, pFormat);
- EA::StdC::Vsnprintf(pDestination, n, pFormat, vList);
- va_end(vList);
- }
- static void TestCRTVsnprintf(char32_t* pDestination, size_t n, const char32_t* pFormat, ...)
- {
- va_list vList;
- va_start(vList, pFormat);
- EA::StdC::Vsnprintf(pDestination, n, pFormat, vList);
- va_end(vList);
- }
- #if EASTDC_VSNPRINTF8_ENABLED
- static void TestCRTVsnprintf8(char8_t* pDestination, size_t n, const char8_t* pFormat, ...)
- {
- va_list vList;
- va_start(vList, pFormat);
- EA::StdC::Vsnprintf8(pDestination, n, pFormat, vList);
- va_end(vList);
- }
- static void TestCRTVsnprintf16(char16_t* pDestination, size_t n, const char16_t* pFormat, ...)
- {
- va_list vList;
- va_start(vList, pFormat);
- EA::StdC::Vsnprintf16(pDestination, n, pFormat, vList);
- va_end(vList);
- }
- static void TestCRTVsnprintf32(char32_t* pDestination, size_t n, const char32_t* pFormat, ...)
- {
- va_list vList;
- va_start(vList, pFormat);
- EA::StdC::Vsnprintf32(pDestination, n, pFormat, vList);
- va_end(vList);
- }
- #endif
- static float FloatFromBitRepr(uint32_t bits)
- {
- union { float f; uint32_t u; } typepun;
- typepun.u = bits;
- return typepun.f;
- }
- static double DoubleFromBitRepr(uint64_t bits)
- {
- union { double d; uint64_t u; } typepun;
- typepun.u = bits;
- return (double)typepun.d;
- }
- static int TestSprintf8(int unused = 0, ...)
- {
- using namespace EA::StdC;
- int nErrorCount(0);
- // int Snprintf(char_t* pDestination, size_t n, const char_t* pFormat, ...);
- {
- char8_t sn18[128];
- Snprintf(sn18, 128, "%5s%-4d%03i", "abc", -12, 3);
- EATEST_VERIFY(!Strcmp(" abc-12 003", sn18));
- Snprintf(sn18, 128, "%.2f", 3.1415);
- EATEST_VERIFY(!Strcmp("3.14", sn18));
- }
- // int Vsnprintf(char_t* pDestination, size_t n, const char_t* pFormat, ...);
- {
- char8_t sn18[128];
- TestCRTVsnprintf(sn18, 128, "%5s%-5d%04i", "abc", -12, 3);
- EATEST_VERIFY(!Strcmp(" abc-12 0003", sn18));
- TestCRTVsnprintf(sn18, 128, "%.2f", 3.1415);
- EATEST_VERIFY(!Strcmp("3.14", sn18));
- }
- #if EASTDC_VSNPRINTF8_ENABLED
- {
- char8_t sn18[128];
- TestCRTVsnprintf8(sn18, 128, "%5s%-5d%04i", "abc", -12, 3);
- EATEST_VERIFY(!Strcmp(" abc-12 0003", sn18));
- TestCRTVsnprintf8(sn18, 128, "%.2f", 3.1415);
- EATEST_VERIFY(!Strcmp("3.14", sn18));
- }
- #endif
- // int Vscprintf(const char_t* pFormat, va_list arguments);
- {
- va_list arguments;
- va_start(arguments, unused);
- int result = Vscprintf("abc", arguments);
- EATEST_VERIFY(result == 3);
- va_end(arguments);
- }
- // template <typename String>
- // int StringVcprintf(String& s, const char8_t* EA_RESTRICT pFormat, va_list arguments)
- {
- va_list arguments;
- va_start(arguments, unused);
- eastl::string8 s8;
- int result = StringVcprintf(s8, "hello", arguments);
- EATEST_VERIFY((result == 5) && (s8 == "hello"));
- va_end(arguments);
- }
- // template <typename String>
- // int StringPrintf(String& s, const typename String::value_type* EA_RESTRICT pFormat, ...)
- {
- eastl::string8 s8;
- int result = StringPrintf(s8, "%s", "hello");
- EATEST_VERIFY((result == 5) && (s8 == "hello"));
- }
- {
- char buffer[128];
- Sprintf(buffer, "%Lf", 42.0l);
- EATEST_VERIFY(Strcmp(buffer, "42.000000") == 0);
- }
- {
- // Test for parsing of PRI constants in format strings
- char8_t buffer[128];
- Sprintf(buffer, "%" PRIxPTR, (intptr_t) 0xDEADBEEF);
- EATEST_VERIFY(Strcmp(buffer, "deadbeef") == 0);
- }
- // Sprintf
- {
- char8_t buffer[128];
- const int kHexValue = 0x12;
- Sprintf(buffer, "%.4x", kHexValue);
- EATEST_VERIFY(Strcmp(buffer, "0012") == 0);
- Sprintf(buffer, "%04x", kHexValue);
- EATEST_VERIFY(Strcmp(buffer, "0012") == 0);
- Sprintf(buffer, "%4.4x", kHexValue);
- EATEST_VERIFY(Strcmp(buffer, "0012") == 0);
- Sprintf(buffer, "%04.4x", kHexValue);
- EATEST_VERIFY(Strcmp(buffer, "0012") == 0);
- Sprintf(buffer, "%4.3x", kHexValue);
- EATEST_VERIFY(Strcmp(buffer, " 012") == 0);
- Sprintf(buffer, "%04.3x", kHexValue);
- EATEST_VERIFY(Strcmp(buffer, " 012") == 0);
- Sprintf(buffer, "%.*x", 4, kHexValue);
- EATEST_VERIFY(Strcmp(buffer, "0012") == 0);
- Sprintf(buffer, "%0*x", 4, kHexValue);
- EATEST_VERIFY(Strcmp(buffer, "0012") == 0);
- Sprintf(buffer, "%*.*x", 4, 4, kHexValue);
- EATEST_VERIFY(Strcmp(buffer, "0012") == 0);
- Sprintf(buffer, "%0*.*x", 4, 4, kHexValue);
- EATEST_VERIFY(Strcmp(buffer, "0012") == 0);
- }
- {
- char8_t buffer[128];
- Sprintf(buffer, "decimal negative: \"%d\"\n", -2345);
- EATEST_VERIFY(Strcmp(buffer, "decimal negative: \"-2345\"\n") == 0);
- Sprintf(buffer, "octal negative: \"%o\"\n", -2345);
- if(sizeof(int) == (4 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, "octal negative: \"37777773327\"\n") == 0);
- else if(sizeof(int) == (8 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, "octal negative: \"1777777777777777773327\"\n") == 0);
- Sprintf(buffer, "hex negative: \"%x\"\n", -2345);
- if(sizeof(int) == (4 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, "hex negative: \"fffff6d7\"\n") == 0);
- else if(sizeof(int) == (8 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, "hex negative: \"fffffffffffff6d7\"\n") == 0);
- Sprintf(buffer, "long decimal number: \"%ld\"\n", -123456L);
- EATEST_VERIFY(Strcmp(buffer, "long decimal number: \"-123456\"\n") == 0);
- Sprintf(buffer, "long octal negative: \"%lo\"\n", -2345L);
- if(sizeof(long) == (4 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, "long octal negative: \"37777773327\"\n") == 0);
- else if(sizeof(long) == (8 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, "long octal negative: \"1777777777777777773327\"\n") == 0);
- Sprintf(buffer, "long unsigned decimal number: \"%lu\"\n", -123456L);
- if(sizeof(long) == (4 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, "long unsigned decimal number: \"4294843840\"\n") == 0);
- else if(sizeof(long) == (8 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, "long unsigned decimal number: \"18446744073709428160\"\n") == 0);
- Sprintf(buffer, "zero-padded LDN: \"%010ld\"\n", -123456L);
- EATEST_VERIFY(Strcmp(buffer, "zero-padded LDN: \"-000123456\"\n") == 0);
- Sprintf(buffer, "left-adjusted ZLDN: \"%-010ld\"\n", -123456L);
- EATEST_VERIFY(Strcmp(buffer, "left-adjusted ZLDN: \"-123456 \"\n") == 0);
- Sprintf(buffer, "space-padded LDN: \"%10ld\"\n", -123456L);
- EATEST_VERIFY(Strcmp(buffer, "space-padded LDN: \" -123456\"\n") == 0);
- Sprintf(buffer, "left-adjusted SLDN: \"%-10ld\"\n", -123456L);
- EATEST_VERIFY(Strcmp(buffer, "left-adjusted SLDN: \"-123456 \"\n") == 0);
- }
- {
- char8_t buffer[1024];
- char8_t str1[] = "abc de";
- char8_t str2[] = "abd def ghi jkl mno pqr stu vwz yz.";
- // The C99 standard specifies that leading zeros only put zeroes in front of numerical types. Spaces for others.
- Sprintf(buffer, "zero-padded string: \"%010s\"\n", str1);
- EATEST_VERIFY(Strcmp(buffer, "zero-padded string: \" abc de\"\n") == 0); // VC++ fails this, as it puts zeroes in front.
- Sprintf(buffer, "left-adjusted Z string: \"%-010s\"\n", str1);
- EATEST_VERIFY(Strcmp(buffer, "left-adjusted Z string: \"abc de \"\n") == 0);
- Sprintf(buffer, "space-padded string: \"%10s\"\n", str1);
- EATEST_VERIFY(Strcmp(buffer, "space-padded string: \" abc de\"\n") == 0);
- Sprintf(buffer, "left-adjusted S string: \"%-10s\"\n", str1);
- EATEST_VERIFY(Strcmp(buffer, "left-adjusted S string: \"abc de \"\n") == 0);
- Sprintf(buffer, "limited string: \"%.22s\"\n", str2);
- EATEST_VERIFY(Strcmp(buffer, "limited string: \"abd def ghi jkl mno pq\"\n") == 0);
- Sprintf(buffer, "null string: \"%s\"\n", (char8_t*)NULL);
- EATEST_VERIFY(Strcmp(buffer, "null string: \"(null)\"\n") == 0);
- Sprintf(buffer, "%10s\n", (char8_t*)NULL);
- EATEST_VERIFY(Strcmp(buffer, " (null)\n") == 0);
- Sprintf(buffer, "%-10s\n", (char8_t*)NULL);
- EATEST_VERIFY(Strcmp(buffer, "(null) \n") == 0);
- Sprintf(buffer, "%*s%*s%*s", -1, "one", -20, "two", -30, "three");
- EATEST_VERIFY(Strcmp(buffer, "onetwo three ") == 0);
- int i;
- memset(buffer, '_', sizeof(buffer));
- Sprintf(buffer, "x%1000s", " ");
- EATEST_VERIFY(buffer[0] == 'x');
- for(i = 0; i < 1000; i++)
- {
- if(buffer[1 + i] != ' ')
- break;
- }
- if(i != 1000)
- EATEST_VERIFY(i == 1000);
- else
- EATEST_VERIFY(buffer[1 + 1000] == 0);
- }
- { // String tests
- // We accept %hc, %c, %lc, %I8c, %I16c, %I32c (regular, regular, wide, char8_t, char16_t, char32_t)
- // We accept %hC, %C, %lC, %I8C, %I16C, %I32C (regular, wide, wide, char8_t, char16_t, char32_t)
- // We accept %hs, %s, %ls, %I8s, %I16s, %I32s (regular, regular, wide, char8_t, char16_t, char32_t)
- // We accept %hS, %S, %lS, %I8s, %I16s, %I32s (regular, wide, wide, char8_t, char16_t, char32_t)
- char8_t buffer[32];
- char8_t dStr8[2] = { 'd', 0 };
- char16_t eStr16[2] = { 'e', 0 };
- char32_t fStr32[2] = { 'f', 0 };
- Sprintf(buffer, "%hc %c %lc %I8c %I16c %I32c", 'a', 'b', EA_WCHAR('c'), (char8_t)'d', (char16_t)'e', (char32_t)'f');
- EATEST_VERIFY(Strcmp(buffer, "a b c d e f") == 0);
- Sprintf(buffer, "%hC %C %lC %I8C %I16C %I32C", 'a', EA_WCHAR('b'), EA_WCHAR('c'), (char8_t)'d', (char16_t)'e', (char32_t)'f');
- EATEST_VERIFY(Strcmp(buffer, "a b c d e f") == 0);
- Sprintf(buffer, "%hs %s %ls %I8s %I16s %I32s", "a", "b", EA_WCHAR("c"), dStr8, eStr16, fStr32);
- EATEST_VERIFY(Strcmp(buffer, "a b c d e f") == 0);
- Sprintf(buffer, "%hS %S %lS %I8S %I16S %I32S", "a", EA_WCHAR("b"), EA_WCHAR("c"), dStr8, eStr16, fStr32);
- EATEST_VERIFY(Strcmp(buffer, "a b c d e f") == 0);
- }
- { // NaN/Inf functionality tests
- char8_t buffer[256];
- const float kFloat32PositiveInfinity = FloatFromBitRepr(UINT32_C(0x7f800000));
- const float kFloat32NegativeInfinity = FloatFromBitRepr(UINT32_C(0xff800000));
- const double kFloat64PositiveInfinity = DoubleFromBitRepr(UINT64_C(0x7ff0000000000000));
- const double kFloat64NegativeInfinity = DoubleFromBitRepr(UINT64_C(0xfff0000000000000));
- const float kFloat32PositiveNaN = FloatFromBitRepr(UINT32_C(0x7fffffff));
- const float kFloat32NegativeNaN = FloatFromBitRepr(UINT32_C(0xffffffff));
- const double kFloat64PositiveNaN = DoubleFromBitRepr(UINT64_C(0x7fffffffffffffff));
- const double kFloat64NegativeNaN = DoubleFromBitRepr(UINT64_C(0xffffffffffffffff));
-
- Sprintf(buffer, "%e %f %g", kFloat32PositiveInfinity, kFloat32PositiveInfinity, kFloat32PositiveInfinity);
- EATEST_VERIFY(Strcmp(buffer, "inf inf inf") == 0);
- Sprintf(buffer, "%e %f %g", kFloat32NegativeInfinity, kFloat32NegativeInfinity, kFloat32NegativeInfinity);
- EATEST_VERIFY(Strcmp(buffer, "-inf -inf -inf") == 0);
- Sprintf(buffer, "%e %f %g", kFloat32PositiveNaN, kFloat32PositiveNaN, kFloat32PositiveNaN);
- EATEST_VERIFY(Strcmp(buffer, "nan nan nan") == 0);
- // The ARM instruction fcvtds (convert single to double point precision) does not maintain the sign of NaN.
- // (Float is always promoted to double in variable length arguments)
- // This seems to work on the Android
- // To consider: Disable this test altogether, as it seems to be too FPU-specific to spend our time with.
- #if defined(EA_PROCESSOR_X86) || defined(EA_PROCESSOR_X86_64) || defined(EA_PROCESSOR_POWERPC)
- Sprintf(buffer, "%e %f %g", kFloat32NegativeNaN, kFloat32NegativeNaN, kFloat32NegativeNaN);
- EATEST_VERIFY(Strcmp(buffer, "-nan -nan -nan") == 0);
- #else
- EA_UNUSED(kFloat32NegativeNaN);
- #endif
- Sprintf(buffer, "%e %f %g", kFloat64PositiveInfinity, kFloat64PositiveInfinity, kFloat64PositiveInfinity);
- EATEST_VERIFY(Strcmp(buffer, "inf inf inf") == 0);
- Sprintf(buffer, "%e %f %g", kFloat64NegativeInfinity, kFloat64NegativeInfinity, kFloat64NegativeInfinity);
- EATEST_VERIFY(Strcmp(buffer, "-inf -inf -inf") == 0);
- Sprintf(buffer, "%e %f %g", kFloat64PositiveNaN, kFloat64PositiveNaN, kFloat64PositiveNaN);
- EATEST_VERIFY(Strcmp(buffer, "nan nan nan") == 0);
- Sprintf(buffer, "%e %f %g", kFloat64NegativeNaN, kFloat64NegativeNaN, kFloat64NegativeNaN);
- EATEST_VERIFY(Strcmp(buffer, "-nan -nan -nan") == 0);
- #if !defined(EA_PLATFORM_CAPILANO)
- // This test should theoretically work on Capilano. But currently it must be disabled or it
- // will cause the runtime to assert. A bug has been logged with MS so hopefully the issue
- // will be resolved in the future. We should try to enable the test later if it is resolved.
- //
- // Link to issue;
- // https://forums.xboxlive.com/questions/48008/is-there-a-bug-in-string-formatting-functions-in-t.html
- const double kSmallestDoubleNum = DoubleFromBitRepr(0x0000000000000001ull);
- Sprintf(buffer, "%f", kSmallestDoubleNum);
- EATEST_VERIFY_F(Strcmp(buffer, "0.000000") == 0, "Result was %s", buffer);
- #endif
- }
- { // Extended functionality tests
- char8_t buffer[256];
- Sprintf(buffer, "%08x %032b", 0xaaaaaaaa, 0xaaaaaaaa);
- EATEST_VERIFY(Strcmp(buffer, "aaaaaaaa 10101010101010101010101010101010") == 0);
- Sprintf(buffer, "%I8u %I8d %I16u %I16d %I32u %I32d %I64u %I64d", 0xff, 0xff, 0xffff, 0xffff, 0xffffffff, 0xffffffff, UINT64_C(0xffffffffffffffff), UINT64_C(0xffffffffffffffff));
- EATEST_VERIFY(Strcmp(buffer, "255 -1 65535 -1 4294967295 -1 18446744073709551615 -1") == 0);
- Sprintf(buffer, "%s %10s", NULL, NULL);
- EATEST_VERIFY(Strcmp(buffer, "(null) (null)") == 0);
- }
- {
- char8_t buffer[1024];
- int i;
- Sprintf(buffer, "e-style >= 1: \"%e\"\n", 12.34);
- EATEST_VERIFY(Strcmp(buffer, "e-style >= 1: \"1.234000e+01\"\n") == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, "e-style >= .1: \"%e\"\n", 0.1234);
- EATEST_VERIFY(Strcmp(buffer, "e-style >= .1: \"1.234000e-01\"\n") == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, "e-style < .1: \"%e\"\n", 0.001234);
- EATEST_VERIFY(Strcmp(buffer, "e-style < .1: \"1.234000e-03\"\n") == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, "e-style big: \"%.60e\"\n", 1e20);
- EATEST_VERIFY(Strcmp(buffer, "e-style big: \"1.000000000000000000000000000000000000000000000000000000000000e+20\"\n") == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, "e-style == .1: \"%e\"\n", 0.1);
- EATEST_VERIFY(Strcmp(buffer, "e-style == .1: \"1.000000e-01\"\n") == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, "f-style >= 1: \"%f\"\n", 12.34);
- EATEST_VERIFY(Strcmp(buffer, "f-style >= 1: \"12.340000\"\n") == 0);
- Sprintf(buffer, "f-style >= 1: \"%.3f\"\n", 12.34);
- EATEST_VERIFY(Strcmp(buffer, "f-style >= 1: \"12.340\"\n") == 0);
- Sprintf(buffer, "f-style >= .1: \"%f\"\n", 0.1234);
- EATEST_VERIFY(Strcmp(buffer, "f-style >= .1: \"0.123400\"\n") == 0);
- Sprintf(buffer, "f-style < .1: \"%f\"\n", 0.001234);
- EATEST_VERIFY(Strcmp(buffer, "f-style < .1: \"0.001234\"\n") == 0);
- Sprintf(buffer, "g-style >= 1: \"%.0g\"\n", 1.234);
- EATEST_VERIFY(Strcmp(buffer, "g-style >= 1: \"1.2\"\n") == 0);//%g takes precision to be 1, even if set to be 0
- Sprintf(buffer, "g-style >= 1: \"%.1g\"\n", 1.234);
- EATEST_VERIFY(Strcmp(buffer, "g-style >= 1: \"1.2\"\n") == 0);
- Sprintf(buffer, "g-style >= 1: \"%.2g\"\n", 1.234);
- EATEST_VERIFY(Strcmp(buffer, "g-style >= 1: \"1.23\"\n") == 0);
- Sprintf(buffer, "g-style >= 1: \"%g\"\n", 12.34);
- EATEST_VERIFY(Strcmp(buffer, "g-style >= 1: \"12.34\"\n") == 0);
- Sprintf(buffer, "g-style >= .1: \"%g\"\n", 0.1234);
- EATEST_VERIFY(Strcmp(buffer, "g-style >= .1: \"0.1234\"\n") == 0);
- Sprintf(buffer, "g-style < .1: \"%g\"\n", 0.001234);
- EATEST_VERIFY(Strcmp(buffer, "g-style < .1: \"0.001234\"\n") == 0);
- Sprintf(buffer, "g-style < .1: \"%g\"\n", 0.001234678);
- EATEST_VERIFY(Strcmp(buffer, "g-style < .1: \"0.001235\"\n") == 0);
- Sprintf(buffer, "g-style big: \"%.60g\"\n", 1e20);
- EATEST_VERIFY(Strcmp(buffer, "g-style big: \"100000000000000000000\"\n") == 0);
- //Sprintf(buffer, "%#.4g\n", 0.0); // The C99 committee has decided in a defect analysis that this is how it should work.
- //EATEST_VERIFY(Strcmp(buffer, "0\n") == 0);
- Sprintf(buffer, " %6.5f\n", .099999999860301614);
- EATEST_VERIFY(Strcmp(buffer, " 0.10000\n") == 0);
- Sprintf(buffer, " %6.5f\n", .1);
- EATEST_VERIFY(Strcmp(buffer, " 0.10000\n") == 0);
- Sprintf(buffer, "x%5.4fx\n", .5);
- EATEST_VERIFY(Strcmp(buffer, "x0.5000x\n") == 0);
- Sprintf(buffer, "%#03x\n", 1);
- EATEST_VERIFY(Strcmp(buffer, "0x1\n") == 0);
- memset(buffer, '_', sizeof(buffer));
- Sprintf(buffer, "%.300f", 1.0);
- EATEST_VERIFY((buffer[0] == '1') && (buffer[1] == '.'));
- for(i = 0; i < 300; i++)
- {
- if(buffer[2 + i] != '0')
- break;
- }
- if(i != 300)
- EATEST_VERIFY(i == 300);
- else
- EATEST_VERIFY(buffer[2 + 300] == 0);
- double d = static_cast<double>(FLT_MIN); // We are intentionally using FLT_MIN and not DBL_MIN.
- d /= 2.0;
- Sprintf(buffer, "%.17e", d); // It should be something like 5.87747175411143___e-39 where count and values of the _ digits vary by hardware.
- buffer[16] = buffer[17] = buffer[18] = '_'; // Replace the uncertain digits with '_' characters, as they are system-dependent.
- EATEST_VERIFY(Strcmp(buffer, "5.87747175411143___e-39") == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, "%15.5e\n", 4.9406564584124654e-307);
- EATEST_VERIFY(Strcmp(buffer, " 4.94066e-307\n") == 0);
- // Exercise bug report on PS3 platform which results in a crash when printing DBL_MAX.
- i = Sprintf(buffer, "%15.8g", DBL_MAX);
- EATEST_VERIFY(i > 0);
- i = Sprintf(buffer, "%15.8g", FLT_MAX);
- EATEST_VERIFY(i > 0);
- }
- {
- char8_t buffer[256];
- const char8_t* pExpected;
- // VC++ sprintf would fail these tests, as the Standard says to print no more
- // than 2 unless necessary, yet VC++ sprintf prints 3 digits exponents.
- Sprintf(buffer, "|%12.4f|%12.4e|%12.4g|", 0.0, 0.0, 0.0);
- EATEST_VERIFY(Strcmp(buffer, "| 0.0000| 0.0000e+00| 0|") == 0);
- Sprintf(buffer, "|%12.4f|%12.4e|%12.4g|", 1.0, 1.0, 1.0);
- EATEST_VERIFY(Strcmp(buffer, "| 1.0000| 1.0000e+00| 1|") == 0);
- Sprintf(buffer, "|%12.4f|%12.4e|%12.4g|", -1.0, -1.0, -1.0);
- EATEST_VERIFY(Strcmp(buffer, "| -1.0000| -1.0000e+00| -1|") == 0);
- Sprintf(buffer, "|%12.4f|%12.4e|%12.4g|", 100.0, 100.0, 100.0);
- EATEST_VERIFY(Strcmp(buffer, "| 100.0000| 1.0000e+02| 100|") == 0);
- Sprintf(buffer, "|%12.4f|%12.4e|%12.4g|", 1000.0, 1000.0, 1000.0);
- EATEST_VERIFY(Strcmp(buffer, "| 1000.0000| 1.0000e+03| 1000|") == 0);
- Sprintf(buffer, "|%12.4f|%12.4e|%12.4g|", 10000.0, 10000.0, 10000.0);
- EATEST_VERIFY(Strcmp(buffer, "| 10000.0000| 1.0000e+04| 1e+04|") == 0);
- // %g picks one of %f or %e, though uses precision differently.
- Sprintf(buffer, "|%12.4f|%12.4e|%12.4g|", 12346.0, 12346.0, 12346.0);
- pExpected = "| 12346.0000| 1.2346e+04| 1.235e+04|";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- Sprintf(buffer, "|%12.4f|%12.4e|%12.4g|", 100000.0, 100000.0, 100000.0);
- pExpected = "| 100000.0000| 1.0000e+05| 1e+05|";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- Sprintf(buffer, "|%12.4f|%12.4e|%12.4g|", 123467.0, 123467.0, 123467.0);
- pExpected = "| 123467.0000| 1.2347e+05| 1.235e+05|";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- }
- {
- char8_t buffer[256];
- // Verify that snprintf follows the C99 convention of returning the number of characters
- // required. This is as opposed to the non-standard way that some libraries just return
- // -1 if the buffer isn't big enough.
- const int kBuf1Capacity = 20;
- char8_t buf1[kBuf1Capacity];
- int n1 = Snprintf(buf1, kBuf1Capacity, "%30s", "foo");
- Sprintf(buffer, "snprintf(\"%%30s\", \"foo\") == %d, \"%.*s\"\n", n1, kBuf1Capacity, buf1);
- EATEST_VERIFY(Strcmp(buffer, "snprintf(\"%30s\", \"foo\") == 30, \" \"\n") == 0); // VC++ fails this, as it's version of snprintf doesn't use C99 standard snprintf return value conventions.
- const int kBuf2Capacity = 512;
- char8_t buf2[kBuf2Capacity];
- int n2 = Snprintf(buf2, kBuf2Capacity, "%.1000u", 10);
- Sprintf(buffer, "snprintf(\"%%.1000u\", 10) == %d\n", n2);
- EATEST_VERIFY(Strcmp(buffer, "snprintf(\"%.1000u\", 10) == 1000\n") == 0); // VC++ fails this, as it's version of snprintf doesn't use C99 standard snprintf return value conventions.
- const int kBuf3Capacity = 512;
- char8_t buf3[kBuf3Capacity];
- char8_t* pString = new char8_t[100000];
- memset(pString, '_', 100000 * sizeof(char8_t));
- pString[100000 - 1] = 0;
- int n3 = Snprintf(buf3, kBuf2Capacity, "%s", pString);
- Sprintf(buffer, "snprintf(\"%%s\", pString) == %d\n", n3);
- EATEST_VERIFY(Strcmp(buffer, "snprintf(\"%s\", pString) == 99999\n") == 0); // VC++ fails this, as it's version of snprintf doesn't use C99 standard snprintf return value conventions.
- delete[] pString;
- int n4 = Snprintf(NULL, 0, "%s", "abc");
- Sprintf(buffer, "snprintf(NULL, \"abc\") == %d\n", n4);
- EATEST_VERIFY(Strcmp(buffer, "snprintf(NULL, \"abc\") == 3\n") == 0); // VC++ fails this, as it's version of snprintf doesn't use C99 standard snprintf return value conventions.
- int n5 = Snprintf(NULL, 100, "%s", "abc");
- Sprintf(buffer, "snprintf(NULL, \"abc\") == %d\n", n5);
- EATEST_VERIFY(Strcmp(buffer, "snprintf(NULL, \"abc\") == 3\n") == 0); // VC++ fails this, as it's version of snprintf doesn't use C99 standard snprintf return value conventions.
- }
- {
- char8_t buffer[16][256];
- int n = 0, i, j, k, m;
- for(i = 0; i < 2; i++)
- {
- for(j = 0; j < 2; j++)
- {
- for(k = 0; k < 2; k++)
- {
- for(m = 0; m < 2; m++)
- {
- char8_t prefix[7];
- char8_t format[128];
- Strcpy(prefix, "%");
- if(i == 0)
- Strcat(prefix, "-");
- if(j == 0)
- Strcat(prefix, "+");
- if(k == 0)
- Strcat(prefix, "#");
- if(m == 0)
- Strcat(prefix, "0");
- #define DEC -123
- #define INT 255
- #define UNS (~0)
- Sprintf(format, "%%5s |%s6d |%s6o |%s6x |%s6X |%s6u |", prefix, prefix, prefix, prefix, prefix);
- Sprintf(buffer[n], format, prefix, DEC, INT, INT, INT, UNS);
- n++;
- }
- }
- }
- }
- EATEST_VERIFY(Strcmp(buffer[ 0], "%-+#0 |-123 |0377 |0xff |0XFF |4294967295 |") == 0);
- EATEST_VERIFY(Strcmp(buffer[ 1], " %-+# |-123 |0377 |0xff |0XFF |4294967295 |") == 0);
- EATEST_VERIFY(Strcmp(buffer[ 2], " %-+0 |-123 |377 |ff |FF |4294967295 |") == 0);
- EATEST_VERIFY(Strcmp(buffer[ 3], " %-+ |-123 |377 |ff |FF |4294967295 |") == 0);
- EATEST_VERIFY(Strcmp(buffer[ 4], " %-#0 |-123 |0377 |0xff |0XFF |4294967295 |") == 0);
- EATEST_VERIFY(Strcmp(buffer[ 5], " %-# |-123 |0377 |0xff |0XFF |4294967295 |") == 0);
- EATEST_VERIFY(Strcmp(buffer[ 6], " %-0 |-123 |377 |ff |FF |4294967295 |") == 0);
- EATEST_VERIFY(Strcmp(buffer[ 7], " %- |-123 |377 |ff |FF |4294967295 |") == 0);
- EATEST_VERIFY(Strcmp(buffer[ 8], " %+#0 |-00123 |000377 |0x00ff |0X00FF |4294967295 |") == 0);
- EATEST_VERIFY(Strcmp(buffer[ 9], " %+# | -123 | 0377 | 0xff | 0XFF |4294967295 |") == 0);
- EATEST_VERIFY(Strcmp(buffer[10], " %+0 |-00123 |000377 |0000ff |0000FF |4294967295 |") == 0);
- EATEST_VERIFY(Strcmp(buffer[11], " %+ | -123 | 377 | ff | FF |4294967295 |") == 0);
- EATEST_VERIFY(Strcmp(buffer[12], " %#0 |-00123 |000377 |0x00ff |0X00FF |4294967295 |") == 0);
- EATEST_VERIFY(Strcmp(buffer[13], " %# | -123 | 0377 | 0xff | 0XFF |4294967295 |") == 0);
- EATEST_VERIFY(Strcmp(buffer[14], " %0 |-00123 |000377 |0000ff |0000FF |4294967295 |") == 0);
- EATEST_VERIFY(Strcmp(buffer[15], " % | -123 | 377 | ff | FF |4294967295 |") == 0);
- }
- {
- char8_t buffer[256];
- const char8_t* pExpected;
- Sprintf(buffer, "%e", 1234567.8); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- pExpected = "1.234568e+06";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- Sprintf(buffer, "%f", 1234567.8);
- pExpected = "1234567.800000";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- Sprintf(buffer, "%g", 1234567.8); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- pExpected = "1.23457e+06";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- Sprintf(buffer, "%g", 123.456);
- pExpected = "123.456";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- Sprintf(buffer, "%g", 1000000.0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- pExpected = "1e+06";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- Sprintf(buffer, "%g", 10.0);
- pExpected = "10";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- Sprintf(buffer, "%g", 0.02);
- pExpected = "0.02";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- Sprintf(buffer, "%.1f", 0.09523f);
- pExpected = "0.1";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- Sprintf(buffer, "%.1f", 0.9523f);
- pExpected = "1.0";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- Sprintf(buffer, "%.1f", -0.9523f);
- pExpected = "-1.0";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- Sprintf(buffer, "%.1e", 0.9523f);
- pExpected = "9.5e-01";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- #if EASTDC_NATIVE_FCVT && defined(_MSC_VER)
- Sprintf(buffer, "%.0e", 0.9523f);
- pExpected = "1e+00";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- #else
- // Note that this test result is incorrect! It should be "1e+00" and not "1.0e00".
- // We have a bug and it needs to be fixed. At least the numerical value is still correct.
- // The problem is that GCC's standard library fcvt and our custom fcvt generate a string
- // of "10" instead of "1" for the case of calling fcvt(0.9523, 0, ...).
- Sprintf(buffer, "%.0e", 0.9523f);
- pExpected = "1.0e+00";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- #endif
- }
- { // Test the ' extension, which cases numbers to be printed with a thousands separator.
- char8_t buffer[64];
- const char8_t* pExpected;
- Sprintf(buffer, "%'u", 123456789);
- EATEST_VERIFY(Strcmp(buffer, "123,456,789") == 0);
- Sprintf(buffer, "%'d", -123456789);
- EATEST_VERIFY(Strcmp(buffer, "-123,456,789") == 0);
- Sprintf(buffer, "%'I8u", 123);
- EATEST_VERIFY(Strcmp(buffer, "123") == 0);
- Sprintf(buffer, "%'I16u", 12345);
- EATEST_VERIFY(Strcmp(buffer, "12,345") == 0);
- Sprintf(buffer, "%'I16d", -12345);
- EATEST_VERIFY(Strcmp(buffer, "-12,345") == 0);
- Sprintf(buffer, "%'I32u", 12345678);
- EATEST_VERIFY(Strcmp(buffer, "12,345,678") == 0);
- Sprintf(buffer, "%'I32d", -12345678);
- EATEST_VERIFY(Strcmp(buffer, "-12,345,678") == 0);
- Sprintf(buffer, "%20I32d", -12345678);
- EATEST_VERIFY(Strcmp(buffer, " -12345678") == 0);
- Sprintf(buffer, "%'20I32d", -12345678); // Verify that the , chars count towards the field width.
- EATEST_VERIFY(Strcmp(buffer, " -12,345,678") == 0);
- Sprintf(buffer, "%'I32x", 0x12345678); // ' has no effect on hex formatting.
- EATEST_VERIFY(Strcmp(buffer, "12345678") == 0);
- Sprintf(buffer, "%'I64u", UINT64_C(1234999995678));
- EATEST_VERIFY(Strcmp(buffer, "1,234,999,995,678") == 0);
- Sprintf(buffer, "%'I64d", INT64_C(-1234599999678));
- EATEST_VERIFY(Strcmp(buffer, "-1,234,599,999,678") == 0);
- Sprintf(buffer, "%'I64x", UINT64_C(0x1234567812345678)); // ' has no effect on hex formatting.
- EATEST_VERIFY(Strcmp(buffer, "1234567812345678") == 0);
- Sprintf(buffer, "%'f", 123456.234);
- EATEST_VERIFY(Strcmp(buffer, "123,456.234000") == 0);
- Sprintf(buffer, "%'e", 1234567.8); // ' has no effect on %e formatting.
- EATEST_VERIFY(Strcmp(buffer, "1.234568e+06") == 0);
- Sprintf(buffer, "%'g", 1234.54); // In some cases %g acts like %f.
- pExpected = "1,234.54";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- Sprintf(buffer, "%'g", 1234567.8); // In some cases %g acts like %f.
- pExpected = "1.23457e+06";
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I8s\n Actual: %I8s", pExpected, buffer);
- }
- {
- char8_t buffer[256];
- Sprintf(buffer, "%hhu", UCHAR_MAX + 2);
- EATEST_VERIFY(Strcmp(buffer, "1") == 0); // VC++ fails this, as it doesn't implement the C99 standard %hh modifier.
- Sprintf(buffer, "%hu", USHRT_MAX + 2);
- EATEST_VERIFY(Strcmp(buffer, "1") == 0);
- }
- {
- char8_t buffer[128];
- Sprintf(buffer, "%5.s", "xyz");
- EATEST_VERIFY(Strcmp(buffer, " ") == 0);
- Sprintf(buffer, "%5.f", 33.3);
- EATEST_VERIFY(Strcmp(buffer, " 33") == 0);
- Sprintf(buffer, "%8.e", 33.3e7);
- EATEST_VERIFY(Strcmp(buffer, " 3e+08") == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, "%8.E", 33.3e7);
- EATEST_VERIFY(Strcmp(buffer, " 3E+08") == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, "%.g", 33.3);
- EATEST_VERIFY(Strcmp(buffer, "3e+01") == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, "%.G", 33.3);
- EATEST_VERIFY(Strcmp(buffer, "3E+01") == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- }
- {
- char8_t buffer[128];
- int precision;
- //for %g, precision 0 is not valid, if specified 0, it is taken as 1
- precision = 0;
- Sprintf(buffer, "%.*g", precision, 3.3);
- EATEST_VERIFY(Strcmp(buffer, "3.3") == 0);
- precision = 0;
- Sprintf(buffer, "%.*G", precision, 3.3);
- EATEST_VERIFY(Strcmp(buffer, "3.3") == 0);
- precision = 0;
- Sprintf(buffer, "%7.*G", precision, 3.33);
- EATEST_VERIFY(Strcmp(buffer, " 3.3") == 0);
- precision = 3;
- Sprintf(buffer, "%04.*o", precision, 33);
- EATEST_VERIFY(Strcmp(buffer, " 041") == 0);
- precision = 7;
- Sprintf(buffer, "%09.*u", precision, 33);
- EATEST_VERIFY(Strcmp(buffer, " 0000033") == 0);
- precision = 3;
- Sprintf(buffer, "%04.*x", precision, 33);
- EATEST_VERIFY(Strcmp(buffer, " 021") == 0);
- precision = 3;
- Sprintf(buffer, "%04.*X", precision, 33);
- EATEST_VERIFY(Strcmp(buffer, " 021") == 0);
- }
- { // EAC tests
- char8_t dest1[1024], dest3[1024];
- // Test #1
- Sprintf(dest1, "Hello. Test.");
- EATEST_VERIFY(Strcmp(dest1, "Hello. Test.") == 0);
- // Test #2
- Sprintf(dest1,"Hello.\\ \\ a\n\n\tTest.");
- EATEST_VERIFY(Strcmp(dest1, "Hello.\\ \\ a\n\n\tTest.") == 0);
- // Test #3
- Sprintf(dest1, "Int. %d %d %d blah%d%d", -1, 1, 0, 392832993, -32903298);
- EATEST_VERIFY(Strcmp(dest1, "Int. -1 1 0 blah392832993-32903298") == 0);
- // Test #4
- Sprintf(dest1,"Float. %f %f %f\n", -0.01f, 10.0f, 0.0f);
- EATEST_VERIFY(Strcmp(dest1, "Float. -0.010000 10.000000 0.000000\n") == 0);
- // Test #5
- Sprintf(dest1, "Str/char8_t: %s %c %c", "test", 'b', 0341);
- EATEST_VERIFY(Strcmp(dest1, "Str/char8_t: test b \341") == 0);
- // Test #6
- Sprintf(dest1,"Hex: %x %X",3829,-392);
- EATEST_VERIFY(Strcmp(dest1, "Hex: ef5 FFFFFE78") == 0);
- // Test #7
- //for(int32_t i = 0; i < 7; i++) We'd need to modify the tests below to deal with this.
- //{
- Sprintf(dest3, "Precision: %%.%df", 0);
- EATEST_VERIFY(Strcmp(dest3, "Precision: %.0f") == 0);
- Sprintf(dest1, dest3, 34.56f);
- EATEST_VERIFY(Strcmp(dest1, "Precision: 35") == 0);
- //}
- // Test #8
- Sprintf(dest1, "Align. %9s %8d %5s %10.2f", "test", 10293, "testtesttest", 10.8f);
- EATEST_VERIFY(Strcmp(dest1, "Align. test 10293 testtesttest 10.80") == 0);
- // Test #9
- Sprintf(dest1, "Align. %-9s %-8d %-5s %-10.2f", "test", 10293, "testtesttest", 10.8f);
- EATEST_VERIFY(Strcmp(dest1, "Align. test 10293 testtesttest 10.80 ") == 0);
- // Test #10
- Sprintf(dest1, "Str: %S", EA_WCHAR("test"));
- EATEST_VERIFY(Strcmp(dest1, "Str: test") == 0);
- // Test #11
- Sprintf(dest1, "Str: %9S", EA_WCHAR("test"));
- EATEST_VERIFY(Strcmp(dest1, "Str: test") == 0);
- // Test #12
- Sprintf(dest1, "Str: %-9S", EA_WCHAR("test"));
- EATEST_VERIFY(Strcmp(dest1, "Str: test ") == 0);
- // Test #13
- Sprintf(dest1, "0x%08x", 0x876543);
- EATEST_VERIFY(Strcmp(dest1, "0x00876543") == 0);
- // Test #14
- Sprintf(dest1, "%08d", -15);
- EATEST_VERIFY(Strcmp(dest1, "-0000015") == 0);
- // Test #15
- Sprintf(dest1, "Int. %i %i %i blah%i%i", -1, 1, 0, 392832993, -32903298);
- EATEST_VERIFY(Strcmp(dest1, "Int. -1 1 0 blah392832993-32903298") == 0);
- // Test #16
- Sprintf(dest1, "%p", 0x38e340);
- EATEST_VERIFY(Strcmp(dest1, "38e340") == 0);
- // Test #17
- Sprintf(dest1, "%u", -372834);
- EATEST_VERIFY(Strcmp(dest1, "4294594462") == 0);
- // Test #18
- int tv1, tv2;
- Sprintf(dest1, "Testing%n%dTests%nabc", &tv1, 4738, &tv2);
- EATEST_VERIFY(Strcmp(dest1, "Testing4738Testsabc") == 0);
- EATEST_VERIFY((tv1 == 7) && (tv2 == 16));
- // Test #19
- Sprintf(dest1, "%o", -372834);
- EATEST_VERIFY(Strcmp(dest1, "37776447636") == 0);
- // Test #20
- Sprintf(dest1, "%%%s", "Hello");
- EATEST_VERIFY(Strcmp(dest1, "%Hello") == 0);
- // Test #21
- Sprintf(dest1, "%I64d", INT64_C(-12345678901234));
- EATEST_VERIFY(Strcmp(dest1, "-12345678901234") == 0);
- // Test #22
- Sprintf(dest1, "%I64u", INT64_C(-12345678901234));
- EATEST_VERIFY(Strcmp(dest1, "18446731728030650382") == 0);
- // Test #23
- Sprintf(dest1, "%I64x", INT64_C(0x1234567890123a));
- EATEST_VERIFY(Strcmp(dest1, "1234567890123a") == 0);
- // Test #24
- Sprintf(dest1, "%I64X", INT64_C(0x1234567890123A));
- EATEST_VERIFY(Strcmp(dest1, "1234567890123A") == 0);
- }
- { // EAC FPU tests
- const float list1f[]={0.832f,0.00832f,8.32f,0.0f,-0.15f};
- const char8_t* list1[]={"0.832000","0.008320","8.320000","0.000000","-0.150000"};
- const float list2f[]={0.0000000000123f,0.000000000123f,0.00000000123f,0.0000000123f
- ,0.000000123f,0.00000123f,0.0000123f,0.000123f,0.00123f,0.0123f,0.123f,1.23f
- ,12.3f,123.0f,1230.0f,12300.0f,123000.0f,1230000.0f,12300000.0f,123000000.0f,12300000000.0f};
- const char8_t* list2[]={"0.000000","0.000000","0.000000","0.000000"
- ,"0.000000","0.000001","0.000012","0.000123","0.001230","0.012300","0.123000","1.230000"
- ,"12.300000","123.000000","1230.000000","12300.000000","123000.000000","1230000.000000",
- "12300000.000000","123000000.000000","12300000000.000000"};
- const char8_t* list22D[]={"0.00","0.00","0.00","0.00"
- ,"0.00","0.00","0.00","0.00","0.00","0.01","0.12","1.23"
- ,"12.30","123.00","1230.00","12300.00","123000.00","1230000.00","12300000.00",
- "123000000.00","12300000000.00"};
- const char8_t* list23DSL[]={"1.230e-11","1.230e-10","1.230e-09","1.230e-08"
- ,"1.230e-07","1.230e-06","1.230e-05","1.230e-04","1.230e-03","1.230e-02","1.230e-01","1.230e+00"
- ,"1.230e+01","1.230e+02","1.230e+03","1.230e+04","1.230e+05","1.230e+06","1.230e+07","1.230e+08"
- ,"1.230e+10"};
- const char8_t* list24DSL[]={"1.230E-11","1.230E-10","1.230E-09","1.230E-08"
- ,"1.230E-07","1.230E-06","1.230E-05","1.230E-04","1.230E-03","1.230E-02","1.230E-01","1.230E+00"
- ,"1.230E+01","1.230E+02","1.230E+03","1.230E+04","1.230E+05","1.230E+06","1.230E+07","1.230E+08"
- ,"1.230E+10"};
- const char8_t* list31DSL[]={"1.23e-11","1.23e-10","1.23e-09","1.23e-08"
- ,"1.23e-07","1.23e-06","1.23e-05","0","0.001","0.012","0.123","1.23"
- ,"12.3","123","1.23e+03","1.23e+04","1.23e+05","1.23e+06","1.23e+07","1.23e+08"
- ,"1.23e+10"};
- const char8_t* list32DSL[]={"1.23E-11","1.23E-10","1.23E-09","1.23E-08"
- ,"1.23E-07","1.23E-06","1.23E-05","0","0.001","0.012","0.123","1.23"
- ,"12.3","123","1.23E+03","1.23E+04","1.23E+05","1.23E+06","1.23E+07","1.23E+08"
- ,"1.23E+10"};
- int32_t list1size = sizeof(list1f)/sizeof(list1f[0]);
- int32_t list2size = sizeof(list2f)/sizeof(list2f[0]);
- int32_t i, error;
- char8_t str[256];
- error = 0;
- for(i = 0; i < list1size; i++)
- {
- Sprintf(str, "%f", list1f[i]);
- if(Strcmp(str, list1[i]) != 0)
- {
- error++;
- EA::UnitTest::Report("\nMismatch(A): %s/%s (Halt if > 2/section A)", str, list1[i]);
- }
- }
- EATEST_VERIFY(error <= 2);
- error = 0;
- for(i = 0; i < list2size - 4; i++) // purposely take out the last 4 due to precision of float
- {
- Sprintf(str, "%f", list2f[i]);
- if(Strcmp(str, list2[i]) != 0)
- {
- error++;
- EA::UnitTest::Report("\nMismatch(B): %s/%s (Halt if > 3/section B)", str, list2[i]);
- }
- }
- EATEST_VERIFY(error <= 3);
- error = 0;
- for(i = 0; i < list2size - 2; i++) // purposely take out the last 2 due to precision of float
- {
- Sprintf(str, "%.2f", list2f[i]);
- if(Strcmp(str, list22D[i]) != 0)
- {
- error++;
- EA::UnitTest::Report("\nMismatch(C): %s/%s (Halt if > 3/section C)", str, list22D[i]);
- }
- }
- EATEST_VERIFY(error <= 3);
- error = 0;
- for(i=0; i < list2size; i++)
- {
- Sprintf(str, "%.3e", list2f[i]);
- if(Strcmp(str, list23DSL[i]) != 0)
- {
- error++;
- EA::UnitTest::Report("\nMismatch(D): %s/%s (Halt if > 3/section D)", str, list23DSL[i]);
- }
- }
- EATEST_VERIFY(error <= 2);
- error = 0;
- for(i = 0; i < list2size; i++)
- {
- Sprintf(str,"%.3E", list2f[i]);
- if(Strcmp(str, list24DSL[i]) != 0)
- {
- error++;
- EA::UnitTest::Report("\nMismatch(E): %s/%s (Halt if > 3/section E)", str, list24DSL[i]);
- }
- }
- EATEST_VERIFY(error <= 2);
- error = 0;
- for(i = 0; i < list2size; i++)
- {
- Sprintf(str,"%.3g", list2f[i]);
- if(Strcmp(str, list31DSL[i]) != 0)
- {
- error++;
- EA::UnitTest::Report("\nMismatch(F): %s/%s (Halt if > 0/section F)", str, list23DSL[i]);
- }
- }
- EATEST_VERIFY(error == 0);
- error=0;
- for (i=0;i<list2size;i++)
- {
- Sprintf(str, "%.3G", list2f[i]);
- if(Strcmp(str, list32DSL[i]) != 0)
- {
- error++;
- EA::UnitTest::Report("\nMismatch(G): %s/%s (Halt if > 0/section G)", str, list24DSL[i]);
- }
- }
- EATEST_VERIFY(error == 0);
- }
- { // Regression for user-reported bug.
- const size_t kBufferSize = 2048;
- char format[16];
- EA::StdC::Snprintf(format, sizeof(format), "%%.%us%%c123", kBufferSize - 1);
- EATEST_VERIFY(Strcmp(format, "%.2047s%c123") == 0);
- auto unique_buffer = eastl::make_unique<char8_t[]>(kBufferSize);
- auto unique_expect = eastl::make_unique<char8_t[]>(kBufferSize + 16);
- auto unique_actual = eastl::make_unique<char8_t[]>(kBufferSize + 16);
- char8_t* buffer = unique_buffer.get();
- char8_t* expectedOutput = unique_expect.get();
- char8_t* actualOutput = unique_actual.get();
- memset(buffer, '?', kBufferSize);
- buffer[kBufferSize - 1] = 0;
- char c = 'A';
- EA::StdC::Snprintf(actualOutput, kBufferSize + 16, format, buffer, c);
- memset(expectedOutput, '?', 2047);
- expectedOutput[2047] = 0;
- strcat(expectedOutput, "A123");
- EATEST_VERIFY(Strcmp(actualOutput, expectedOutput) == 0);
- }
- {
- static const int kSourceSize = 1024 * 5;
- static const int kOutputSize = kSourceSize + 100;
- char16_t value[kSourceSize];
- char8_t destination[kOutputSize];
- char8_t comparison[kOutputSize];
- for(int i = 0; i < kSourceSize - 1; ++i)
- {
- value[i] = '0' + (i % 10);
- comparison[i] = '0' + (i % 10);
- }
- value[kSourceSize - 1] = 0;
- comparison[kSourceSize - 1] = 0;
- EA::StdC::Snprintf(destination, kOutputSize, "%I16s", value);
- EATEST_VERIFY(Strcmp(destination, comparison) == 0);
- EA::StdC::Snprintf(destination, kOutputSize, "%.10I16s", value);
- EATEST_VERIFY(Strcmp(destination, "0123456789") == 0);
- }
- /* Copied from rwstdc but not completed.
- // Compare with Sprintf
- {
- char8_t buffer1[128];
- char8_t buffer2[128];
- char8_t* test = "test %d %5.2f %s \n \t\t\\\\ %X";
- Sprintf(buffer1, test, -3923, 0.38293, "test", 4568);
- Snprintf(buffer2, 128, test, -3923, 0.38293, "test", 4568);
- EATEST_VERIFY(strcmp(buffer1, buffer2) == 0);
- }
- // Compare with standard sprintf
- {
- char8_t buffer1[128];
- char8_t buffer2[128];
- char* test = "test %d %5.2f %s \n \t\t\\\\ %X";
- sprintf(buffer1, test, -3923, 0.38293, "test", 4568);
- Snprintf(buffer2, 128, test, -3923, 0.38293, "test", 4568);
- EATEST_VERIFY(strcmp(buffer1, buffer2) == 0);
- }
- {
- float sum = 1035.32432f;
- float ave = 34.3f;
- float min = 343.34f;
- float max = 576.3f;
- char test[] = "NumberEvents: %5d, TotalDuration: %12.4f ms\nAve: %12.4f ms = %6.2f Hz\nMin: %12.4f ms = %6.2f Hz\nMax: %12.4f ms = %6.2f Hz\n";
- int res = Snprintf(snprintfString, bufferLength,
- "NumberEvents: %5d, TotalDuration: %12.4f ms\nAve: %12.4f ms = %6.2f Hz\nMin: %12.4f ms = %6.2f Hz\nMax: %12.4f ms = %6.2f Hz\n",
- bufferLength, sum, ave, 1000.0f/ave, min, 1000.0f/min, max, 1000.0f/max);
- // Full String
- char testString[384];
- sprintf(testString, test, 384, sum, ave, 1000.0f/ave, min, 1000.0f/min, max, 1000.0f/max);
- EATEST_VERIFY(strcmp(snprintfString, testString) == 0);
- // Truncated string.
- const size_t origStringSize = strlen(snprintfString);
- for(size_t i = 0; i < origStringSize; i++)
- {
- res = Snprintf(snprintfString, i, test, 384, sum, ave, 1000.0f/ave, min, 1000.0f/min, max, 1000.0f/max);
- EATEST_VERIFY(res == origStringSize);
- }
- }
- {
- int testData = 123;
- char* test = "'%d' '%10d' '%-10d'";
- sprintf(expectedString, test, testData, testData, testData);
- Snprintf(snprintfString, bufferLength, test, testData, testData, testData);
- EATEST_VERIFY(strcmp(expectedString, snprintfString) == 0);
- }
- */
- return nErrorCount;
- }
- static int TestSprintf16(int unused = 0, ...)
- {
- using namespace EA::StdC;
- int nErrorCount(0);
- // int Snprintf(char_t* pDestination, size_t n, const char_t* pFormat, ...);
- {
- char16_t sn18[128];
- Snprintf(sn18, 128, EA_CHAR16("%5s%-4d%03i"), EA_WCHAR("abc"), -12, 3);
- EATEST_VERIFY(!Strcmp(EA_CHAR16(" abc-12 003"), sn18));
- Snprintf(sn18, 128, EA_CHAR16("%.2f"), 3.1415);
- EATEST_VERIFY(!Strcmp(EA_CHAR16("3.14"), sn18));
- }
- // int Vsnprintf(char_t* pDestination, size_t n, const char_t* pFormat, ...);
- {
- char16_t sn18[128];
- TestCRTVsnprintf(sn18, 128, EA_CHAR16("%5s%-5d%04i"), EA_WCHAR("abc"), -12, 3);
- EATEST_VERIFY(!Strcmp(EA_CHAR16(" abc-12 0003"), sn18));
- TestCRTVsnprintf(sn18, 128, EA_CHAR16("%.2f"), 3.1415);
- EATEST_VERIFY(!Strcmp(EA_CHAR16("3.14"), sn18));
- }
- #if EASTDC_VSNPRINTF8_ENABLED
- {
- char16_t sn18[128];
- TestCRTVsnprintf16(sn18, 128, EA_CHAR16("%5s%-5d%04i"), EA_WCHAR("abc"), -12, 3);
- EATEST_VERIFY(!Strcmp(EA_CHAR16(" abc-12 0003"), sn18));
- TestCRTVsnprintf16(sn18, 128, EA_CHAR16("%.2f"), 3.1415);
- EATEST_VERIFY(!Strcmp(EA_CHAR16("3.14"), sn18));
- }
- #endif
- // int Vscprintf(const char_t* pFormat, va_list arguments);
- {
- va_list arguments;
- va_start(arguments, unused);
- int result = Vscprintf(EA_CHAR16("abc"), arguments);
- EATEST_VERIFY(result == 3);
- va_end(arguments);
- }
- // template <typename String>
- // int StringVcprintf(String& s, const char8_t* EA_RESTRICT pFormat, va_list arguments)
- {
- va_list arguments;
- va_start(arguments, unused);
- eastl::string16 s16;
- int result = StringVcprintf(s16, EA_CHAR16("hello"), arguments);
- EATEST_VERIFY((result == 5) && (s16 == EA_CHAR16("hello")));
- va_end(arguments);
- }
- // template <typename String>
- // int StringPrintf(String& s, const typename String::value_type* EA_RESTRICT pFormat, ...)
- {
- eastl::string16 s16;
- int result = StringPrintf(s16, EA_CHAR16("%s"), EA_WCHAR("hello"));
- EATEST_VERIFY((result == 5) && (s16 == EA_CHAR16("hello")));
- }
- {
- char16_t buffer[128];
- const int kHexValue = 0x12;
- Sprintf(buffer, EA_CHAR16("%.4x"), kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("0012")) == 0);
- Sprintf(buffer, EA_CHAR16("%04x"), kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("0012")) == 0);
- Sprintf(buffer, EA_CHAR16("%4.4x"), kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("0012")) == 0);
- Sprintf(buffer, EA_CHAR16("%04.4x"), kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("0012")) == 0);
- Sprintf(buffer, EA_CHAR16("%4.3x"), kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" 012")) == 0);
- Sprintf(buffer, EA_CHAR16("%04.3x"), kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" 012")) == 0);
- Sprintf(buffer, EA_CHAR16("%.*x"), 4, kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("0012")) == 0);
- Sprintf(buffer, EA_CHAR16("%0*x"), 4, kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("0012")) == 0);
- Sprintf(buffer, EA_CHAR16("%*.*x"), 4, 4, kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("0012")) == 0);
- Sprintf(buffer, EA_CHAR16("%0*.*x"), 4, 4, kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("0012")) == 0);
- }
- {
- char16_t buffer[128];
- Sprintf(buffer, EA_CHAR16("decimal negative: \"%d\"\n"), -2345);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("decimal negative: \"-2345\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("octal negative: \"%o\"\n"), -2345);
- if(sizeof(int) == (4 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("octal negative: \"37777773327\"\n")) == 0);
- else if(sizeof(int) == (8 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("octal negative: \"1777777777777777773327\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("hex negative: \"%x\"\n"), -2345);
- if(sizeof(int) == (4 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("hex negative: \"fffff6d7\"\n")) == 0);
- else if(sizeof(int) == (8 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("hex negative: \"fffffffffffff6d7\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("long decimal number: \"%ld\"\n"), -123456L);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("long decimal number: \"-123456\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("long octal negative: \"%lo\"\n"), -2345L);
- if(sizeof(long) == (4 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("long octal negative: \"37777773327\"\n")) == 0);
- else if(sizeof(long) == (8 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("long octal negative: \"1777777777777777773327\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("long unsigned decimal number: \"%lu\"\n"), -123456L);
- if(sizeof(long) == (4 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("long unsigned decimal number: \"4294843840\"\n")) == 0);
- else if(sizeof(long) == (8 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("long unsigned decimal number: \"18446744073709428160\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("zero-padded LDN: \"%010ld\"\n"), -123456L);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("zero-padded LDN: \"-000123456\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("left-adjusted ZLDN: \"%-010ld\"\n"), -123456L);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("left-adjusted ZLDN: \"-123456 \"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("space-padded LDN: \"%10ld\"\n"), -123456L);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("space-padded LDN: \" -123456\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("left-adjusted SLDN: \"%-10ld\"\n"), -123456L);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("left-adjusted SLDN: \"-123456 \"\n")) == 0);
- }
- {
- char16_t buffer[1024];
- wchar_t str1[64]; Strlcpy(str1, EA_WCHAR("abc de"), EAArrayCount(str1)); // Can't do str1[64] = EA_CHAR16("abc de") because some compilers don't support 16 bit string literals.
- wchar_t str2[64]; Strlcpy(str2, EA_WCHAR("abd def ghi jkl mno pqr stu vwz yz."), EAArrayCount(str2));
- // The C99 standard specifies that leading zeros only put zeroes in front of numerical types. Spaces for others.
- Sprintf(buffer, EA_CHAR16("zero-padded string: \"%010s\"\n"), str1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("zero-padded string: \" abc de\"\n")) == 0); // VC++ fails this, as it puts zeroes in front.
- Sprintf(buffer, EA_CHAR16("left-adjusted Z string: \"%-010s\"\n"), str1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("left-adjusted Z string: \"abc de \"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("space-padded string: \"%10s\"\n"), str1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("space-padded string: \" abc de\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("left-adjusted S string: \"%-10s\"\n"), str1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("left-adjusted S string: \"abc de \"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("limited string: \"%.22s\"\n"), str2);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("limited string: \"abd def ghi jkl mno pq\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("null string: \"%s\"\n"), (wchar_t*)NULL);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("null string: \"(null)\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("%10s\n"), (wchar_t*)NULL);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" (null)\n")) == 0);
- Sprintf(buffer, EA_CHAR16("%-10s\n"), (wchar_t*)NULL);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("(null) \n")) == 0);
- Sprintf(buffer, EA_CHAR16("%*s%*s%*s"), -1, EA_WCHAR("one"), -20, EA_WCHAR("two"), -30, EA_WCHAR("three"));
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("onetwo three ")) == 0);
- int i;
- memset(buffer, '_', sizeof(buffer));
- Sprintf(buffer, EA_CHAR16("x%1000ls"), EA_WCHAR(" "));
- EATEST_VERIFY(buffer[0] == 'x');
- for(i = 0; i < 1000; i++)
- {
- if(buffer[1 + i] != ' ')
- break;
- }
- if(i != 1000)
- EATEST_VERIFY(i == 1000);
- else
- EATEST_VERIFY(buffer[1 + 1000] == EA_CHAR16('\0'));
- }
- { // String tests
- // We accept %hc, %c, %lc, %I8c, %I16c, %I32c (regular, regular, wide, char8_t, char16_t, char32_t)
- // We accept %hC, %C, %lC, %I8C, %I16C, %I32C (regular, wide, wide, char8_t, char16_t, char32_t)
- // We accept %hs, %s, %ls, %I8s, %I16s, %I32s (regular, regular, wide, char8_t, char16_t, char32_t)
- // We accept %hS, %S, %lS, %I8s, %I16s, %I32s (regular, wide, wide, char8_t, char16_t, char32_t)
- char16_t buffer[32];
- char8_t dStr8[2] = { 'd', 0 };
- char16_t eStr16[2] = { 'e', 0 };
- char32_t fStr32[2] = { 'f', 0 };
- #if EASPRINTF_MS_STYLE_S_FORMAT // Microsoft style means that the meanings of S and s are reversed for non-char8_t Sprintf.
- Sprintf(buffer, EA_CHAR16("%hc %c %lc %I8c %I16c %I32c"), 'a', EA_WCHAR('b'), EA_WCHAR('c'), (char8_t)'d', (char16_t)'e', (char32_t)'f');
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("a b c d e f")) == 0);
- Sprintf(buffer, EA_CHAR16("%hC %C %lC %I8C %I16C %I32C"), 'a', 'b', EA_WCHAR('c'), (char8_t)'d', (char16_t)'e', (char32_t)'f');
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("a b c d e f")) == 0);
- Sprintf(buffer, EA_CHAR16("%hs %s %ls %I8s %I16s %I32s"), "a", EA_WCHAR("b"), EA_WCHAR("c"), dStr8, eStr16, fStr32);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("a b c d e f")) == 0);
- Sprintf(buffer, EA_CHAR16("%hS %S %lS %I8S %I16S %I32S"), "a", "b", EA_WCHAR("c"), dStr8, eStr16, fStr32);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("a b c d e f")) == 0);
- #else
- Sprintf(buffer, EA_CHAR16("%hc %c %lc %I8c %I16c %I32c"), 'a', 'b', EA_WCHAR('c'), (char8_t)'d', (char16_t)'e', (char32_t)'f');
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("a b c d e f")) == 0);
- Sprintf(buffer, EA_CHAR16("%hC %C %lC %I8C %I16C %I32C"), 'a', EA_WCHAR('b'), EA_WCHAR('c'), (char8_t)'d', (char16_t)'e', (char32_t)'f');
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("a b c d e f)") == 0);
- Sprintf(buffer, EA_CHAR16("%hs %s %ls %I8s %I16s %I32s"), "a", "b", EA_WCHAR("c"), dStr8, eStr16, fStr32);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("a b c d e f")) == 0);
- Sprintf(buffer, EA_CHAR16("%hS %S %lS %I8S %I16S %I32S"), "a", EA_WCHAR("b"), EA_WCHAR("c"), dStr8, eStr16, fStr32);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("a b c d e f")) == 0);
- #endif
- }
- {
- char16_t buffer[1024];
- int i;
- Sprintf(buffer, EA_CHAR16("e-style >= 1: \"%e\"\n"), 12.34);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("e-style >= 1: \"1.234000e+01\"\n")) == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, EA_CHAR16("e-style >= .1: \"%e\"\n"), 0.1234);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("e-style >= .1: \"1.234000e-01\"\n")) == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, EA_CHAR16("e-style < .1: \"%e\"\n"), 0.001234);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("e-style < .1: \"1.234000e-03\"\n")) == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, EA_CHAR16("e-style big: \"%.60e\"\n"), 1e20);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("e-style big: \"1.000000000000000000000000000000000000000000000000000000000000e+20\"\n")) == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, EA_CHAR16("e-style == .1: \"%e\"\n"), 0.1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("e-style == .1: \"1.000000e-01\"\n")) == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, EA_CHAR16("f-style >= 1: \"%f\"\n"), 12.34);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("f-style >= 1: \"12.340000\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("f-style >= .1: \"%f\"\n"), 0.1234);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("f-style >= .1: \"0.123400\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("f-style < .1: \"%f\"\n"), 0.001234);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("f-style < .1: \"0.001234\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("g-style >= 1: \"%g\"\n"), 12.34);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("g-style >= 1: \"12.34\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("g-style >= .1: \"%g\"\n"), 0.1234);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("g-style >= .1: \"0.1234\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("g-style < .1: \"%g\"\n"), 0.001234);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("g-style < .1: \"0.001234\"\n")) == 0);
- Sprintf(buffer, EA_CHAR16("g-style big: \"%.60g\"\n"), 1e20);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("g-style big: \"100000000000000000000\"\n")) == 0);
- //Sprintf(buffer, EA_CHAR16("%#.4g\n"), 0.0); // The C99 committee has decided in a defect analysis that this is how it should work.
- //EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("0\n")) == 0);
- Sprintf(buffer, EA_CHAR16(" %6.5f\n"), .099999999860301614);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" 0.10000\n")) == 0);
- Sprintf(buffer, EA_CHAR16(" %6.5f\n"), .1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" 0.10000\n")) == 0);
- Sprintf(buffer, EA_CHAR16("x%5.4fx\n"), .5);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("x0.5000x\n")) == 0);
- Sprintf(buffer, EA_CHAR16("%#03x\n"), 1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("0x1\n")) == 0);
- memset(buffer, '_', sizeof(buffer));
- Sprintf(buffer, EA_CHAR16("%.300f"), 1.0);
- EATEST_VERIFY((buffer[0] == '1') && (buffer[1] == '.'));
- for(i = 0; i < 300; i++)
- {
- if(buffer[2 + i] != '0')
- break;
- }
- if(i != 300)
- EATEST_VERIFY(i == 300);
- else
- EATEST_VERIFY(buffer[2 + 300] == EA_CHAR16('\0'));
- // Operations on FLT_MIN are undefined on Neon
- double d = static_cast<double>(FLT_MIN); // We are intentionally using FLT_MIN and not DBL_MIN.
- d /= 2.0;
- Sprintf(buffer, EA_CHAR16("%.17e"), d); // It should be something like 5.87747175411143___e-39 where count and values of the _ digits vary by hardware.
- buffer[16] = buffer[17] = buffer[18] = '_'; // Replace the uncertain digits with '_' characters, as they are system-dependent.
-
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("5.87747175411143___e-39")) == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, EA_CHAR16("%15.5e\n"), 4.9406564584124654e-307);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" 4.94066e-307\n")) == 0);
- }
- {
- char16_t buffer[256];
- const char16_t* pExpected;
- // VC++ sprintf would fail these tests, as the Standard says to print no more
- // than 2 unless necessary, yet VC++ sprintf prints 3 digits exponents.
- Sprintf(buffer, EA_CHAR16("|%12.4f|%12.4e|%12.4g|"), 0.0, 0.0, 0.0);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("| 0.0000| 0.0000e+00| 0|")) == 0);
- Sprintf(buffer, EA_CHAR16("|%12.4f|%12.4e|%12.4g|"), 1.0, 1.0, 1.0);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("| 1.0000| 1.0000e+00| 1|")) == 0);
- Sprintf(buffer, EA_CHAR16("|%12.4f|%12.4e|%12.4g|"), -1.0, -1.0, -1.0);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("| -1.0000| -1.0000e+00| -1|")) == 0);
- Sprintf(buffer, EA_CHAR16("|%12.4f|%12.4e|%12.4g|"), 100.0, 100.0, 100.0);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("| 100.0000| 1.0000e+02| 100|")) == 0);
- Sprintf(buffer, EA_CHAR16("|%12.4f|%12.4e|%12.4g|"), 1000.0, 1000.0, 1000.0);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("| 1000.0000| 1.0000e+03| 1000|")) == 0);
- Sprintf(buffer, EA_CHAR16("|%12.4f|%12.4e|%12.4g|"), 10000.0, 10000.0, 10000.0);
- EATEST_VERIFY(Strcmp(buffer,EA_CHAR16("| 10000.0000| 1.0000e+04| 1e+04|")) == 0);
- Sprintf(buffer, EA_CHAR16("|%12.4f|%12.4e|%12.4g|"), 12346.0, 12346.0, 12346.0);
- pExpected = EA_CHAR16("| 12346.0000| 1.2346e+04| 1.235e+04|");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I16s\n Actual: %I16s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR16("|%12.4f|%12.4e|%12.4g|"), 100000.0, 100000.0, 100000.0);
- pExpected = EA_CHAR16("| 100000.0000| 1.0000e+05| 1e+05|");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I16s\n Actual: %I16s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR16("|%12.4f|%12.4e|%12.4g|"), 123467.0, 123467.0, 123467.0);
- pExpected = EA_CHAR16("| 123467.0000| 1.2347e+05| 1.235e+05|");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I16s\n Actual: %I16s", pExpected, buffer);
- }
- {
- char16_t buffer[256];
- // Verify that snprintf follows the C99 convention of returning the number of characters
- // required. This is as opposed to the non-standard way that some libraries just return
- // -1 if the buffer isn't big enough.
- const int kBuf1Capacity = 20;
- wchar_t buf1[kBuf1Capacity];
- int n1 = Snprintf(buf1, kBuf1Capacity, EA_WCHAR("%30I16s"), EA_CHAR16("foo"));
- Sprintf(buffer, EA_CHAR16("snprintf(\"%%30s\", \"foo\") == %d, \"%.*s\"\n"), n1, kBuf1Capacity, buf1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("snprintf(\"%30s\", \"foo\") == 30, \" \"\n")) == 0); // VC++ fails this, as it's version of snprintf doesn't use C99 standard snprintf return value conventions.
- const int kBuf2Capacity = 512;
- char16_t buf2[kBuf2Capacity];
- int n2 = Snprintf(buf2, kBuf2Capacity, EA_CHAR16("%.1000u"), 10);
- Sprintf(buffer, EA_CHAR16("snprintf(\"%%.1000u\", 10) == %d\n"), n2);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("snprintf(\"%.1000u\", 10) == 1000\n")) == 0); // VC++ fails this, as it's version of snprintf doesn't use C99 standard snprintf return value conventions.
- const int kBuf3Capacity = 512;
- char16_t buf3[kBuf3Capacity];
- char16_t* pString = new char16_t[100000];
- memset(pString, '_', 100000 * sizeof(char16_t));
- pString[100000 - 1] = 0;
- int n3 = Snprintf(buf3, kBuf2Capacity, EA_CHAR16("%I16s"), pString);
- Sprintf(buffer, EA_CHAR16("snprintf(\"%%s\", pString) == %d\n"), n3);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("snprintf(\"%s\", pString) == 99999\n")) == 0); // VC++ fails this, as it's version of snprintf doesn't use C99 standard snprintf return value conventions.
- delete[] pString;
- int n4 = Snprintf(NULL, 0, EA_CHAR16("%I16s"), EA_CHAR16("abc"));
- Sprintf(buffer, EA_CHAR16("snprintf(NULL, \"abc\") == %d\n"), n4);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("snprintf(NULL, \"abc\") == 3\n")) == 0); // VC++ fails this, as it's version of snprintf doesn't use C99 standard snprintf return value conventions.
- int n5 = Snprintf(NULL, 100, EA_CHAR16("%I16s"), EA_CHAR16("abc"));
- Sprintf(buffer, EA_CHAR16("snprintf(NULL, \"abc\") == %d\n"), n5);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("snprintf(NULL, \"abc\") == 3\n")) == 0); // VC++ fails this, as it's version of snprintf doesn't use C99 standard snprintf return value conventions.
- }
- {
- char16_t buffer[16][256];
- int n = 0, i, j, k, m;
- for(i = 0; i < 2; i++)
- {
- for(j = 0; j < 2; j++)
- {
- for(k = 0; k < 2; k++)
- {
- for(m = 0; m < 2; m++)
- {
- wchar_t prefix[7];
- char16_t format[128];
- Strcpy(prefix, EA_WCHAR("%"));
- if(i == 0)
- Strcat(prefix, EA_WCHAR("-"));
- if(j == 0)
- Strcat(prefix, EA_WCHAR("+"));
- if(k == 0)
- Strcat(prefix, EA_WCHAR("#"));
- if(m == 0)
- Strcat(prefix, EA_WCHAR("0"));
- #define DEC -123
- #define INT 255
- #define UNS (~0)
- Sprintf(format, EA_CHAR16("%%5s |%s6d |%s6o |%s6x |%s6X |%s6u |"), prefix, prefix, prefix, prefix, prefix);
- Sprintf(buffer[n], format, prefix, DEC, INT, INT, INT, UNS);
- n++;
- }
- }
- }
- }
- EATEST_VERIFY(Strcmp(buffer[ 0], EA_CHAR16("%-+#0 |-123 |0377 |0xff |0XFF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 1], EA_CHAR16(" %-+# |-123 |0377 |0xff |0XFF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 2], EA_CHAR16(" %-+0 |-123 |377 |ff |FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 3], EA_CHAR16(" %-+ |-123 |377 |ff |FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 4], EA_CHAR16(" %-#0 |-123 |0377 |0xff |0XFF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 5], EA_CHAR16(" %-# |-123 |0377 |0xff |0XFF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 6], EA_CHAR16(" %-0 |-123 |377 |ff |FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 7], EA_CHAR16(" %- |-123 |377 |ff |FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 8], EA_CHAR16(" %+#0 |-00123 |000377 |0x00ff |0X00FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 9], EA_CHAR16(" %+# | -123 | 0377 | 0xff | 0XFF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[10], EA_CHAR16(" %+0 |-00123 |000377 |0000ff |0000FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[11], EA_CHAR16(" %+ | -123 | 377 | ff | FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[12], EA_CHAR16(" %#0 |-00123 |000377 |0x00ff |0X00FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[13], EA_CHAR16(" %# | -123 | 0377 | 0xff | 0XFF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[14], EA_CHAR16(" %0 |-00123 |000377 |0000ff |0000FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[15], EA_CHAR16(" % | -123 | 377 | ff | FF |4294967295 |")) == 0);
- }
- {
- char16_t buffer[256];
- const char16_t* pExpected;
- Sprintf(buffer, EA_CHAR16("%e"), 1234567.8); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- pExpected = EA_CHAR16("1.234568e+06");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I16s\n Actual: %I16s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR16("%f"), 1234567.8);
- pExpected = EA_CHAR16("1234567.800000");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I16s\n Actual: %I16s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR16("%g"), 1234567.8); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- pExpected = EA_CHAR16("1.23457e+06");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I16s\n Actual: %I16s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR16("%g"), 123.456);
- pExpected = EA_CHAR16("123.456");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I16s\n Actual: %I16s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR16("%g"), 1000000.0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- pExpected = EA_CHAR16("1e+06");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I16s\n Actual: %I16s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR16("%g"), 10.0);
- pExpected = EA_CHAR16("10");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I16s\n Actual: %I16s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR16("%g"), 0.02);
- pExpected = EA_CHAR16("0.02");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I16s\n Actual: %I16s", pExpected, buffer);
- }
- { // Test the ' extension, that prints numbers with a thousands separator.
- char16_t buffer[64];
- const char16_t* pExpected;
- Sprintf(buffer, EA_CHAR16("%'u"), 123456789);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("123,456,789")) == 0);
- Sprintf(buffer, EA_CHAR16("%'d"), -123456789);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("-123,456,789")) == 0);
- Sprintf(buffer, EA_CHAR16("%'I8u"), 123);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("123")) == 0);
- Sprintf(buffer, EA_CHAR16("%'I16u"), 12345);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("12,345")) == 0);
- Sprintf(buffer, EA_CHAR16("%'I16d"), -12345);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("-12,345")) == 0);
- Sprintf(buffer, EA_CHAR16("%'I32u"), 12345678);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("12,345,678")) == 0);
- Sprintf(buffer, EA_CHAR16("%'I32d"), -12345678);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("-12,345,678")) == 0);
- Sprintf(buffer, EA_CHAR16("%20I32d"), -12345678);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" -12345678")) == 0);
- Sprintf(buffer, EA_CHAR16("%'20I32d"), -12345678); // Verify that the , chars count towards the field width.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" -12,345,678")) == 0);
- Sprintf(buffer, EA_CHAR16("%'I32x"), 0x12345678); // ' has no effect on hex formatting.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("12345678")) == 0);
- Sprintf(buffer, EA_CHAR16("%'I64u"), UINT64_C(1234999995678));
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("1,234,999,995,678")) == 0);
- Sprintf(buffer, EA_CHAR16("%'I64d"), INT64_C(-1234599999678));
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("-1,234,599,999,678")) == 0);
- Sprintf(buffer, EA_CHAR16("%'I64x"), UINT64_C(0x1234567812345678)); // ' has no effect on hex formatting.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("1234567812345678")) == 0);
- Sprintf(buffer, EA_CHAR16("%'f"), 123456.234);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("123,456.234000")) == 0);
- Sprintf(buffer, EA_CHAR16("%'e"), 1234567.8); // ' has no effect on %e formatting.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("1.234568e+06")) == 0);
- Sprintf(buffer, EA_CHAR16("%'g"), 1234.54); // In some cases %g acts like %f.
- pExpected = EA_CHAR16("1,234.54");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I16s\n Actual: %I16s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR16("%'g"), 1234567.8); // In some cases %g acts like %f.
- pExpected = EA_CHAR16("1.23457e+06");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I16s\n Actual: %I16s", pExpected, buffer);
- }
- {
- char16_t buffer[256];
- Sprintf(buffer, EA_CHAR16("%hhu"), UCHAR_MAX + 2);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("1")) == 0); // VC++ fails this, as it doesn't implement the C99 standard %hh modifier.
- Sprintf(buffer, EA_CHAR16("%hu"), USHRT_MAX + 2);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("1")) == 0);
- }
- {
- char16_t buffer[128];
- const char16_t* pExpected;
- Sprintf(buffer, EA_CHAR16("%5.s"), EA_WCHAR("xyz"));
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" ")) == 0);
- Sprintf(buffer, EA_CHAR16("%5.f"), 33.3);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" 33")) == 0);
- Sprintf(buffer, EA_CHAR16("%8.e"), 33.3e7); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" 3e+08")) == 0);
- Sprintf(buffer, EA_CHAR16("%8.E"), 33.3e7); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" 3E+08")) == 0);
- Sprintf(buffer, EA_CHAR16("%.g"), 33.3); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- pExpected = EA_CHAR16("3e+01");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I16s\n Actual: %I16s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR16("%.G"), 33.3); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- pExpected = EA_CHAR16("3E+01");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I16s\n Actual: %I16s", pExpected, buffer);
- }
- {
- char16_t buffer[128];
- int precision;
- precision = 0;
- Sprintf(buffer, EA_CHAR16("%.*g"), precision, 3.3);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("3")) == 0);
- precision = 0;
- Sprintf(buffer, EA_CHAR16("%.*G"), precision, 3.3);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16("3")) == 0);
- precision = 0;
- Sprintf(buffer, EA_CHAR16("%7.*G"), precision, 3.33);
- EATEST_VERIFY(Strcmp(buffer,EA_CHAR16(" 3")) == 0);
- precision = 3;
- Sprintf(buffer, EA_CHAR16("%04.*o"), precision, 33);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" 041")) == 0);
- precision = 7;
- Sprintf(buffer, EA_CHAR16("%09.*u"), precision, 33);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" 0000033")) == 0);
- precision = 3;
- Sprintf(buffer, EA_CHAR16("%04.*x"), precision, 33);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" 021")) == 0);
- precision = 3;
- Sprintf(buffer, EA_CHAR16("%04.*X"), precision, 33);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR16(" 021")) == 0);
- }
- {
- static const int kSourceSize = 1024 * 5;
- static const int kOutputSize = kSourceSize + 100;
- char8_t value[kSourceSize];
- char16_t destination[kOutputSize];
- char16_t comparison[kOutputSize];
- for(int i = 0; i < kSourceSize - 1; ++i)
- {
- value[i] = '0' + (i % 10);
- comparison[i] = '0' + (i % 10);
- }
- value[kSourceSize - 1] = 0;
- comparison[kSourceSize - 1] = 0;
- EA::StdC::Snprintf(destination, kOutputSize, EA_CHAR16("%I8s"), value);
- EATEST_VERIFY(Strcmp(destination, comparison) == 0);
- EA::StdC::Snprintf(destination, kOutputSize, EA_CHAR16("%.10I8s"), value);
- EATEST_VERIFY(Strcmp(destination, EA_CHAR16("0123456789")) == 0);
- }
- return nErrorCount;
- }
- static int TestSprintf32(int unused = 0, ...)
- {
- using namespace EA::StdC;
- int nErrorCount(0);
- // int Snprintf(char_t* pDestination, size_t n, const char_t* pFormat, ...);
- {
- char32_t sn18[32];
- Snprintf(sn18, EAArrayCount(sn18), EA_CHAR32("%5s%-4d%03i"), EA_WCHAR("abc"), -12, 3);
- EATEST_VERIFY(!Strcmp(EA_CHAR32(" abc-12 003"), sn18));
- Snprintf(sn18, EAArrayCount(sn18), EA_CHAR32("%.2f"), 3.1415);
- EATEST_VERIFY(!Strcmp(EA_CHAR32("3.14"), sn18));
- }
- // int Vsnprintf(char_t* pDestination, size_t n, const char_t* pFormat, ...);
- {
- char32_t sn18[32];
- TestCRTVsnprintf(sn18, EAArrayCount(sn18), EA_CHAR32("%5s%-5d%04i"), EA_WCHAR("abc"), -12, 3);
- EATEST_VERIFY(!Strcmp(EA_CHAR32(" abc-12 0003"), sn18));
- TestCRTVsnprintf(sn18, EAArrayCount(sn18), EA_CHAR32("%.2f"), 3.1415);
- EATEST_VERIFY(!Strcmp(EA_CHAR32("3.14"), sn18));
- }
- #if EASTDC_VSNPRINTF8_ENABLED
- {
- char32_t sn18[32];
- TestCRTVsnprintf32(sn18, EAArrayCount(sn18), EA_CHAR32("%5s%-5d%04i"), EA_WCHAR("abc"), -12, 3);
- EATEST_VERIFY(!Strcmp(EA_CHAR32(" abc-12 0003"), sn18));
- TestCRTVsnprintf32(sn18, EAArrayCount(sn18), EA_CHAR32("%.2f"), 3.1415);
- EATEST_VERIFY(!Strcmp(EA_CHAR32("3.14"), sn18));
- }
- #endif
- // int Vscprintf(const char_t* pFormat, va_list arguments);
- {
- va_list arguments;
- va_start(arguments, unused);
- int result = Vscprintf(EA_CHAR32("abc"), arguments);
- EATEST_VERIFY(result == 3);
- va_end(arguments);
- }
- // template <typename String>
- // int StringVcprintf(String& s, const char8_t* EA_RESTRICT pFormat, va_list arguments)
- {
- va_list arguments;
- va_start(arguments, unused);
- eastl::string32 s32;
- int result = StringVcprintf(s32, EA_CHAR32("hello"), arguments);
- EATEST_VERIFY((result == 5) && (s32 == EA_CHAR32("hello")));
- va_end(arguments);
- }
- // template <typename String>
- // int StringPrintf(String& s, const typename String::value_type* EA_RESTRICT pFormat, ...)
- {
- eastl::string32 s32;
- int result = StringPrintf(s32, EA_CHAR32("%s"), EA_WCHAR("hello"));
- EATEST_VERIFY((result == 5) && (s32 == EA_CHAR32("hello")));
- }
- {
- char32_t buffer[32];
- const int kHexValue = 0x12;
- Sprintf(buffer, EA_CHAR32("%.4x"), kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("0012")) == 0);
- Sprintf(buffer, EA_CHAR32("%04x"), kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("0012")) == 0);
- Sprintf(buffer, EA_CHAR32("%4.4x"), kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("0012")) == 0);
- Sprintf(buffer, EA_CHAR32("%04.4x"), kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("0012")) == 0);
- Sprintf(buffer, EA_CHAR32("%4.3x"), kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" 012")) == 0);
- Sprintf(buffer, EA_CHAR32("%04.3x"), kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" 012")) == 0);
- Sprintf(buffer, EA_CHAR32("%.*x"), 4, kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("0012")) == 0);
- Sprintf(buffer, EA_CHAR32("%0*x"), 4, kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("0012")) == 0);
- Sprintf(buffer, EA_CHAR32("%*.*x"), 4, 4, kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("0012")) == 0);
- Sprintf(buffer, EA_CHAR32("%0*.*x"), 4, 4, kHexValue);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("0012")) == 0);
- }
- {
- char32_t buffer[96];
- Sprintf(buffer, EA_CHAR32("decimal negative: \"%d\"\n"), -2345);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("decimal negative: \"-2345\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("octal negative: \"%o\"\n"), -2345);
- if(sizeof(int) == (4 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("octal negative: \"37777773327\"\n")) == 0);
- else if(sizeof(int) == (8 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("octal negative: \"1777777777777777773327\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("hex negative: \"%x\"\n"), -2345);
- if(sizeof(int) == (4 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("hex negative: \"fffff6d7\"\n")) == 0);
- else if(sizeof(int) == (8 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("hex negative: \"fffffffffffff6d7\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("long decimal number: \"%ld\"\n"), -123456L);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("long decimal number: \"-123456\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("long octal negative: \"%lo\"\n"), -2345L);
- if(sizeof(long) == (4 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("long octal negative: \"37777773327\"\n")) == 0);
- else if(sizeof(long) == (8 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("long octal negative: \"1777777777777777773327\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("long unsigned decimal number: \"%lu\"\n"), -123456L);
- if(sizeof(long) == (4 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("long unsigned decimal number: \"4294843840\"\n")) == 0);
- else if(sizeof(long) == (8 + (__FILE__[0] / 100000))) // Trickery here to avoid compiler warnings.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("long unsigned decimal number: \"18446744073709428160\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("zero-padded LDN: \"%010ld\"\n"), -123456L);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("zero-padded LDN: \"-000123456\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("left-adjusted ZLDN: \"%-010ld\"\n"), -123456L);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("left-adjusted ZLDN: \"-123456 \"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("space-padded LDN: \"%10ld\"\n"), -123456L);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("space-padded LDN: \" -123456\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("left-adjusted SLDN: \"%-10ld\"\n"), -123456L);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("left-adjusted SLDN: \"-123456 \"\n")) == 0);
- }
- {
- char32_t buffer[1024];
- wchar_t str1[64]; Strlcpy(str1, EA_WCHAR("abc de"), EAArrayCount(str1)); // Can't do str1[64] = EA_CHAR32("abc de") because some compilers don't support 32 bit string literals.
- wchar_t str2[64]; Strlcpy(str2, EA_WCHAR("abd def ghi jkl mno pqr stu vwz yz."), EAArrayCount(str2));
- // The C99 standard specifies that leading zeros only put zeroes in front of numerical types. Spaces for others.
- Sprintf(buffer, EA_CHAR32("zero-padded string: \"%010s\"\n"), str1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("zero-padded string: \" abc de\"\n")) == 0); // VC++ fails this, as it puts zeroes in front.
- Sprintf(buffer, EA_CHAR32("left-adjusted Z string: \"%-010s\"\n"), str1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("left-adjusted Z string: \"abc de \"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("space-padded string: \"%10s\"\n"), str1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("space-padded string: \" abc de\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("left-adjusted S string: \"%-10s\"\n"), str1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("left-adjusted S string: \"abc de \"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("limited string: \"%.22s\"\n"), str2);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("limited string: \"abd def ghi jkl mno pq\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("null string: \"%s\"\n"), (wchar_t*)NULL);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("null string: \"(null)\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("%10s\n"), (wchar_t*)NULL);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" (null)\n")) == 0);
- Sprintf(buffer, EA_CHAR32("%-10s\n"), (wchar_t*)NULL);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("(null) \n")) == 0);
- Sprintf(buffer, EA_CHAR32("%*s%*s%*s"), -1, EA_WCHAR("one"), -20, EA_WCHAR("two"), -30, EA_WCHAR("three"));
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("onetwo three ")) == 0);
- int i;
- memset(buffer, '_', sizeof(buffer));
- Sprintf(buffer, EA_CHAR32("x%1000ls"), EA_WCHAR(" "));
- EATEST_VERIFY(buffer[0] == 'x');
- for(i = 0; i < 1000; i++)
- {
- if(buffer[1 + i] != ' ')
- break;
- }
- if(i != 1000)
- EATEST_VERIFY(i == 1000);
- else
- EATEST_VERIFY(buffer[1 + 1000] == 0);
- }
- { // String tests
- // We accept %hc, %c, %lc, %I8c, %I16c, %I32c (regular, regular, wide, char8_t, char16_t, char32_t)
- // We accept %hC, %C, %lC, %I8C, %I16C, %I32C (regular, wide, wide, char8_t, char16_t, char32_t)
- // We accept %hs, %s, %ls, %I8s, %I16s, %I32s (regular, regular, wide, char8_t, char16_t, char32_t)
- // We accept %hS, %S, %lS, %I8s, %I16s, %I32s (regular, wide, wide, char8_t, char16_t, char32_t)
- char32_t buffer[32];
- char8_t dStr8[2] = { 'd', 0 };
- char16_t eStr16[2] = { 'e', 0 };
- char32_t fStr32[2] = { 'f', 0 };
- #if EASPRINTF_MS_STYLE_S_FORMAT // Microsoft style means that the meanings of S and s are reversed for non-char8_t Sprintf.
- Sprintf(buffer, EA_CHAR32("%hc %c %lc %I8c %I16c %I32c"), 'a', EA_WCHAR('b'), EA_WCHAR('c'), (char8_t)'d', (char16_t)'e', (char32_t)'f');
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("a b c d e f")) == 0);
- Sprintf(buffer, EA_CHAR32("%hC %C %lC %I8C %I16C %I32C"), 'a', 'b', EA_WCHAR('c'), (char8_t)'d', (char16_t)'e', (char32_t)'f');
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("a b c d e f")) == 0);
- Sprintf(buffer, EA_CHAR32("%hs %s %ls %I8s %I16s %I32s"), "a", EA_WCHAR("b"), EA_WCHAR("c"), dStr8, eStr16, fStr32);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("a b c d e f")) == 0);
- Sprintf(buffer, EA_CHAR32("%hS %S %lS %I8S %I16S %I32S"), "a", "b", EA_WCHAR("c"), dStr8, eStr16, fStr32);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("a b c d e f")) == 0);
- #else
- Sprintf(buffer, EA_CHAR32("%hc %c %lc %I8c %I16c %I32c"), 'a', 'b', EA_WCHAR('c'), (char8_t)'d', (char16_t)'e', (char32_t)'f');
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("a b c d e f")) == 0);
- Sprintf(buffer, EA_CHAR32("%hC %C %lC %I8C %I16C %I32C"), 'a', EA_WCHAR('b'), EA_WCHAR('c'), (char8_t)'d', (char16_t)'e', (char32_t)'f');
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("a b c d e f)") == 0);
- Sprintf(buffer, EA_CHAR32("%hs %s %ls %I8s %I16s %I32s"), "a", "b", EA_WCHAR("c"), dStr8, eStr16, fStr32);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("a b c d e f")) == 0);
- Sprintf(buffer, EA_CHAR32("%hS %S %lS %I8S %I16S %I32S"), "a", EA_WCHAR("b"), EA_WCHAR("c"), dStr8, eStr16, fStr32);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("a b c d e f")) == 0);
- #endif
- }
- {
- char32_t buffer[384];
- int i;
- Sprintf(buffer, EA_CHAR32("e-style >= 1: \"%e\"\n"), 12.34);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("e-style >= 1: \"1.234000e+01\"\n")) == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, EA_CHAR32("e-style >= .1: \"%e\"\n"), 0.1234);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("e-style >= .1: \"1.234000e-01\"\n")) == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, EA_CHAR32("e-style < .1: \"%e\"\n"), 0.001234);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("e-style < .1: \"1.234000e-03\"\n")) == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, EA_CHAR32("e-style big: \"%.60e\"\n"), 1e20);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("e-style big: \"1.000000000000000000000000000000000000000000000000000000000000e+20\"\n")) == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, EA_CHAR32("e-style == .1: \"%e\"\n"), 0.1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("e-style == .1: \"1.000000e-01\"\n")) == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, EA_CHAR32("f-style >= 1: \"%f\"\n"), 12.34);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("f-style >= 1: \"12.340000\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("f-style >= .1: \"%f\"\n"), 0.1234);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("f-style >= .1: \"0.123400\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("f-style < .1: \"%f\"\n"), 0.001234);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("f-style < .1: \"0.001234\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("g-style >= 1: \"%g\"\n"), 12.34);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("g-style >= 1: \"12.34\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("g-style >= .1: \"%g\"\n"), 0.1234);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("g-style >= .1: \"0.1234\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("g-style < .1: \"%g\"\n"), 0.001234);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("g-style < .1: \"0.001234\"\n")) == 0);
- Sprintf(buffer, EA_CHAR32("g-style big: \"%.60g\"\n"), 1e20);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("g-style big: \"100000000000000000000\"\n")) == 0);
- //Sprintf(buffer, EA_CHAR32("%#.4g\n"), 0.0); // The C99 committee has decided in a defect analysis that this is how it should work.
- //EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("0\n")) == 0);
- Sprintf(buffer, EA_CHAR32(" %6.5f\n"), .099999999860301614);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" 0.10000\n")) == 0);
- Sprintf(buffer, EA_CHAR32(" %6.5f\n"), .1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" 0.10000\n")) == 0);
- Sprintf(buffer, EA_CHAR32("x%5.4fx\n"), .5);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("x0.5000x\n")) == 0);
- Sprintf(buffer, EA_CHAR32("%#03x\n"), 1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("0x1\n")) == 0);
- memset(buffer, '_', sizeof(buffer));
- Sprintf(buffer, EA_CHAR32("%.300f"), 1.0);
- EATEST_VERIFY((buffer[0] == '1') && (buffer[1] == '.'));
- for(i = 0; i < 300; i++)
- {
- if(buffer[2 + i] != '0')
- break;
- }
- if(i != 300)
- EATEST_VERIFY(i == 300);
- else
- EATEST_VERIFY(buffer[2 + 300] == 0);
- double d = static_cast<double>(FLT_MIN); // We are intentionally using FLT_MIN and not DBL_MIN.
- d /= 2.0;
- Sprintf(buffer, EA_CHAR32("%.17e"), d); // It should be something like 5.87747175411143___e-39 where count and values of the _ digits vary by hardware.
- buffer[16] = buffer[17] = buffer[18] = '_'; // Replace the uncertain digits with '_' characters, as they are system-dependent.
-
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("5.87747175411143___e-39")) == 0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- Sprintf(buffer, EA_CHAR32("%15.5e\n"), 4.9406564584124654e-307);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" 4.94066e-307\n")) == 0);
- }
- {
- char32_t buffer[96];
- const char32_t* pExpected;
- // VC++ sprintf would fail these tests, as the Standard says to print no more
- // than 2 unless necessary, yet VC++ sprintf prints 3 digits exponents.
- Sprintf(buffer, EA_CHAR32("|%12.4f|%12.4e|%12.4g|"), 0.0, 0.0, 0.0);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("| 0.0000| 0.0000e+00| 0|")) == 0);
- Sprintf(buffer, EA_CHAR32("|%12.4f|%12.4e|%12.4g|"), 1.0, 1.0, 1.0);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("| 1.0000| 1.0000e+00| 1|")) == 0);
- Sprintf(buffer, EA_CHAR32("|%12.4f|%12.4e|%12.4g|"), -1.0, -1.0, -1.0);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("| -1.0000| -1.0000e+00| -1|")) == 0);
- Sprintf(buffer, EA_CHAR32("|%12.4f|%12.4e|%12.4g|"), 100.0, 100.0, 100.0);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("| 100.0000| 1.0000e+02| 100|")) == 0);
- Sprintf(buffer, EA_CHAR32("|%12.4f|%12.4e|%12.4g|"), 1000.0, 1000.0, 1000.0);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("| 1000.0000| 1.0000e+03| 1000|")) == 0);
- Sprintf(buffer, EA_CHAR32("|%12.4f|%12.4e|%12.4g|"), 10000.0, 10000.0, 10000.0);
- EATEST_VERIFY(Strcmp(buffer,EA_CHAR32("| 10000.0000| 1.0000e+04| 1e+04|")) == 0);
- Sprintf(buffer, EA_CHAR32("|%12.4f|%12.4e|%12.4g|"), 12346.0, 12346.0, 12346.0);
- pExpected = EA_CHAR32("| 12346.0000| 1.2346e+04| 1.235e+04|");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I32s\n Actual: %I32s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR32("|%12.4f|%12.4e|%12.4g|"), 100000.0, 100000.0, 100000.0);
- pExpected = EA_CHAR32("| 100000.0000| 1.0000e+05| 1e+05|");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I32s\n Actual: %I32s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR32("|%12.4f|%12.4e|%12.4g|"), 123467.0, 123467.0, 123467.0);
- pExpected = EA_CHAR32("| 123467.0000| 1.2347e+05| 1.235e+05|");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I32s\n Actual: %I32s", pExpected, buffer);
- }
- {
- char32_t buffer[96];
- // Verify that snprintf follows the C99 convention of returning the number of characters
- // required. This is as opposed to the non-standard way that some libraries just return
- // -1 if the buffer isn't big enough.
- const int kBuf1Capacity = 20;
- wchar_t buf1[kBuf1Capacity];
- int n1 = Snprintf(buf1, kBuf1Capacity, EA_WCHAR("%30I32s"), EA_CHAR32("foo"));
- Sprintf(buffer, EA_CHAR32("snprintf(\"%%30s\", \"foo\") == %d, \"%.*s\"\n"), n1, kBuf1Capacity, buf1);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("snprintf(\"%30s\", \"foo\") == 30, \" \"\n")) == 0); // VC++ fails this, as it's version of snprintf doesn't use C99 standard snprintf return value conventions.
- const int kBuf2Capacity = 512;
- char32_t buf2[kBuf2Capacity];
- int n2 = Snprintf(buf2, kBuf2Capacity, EA_CHAR32("%.1000u"), 10);
- Sprintf(buffer, EA_CHAR32("snprintf(\"%%.1000u\", 10) == %d\n"), n2);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("snprintf(\"%.1000u\", 10) == 1000\n")) == 0); // VC++ fails this, as it's version of snprintf doesn't use C99 standard snprintf return value conventions.
- const int kBuf3Capacity = 512;
- char32_t buf3[kBuf3Capacity];
- char32_t* pString = new char32_t[100000];
- memset(pString, '_', 100000 * sizeof(char32_t));
- pString[100000 - 1] = 0;
- int n3 = Snprintf(buf3, kBuf2Capacity, EA_CHAR32("%I32s"), pString);
- Sprintf(buffer, EA_CHAR32("snprintf(\"%%s\", pString) == %d\n"), n3);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("snprintf(\"%s\", pString) == 99999\n")) == 0); // VC++ fails this, as it's version of snprintf doesn't use C99 standard snprintf return value conventions.
- delete[] pString;
- int n4 = Snprintf(NULL, 0, EA_CHAR32("%I32s"), EA_CHAR32("abc"));
- Sprintf(buffer, EA_CHAR32("snprintf(NULL, \"abc\") == %d\n"), n4);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("snprintf(NULL, \"abc\") == 3\n")) == 0); // VC++ fails this, as it's version of snprintf doesn't use C99 standard snprintf return value conventions.
- int n5 = Snprintf(NULL, 100, EA_CHAR32("%I32s"), EA_CHAR32("abc"));
- Sprintf(buffer, EA_CHAR32("snprintf(NULL, \"abc\") == %d\n"), n5);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("snprintf(NULL, \"abc\") == 3\n")) == 0); // VC++ fails this, as it's version of snprintf doesn't use C99 standard snprintf return value conventions.
- }
- {
- char32_t buffer[16][64];
- int n = 0, i, j, k, m;
- for(i = 0; i < 2; i++)
- {
- for(j = 0; j < 2; j++)
- {
- for(k = 0; k < 2; k++)
- {
- for(m = 0; m < 2; m++)
- {
- wchar_t prefix[7];
- char32_t format[96];
- Strcpy(prefix, EA_WCHAR("%"));
- if(i == 0)
- Strcat(prefix, EA_WCHAR("-"));
- if(j == 0)
- Strcat(prefix, EA_WCHAR("+"));
- if(k == 0)
- Strcat(prefix, EA_WCHAR("#"));
- if(m == 0)
- Strcat(prefix, EA_WCHAR("0"));
- #define DEC -123
- #define INT 255
- #define UNS (~0)
- Sprintf(format, EA_CHAR32("%%5s |%s6d |%s6o |%s6x |%s6X |%s6u |"), prefix, prefix, prefix, prefix, prefix);
- Sprintf(buffer[n], format, prefix, DEC, INT, INT, INT, UNS);
- n++;
- }
- }
- }
- }
- EATEST_VERIFY(Strcmp(buffer[ 0], EA_CHAR32("%-+#0 |-123 |0377 |0xff |0XFF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 1], EA_CHAR32(" %-+# |-123 |0377 |0xff |0XFF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 2], EA_CHAR32(" %-+0 |-123 |377 |ff |FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 3], EA_CHAR32(" %-+ |-123 |377 |ff |FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 4], EA_CHAR32(" %-#0 |-123 |0377 |0xff |0XFF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 5], EA_CHAR32(" %-# |-123 |0377 |0xff |0XFF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 6], EA_CHAR32(" %-0 |-123 |377 |ff |FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 7], EA_CHAR32(" %- |-123 |377 |ff |FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 8], EA_CHAR32(" %+#0 |-00123 |000377 |0x00ff |0X00FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[ 9], EA_CHAR32(" %+# | -123 | 0377 | 0xff | 0XFF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[10], EA_CHAR32(" %+0 |-00123 |000377 |0000ff |0000FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[11], EA_CHAR32(" %+ | -123 | 377 | ff | FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[12], EA_CHAR32(" %#0 |-00123 |000377 |0x00ff |0X00FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[13], EA_CHAR32(" %# | -123 | 0377 | 0xff | 0XFF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[14], EA_CHAR32(" %0 |-00123 |000377 |0000ff |0000FF |4294967295 |")) == 0);
- EATEST_VERIFY(Strcmp(buffer[15], EA_CHAR32(" % | -123 | 377 | ff | FF |4294967295 |")) == 0);
- }
- {
- char32_t buffer[256];
- const char32_t* pExpected;
- Sprintf(buffer, EA_CHAR32("%e"), 1234567.8); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- pExpected = EA_CHAR32("1.234568e+06");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I32s\n Actual: %I32s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR32("%f"), 1234567.8);
- pExpected = EA_CHAR32("1234567.800000");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I32s\n Actual: %I32s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR32("%g"), 1234567.8); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- pExpected = EA_CHAR32("1.23457e+06");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I32s\n Actual: %I32s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR32("%g"), 123.456);
- pExpected = EA_CHAR32("123.456");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I32s\n Actual: %I32s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR32("%g"), 1000000.0); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- pExpected = EA_CHAR32("1e+06");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I32s\n Actual: %I32s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR32("%g"), 10.0);
- pExpected = EA_CHAR32("10");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I32s\n Actual: %I32s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR32("%g"), 0.02);
- pExpected = EA_CHAR32("0.02");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I32s\n Actual: %I32s", pExpected, buffer);
- }
- { // Test the ' extension, which cases numbers to be printed with a thousands separator.
- char32_t buffer[64];
- const char32_t* pExpected;
- Sprintf(buffer, EA_CHAR32("%'u"), 123456789);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("123,456,789")) == 0);
- Sprintf(buffer, EA_CHAR32("%'d"), -123456789);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("-123,456,789")) == 0);
- Sprintf(buffer, EA_CHAR32("%'I8u"), 123);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("123")) == 0);
- Sprintf(buffer, EA_CHAR32("%'I16u"), 12345);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("12,345")) == 0);
- Sprintf(buffer, EA_CHAR32("%'I16d"), -12345);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("-12,345")) == 0);
- Sprintf(buffer, EA_CHAR32("%'I32u"), 12345678);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("12,345,678")) == 0);
- Sprintf(buffer, EA_CHAR32("%'I32d"), -12345678);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("-12,345,678")) == 0);
- Sprintf(buffer, EA_CHAR32("%20I32d"), -12345678);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" -12345678")) == 0);
- Sprintf(buffer, EA_CHAR32("%'20I32d"), -12345678); // Verify that the , chars count towards the field width.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" -12,345,678")) == 0);
- Sprintf(buffer, EA_CHAR32("%'I32x"), 0x12345678); // ' has no effect on hex formatting.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("12345678")) == 0);
- Sprintf(buffer, EA_CHAR32("%'I64u"), UINT64_C(1234999995678));
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("1,234,999,995,678")) == 0);
- Sprintf(buffer, EA_CHAR32("%'I64d"), INT64_C(-1234599999678));
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("-1,234,599,999,678")) == 0);
- Sprintf(buffer, EA_CHAR32("%'I64x"), UINT64_C(0x1234567812345678)); // ' has no effect on hex formatting.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("1234567812345678")) == 0);
- Sprintf(buffer, EA_CHAR32("%'f"), 123456.234);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("123,456.234000")) == 0);
- Sprintf(buffer, EA_CHAR32("%'e"), 1234567.8); // ' has no effect on %e formatting.
- pExpected = EA_CHAR32("1.234568e+06");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I32s\n Actual: %I32s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR32("%'g"), 1234.54); // In some cases %g acts like %f.
- pExpected = EA_CHAR32("1,234.54");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I32s\n Actual: %I32s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR32("%'g"), 1234567.8); // In some cases %g acts like %f.
- pExpected = EA_CHAR32("1.23457e+06");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I32s\n Actual: %I32s", pExpected, buffer);
- }
- {
- char32_t buffer[256];
- Sprintf(buffer, EA_CHAR32("%hhu"), UCHAR_MAX + 2);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("1")) == 0); // VC++ fails this, as it doesn't implement the C99 standard %hh modifier.
- Sprintf(buffer, EA_CHAR32("%hu"), USHRT_MAX + 2);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("1")) == 0);
- }
- {
- char32_t buffer[128];
- const char32_t* pExpected;
- Sprintf(buffer, EA_CHAR32("%5.s"), EA_WCHAR("xyz"));
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" ")) == 0);
- Sprintf(buffer, EA_CHAR32("%5.f"), 33.3);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" 33")) == 0);
- Sprintf(buffer, EA_CHAR32("%8.e"), 33.3e7); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" 3e+08")) == 0);
- Sprintf(buffer, EA_CHAR32("%8.E"), 33.3e7); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" 3E+08")) == 0);
- Sprintf(buffer, EA_CHAR32("%.g"), 33.3); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- pExpected = EA_CHAR32("3e+01");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I32s\n Actual: %I32s", pExpected, buffer);
- Sprintf(buffer, EA_CHAR32("%.G"), 33.3); // VC++ sprintf would fail this, as it uses 3 exponent digits, but the Standard says to print no more than 2 unless necessary.
- pExpected = EA_CHAR32("3E+01");
- EATEST_VERIFY_F(Strcmp(buffer, pExpected) == 0, "\n Expected: %I32s\n Actual: %I32s", pExpected, buffer);
- }
- {
- char32_t buffer[128];
- int precision;
- precision = 0;
- Sprintf(buffer, EA_CHAR32("%.*g"), precision, 3.3);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("3")) == 0);
- precision = 0;
- Sprintf(buffer, EA_CHAR32("%.*G"), precision, 3.3);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32("3")) == 0);
- precision = 0;
- Sprintf(buffer, EA_CHAR32("%7.*G"), precision, 3.33);
- EATEST_VERIFY(Strcmp(buffer,EA_CHAR32(" 3")) == 0);
- precision = 3;
- Sprintf(buffer, EA_CHAR32("%04.*o"), precision, 33);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" 041")) == 0);
- precision = 7;
- Sprintf(buffer, EA_CHAR32("%09.*u"), precision, 33);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" 0000033")) == 0);
- precision = 3;
- Sprintf(buffer, EA_CHAR32("%04.*x"), precision, 33);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" 021")) == 0);
- precision = 3;
- Sprintf(buffer, EA_CHAR32("%04.*X"), precision, 33);
- EATEST_VERIFY(Strcmp(buffer, EA_CHAR32(" 021")) == 0);
- }
- {
- static const int kSourceSize = 1024 * 5;
- static const int kOutputSize = kSourceSize + 100;
- char8_t value[kSourceSize];
- char32_t destination[kOutputSize];
- char32_t comparison[kOutputSize];
- for(int i = 0; i < kSourceSize - 1; ++i)
- {
- value[i] = '0' + (i % 10);
- comparison[i] = '0' + (i % 10);
- }
- value[kSourceSize - 1] = 0;
- comparison[kSourceSize - 1] = 0;
- EA::StdC::Snprintf(destination, kOutputSize, EA_CHAR32("%I8s"), value);
- EATEST_VERIFY(Strcmp(destination, comparison) == 0);
- EA::StdC::Snprintf(destination, kOutputSize, EA_CHAR32("%.10I8s"), value);
- EATEST_VERIFY(Strcmp(destination, EA_CHAR32("0123456789")) == 0);
- }
- return nErrorCount;
- }
- static int TestDrintf8()
- {
- using namespace EA::StdC;
- int nErrorCount = 0;
- {
- int result;
- Dprintf("Begin Dprintf (debug output printf) testing...\n");
- // EASTDC_API int Vdprintf(const char8_t* EA_RESTRICT pFormat, va_list arguments);
- // EASTDC_API int Dprintf(const char8_t* EA_RESTRICT pFormat, ...);
- eastl::string8 sBuffer;
- for(eastl_size_t i = 0; i < 1024; i++) // This size should be > than the size of the buffer(s) used in PlatformLogWriter8, though those buffer sizes aren't publicly exposed.
- sBuffer.push_back('a' + (char8_t)(i % 26));
- EA::UnitTest::Rand rand((uint32_t)EA::StdC::GetTime());
- for(eastl_size_t i = 0; i < 1024; i += rand.RandRange(1, 100))
- {
- char formatBuffer[32]; // Something like "%.52s"
- Sprintf(formatBuffer, "%%.%ds\n", i); // Use \n because some debug output systems might otherwise get overwhelmed.
- result = Dprintf(formatBuffer, sBuffer.c_str());
- EATEST_VERIFY(result > 0);
- }
- #if EASTDC_PRINTF_DEBUG_ENABLED
- // EASTDC_API int Fprintf(FILE* EA_RESTRICT pFile, const char8_t* EA_RESTRICT pFormat, ...);
- // EASTDC_API int Printf(const char8_t* EA_RESTRICT pFormat, ...);
- // EASTDC_API int Vfprintf(FILE* EA_RESTRICT pFile, const char8_t* EA_RESTRICT pFormat, va_list arguments);
- // EASTDC_API int Vprintf(const char8_t* EA_RESTRICT pFormat, va_list arguments);
- result = Printf("%s", "Printf test (EASTDC_PRINTF_DEBUG_ENABLED).\n");
- EATEST_VERIFY(result > 0);
- result = Fprintf(stdout, "%s", "Printf test (EASTDC_PRINTF_DEBUG_ENABLED).\n");
- EATEST_VERIFY(result > 0);
- #endif
- Dprintf("End Dprintf (debug output printf) testing.\n");
- }
- return nErrorCount;
- }
- static int TestOsprintf8()
- {
- using namespace EA::StdC;
- int nErrorCount = 0;
- {
- char8_t buffer[32];
- int result;
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, "%0:d", (int)0);
- EATEST_VERIFY((result == 1) && Strcmp(buffer, "0") == 0);
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, "%2:1.0f %3:d %1:c", (char)'3', (float)1.f, (int)2);
- EATEST_VERIFY((result == 5) && Strcmp(buffer, "1 2 3") == 0);
- // Test 0-based ordering
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, "%1:1.0f %2:d %0:c", (char)'3', (float)1.f, (int)2);
- EATEST_VERIFY((result == 5) && Strcmp(buffer, "1 2 3") == 0);
- // Test format limit (currently 21 spans)
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, " %0:d %1:d %2:d %3:d %4:d %5:d %6:d %7:d %8:d %9:d ", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
- EATEST_VERIFY((result == 28) && Strcmp(buffer, " 0 1 2 3 4 5 6 7 8 9 " ) == 0);
- // Test format overflow
- // Tests below are disabled by default because they trigger runtime asserts which break auto-testing.
- // They can be enabled by running these tests in interactive mode, in which case you'll have to manually
- // dismiss assertion failures for these.
- if(EA::UnitTest::GetInteractive())
- {
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, " %0:d %1:d %2:d %3:d %4:d %5:d %6:d %7:d %8:d %9:d %9:d ", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9);
- EATEST_VERIFY(result == -1);
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, "%00000000000000000000:f", 0.f);
- EATEST_VERIFY(result == -1);
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, "%0:000000000000000000f", 0.f);
- EATEST_VERIFY(result == -1);
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, "%0:.000000000000000000f", 0.f);
- EATEST_VERIFY(result == -1);
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, "%000000000000000000:000000000000000000.000000000000000000f", 0.f);
- EATEST_VERIFY(result == -1);
- }
- // Test OVsnprintf capacity limits
- memset(buffer, 0, sizeof(buffer));
- result = OSnprintf(buffer, 0, "%2:1.0f %3:d %1:c", (char)'3', (float)1.f, (int)2);
- EATEST_VERIFY((result == 5) && (buffer[0] == 0));
- }
- return nErrorCount;
- }
- static int TestOsprintf16()
- {
- using namespace EA::StdC;
- int nErrorCount = 0;
- {
- char16_t buffer[128];
- int result;
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR16("%0:d"), (int)0);
- EATEST_VERIFY((result == 1) && Strcmp(buffer, EA_CHAR16("0")) == 0);
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR16("%2:1.0f %3:d %1:c"), (char)'3', (float)1.f, (int)2);
- EATEST_VERIFY((result == 5) && Strcmp(buffer, EA_CHAR16("1 2 3")) == 0);
- // Test 0-based ordering
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR16("%1:1.0f %2:d %0:c"), (char)'3', (float)1.f, (int)2);
- EATEST_VERIFY((result == 5) && Strcmp(buffer, EA_CHAR16("1 2 3")) == 0);
- // Test format limit (currently 21 spans)
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR16(" %0:d %1:d %2:d %3:d %4:d %5:d %6:d %7:d %8:d %9:d "), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
- EATEST_VERIFY((result == 28) && Strcmp(buffer, EA_CHAR16(" 0 1 2 3 4 5 6 7 8 9 ")) == 0);
- // Test format overflow
- // Tests below are disabled by default because they trigger runtime asserts which break auto-testing.
- // They can be enabled by running these tests in interactive mode, in which case you'll have to manually
- // dismiss assertion failures for these.
- if(EA::UnitTest::GetInteractive())
- {
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR16(" %0:d %1:d %2:d %3:d %4:d %5:d %6:d %7:d %8:d %9:d %9:d "), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9);
- EATEST_VERIFY(result == -1);
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR16("%00000000000000000000:f"), 0.f);
- EATEST_VERIFY(result == -1);
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR16("%0:000000000000000000f"), 0.f);
- EATEST_VERIFY(result == -1);
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR16("%0:.000000000000000000f"), 0.f);
- EATEST_VERIFY(result == -1);
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR16("%000000000000000000:000000000000000000.000000000000000000f"), 0.f);
- EATEST_VERIFY(result == -1);
- }
- // Test OVsnprintf capacity limits
- memset(buffer, 0, sizeof(buffer));
- result = OSnprintf(buffer, 0, EA_CHAR16("%2:1.0f %3:d %1:c"), (char)'3', (float)1.f, (int)2);
- EATEST_VERIFY((result == 5) && (buffer[0] == 0));
- }
- return nErrorCount;
- }
- static int TestOsprintf32()
- {
- using namespace EA::StdC;
- int nErrorCount = 0;
- {
- char32_t buffer[128];
- int result;
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR32("%0:d"), (int)0);
- EATEST_VERIFY((result == 1) && Strcmp(buffer, EA_CHAR32("0")) == 0);
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR32("%2:1.0f %3:d %1:c"), (char)'3', (float)1.f, (int)2);
- EATEST_VERIFY((result == 5) && Strcmp(buffer, EA_CHAR32("1 2 3")) == 0);
- // Test 0-based ordering
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR32("%1:1.0f %2:d %0:c"), (char)'3', (float)1.f, (int)2);
- EATEST_VERIFY((result == 5) && Strcmp(buffer, EA_CHAR32("1 2 3")) == 0);
- // Test format limit (currently 21 spans)
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR32(" %0:d %1:d %2:d %3:d %4:d %5:d %6:d %7:d %8:d %9:d "), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
- EATEST_VERIFY((result == 28) && Strcmp(buffer, EA_CHAR32(" 0 1 2 3 4 5 6 7 8 9 ")) == 0);
- // Test format overflow
- // Tests below are disabled by default because they trigger runtime asserts which break auto-testing.
- // They can be enabled by running these tests in interactive mode, in which case you'll have to manually
- // dismiss assertion failures for these.
- if(EA::UnitTest::GetInteractive())
- {
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR32(" %0:d %1:d %2:d %3:d %4:d %5:d %6:d %7:d %8:d %9:d %9:d "), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9);
- EATEST_VERIFY(result == -1);
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR32("%00000000000000000000:f"), 0.f);
- EATEST_VERIFY(result == -1);
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR32("%0:000000000000000000f"), 0.f);
- EATEST_VERIFY(result == -1);
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR32("%0:.000000000000000000f"), 0.f);
- EATEST_VERIFY(result == -1);
- memset(buffer, 0, sizeof(buffer));
- result = OSprintf(buffer, EA_CHAR32("%000000000000000000:000000000000000000.000000000000000000f"), 0.f);
- EATEST_VERIFY(result == -1);
- }
- // Test OVsnprintf capacity limits
- memset(buffer, 0, sizeof(buffer));
- result = OSnprintf(buffer, 0, EA_CHAR32("%2:1.0f %3:d %1:c"), (char)'3', (float)1.f, (int)2);
- EATEST_VERIFY((result == 5) && (buffer[0] == 0));
- }
- return nErrorCount;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // TestDeprecated
- ///////////////////////////////////////////////////////////////////////////////
- static int StringWriterOld8(const char8_t* EA_RESTRICT pData, size_t nCount, void* EA_RESTRICT pContext8)
- {
- eastl::string8* pString8 = static_cast<eastl::string8*>(pContext8);
- pString8->append(pData, (eastl_size_t)nCount);
- return (int)nCount;
- }
- static int StringWriterOld16(const char16_t* EA_RESTRICT pData, size_t nCount, void* EA_RESTRICT pContext16)
- {
- eastl::string16* pString16 = static_cast<eastl::string16*>(pContext16);
- pString16->append(pData, (eastl_size_t)nCount);
- return (int)nCount;
- }
- static int TestDeprecated()
- {
- using namespace EA::StdC;
- int nErrorCount = 0;
- {
- eastl::string8 s8;
- eastl::string16 s16;
- int result;
- result = Cprintf(StringWriterOld8, &s8, "Hello world");
- EATEST_VERIFY(result == (int)Strlen("Hello world"));
- EATEST_VERIFY(s8 == "Hello world");
- result = Cprintf(StringWriterOld16, &s16, EA_CHAR16("Hello world"));
- EATEST_VERIFY(result == (int)Strlen(EA_CHAR16("Hello world")));
- EATEST_VERIFY(s16 == EA_CHAR16("Hello world"));
- }
- return nErrorCount;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // TestSprintf
- ///////////////////////////////////////////////////////////////////////////////
- int TestSprintf()
- {
- int nErrorCount(0);
- EA::UnitTest::Report("TestSprintf\n");
- // Regular sprintf
- nErrorCount += TestSprintf8();
- nErrorCount += TestSprintf16();
- nErrorCount += TestSprintf32();
- // Dprintf
- nErrorCount += TestDrintf8();
- // Ordered sprintf
- nErrorCount += TestOsprintf8();
- nErrorCount += TestOsprintf16();
- nErrorCount += TestOsprintf32();
- // Test deprecated functionality
- nErrorCount += TestDeprecated();
- return nErrorCount;
- }
|