YAMLIOTest.cpp 74 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007
  1. //===- unittest/Support/YAMLIOTest.cpp ------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/ADT/BitmaskEnum.h"
  9. #include "llvm/ADT/StringMap.h"
  10. #include "llvm/ADT/StringRef.h"
  11. #include "llvm/ADT/Twine.h"
  12. #include "llvm/Support/Casting.h"
  13. #include "llvm/Support/Endian.h"
  14. #include "llvm/Support/Format.h"
  15. #include "llvm/Support/YAMLTraits.h"
  16. #include "gmock/gmock.h"
  17. #include "gtest/gtest.h"
  18. using llvm::yaml::Hex16;
  19. using llvm::yaml::Hex32;
  20. using llvm::yaml::Hex64;
  21. using llvm::yaml::Hex8;
  22. using llvm::yaml::Input;
  23. using llvm::yaml::IO;
  24. using llvm::yaml::isNumeric;
  25. using llvm::yaml::MappingNormalization;
  26. using llvm::yaml::MappingTraits;
  27. using llvm::yaml::Output;
  28. using llvm::yaml::ScalarTraits;
  29. using ::testing::StartsWith;
  30. static void suppressErrorMessages(const llvm::SMDiagnostic &, void *) {
  31. }
  32. //===----------------------------------------------------------------------===//
  33. // Test MappingTraits
  34. //===----------------------------------------------------------------------===//
  35. struct FooBar {
  36. int foo;
  37. int bar;
  38. };
  39. typedef std::vector<FooBar> FooBarSequence;
  40. LLVM_YAML_IS_SEQUENCE_VECTOR(FooBar)
  41. struct FooBarContainer {
  42. FooBarSequence fbs;
  43. };
  44. namespace llvm {
  45. namespace yaml {
  46. template <>
  47. struct MappingTraits<FooBar> {
  48. static void mapping(IO &io, FooBar& fb) {
  49. io.mapRequired("foo", fb.foo);
  50. io.mapRequired("bar", fb.bar);
  51. }
  52. };
  53. template <> struct MappingTraits<FooBarContainer> {
  54. static void mapping(IO &io, FooBarContainer &fb) {
  55. io.mapRequired("fbs", fb.fbs);
  56. }
  57. };
  58. }
  59. }
  60. //
  61. // Test the reading of a yaml mapping
  62. //
  63. TEST(YAMLIO, TestMapRead) {
  64. FooBar doc;
  65. {
  66. Input yin("---\nfoo: 3\nbar: 5\n...\n");
  67. yin >> doc;
  68. EXPECT_FALSE(yin.error());
  69. EXPECT_EQ(doc.foo, 3);
  70. EXPECT_EQ(doc.bar, 5);
  71. }
  72. {
  73. Input yin("{foo: 3, bar: 5}");
  74. yin >> doc;
  75. EXPECT_FALSE(yin.error());
  76. EXPECT_EQ(doc.foo, 3);
  77. EXPECT_EQ(doc.bar, 5);
  78. }
  79. }
  80. TEST(YAMLIO, TestMalformedMapRead) {
  81. FooBar doc;
  82. Input yin("{foo: 3; bar: 5}", nullptr, suppressErrorMessages);
  83. yin >> doc;
  84. EXPECT_TRUE(!!yin.error());
  85. }
  86. //
  87. // Test the reading of a yaml sequence of mappings
  88. //
  89. TEST(YAMLIO, TestSequenceMapRead) {
  90. FooBarSequence seq;
  91. Input yin("---\n - foo: 3\n bar: 5\n - foo: 7\n bar: 9\n...\n");
  92. yin >> seq;
  93. EXPECT_FALSE(yin.error());
  94. EXPECT_EQ(seq.size(), 2UL);
  95. FooBar& map1 = seq[0];
  96. FooBar& map2 = seq[1];
  97. EXPECT_EQ(map1.foo, 3);
  98. EXPECT_EQ(map1.bar, 5);
  99. EXPECT_EQ(map2.foo, 7);
  100. EXPECT_EQ(map2.bar, 9);
  101. }
  102. //
  103. // Test the reading of a map containing a yaml sequence of mappings
  104. //
  105. TEST(YAMLIO, TestContainerSequenceMapRead) {
  106. {
  107. FooBarContainer cont;
  108. Input yin2("---\nfbs:\n - foo: 3\n bar: 5\n - foo: 7\n bar: 9\n...\n");
  109. yin2 >> cont;
  110. EXPECT_FALSE(yin2.error());
  111. EXPECT_EQ(cont.fbs.size(), 2UL);
  112. EXPECT_EQ(cont.fbs[0].foo, 3);
  113. EXPECT_EQ(cont.fbs[0].bar, 5);
  114. EXPECT_EQ(cont.fbs[1].foo, 7);
  115. EXPECT_EQ(cont.fbs[1].bar, 9);
  116. }
  117. {
  118. FooBarContainer cont;
  119. Input yin("---\nfbs:\n...\n");
  120. yin >> cont;
  121. // Okay: Empty node represents an empty array.
  122. EXPECT_FALSE(yin.error());
  123. EXPECT_EQ(cont.fbs.size(), 0UL);
  124. }
  125. {
  126. FooBarContainer cont;
  127. Input yin("---\nfbs: !!null null\n...\n");
  128. yin >> cont;
  129. // Okay: null represents an empty array.
  130. EXPECT_FALSE(yin.error());
  131. EXPECT_EQ(cont.fbs.size(), 0UL);
  132. }
  133. {
  134. FooBarContainer cont;
  135. Input yin("---\nfbs: ~\n...\n");
  136. yin >> cont;
  137. // Okay: null represents an empty array.
  138. EXPECT_FALSE(yin.error());
  139. EXPECT_EQ(cont.fbs.size(), 0UL);
  140. }
  141. {
  142. FooBarContainer cont;
  143. Input yin("---\nfbs: null\n...\n");
  144. yin >> cont;
  145. // Okay: null represents an empty array.
  146. EXPECT_FALSE(yin.error());
  147. EXPECT_EQ(cont.fbs.size(), 0UL);
  148. }
  149. }
  150. //
  151. // Test the reading of a map containing a malformed yaml sequence
  152. //
  153. TEST(YAMLIO, TestMalformedContainerSequenceMapRead) {
  154. {
  155. FooBarContainer cont;
  156. Input yin("---\nfbs:\n foo: 3\n bar: 5\n...\n", nullptr,
  157. suppressErrorMessages);
  158. yin >> cont;
  159. // Error: fbs is not a sequence.
  160. EXPECT_TRUE(!!yin.error());
  161. EXPECT_EQ(cont.fbs.size(), 0UL);
  162. }
  163. {
  164. FooBarContainer cont;
  165. Input yin("---\nfbs: 'scalar'\n...\n", nullptr, suppressErrorMessages);
  166. yin >> cont;
  167. // This should be an error.
  168. EXPECT_TRUE(!!yin.error());
  169. EXPECT_EQ(cont.fbs.size(), 0UL);
  170. }
  171. }
  172. //
  173. // Test writing then reading back a sequence of mappings
  174. //
  175. TEST(YAMLIO, TestSequenceMapWriteAndRead) {
  176. std::string intermediate;
  177. {
  178. FooBar entry1;
  179. entry1.foo = 10;
  180. entry1.bar = -3;
  181. FooBar entry2;
  182. entry2.foo = 257;
  183. entry2.bar = 0;
  184. FooBarSequence seq;
  185. seq.push_back(entry1);
  186. seq.push_back(entry2);
  187. llvm::raw_string_ostream ostr(intermediate);
  188. Output yout(ostr);
  189. yout << seq;
  190. }
  191. {
  192. Input yin(intermediate);
  193. FooBarSequence seq2;
  194. yin >> seq2;
  195. EXPECT_FALSE(yin.error());
  196. EXPECT_EQ(seq2.size(), 2UL);
  197. FooBar& map1 = seq2[0];
  198. FooBar& map2 = seq2[1];
  199. EXPECT_EQ(map1.foo, 10);
  200. EXPECT_EQ(map1.bar, -3);
  201. EXPECT_EQ(map2.foo, 257);
  202. EXPECT_EQ(map2.bar, 0);
  203. }
  204. }
  205. //
  206. // Test YAML filename handling.
  207. //
  208. static void testErrorFilename(const llvm::SMDiagnostic &Error, void *) {
  209. EXPECT_EQ(Error.getFilename(), "foo.yaml");
  210. }
  211. TEST(YAMLIO, TestGivenFilename) {
  212. auto Buffer = llvm::MemoryBuffer::getMemBuffer("{ x: 42 }", "foo.yaml");
  213. Input yin(*Buffer, nullptr, testErrorFilename);
  214. FooBar Value;
  215. yin >> Value;
  216. EXPECT_TRUE(!!yin.error());
  217. }
  218. struct WithStringField {
  219. std::string str1;
  220. std::string str2;
  221. std::string str3;
  222. };
  223. namespace llvm {
  224. namespace yaml {
  225. template <> struct MappingTraits<WithStringField> {
  226. static void mapping(IO &io, WithStringField &fb) {
  227. io.mapRequired("str1", fb.str1);
  228. io.mapRequired("str2", fb.str2);
  229. io.mapRequired("str3", fb.str3);
  230. }
  231. };
  232. } // namespace yaml
  233. } // namespace llvm
  234. TEST(YAMLIO, MultilineStrings) {
  235. WithStringField Original;
  236. Original.str1 = "a multiline string\nfoobarbaz";
  237. Original.str2 = "another one\rfoobarbaz";
  238. Original.str3 = "a one-line string";
  239. std::string Serialized;
  240. {
  241. llvm::raw_string_ostream OS(Serialized);
  242. Output YOut(OS);
  243. YOut << Original;
  244. }
  245. auto Expected = "---\n"
  246. "str1: 'a multiline string\n"
  247. "foobarbaz'\n"
  248. "str2: 'another one\r"
  249. "foobarbaz'\n"
  250. "str3: a one-line string\n"
  251. "...\n";
  252. ASSERT_EQ(Serialized, Expected);
  253. // Also check it parses back without the errors.
  254. WithStringField Deserialized;
  255. {
  256. Input YIn(Serialized);
  257. YIn >> Deserialized;
  258. ASSERT_FALSE(YIn.error())
  259. << "Parsing error occurred during deserialization. Serialized string:\n"
  260. << Serialized;
  261. }
  262. EXPECT_EQ(Original.str1, Deserialized.str1);
  263. EXPECT_EQ(Original.str2, Deserialized.str2);
  264. EXPECT_EQ(Original.str3, Deserialized.str3);
  265. }
  266. TEST(YAMLIO, NoQuotesForTab) {
  267. WithStringField WithTab;
  268. WithTab.str1 = "aba\tcaba";
  269. std::string Serialized;
  270. {
  271. llvm::raw_string_ostream OS(Serialized);
  272. Output YOut(OS);
  273. YOut << WithTab;
  274. }
  275. auto ExpectedPrefix = "---\n"
  276. "str1: aba\tcaba\n";
  277. EXPECT_THAT(Serialized, StartsWith(ExpectedPrefix));
  278. }
  279. //===----------------------------------------------------------------------===//
  280. // Test built-in types
  281. //===----------------------------------------------------------------------===//
  282. struct BuiltInTypes {
  283. llvm::StringRef str;
  284. std::string stdstr;
  285. uint64_t u64;
  286. uint32_t u32;
  287. uint16_t u16;
  288. uint8_t u8;
  289. bool b;
  290. int64_t s64;
  291. int32_t s32;
  292. int16_t s16;
  293. int8_t s8;
  294. float f;
  295. double d;
  296. Hex8 h8;
  297. Hex16 h16;
  298. Hex32 h32;
  299. Hex64 h64;
  300. };
  301. namespace llvm {
  302. namespace yaml {
  303. template <>
  304. struct MappingTraits<BuiltInTypes> {
  305. static void mapping(IO &io, BuiltInTypes& bt) {
  306. io.mapRequired("str", bt.str);
  307. io.mapRequired("stdstr", bt.stdstr);
  308. io.mapRequired("u64", bt.u64);
  309. io.mapRequired("u32", bt.u32);
  310. io.mapRequired("u16", bt.u16);
  311. io.mapRequired("u8", bt.u8);
  312. io.mapRequired("b", bt.b);
  313. io.mapRequired("s64", bt.s64);
  314. io.mapRequired("s32", bt.s32);
  315. io.mapRequired("s16", bt.s16);
  316. io.mapRequired("s8", bt.s8);
  317. io.mapRequired("f", bt.f);
  318. io.mapRequired("d", bt.d);
  319. io.mapRequired("h8", bt.h8);
  320. io.mapRequired("h16", bt.h16);
  321. io.mapRequired("h32", bt.h32);
  322. io.mapRequired("h64", bt.h64);
  323. }
  324. };
  325. }
  326. }
  327. //
  328. // Test the reading of all built-in scalar conversions
  329. //
  330. TEST(YAMLIO, TestReadBuiltInTypes) {
  331. BuiltInTypes map;
  332. Input yin("---\n"
  333. "str: hello there\n"
  334. "stdstr: hello where?\n"
  335. "u64: 5000000000\n"
  336. "u32: 4000000000\n"
  337. "u16: 65000\n"
  338. "u8: 255\n"
  339. "b: false\n"
  340. "s64: -5000000000\n"
  341. "s32: -2000000000\n"
  342. "s16: -32000\n"
  343. "s8: -127\n"
  344. "f: 137.125\n"
  345. "d: -2.8625\n"
  346. "h8: 0xFF\n"
  347. "h16: 0x8765\n"
  348. "h32: 0xFEDCBA98\n"
  349. "h64: 0xFEDCBA9876543210\n"
  350. "...\n");
  351. yin >> map;
  352. EXPECT_FALSE(yin.error());
  353. EXPECT_TRUE(map.str.equals("hello there"));
  354. EXPECT_TRUE(map.stdstr == "hello where?");
  355. EXPECT_EQ(map.u64, 5000000000ULL);
  356. EXPECT_EQ(map.u32, 4000000000U);
  357. EXPECT_EQ(map.u16, 65000);
  358. EXPECT_EQ(map.u8, 255);
  359. EXPECT_EQ(map.b, false);
  360. EXPECT_EQ(map.s64, -5000000000LL);
  361. EXPECT_EQ(map.s32, -2000000000L);
  362. EXPECT_EQ(map.s16, -32000);
  363. EXPECT_EQ(map.s8, -127);
  364. EXPECT_EQ(map.f, 137.125);
  365. EXPECT_EQ(map.d, -2.8625);
  366. EXPECT_EQ(map.h8, Hex8(255));
  367. EXPECT_EQ(map.h16, Hex16(0x8765));
  368. EXPECT_EQ(map.h32, Hex32(0xFEDCBA98));
  369. EXPECT_EQ(map.h64, Hex64(0xFEDCBA9876543210LL));
  370. }
  371. //
  372. // Test writing then reading back all built-in scalar types
  373. //
  374. TEST(YAMLIO, TestReadWriteBuiltInTypes) {
  375. std::string intermediate;
  376. {
  377. BuiltInTypes map;
  378. map.str = "one two";
  379. map.stdstr = "three four";
  380. map.u64 = 6000000000ULL;
  381. map.u32 = 3000000000U;
  382. map.u16 = 50000;
  383. map.u8 = 254;
  384. map.b = true;
  385. map.s64 = -6000000000LL;
  386. map.s32 = -2000000000;
  387. map.s16 = -32000;
  388. map.s8 = -128;
  389. map.f = 3.25;
  390. map.d = -2.8625;
  391. map.h8 = 254;
  392. map.h16 = 50000;
  393. map.h32 = 3000000000U;
  394. map.h64 = 6000000000LL;
  395. llvm::raw_string_ostream ostr(intermediate);
  396. Output yout(ostr);
  397. yout << map;
  398. }
  399. {
  400. Input yin(intermediate);
  401. BuiltInTypes map;
  402. yin >> map;
  403. EXPECT_FALSE(yin.error());
  404. EXPECT_TRUE(map.str.equals("one two"));
  405. EXPECT_TRUE(map.stdstr == "three four");
  406. EXPECT_EQ(map.u64, 6000000000ULL);
  407. EXPECT_EQ(map.u32, 3000000000U);
  408. EXPECT_EQ(map.u16, 50000);
  409. EXPECT_EQ(map.u8, 254);
  410. EXPECT_EQ(map.b, true);
  411. EXPECT_EQ(map.s64, -6000000000LL);
  412. EXPECT_EQ(map.s32, -2000000000L);
  413. EXPECT_EQ(map.s16, -32000);
  414. EXPECT_EQ(map.s8, -128);
  415. EXPECT_EQ(map.f, 3.25);
  416. EXPECT_EQ(map.d, -2.8625);
  417. EXPECT_EQ(map.h8, Hex8(254));
  418. EXPECT_EQ(map.h16, Hex16(50000));
  419. EXPECT_EQ(map.h32, Hex32(3000000000U));
  420. EXPECT_EQ(map.h64, Hex64(6000000000LL));
  421. }
  422. }
  423. //===----------------------------------------------------------------------===//
  424. // Test endian-aware types
  425. //===----------------------------------------------------------------------===//
  426. struct EndianTypes {
  427. typedef llvm::support::detail::packed_endian_specific_integral<
  428. float, llvm::support::little, llvm::support::unaligned>
  429. ulittle_float;
  430. typedef llvm::support::detail::packed_endian_specific_integral<
  431. double, llvm::support::little, llvm::support::unaligned>
  432. ulittle_double;
  433. llvm::support::ulittle64_t u64;
  434. llvm::support::ulittle32_t u32;
  435. llvm::support::ulittle16_t u16;
  436. llvm::support::little64_t s64;
  437. llvm::support::little32_t s32;
  438. llvm::support::little16_t s16;
  439. ulittle_float f;
  440. ulittle_double d;
  441. };
  442. namespace llvm {
  443. namespace yaml {
  444. template <> struct MappingTraits<EndianTypes> {
  445. static void mapping(IO &io, EndianTypes &et) {
  446. io.mapRequired("u64", et.u64);
  447. io.mapRequired("u32", et.u32);
  448. io.mapRequired("u16", et.u16);
  449. io.mapRequired("s64", et.s64);
  450. io.mapRequired("s32", et.s32);
  451. io.mapRequired("s16", et.s16);
  452. io.mapRequired("f", et.f);
  453. io.mapRequired("d", et.d);
  454. }
  455. };
  456. }
  457. }
  458. //
  459. // Test the reading of all endian scalar conversions
  460. //
  461. TEST(YAMLIO, TestReadEndianTypes) {
  462. EndianTypes map;
  463. Input yin("---\n"
  464. "u64: 5000000000\n"
  465. "u32: 4000000000\n"
  466. "u16: 65000\n"
  467. "s64: -5000000000\n"
  468. "s32: -2000000000\n"
  469. "s16: -32000\n"
  470. "f: 3.25\n"
  471. "d: -2.8625\n"
  472. "...\n");
  473. yin >> map;
  474. EXPECT_FALSE(yin.error());
  475. EXPECT_EQ(map.u64, 5000000000ULL);
  476. EXPECT_EQ(map.u32, 4000000000U);
  477. EXPECT_EQ(map.u16, 65000);
  478. EXPECT_EQ(map.s64, -5000000000LL);
  479. EXPECT_EQ(map.s32, -2000000000L);
  480. EXPECT_EQ(map.s16, -32000);
  481. EXPECT_EQ(map.f, 3.25f);
  482. EXPECT_EQ(map.d, -2.8625);
  483. }
  484. //
  485. // Test writing then reading back all endian-aware scalar types
  486. //
  487. TEST(YAMLIO, TestReadWriteEndianTypes) {
  488. std::string intermediate;
  489. {
  490. EndianTypes map;
  491. map.u64 = 6000000000ULL;
  492. map.u32 = 3000000000U;
  493. map.u16 = 50000;
  494. map.s64 = -6000000000LL;
  495. map.s32 = -2000000000;
  496. map.s16 = -32000;
  497. map.f = 3.25f;
  498. map.d = -2.8625;
  499. llvm::raw_string_ostream ostr(intermediate);
  500. Output yout(ostr);
  501. yout << map;
  502. }
  503. {
  504. Input yin(intermediate);
  505. EndianTypes map;
  506. yin >> map;
  507. EXPECT_FALSE(yin.error());
  508. EXPECT_EQ(map.u64, 6000000000ULL);
  509. EXPECT_EQ(map.u32, 3000000000U);
  510. EXPECT_EQ(map.u16, 50000);
  511. EXPECT_EQ(map.s64, -6000000000LL);
  512. EXPECT_EQ(map.s32, -2000000000L);
  513. EXPECT_EQ(map.s16, -32000);
  514. EXPECT_EQ(map.f, 3.25f);
  515. EXPECT_EQ(map.d, -2.8625);
  516. }
  517. }
  518. enum class Enum : uint16_t { One, Two };
  519. enum class BitsetEnum : uint16_t {
  520. ZeroOne = 0x01,
  521. OneZero = 0x10,
  522. LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ OneZero),
  523. };
  524. LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
  525. struct EndianEnums {
  526. llvm::support::little_t<Enum> LittleEnum;
  527. llvm::support::big_t<Enum> BigEnum;
  528. llvm::support::little_t<BitsetEnum> LittleBitset;
  529. llvm::support::big_t<BitsetEnum> BigBitset;
  530. };
  531. namespace llvm {
  532. namespace yaml {
  533. template <> struct ScalarEnumerationTraits<Enum> {
  534. static void enumeration(IO &io, Enum &E) {
  535. io.enumCase(E, "One", Enum::One);
  536. io.enumCase(E, "Two", Enum::Two);
  537. }
  538. };
  539. template <> struct ScalarBitSetTraits<BitsetEnum> {
  540. static void bitset(IO &io, BitsetEnum &E) {
  541. io.bitSetCase(E, "ZeroOne", BitsetEnum::ZeroOne);
  542. io.bitSetCase(E, "OneZero", BitsetEnum::OneZero);
  543. }
  544. };
  545. template <> struct MappingTraits<EndianEnums> {
  546. static void mapping(IO &io, EndianEnums &EE) {
  547. io.mapRequired("LittleEnum", EE.LittleEnum);
  548. io.mapRequired("BigEnum", EE.BigEnum);
  549. io.mapRequired("LittleBitset", EE.LittleBitset);
  550. io.mapRequired("BigBitset", EE.BigBitset);
  551. }
  552. };
  553. } // namespace yaml
  554. } // namespace llvm
  555. TEST(YAMLIO, TestReadEndianEnums) {
  556. EndianEnums map;
  557. Input yin("---\n"
  558. "LittleEnum: One\n"
  559. "BigEnum: Two\n"
  560. "LittleBitset: [ ZeroOne ]\n"
  561. "BigBitset: [ ZeroOne, OneZero ]\n"
  562. "...\n");
  563. yin >> map;
  564. EXPECT_FALSE(yin.error());
  565. EXPECT_EQ(Enum::One, map.LittleEnum);
  566. EXPECT_EQ(Enum::Two, map.BigEnum);
  567. EXPECT_EQ(BitsetEnum::ZeroOne, map.LittleBitset);
  568. EXPECT_EQ(BitsetEnum::ZeroOne | BitsetEnum::OneZero, map.BigBitset);
  569. }
  570. TEST(YAMLIO, TestReadWriteEndianEnums) {
  571. std::string intermediate;
  572. {
  573. EndianEnums map;
  574. map.LittleEnum = Enum::Two;
  575. map.BigEnum = Enum::One;
  576. map.LittleBitset = BitsetEnum::OneZero | BitsetEnum::ZeroOne;
  577. map.BigBitset = BitsetEnum::OneZero;
  578. llvm::raw_string_ostream ostr(intermediate);
  579. Output yout(ostr);
  580. yout << map;
  581. }
  582. {
  583. Input yin(intermediate);
  584. EndianEnums map;
  585. yin >> map;
  586. EXPECT_FALSE(yin.error());
  587. EXPECT_EQ(Enum::Two, map.LittleEnum);
  588. EXPECT_EQ(Enum::One, map.BigEnum);
  589. EXPECT_EQ(BitsetEnum::OneZero | BitsetEnum::ZeroOne, map.LittleBitset);
  590. EXPECT_EQ(BitsetEnum::OneZero, map.BigBitset);
  591. }
  592. }
  593. struct StringTypes {
  594. llvm::StringRef str1;
  595. llvm::StringRef str2;
  596. llvm::StringRef str3;
  597. llvm::StringRef str4;
  598. llvm::StringRef str5;
  599. llvm::StringRef str6;
  600. llvm::StringRef str7;
  601. llvm::StringRef str8;
  602. llvm::StringRef str9;
  603. llvm::StringRef str10;
  604. llvm::StringRef str11;
  605. std::string stdstr1;
  606. std::string stdstr2;
  607. std::string stdstr3;
  608. std::string stdstr4;
  609. std::string stdstr5;
  610. std::string stdstr6;
  611. std::string stdstr7;
  612. std::string stdstr8;
  613. std::string stdstr9;
  614. std::string stdstr10;
  615. std::string stdstr11;
  616. std::string stdstr12;
  617. std::string stdstr13;
  618. };
  619. namespace llvm {
  620. namespace yaml {
  621. template <>
  622. struct MappingTraits<StringTypes> {
  623. static void mapping(IO &io, StringTypes& st) {
  624. io.mapRequired("str1", st.str1);
  625. io.mapRequired("str2", st.str2);
  626. io.mapRequired("str3", st.str3);
  627. io.mapRequired("str4", st.str4);
  628. io.mapRequired("str5", st.str5);
  629. io.mapRequired("str6", st.str6);
  630. io.mapRequired("str7", st.str7);
  631. io.mapRequired("str8", st.str8);
  632. io.mapRequired("str9", st.str9);
  633. io.mapRequired("str10", st.str10);
  634. io.mapRequired("str11", st.str11);
  635. io.mapRequired("stdstr1", st.stdstr1);
  636. io.mapRequired("stdstr2", st.stdstr2);
  637. io.mapRequired("stdstr3", st.stdstr3);
  638. io.mapRequired("stdstr4", st.stdstr4);
  639. io.mapRequired("stdstr5", st.stdstr5);
  640. io.mapRequired("stdstr6", st.stdstr6);
  641. io.mapRequired("stdstr7", st.stdstr7);
  642. io.mapRequired("stdstr8", st.stdstr8);
  643. io.mapRequired("stdstr9", st.stdstr9);
  644. io.mapRequired("stdstr10", st.stdstr10);
  645. io.mapRequired("stdstr11", st.stdstr11);
  646. io.mapRequired("stdstr12", st.stdstr12);
  647. io.mapRequired("stdstr13", st.stdstr13);
  648. }
  649. };
  650. }
  651. }
  652. TEST(YAMLIO, TestReadWriteStringTypes) {
  653. std::string intermediate;
  654. {
  655. StringTypes map;
  656. map.str1 = "'aaa";
  657. map.str2 = "\"bbb";
  658. map.str3 = "`ccc";
  659. map.str4 = "@ddd";
  660. map.str5 = "";
  661. map.str6 = "0000000004000000";
  662. map.str7 = "true";
  663. map.str8 = "FALSE";
  664. map.str9 = "~";
  665. map.str10 = "0.2e20";
  666. map.str11 = "0x30";
  667. map.stdstr1 = "'eee";
  668. map.stdstr2 = "\"fff";
  669. map.stdstr3 = "`ggg";
  670. map.stdstr4 = "@hhh";
  671. map.stdstr5 = "";
  672. map.stdstr6 = "0000000004000000";
  673. map.stdstr7 = "true";
  674. map.stdstr8 = "FALSE";
  675. map.stdstr9 = "~";
  676. map.stdstr10 = "0.2e20";
  677. map.stdstr11 = "0x30";
  678. map.stdstr12 = "- match";
  679. map.stdstr13.assign("\0a\0b\0", 5);
  680. llvm::raw_string_ostream ostr(intermediate);
  681. Output yout(ostr);
  682. yout << map;
  683. }
  684. llvm::StringRef flowOut(intermediate);
  685. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'''aaa"));
  686. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'\"bbb'"));
  687. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'`ccc'"));
  688. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'@ddd'"));
  689. EXPECT_NE(llvm::StringRef::npos, flowOut.find("''\n"));
  690. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0000000004000000'\n"));
  691. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'true'\n"));
  692. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'FALSE'\n"));
  693. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'~'\n"));
  694. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0.2e20'\n"));
  695. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0x30'\n"));
  696. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'- match'\n"));
  697. EXPECT_NE(std::string::npos, flowOut.find("'''eee"));
  698. EXPECT_NE(std::string::npos, flowOut.find("'\"fff'"));
  699. EXPECT_NE(std::string::npos, flowOut.find("'`ggg'"));
  700. EXPECT_NE(std::string::npos, flowOut.find("'@hhh'"));
  701. EXPECT_NE(std::string::npos, flowOut.find("''\n"));
  702. EXPECT_NE(std::string::npos, flowOut.find("'0000000004000000'\n"));
  703. EXPECT_NE(std::string::npos, flowOut.find("\"\\0a\\0b\\0\""));
  704. {
  705. Input yin(intermediate);
  706. StringTypes map;
  707. yin >> map;
  708. EXPECT_FALSE(yin.error());
  709. EXPECT_TRUE(map.str1.equals("'aaa"));
  710. EXPECT_TRUE(map.str2.equals("\"bbb"));
  711. EXPECT_TRUE(map.str3.equals("`ccc"));
  712. EXPECT_TRUE(map.str4.equals("@ddd"));
  713. EXPECT_TRUE(map.str5.equals(""));
  714. EXPECT_TRUE(map.str6.equals("0000000004000000"));
  715. EXPECT_TRUE(map.stdstr1 == "'eee");
  716. EXPECT_TRUE(map.stdstr2 == "\"fff");
  717. EXPECT_TRUE(map.stdstr3 == "`ggg");
  718. EXPECT_TRUE(map.stdstr4 == "@hhh");
  719. EXPECT_TRUE(map.stdstr5 == "");
  720. EXPECT_TRUE(map.stdstr6 == "0000000004000000");
  721. EXPECT_EQ(std::string("\0a\0b\0", 5), map.stdstr13);
  722. }
  723. }
  724. //===----------------------------------------------------------------------===//
  725. // Test ScalarEnumerationTraits
  726. //===----------------------------------------------------------------------===//
  727. enum Colors {
  728. cRed,
  729. cBlue,
  730. cGreen,
  731. cYellow
  732. };
  733. struct ColorMap {
  734. Colors c1;
  735. Colors c2;
  736. Colors c3;
  737. Colors c4;
  738. Colors c5;
  739. Colors c6;
  740. };
  741. namespace llvm {
  742. namespace yaml {
  743. template <>
  744. struct ScalarEnumerationTraits<Colors> {
  745. static void enumeration(IO &io, Colors &value) {
  746. io.enumCase(value, "red", cRed);
  747. io.enumCase(value, "blue", cBlue);
  748. io.enumCase(value, "green", cGreen);
  749. io.enumCase(value, "yellow",cYellow);
  750. }
  751. };
  752. template <>
  753. struct MappingTraits<ColorMap> {
  754. static void mapping(IO &io, ColorMap& c) {
  755. io.mapRequired("c1", c.c1);
  756. io.mapRequired("c2", c.c2);
  757. io.mapRequired("c3", c.c3);
  758. io.mapOptional("c4", c.c4, cBlue); // supplies default
  759. io.mapOptional("c5", c.c5, cYellow); // supplies default
  760. io.mapOptional("c6", c.c6, cRed); // supplies default
  761. }
  762. };
  763. }
  764. }
  765. //
  766. // Test reading enumerated scalars
  767. //
  768. TEST(YAMLIO, TestEnumRead) {
  769. ColorMap map;
  770. Input yin("---\n"
  771. "c1: blue\n"
  772. "c2: red\n"
  773. "c3: green\n"
  774. "c5: yellow\n"
  775. "...\n");
  776. yin >> map;
  777. EXPECT_FALSE(yin.error());
  778. EXPECT_EQ(cBlue, map.c1);
  779. EXPECT_EQ(cRed, map.c2);
  780. EXPECT_EQ(cGreen, map.c3);
  781. EXPECT_EQ(cBlue, map.c4); // tests default
  782. EXPECT_EQ(cYellow,map.c5); // tests overridden
  783. EXPECT_EQ(cRed, map.c6); // tests default
  784. }
  785. //===----------------------------------------------------------------------===//
  786. // Test ScalarBitSetTraits
  787. //===----------------------------------------------------------------------===//
  788. enum MyFlags {
  789. flagNone = 0,
  790. flagBig = 1 << 0,
  791. flagFlat = 1 << 1,
  792. flagRound = 1 << 2,
  793. flagPointy = 1 << 3
  794. };
  795. inline MyFlags operator|(MyFlags a, MyFlags b) {
  796. return static_cast<MyFlags>(
  797. static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
  798. }
  799. struct FlagsMap {
  800. MyFlags f1;
  801. MyFlags f2;
  802. MyFlags f3;
  803. MyFlags f4;
  804. };
  805. namespace llvm {
  806. namespace yaml {
  807. template <>
  808. struct ScalarBitSetTraits<MyFlags> {
  809. static void bitset(IO &io, MyFlags &value) {
  810. io.bitSetCase(value, "big", flagBig);
  811. io.bitSetCase(value, "flat", flagFlat);
  812. io.bitSetCase(value, "round", flagRound);
  813. io.bitSetCase(value, "pointy",flagPointy);
  814. }
  815. };
  816. template <>
  817. struct MappingTraits<FlagsMap> {
  818. static void mapping(IO &io, FlagsMap& c) {
  819. io.mapRequired("f1", c.f1);
  820. io.mapRequired("f2", c.f2);
  821. io.mapRequired("f3", c.f3);
  822. io.mapOptional("f4", c.f4, flagRound);
  823. }
  824. };
  825. }
  826. }
  827. //
  828. // Test reading flow sequence representing bit-mask values
  829. //
  830. TEST(YAMLIO, TestFlagsRead) {
  831. FlagsMap map;
  832. Input yin("---\n"
  833. "f1: [ big ]\n"
  834. "f2: [ round, flat ]\n"
  835. "f3: []\n"
  836. "...\n");
  837. yin >> map;
  838. EXPECT_FALSE(yin.error());
  839. EXPECT_EQ(flagBig, map.f1);
  840. EXPECT_EQ(flagRound|flagFlat, map.f2);
  841. EXPECT_EQ(flagNone, map.f3); // check empty set
  842. EXPECT_EQ(flagRound, map.f4); // check optional key
  843. }
  844. //
  845. // Test writing then reading back bit-mask values
  846. //
  847. TEST(YAMLIO, TestReadWriteFlags) {
  848. std::string intermediate;
  849. {
  850. FlagsMap map;
  851. map.f1 = flagBig;
  852. map.f2 = flagRound | flagFlat;
  853. map.f3 = flagNone;
  854. map.f4 = flagNone;
  855. llvm::raw_string_ostream ostr(intermediate);
  856. Output yout(ostr);
  857. yout << map;
  858. }
  859. {
  860. Input yin(intermediate);
  861. FlagsMap map2;
  862. yin >> map2;
  863. EXPECT_FALSE(yin.error());
  864. EXPECT_EQ(flagBig, map2.f1);
  865. EXPECT_EQ(flagRound|flagFlat, map2.f2);
  866. EXPECT_EQ(flagNone, map2.f3);
  867. //EXPECT_EQ(flagRound, map2.f4); // check optional key
  868. }
  869. }
  870. //===----------------------------------------------------------------------===//
  871. // Test ScalarTraits
  872. //===----------------------------------------------------------------------===//
  873. struct MyCustomType {
  874. int length;
  875. int width;
  876. };
  877. struct MyCustomTypeMap {
  878. MyCustomType f1;
  879. MyCustomType f2;
  880. int f3;
  881. };
  882. namespace llvm {
  883. namespace yaml {
  884. template <>
  885. struct MappingTraits<MyCustomTypeMap> {
  886. static void mapping(IO &io, MyCustomTypeMap& s) {
  887. io.mapRequired("f1", s.f1);
  888. io.mapRequired("f2", s.f2);
  889. io.mapRequired("f3", s.f3);
  890. }
  891. };
  892. // MyCustomType is formatted as a yaml scalar. A value of
  893. // {length=3, width=4} would be represented in yaml as "3 by 4".
  894. template<>
  895. struct ScalarTraits<MyCustomType> {
  896. static void output(const MyCustomType &value, void* ctxt, llvm::raw_ostream &out) {
  897. out << llvm::format("%d by %d", value.length, value.width);
  898. }
  899. static StringRef input(StringRef scalar, void* ctxt, MyCustomType &value) {
  900. size_t byStart = scalar.find("by");
  901. if ( byStart != StringRef::npos ) {
  902. StringRef lenStr = scalar.slice(0, byStart);
  903. lenStr = lenStr.rtrim();
  904. if ( lenStr.getAsInteger(0, value.length) ) {
  905. return "malformed length";
  906. }
  907. StringRef widthStr = scalar.drop_front(byStart+2);
  908. widthStr = widthStr.ltrim();
  909. if ( widthStr.getAsInteger(0, value.width) ) {
  910. return "malformed width";
  911. }
  912. return StringRef();
  913. }
  914. else {
  915. return "malformed by";
  916. }
  917. }
  918. static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
  919. };
  920. }
  921. }
  922. //
  923. // Test writing then reading back custom values
  924. //
  925. TEST(YAMLIO, TestReadWriteMyCustomType) {
  926. std::string intermediate;
  927. {
  928. MyCustomTypeMap map;
  929. map.f1.length = 1;
  930. map.f1.width = 4;
  931. map.f2.length = 100;
  932. map.f2.width = 400;
  933. map.f3 = 10;
  934. llvm::raw_string_ostream ostr(intermediate);
  935. Output yout(ostr);
  936. yout << map;
  937. }
  938. {
  939. Input yin(intermediate);
  940. MyCustomTypeMap map2;
  941. yin >> map2;
  942. EXPECT_FALSE(yin.error());
  943. EXPECT_EQ(1, map2.f1.length);
  944. EXPECT_EQ(4, map2.f1.width);
  945. EXPECT_EQ(100, map2.f2.length);
  946. EXPECT_EQ(400, map2.f2.width);
  947. EXPECT_EQ(10, map2.f3);
  948. }
  949. }
  950. //===----------------------------------------------------------------------===//
  951. // Test BlockScalarTraits
  952. //===----------------------------------------------------------------------===//
  953. struct MultilineStringType {
  954. std::string str;
  955. };
  956. struct MultilineStringTypeMap {
  957. MultilineStringType name;
  958. MultilineStringType description;
  959. MultilineStringType ingredients;
  960. MultilineStringType recipes;
  961. MultilineStringType warningLabels;
  962. MultilineStringType documentation;
  963. int price;
  964. };
  965. namespace llvm {
  966. namespace yaml {
  967. template <>
  968. struct MappingTraits<MultilineStringTypeMap> {
  969. static void mapping(IO &io, MultilineStringTypeMap& s) {
  970. io.mapRequired("name", s.name);
  971. io.mapRequired("description", s.description);
  972. io.mapRequired("ingredients", s.ingredients);
  973. io.mapRequired("recipes", s.recipes);
  974. io.mapRequired("warningLabels", s.warningLabels);
  975. io.mapRequired("documentation", s.documentation);
  976. io.mapRequired("price", s.price);
  977. }
  978. };
  979. // MultilineStringType is formatted as a yaml block literal scalar. A value of
  980. // "Hello\nWorld" would be represented in yaml as
  981. // |
  982. // Hello
  983. // World
  984. template <>
  985. struct BlockScalarTraits<MultilineStringType> {
  986. static void output(const MultilineStringType &value, void *ctxt,
  987. llvm::raw_ostream &out) {
  988. out << value.str;
  989. }
  990. static StringRef input(StringRef scalar, void *ctxt,
  991. MultilineStringType &value) {
  992. value.str = scalar.str();
  993. return StringRef();
  994. }
  995. };
  996. }
  997. }
  998. LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MultilineStringType)
  999. //
  1000. // Test writing then reading back custom values
  1001. //
  1002. TEST(YAMLIO, TestReadWriteMultilineStringType) {
  1003. std::string intermediate;
  1004. {
  1005. MultilineStringTypeMap map;
  1006. map.name.str = "An Item";
  1007. map.description.str = "Hello\nWorld";
  1008. map.ingredients.str = "SubItem 1\nSub Item 2\n\nSub Item 3\n";
  1009. map.recipes.str = "\n\nTest 1\n\n\n";
  1010. map.warningLabels.str = "";
  1011. map.documentation.str = "\n\n";
  1012. map.price = 350;
  1013. llvm::raw_string_ostream ostr(intermediate);
  1014. Output yout(ostr);
  1015. yout << map;
  1016. }
  1017. {
  1018. Input yin(intermediate);
  1019. MultilineStringTypeMap map2;
  1020. yin >> map2;
  1021. EXPECT_FALSE(yin.error());
  1022. EXPECT_EQ(map2.name.str, "An Item\n");
  1023. EXPECT_EQ(map2.description.str, "Hello\nWorld\n");
  1024. EXPECT_EQ(map2.ingredients.str, "SubItem 1\nSub Item 2\n\nSub Item 3\n");
  1025. EXPECT_EQ(map2.recipes.str, "\n\nTest 1\n");
  1026. EXPECT_TRUE(map2.warningLabels.str.empty());
  1027. EXPECT_TRUE(map2.documentation.str.empty());
  1028. EXPECT_EQ(map2.price, 350);
  1029. }
  1030. }
  1031. //
  1032. // Test writing then reading back custom values
  1033. //
  1034. TEST(YAMLIO, TestReadWriteBlockScalarDocuments) {
  1035. std::string intermediate;
  1036. {
  1037. std::vector<MultilineStringType> documents;
  1038. MultilineStringType doc;
  1039. doc.str = "Hello\nWorld";
  1040. documents.push_back(doc);
  1041. llvm::raw_string_ostream ostr(intermediate);
  1042. Output yout(ostr);
  1043. yout << documents;
  1044. // Verify that the block scalar header was written out on the same line
  1045. // as the document marker.
  1046. EXPECT_NE(llvm::StringRef::npos, llvm::StringRef(ostr.str()).find("--- |"));
  1047. }
  1048. {
  1049. Input yin(intermediate);
  1050. std::vector<MultilineStringType> documents2;
  1051. yin >> documents2;
  1052. EXPECT_FALSE(yin.error());
  1053. EXPECT_EQ(documents2.size(), size_t(1));
  1054. EXPECT_EQ(documents2[0].str, "Hello\nWorld\n");
  1055. }
  1056. }
  1057. TEST(YAMLIO, TestReadWriteBlockScalarValue) {
  1058. std::string intermediate;
  1059. {
  1060. MultilineStringType doc;
  1061. doc.str = "Just a block\nscalar doc";
  1062. llvm::raw_string_ostream ostr(intermediate);
  1063. Output yout(ostr);
  1064. yout << doc;
  1065. }
  1066. {
  1067. Input yin(intermediate);
  1068. MultilineStringType doc;
  1069. yin >> doc;
  1070. EXPECT_FALSE(yin.error());
  1071. EXPECT_EQ(doc.str, "Just a block\nscalar doc\n");
  1072. }
  1073. }
  1074. //===----------------------------------------------------------------------===//
  1075. // Test flow sequences
  1076. //===----------------------------------------------------------------------===//
  1077. LLVM_YAML_STRONG_TYPEDEF(int, MyNumber)
  1078. LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(MyNumber)
  1079. LLVM_YAML_STRONG_TYPEDEF(llvm::StringRef, MyString)
  1080. LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(MyString)
  1081. namespace llvm {
  1082. namespace yaml {
  1083. template<>
  1084. struct ScalarTraits<MyNumber> {
  1085. static void output(const MyNumber &value, void *, llvm::raw_ostream &out) {
  1086. out << value;
  1087. }
  1088. static StringRef input(StringRef scalar, void *, MyNumber &value) {
  1089. long long n;
  1090. if ( getAsSignedInteger(scalar, 0, n) )
  1091. return "invalid number";
  1092. value = n;
  1093. return StringRef();
  1094. }
  1095. static QuotingType mustQuote(StringRef) { return QuotingType::None; }
  1096. };
  1097. template <> struct ScalarTraits<MyString> {
  1098. using Impl = ScalarTraits<StringRef>;
  1099. static void output(const MyString &V, void *Ctx, raw_ostream &OS) {
  1100. Impl::output(V, Ctx, OS);
  1101. }
  1102. static StringRef input(StringRef S, void *Ctx, MyString &V) {
  1103. return Impl::input(S, Ctx, V.value);
  1104. }
  1105. static QuotingType mustQuote(StringRef S) {
  1106. return Impl::mustQuote(S);
  1107. }
  1108. };
  1109. }
  1110. }
  1111. struct NameAndNumbers {
  1112. llvm::StringRef name;
  1113. std::vector<MyString> strings;
  1114. std::vector<MyNumber> single;
  1115. std::vector<MyNumber> numbers;
  1116. };
  1117. namespace llvm {
  1118. namespace yaml {
  1119. template <>
  1120. struct MappingTraits<NameAndNumbers> {
  1121. static void mapping(IO &io, NameAndNumbers& nn) {
  1122. io.mapRequired("name", nn.name);
  1123. io.mapRequired("strings", nn.strings);
  1124. io.mapRequired("single", nn.single);
  1125. io.mapRequired("numbers", nn.numbers);
  1126. }
  1127. };
  1128. }
  1129. }
  1130. typedef std::vector<MyNumber> MyNumberFlowSequence;
  1131. LLVM_YAML_IS_SEQUENCE_VECTOR(MyNumberFlowSequence)
  1132. struct NameAndNumbersFlow {
  1133. llvm::StringRef name;
  1134. std::vector<MyNumberFlowSequence> sequenceOfNumbers;
  1135. };
  1136. namespace llvm {
  1137. namespace yaml {
  1138. template <>
  1139. struct MappingTraits<NameAndNumbersFlow> {
  1140. static void mapping(IO &io, NameAndNumbersFlow& nn) {
  1141. io.mapRequired("name", nn.name);
  1142. io.mapRequired("sequenceOfNumbers", nn.sequenceOfNumbers);
  1143. }
  1144. };
  1145. }
  1146. }
  1147. //
  1148. // Test writing then reading back custom values
  1149. //
  1150. TEST(YAMLIO, TestReadWriteMyFlowSequence) {
  1151. std::string intermediate;
  1152. {
  1153. NameAndNumbers map;
  1154. map.name = "hello";
  1155. map.strings.push_back(llvm::StringRef("one"));
  1156. map.strings.push_back(llvm::StringRef("two"));
  1157. map.single.push_back(1);
  1158. map.numbers.push_back(10);
  1159. map.numbers.push_back(-30);
  1160. map.numbers.push_back(1024);
  1161. llvm::raw_string_ostream ostr(intermediate);
  1162. Output yout(ostr);
  1163. yout << map;
  1164. // Verify sequences were written in flow style
  1165. ostr.flush();
  1166. llvm::StringRef flowOut(intermediate);
  1167. EXPECT_NE(llvm::StringRef::npos, flowOut.find("one, two"));
  1168. EXPECT_NE(llvm::StringRef::npos, flowOut.find("10, -30, 1024"));
  1169. }
  1170. {
  1171. Input yin(intermediate);
  1172. NameAndNumbers map2;
  1173. yin >> map2;
  1174. EXPECT_FALSE(yin.error());
  1175. EXPECT_TRUE(map2.name.equals("hello"));
  1176. EXPECT_EQ(map2.strings.size(), 2UL);
  1177. EXPECT_TRUE(map2.strings[0].value.equals("one"));
  1178. EXPECT_TRUE(map2.strings[1].value.equals("two"));
  1179. EXPECT_EQ(map2.single.size(), 1UL);
  1180. EXPECT_EQ(1, map2.single[0]);
  1181. EXPECT_EQ(map2.numbers.size(), 3UL);
  1182. EXPECT_EQ(10, map2.numbers[0]);
  1183. EXPECT_EQ(-30, map2.numbers[1]);
  1184. EXPECT_EQ(1024, map2.numbers[2]);
  1185. }
  1186. }
  1187. //
  1188. // Test writing then reading back a sequence of flow sequences.
  1189. //
  1190. TEST(YAMLIO, TestReadWriteSequenceOfMyFlowSequence) {
  1191. std::string intermediate;
  1192. {
  1193. NameAndNumbersFlow map;
  1194. map.name = "hello";
  1195. MyNumberFlowSequence single = { 0 };
  1196. MyNumberFlowSequence numbers = { 12, 1, -512 };
  1197. map.sequenceOfNumbers.push_back(single);
  1198. map.sequenceOfNumbers.push_back(numbers);
  1199. map.sequenceOfNumbers.push_back(MyNumberFlowSequence());
  1200. llvm::raw_string_ostream ostr(intermediate);
  1201. Output yout(ostr);
  1202. yout << map;
  1203. // Verify sequences were written in flow style
  1204. // and that the parent sequence used '-'.
  1205. ostr.flush();
  1206. llvm::StringRef flowOut(intermediate);
  1207. EXPECT_NE(llvm::StringRef::npos, flowOut.find("- [ 0 ]"));
  1208. EXPECT_NE(llvm::StringRef::npos, flowOut.find("- [ 12, 1, -512 ]"));
  1209. EXPECT_NE(llvm::StringRef::npos, flowOut.find("- [ ]"));
  1210. }
  1211. {
  1212. Input yin(intermediate);
  1213. NameAndNumbersFlow map2;
  1214. yin >> map2;
  1215. EXPECT_FALSE(yin.error());
  1216. EXPECT_TRUE(map2.name.equals("hello"));
  1217. EXPECT_EQ(map2.sequenceOfNumbers.size(), 3UL);
  1218. EXPECT_EQ(map2.sequenceOfNumbers[0].size(), 1UL);
  1219. EXPECT_EQ(0, map2.sequenceOfNumbers[0][0]);
  1220. EXPECT_EQ(map2.sequenceOfNumbers[1].size(), 3UL);
  1221. EXPECT_EQ(12, map2.sequenceOfNumbers[1][0]);
  1222. EXPECT_EQ(1, map2.sequenceOfNumbers[1][1]);
  1223. EXPECT_EQ(-512, map2.sequenceOfNumbers[1][2]);
  1224. EXPECT_TRUE(map2.sequenceOfNumbers[2].empty());
  1225. }
  1226. }
  1227. //===----------------------------------------------------------------------===//
  1228. // Test normalizing/denormalizing
  1229. //===----------------------------------------------------------------------===//
  1230. LLVM_YAML_STRONG_TYPEDEF(uint32_t, TotalSeconds)
  1231. typedef std::vector<TotalSeconds> SecondsSequence;
  1232. LLVM_YAML_IS_SEQUENCE_VECTOR(TotalSeconds)
  1233. namespace llvm {
  1234. namespace yaml {
  1235. template <>
  1236. struct MappingTraits<TotalSeconds> {
  1237. class NormalizedSeconds {
  1238. public:
  1239. NormalizedSeconds(IO &io)
  1240. : hours(0), minutes(0), seconds(0) {
  1241. }
  1242. NormalizedSeconds(IO &, TotalSeconds &secs)
  1243. : hours(secs/3600),
  1244. minutes((secs - (hours*3600))/60),
  1245. seconds(secs % 60) {
  1246. }
  1247. TotalSeconds denormalize(IO &) {
  1248. return TotalSeconds(hours*3600 + minutes*60 + seconds);
  1249. }
  1250. uint32_t hours;
  1251. uint8_t minutes;
  1252. uint8_t seconds;
  1253. };
  1254. static void mapping(IO &io, TotalSeconds &secs) {
  1255. MappingNormalization<NormalizedSeconds, TotalSeconds> keys(io, secs);
  1256. io.mapOptional("hours", keys->hours, 0);
  1257. io.mapOptional("minutes", keys->minutes, 0);
  1258. io.mapRequired("seconds", keys->seconds);
  1259. }
  1260. };
  1261. }
  1262. }
  1263. //
  1264. // Test the reading of a yaml sequence of mappings
  1265. //
  1266. TEST(YAMLIO, TestReadMySecondsSequence) {
  1267. SecondsSequence seq;
  1268. Input yin("---\n - hours: 1\n seconds: 5\n - seconds: 59\n...\n");
  1269. yin >> seq;
  1270. EXPECT_FALSE(yin.error());
  1271. EXPECT_EQ(seq.size(), 2UL);
  1272. EXPECT_EQ(seq[0], 3605U);
  1273. EXPECT_EQ(seq[1], 59U);
  1274. }
  1275. //
  1276. // Test writing then reading back custom values
  1277. //
  1278. TEST(YAMLIO, TestReadWriteMySecondsSequence) {
  1279. std::string intermediate;
  1280. {
  1281. SecondsSequence seq;
  1282. seq.push_back(4000);
  1283. seq.push_back(500);
  1284. seq.push_back(59);
  1285. llvm::raw_string_ostream ostr(intermediate);
  1286. Output yout(ostr);
  1287. yout << seq;
  1288. }
  1289. {
  1290. Input yin(intermediate);
  1291. SecondsSequence seq2;
  1292. yin >> seq2;
  1293. EXPECT_FALSE(yin.error());
  1294. EXPECT_EQ(seq2.size(), 3UL);
  1295. EXPECT_EQ(seq2[0], 4000U);
  1296. EXPECT_EQ(seq2[1], 500U);
  1297. EXPECT_EQ(seq2[2], 59U);
  1298. }
  1299. }
  1300. //===----------------------------------------------------------------------===//
  1301. // Test dynamic typing
  1302. //===----------------------------------------------------------------------===//
  1303. enum AFlags {
  1304. a1,
  1305. a2,
  1306. a3
  1307. };
  1308. enum BFlags {
  1309. b1,
  1310. b2,
  1311. b3
  1312. };
  1313. enum Kind {
  1314. kindA,
  1315. kindB
  1316. };
  1317. struct KindAndFlags {
  1318. KindAndFlags() : kind(kindA), flags(0) { }
  1319. KindAndFlags(Kind k, uint32_t f) : kind(k), flags(f) { }
  1320. Kind kind;
  1321. uint32_t flags;
  1322. };
  1323. typedef std::vector<KindAndFlags> KindAndFlagsSequence;
  1324. LLVM_YAML_IS_SEQUENCE_VECTOR(KindAndFlags)
  1325. namespace llvm {
  1326. namespace yaml {
  1327. template <>
  1328. struct ScalarEnumerationTraits<AFlags> {
  1329. static void enumeration(IO &io, AFlags &value) {
  1330. io.enumCase(value, "a1", a1);
  1331. io.enumCase(value, "a2", a2);
  1332. io.enumCase(value, "a3", a3);
  1333. }
  1334. };
  1335. template <>
  1336. struct ScalarEnumerationTraits<BFlags> {
  1337. static void enumeration(IO &io, BFlags &value) {
  1338. io.enumCase(value, "b1", b1);
  1339. io.enumCase(value, "b2", b2);
  1340. io.enumCase(value, "b3", b3);
  1341. }
  1342. };
  1343. template <>
  1344. struct ScalarEnumerationTraits<Kind> {
  1345. static void enumeration(IO &io, Kind &value) {
  1346. io.enumCase(value, "A", kindA);
  1347. io.enumCase(value, "B", kindB);
  1348. }
  1349. };
  1350. template <>
  1351. struct MappingTraits<KindAndFlags> {
  1352. static void mapping(IO &io, KindAndFlags& kf) {
  1353. io.mapRequired("kind", kf.kind);
  1354. // Type of "flags" field varies depending on "kind" field.
  1355. // Use memcpy here to avoid breaking strict aliasing rules.
  1356. if (kf.kind == kindA) {
  1357. AFlags aflags = static_cast<AFlags>(kf.flags);
  1358. io.mapRequired("flags", aflags);
  1359. kf.flags = aflags;
  1360. } else {
  1361. BFlags bflags = static_cast<BFlags>(kf.flags);
  1362. io.mapRequired("flags", bflags);
  1363. kf.flags = bflags;
  1364. }
  1365. }
  1366. };
  1367. }
  1368. }
  1369. //
  1370. // Test the reading of a yaml sequence dynamic types
  1371. //
  1372. TEST(YAMLIO, TestReadKindAndFlagsSequence) {
  1373. KindAndFlagsSequence seq;
  1374. Input yin("---\n - kind: A\n flags: a2\n - kind: B\n flags: b1\n...\n");
  1375. yin >> seq;
  1376. EXPECT_FALSE(yin.error());
  1377. EXPECT_EQ(seq.size(), 2UL);
  1378. EXPECT_EQ(seq[0].kind, kindA);
  1379. EXPECT_EQ(seq[0].flags, (uint32_t)a2);
  1380. EXPECT_EQ(seq[1].kind, kindB);
  1381. EXPECT_EQ(seq[1].flags, (uint32_t)b1);
  1382. }
  1383. //
  1384. // Test writing then reading back dynamic types
  1385. //
  1386. TEST(YAMLIO, TestReadWriteKindAndFlagsSequence) {
  1387. std::string intermediate;
  1388. {
  1389. KindAndFlagsSequence seq;
  1390. seq.push_back(KindAndFlags(kindA,a1));
  1391. seq.push_back(KindAndFlags(kindB,b1));
  1392. seq.push_back(KindAndFlags(kindA,a2));
  1393. seq.push_back(KindAndFlags(kindB,b2));
  1394. seq.push_back(KindAndFlags(kindA,a3));
  1395. llvm::raw_string_ostream ostr(intermediate);
  1396. Output yout(ostr);
  1397. yout << seq;
  1398. }
  1399. {
  1400. Input yin(intermediate);
  1401. KindAndFlagsSequence seq2;
  1402. yin >> seq2;
  1403. EXPECT_FALSE(yin.error());
  1404. EXPECT_EQ(seq2.size(), 5UL);
  1405. EXPECT_EQ(seq2[0].kind, kindA);
  1406. EXPECT_EQ(seq2[0].flags, (uint32_t)a1);
  1407. EXPECT_EQ(seq2[1].kind, kindB);
  1408. EXPECT_EQ(seq2[1].flags, (uint32_t)b1);
  1409. EXPECT_EQ(seq2[2].kind, kindA);
  1410. EXPECT_EQ(seq2[2].flags, (uint32_t)a2);
  1411. EXPECT_EQ(seq2[3].kind, kindB);
  1412. EXPECT_EQ(seq2[3].flags, (uint32_t)b2);
  1413. EXPECT_EQ(seq2[4].kind, kindA);
  1414. EXPECT_EQ(seq2[4].flags, (uint32_t)a3);
  1415. }
  1416. }
  1417. //===----------------------------------------------------------------------===//
  1418. // Test document list
  1419. //===----------------------------------------------------------------------===//
  1420. struct FooBarMap {
  1421. int foo;
  1422. int bar;
  1423. };
  1424. typedef std::vector<FooBarMap> FooBarMapDocumentList;
  1425. LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(FooBarMap)
  1426. namespace llvm {
  1427. namespace yaml {
  1428. template <>
  1429. struct MappingTraits<FooBarMap> {
  1430. static void mapping(IO &io, FooBarMap& fb) {
  1431. io.mapRequired("foo", fb.foo);
  1432. io.mapRequired("bar", fb.bar);
  1433. }
  1434. };
  1435. }
  1436. }
  1437. //
  1438. // Test the reading of a yaml mapping
  1439. //
  1440. TEST(YAMLIO, TestDocRead) {
  1441. FooBarMap doc;
  1442. Input yin("---\nfoo: 3\nbar: 5\n...\n");
  1443. yin >> doc;
  1444. EXPECT_FALSE(yin.error());
  1445. EXPECT_EQ(doc.foo, 3);
  1446. EXPECT_EQ(doc.bar,5);
  1447. }
  1448. //
  1449. // Test writing then reading back a sequence of mappings
  1450. //
  1451. TEST(YAMLIO, TestSequenceDocListWriteAndRead) {
  1452. std::string intermediate;
  1453. {
  1454. FooBarMap doc1;
  1455. doc1.foo = 10;
  1456. doc1.bar = -3;
  1457. FooBarMap doc2;
  1458. doc2.foo = 257;
  1459. doc2.bar = 0;
  1460. std::vector<FooBarMap> docList;
  1461. docList.push_back(doc1);
  1462. docList.push_back(doc2);
  1463. llvm::raw_string_ostream ostr(intermediate);
  1464. Output yout(ostr);
  1465. yout << docList;
  1466. }
  1467. {
  1468. Input yin(intermediate);
  1469. std::vector<FooBarMap> docList2;
  1470. yin >> docList2;
  1471. EXPECT_FALSE(yin.error());
  1472. EXPECT_EQ(docList2.size(), 2UL);
  1473. FooBarMap& map1 = docList2[0];
  1474. FooBarMap& map2 = docList2[1];
  1475. EXPECT_EQ(map1.foo, 10);
  1476. EXPECT_EQ(map1.bar, -3);
  1477. EXPECT_EQ(map2.foo, 257);
  1478. EXPECT_EQ(map2.bar, 0);
  1479. }
  1480. }
  1481. //===----------------------------------------------------------------------===//
  1482. // Test document tags
  1483. //===----------------------------------------------------------------------===//
  1484. struct MyDouble {
  1485. MyDouble() : value(0.0) { }
  1486. MyDouble(double x) : value(x) { }
  1487. double value;
  1488. };
  1489. LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyDouble)
  1490. namespace llvm {
  1491. namespace yaml {
  1492. template <>
  1493. struct MappingTraits<MyDouble> {
  1494. static void mapping(IO &io, MyDouble &d) {
  1495. if (io.mapTag("!decimal", true)) {
  1496. mappingDecimal(io, d);
  1497. } else if (io.mapTag("!fraction")) {
  1498. mappingFraction(io, d);
  1499. }
  1500. }
  1501. static void mappingDecimal(IO &io, MyDouble &d) {
  1502. io.mapRequired("value", d.value);
  1503. }
  1504. static void mappingFraction(IO &io, MyDouble &d) {
  1505. double num, denom;
  1506. io.mapRequired("numerator", num);
  1507. io.mapRequired("denominator", denom);
  1508. // convert fraction to double
  1509. d.value = num/denom;
  1510. }
  1511. };
  1512. }
  1513. }
  1514. //
  1515. // Test the reading of two different tagged yaml documents.
  1516. //
  1517. TEST(YAMLIO, TestTaggedDocuments) {
  1518. std::vector<MyDouble> docList;
  1519. Input yin("--- !decimal\nvalue: 3.0\n"
  1520. "--- !fraction\nnumerator: 9.0\ndenominator: 2\n...\n");
  1521. yin >> docList;
  1522. EXPECT_FALSE(yin.error());
  1523. EXPECT_EQ(docList.size(), 2UL);
  1524. EXPECT_EQ(docList[0].value, 3.0);
  1525. EXPECT_EQ(docList[1].value, 4.5);
  1526. }
  1527. //
  1528. // Test writing then reading back tagged documents
  1529. //
  1530. TEST(YAMLIO, TestTaggedDocumentsWriteAndRead) {
  1531. std::string intermediate;
  1532. {
  1533. MyDouble a(10.25);
  1534. MyDouble b(-3.75);
  1535. std::vector<MyDouble> docList;
  1536. docList.push_back(a);
  1537. docList.push_back(b);
  1538. llvm::raw_string_ostream ostr(intermediate);
  1539. Output yout(ostr);
  1540. yout << docList;
  1541. }
  1542. {
  1543. Input yin(intermediate);
  1544. std::vector<MyDouble> docList2;
  1545. yin >> docList2;
  1546. EXPECT_FALSE(yin.error());
  1547. EXPECT_EQ(docList2.size(), 2UL);
  1548. EXPECT_EQ(docList2[0].value, 10.25);
  1549. EXPECT_EQ(docList2[1].value, -3.75);
  1550. }
  1551. }
  1552. //===----------------------------------------------------------------------===//
  1553. // Test mapping validation
  1554. //===----------------------------------------------------------------------===//
  1555. struct MyValidation {
  1556. double value;
  1557. };
  1558. LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyValidation)
  1559. namespace llvm {
  1560. namespace yaml {
  1561. template <>
  1562. struct MappingTraits<MyValidation> {
  1563. static void mapping(IO &io, MyValidation &d) {
  1564. io.mapRequired("value", d.value);
  1565. }
  1566. static StringRef validate(IO &io, MyValidation &d) {
  1567. if (d.value < 0)
  1568. return "negative value";
  1569. return StringRef();
  1570. }
  1571. };
  1572. }
  1573. }
  1574. //
  1575. // Test that validate() is called and complains about the negative value.
  1576. //
  1577. TEST(YAMLIO, TestValidatingInput) {
  1578. std::vector<MyValidation> docList;
  1579. Input yin("--- \nvalue: 3.0\n"
  1580. "--- \nvalue: -1.0\n...\n",
  1581. nullptr, suppressErrorMessages);
  1582. yin >> docList;
  1583. EXPECT_TRUE(!!yin.error());
  1584. }
  1585. //===----------------------------------------------------------------------===//
  1586. // Test flow mapping
  1587. //===----------------------------------------------------------------------===//
  1588. struct FlowFooBar {
  1589. int foo;
  1590. int bar;
  1591. FlowFooBar() : foo(0), bar(0) {}
  1592. FlowFooBar(int foo, int bar) : foo(foo), bar(bar) {}
  1593. };
  1594. typedef std::vector<FlowFooBar> FlowFooBarSequence;
  1595. LLVM_YAML_IS_SEQUENCE_VECTOR(FlowFooBar)
  1596. struct FlowFooBarDoc {
  1597. FlowFooBar attribute;
  1598. FlowFooBarSequence seq;
  1599. };
  1600. namespace llvm {
  1601. namespace yaml {
  1602. template <>
  1603. struct MappingTraits<FlowFooBar> {
  1604. static void mapping(IO &io, FlowFooBar &fb) {
  1605. io.mapRequired("foo", fb.foo);
  1606. io.mapRequired("bar", fb.bar);
  1607. }
  1608. static const bool flow = true;
  1609. };
  1610. template <>
  1611. struct MappingTraits<FlowFooBarDoc> {
  1612. static void mapping(IO &io, FlowFooBarDoc &fb) {
  1613. io.mapRequired("attribute", fb.attribute);
  1614. io.mapRequired("seq", fb.seq);
  1615. }
  1616. };
  1617. }
  1618. }
  1619. //
  1620. // Test writing then reading back custom mappings
  1621. //
  1622. TEST(YAMLIO, TestReadWriteMyFlowMapping) {
  1623. std::string intermediate;
  1624. {
  1625. FlowFooBarDoc doc;
  1626. doc.attribute = FlowFooBar(42, 907);
  1627. doc.seq.push_back(FlowFooBar(1, 2));
  1628. doc.seq.push_back(FlowFooBar(0, 0));
  1629. doc.seq.push_back(FlowFooBar(-1, 1024));
  1630. llvm::raw_string_ostream ostr(intermediate);
  1631. Output yout(ostr);
  1632. yout << doc;
  1633. // Verify that mappings were written in flow style
  1634. ostr.flush();
  1635. llvm::StringRef flowOut(intermediate);
  1636. EXPECT_NE(llvm::StringRef::npos, flowOut.find("{ foo: 42, bar: 907 }"));
  1637. EXPECT_NE(llvm::StringRef::npos, flowOut.find("- { foo: 1, bar: 2 }"));
  1638. EXPECT_NE(llvm::StringRef::npos, flowOut.find("- { foo: 0, bar: 0 }"));
  1639. EXPECT_NE(llvm::StringRef::npos, flowOut.find("- { foo: -1, bar: 1024 }"));
  1640. }
  1641. {
  1642. Input yin(intermediate);
  1643. FlowFooBarDoc doc2;
  1644. yin >> doc2;
  1645. EXPECT_FALSE(yin.error());
  1646. EXPECT_EQ(doc2.attribute.foo, 42);
  1647. EXPECT_EQ(doc2.attribute.bar, 907);
  1648. EXPECT_EQ(doc2.seq.size(), 3UL);
  1649. EXPECT_EQ(doc2.seq[0].foo, 1);
  1650. EXPECT_EQ(doc2.seq[0].bar, 2);
  1651. EXPECT_EQ(doc2.seq[1].foo, 0);
  1652. EXPECT_EQ(doc2.seq[1].bar, 0);
  1653. EXPECT_EQ(doc2.seq[2].foo, -1);
  1654. EXPECT_EQ(doc2.seq[2].bar, 1024);
  1655. }
  1656. }
  1657. //===----------------------------------------------------------------------===//
  1658. // Test error handling
  1659. //===----------------------------------------------------------------------===//
  1660. //
  1661. // Test error handling of unknown enumerated scalar
  1662. //
  1663. TEST(YAMLIO, TestColorsReadError) {
  1664. ColorMap map;
  1665. Input yin("---\n"
  1666. "c1: blue\n"
  1667. "c2: purple\n"
  1668. "c3: green\n"
  1669. "...\n",
  1670. /*Ctxt=*/nullptr,
  1671. suppressErrorMessages);
  1672. yin >> map;
  1673. EXPECT_TRUE(!!yin.error());
  1674. }
  1675. //
  1676. // Test error handling of flow sequence with unknown value
  1677. //
  1678. TEST(YAMLIO, TestFlagsReadError) {
  1679. FlagsMap map;
  1680. Input yin("---\n"
  1681. "f1: [ big ]\n"
  1682. "f2: [ round, hollow ]\n"
  1683. "f3: []\n"
  1684. "...\n",
  1685. /*Ctxt=*/nullptr,
  1686. suppressErrorMessages);
  1687. yin >> map;
  1688. EXPECT_TRUE(!!yin.error());
  1689. }
  1690. //
  1691. // Test error handling reading built-in uint8_t type
  1692. //
  1693. TEST(YAMLIO, TestReadBuiltInTypesUint8Error) {
  1694. std::vector<uint8_t> seq;
  1695. Input yin("---\n"
  1696. "- 255\n"
  1697. "- 0\n"
  1698. "- 257\n"
  1699. "...\n",
  1700. /*Ctxt=*/nullptr,
  1701. suppressErrorMessages);
  1702. yin >> seq;
  1703. EXPECT_TRUE(!!yin.error());
  1704. }
  1705. //
  1706. // Test error handling reading built-in uint16_t type
  1707. //
  1708. TEST(YAMLIO, TestReadBuiltInTypesUint16Error) {
  1709. std::vector<uint16_t> seq;
  1710. Input yin("---\n"
  1711. "- 65535\n"
  1712. "- 0\n"
  1713. "- 66000\n"
  1714. "...\n",
  1715. /*Ctxt=*/nullptr,
  1716. suppressErrorMessages);
  1717. yin >> seq;
  1718. EXPECT_TRUE(!!yin.error());
  1719. }
  1720. //
  1721. // Test error handling reading built-in uint32_t type
  1722. //
  1723. TEST(YAMLIO, TestReadBuiltInTypesUint32Error) {
  1724. std::vector<uint32_t> seq;
  1725. Input yin("---\n"
  1726. "- 4000000000\n"
  1727. "- 0\n"
  1728. "- 5000000000\n"
  1729. "...\n",
  1730. /*Ctxt=*/nullptr,
  1731. suppressErrorMessages);
  1732. yin >> seq;
  1733. EXPECT_TRUE(!!yin.error());
  1734. }
  1735. //
  1736. // Test error handling reading built-in uint64_t type
  1737. //
  1738. TEST(YAMLIO, TestReadBuiltInTypesUint64Error) {
  1739. std::vector<uint64_t> seq;
  1740. Input yin("---\n"
  1741. "- 18446744073709551615\n"
  1742. "- 0\n"
  1743. "- 19446744073709551615\n"
  1744. "...\n",
  1745. /*Ctxt=*/nullptr,
  1746. suppressErrorMessages);
  1747. yin >> seq;
  1748. EXPECT_TRUE(!!yin.error());
  1749. }
  1750. //
  1751. // Test error handling reading built-in int8_t type
  1752. //
  1753. TEST(YAMLIO, TestReadBuiltInTypesint8OverError) {
  1754. std::vector<int8_t> seq;
  1755. Input yin("---\n"
  1756. "- -128\n"
  1757. "- 0\n"
  1758. "- 127\n"
  1759. "- 128\n"
  1760. "...\n",
  1761. /*Ctxt=*/nullptr,
  1762. suppressErrorMessages);
  1763. yin >> seq;
  1764. EXPECT_TRUE(!!yin.error());
  1765. }
  1766. //
  1767. // Test error handling reading built-in int8_t type
  1768. //
  1769. TEST(YAMLIO, TestReadBuiltInTypesint8UnderError) {
  1770. std::vector<int8_t> seq;
  1771. Input yin("---\n"
  1772. "- -128\n"
  1773. "- 0\n"
  1774. "- 127\n"
  1775. "- -129\n"
  1776. "...\n",
  1777. /*Ctxt=*/nullptr,
  1778. suppressErrorMessages);
  1779. yin >> seq;
  1780. EXPECT_TRUE(!!yin.error());
  1781. }
  1782. //
  1783. // Test error handling reading built-in int16_t type
  1784. //
  1785. TEST(YAMLIO, TestReadBuiltInTypesint16UnderError) {
  1786. std::vector<int16_t> seq;
  1787. Input yin("---\n"
  1788. "- 32767\n"
  1789. "- 0\n"
  1790. "- -32768\n"
  1791. "- -32769\n"
  1792. "...\n",
  1793. /*Ctxt=*/nullptr,
  1794. suppressErrorMessages);
  1795. yin >> seq;
  1796. EXPECT_TRUE(!!yin.error());
  1797. }
  1798. //
  1799. // Test error handling reading built-in int16_t type
  1800. //
  1801. TEST(YAMLIO, TestReadBuiltInTypesint16OverError) {
  1802. std::vector<int16_t> seq;
  1803. Input yin("---\n"
  1804. "- 32767\n"
  1805. "- 0\n"
  1806. "- -32768\n"
  1807. "- 32768\n"
  1808. "...\n",
  1809. /*Ctxt=*/nullptr,
  1810. suppressErrorMessages);
  1811. yin >> seq;
  1812. EXPECT_TRUE(!!yin.error());
  1813. }
  1814. //
  1815. // Test error handling reading built-in int32_t type
  1816. //
  1817. TEST(YAMLIO, TestReadBuiltInTypesint32UnderError) {
  1818. std::vector<int32_t> seq;
  1819. Input yin("---\n"
  1820. "- 2147483647\n"
  1821. "- 0\n"
  1822. "- -2147483648\n"
  1823. "- -2147483649\n"
  1824. "...\n",
  1825. /*Ctxt=*/nullptr,
  1826. suppressErrorMessages);
  1827. yin >> seq;
  1828. EXPECT_TRUE(!!yin.error());
  1829. }
  1830. //
  1831. // Test error handling reading built-in int32_t type
  1832. //
  1833. TEST(YAMLIO, TestReadBuiltInTypesint32OverError) {
  1834. std::vector<int32_t> seq;
  1835. Input yin("---\n"
  1836. "- 2147483647\n"
  1837. "- 0\n"
  1838. "- -2147483648\n"
  1839. "- 2147483649\n"
  1840. "...\n",
  1841. /*Ctxt=*/nullptr,
  1842. suppressErrorMessages);
  1843. yin >> seq;
  1844. EXPECT_TRUE(!!yin.error());
  1845. }
  1846. //
  1847. // Test error handling reading built-in int64_t type
  1848. //
  1849. TEST(YAMLIO, TestReadBuiltInTypesint64UnderError) {
  1850. std::vector<int64_t> seq;
  1851. Input yin("---\n"
  1852. "- -9223372036854775808\n"
  1853. "- 0\n"
  1854. "- 9223372036854775807\n"
  1855. "- -9223372036854775809\n"
  1856. "...\n",
  1857. /*Ctxt=*/nullptr,
  1858. suppressErrorMessages);
  1859. yin >> seq;
  1860. EXPECT_TRUE(!!yin.error());
  1861. }
  1862. //
  1863. // Test error handling reading built-in int64_t type
  1864. //
  1865. TEST(YAMLIO, TestReadBuiltInTypesint64OverError) {
  1866. std::vector<int64_t> seq;
  1867. Input yin("---\n"
  1868. "- -9223372036854775808\n"
  1869. "- 0\n"
  1870. "- 9223372036854775807\n"
  1871. "- 9223372036854775809\n"
  1872. "...\n",
  1873. /*Ctxt=*/nullptr,
  1874. suppressErrorMessages);
  1875. yin >> seq;
  1876. EXPECT_TRUE(!!yin.error());
  1877. }
  1878. //
  1879. // Test error handling reading built-in float type
  1880. //
  1881. TEST(YAMLIO, TestReadBuiltInTypesFloatError) {
  1882. std::vector<float> seq;
  1883. Input yin("---\n"
  1884. "- 0.0\n"
  1885. "- 1000.1\n"
  1886. "- -123.456\n"
  1887. "- 1.2.3\n"
  1888. "...\n",
  1889. /*Ctxt=*/nullptr,
  1890. suppressErrorMessages);
  1891. yin >> seq;
  1892. EXPECT_TRUE(!!yin.error());
  1893. }
  1894. //
  1895. // Test error handling reading built-in float type
  1896. //
  1897. TEST(YAMLIO, TestReadBuiltInTypesDoubleError) {
  1898. std::vector<double> seq;
  1899. Input yin("---\n"
  1900. "- 0.0\n"
  1901. "- 1000.1\n"
  1902. "- -123.456\n"
  1903. "- 1.2.3\n"
  1904. "...\n",
  1905. /*Ctxt=*/nullptr,
  1906. suppressErrorMessages);
  1907. yin >> seq;
  1908. EXPECT_TRUE(!!yin.error());
  1909. }
  1910. //
  1911. // Test error handling reading built-in Hex8 type
  1912. //
  1913. LLVM_YAML_IS_SEQUENCE_VECTOR(Hex8)
  1914. TEST(YAMLIO, TestReadBuiltInTypesHex8Error) {
  1915. std::vector<Hex8> seq;
  1916. Input yin("---\n"
  1917. "- 0x12\n"
  1918. "- 0xFE\n"
  1919. "- 0x123\n"
  1920. "...\n",
  1921. /*Ctxt=*/nullptr,
  1922. suppressErrorMessages);
  1923. yin >> seq;
  1924. EXPECT_TRUE(!!yin.error());
  1925. }
  1926. //
  1927. // Test error handling reading built-in Hex16 type
  1928. //
  1929. LLVM_YAML_IS_SEQUENCE_VECTOR(Hex16)
  1930. TEST(YAMLIO, TestReadBuiltInTypesHex16Error) {
  1931. std::vector<Hex16> seq;
  1932. Input yin("---\n"
  1933. "- 0x0012\n"
  1934. "- 0xFEFF\n"
  1935. "- 0x12345\n"
  1936. "...\n",
  1937. /*Ctxt=*/nullptr,
  1938. suppressErrorMessages);
  1939. yin >> seq;
  1940. EXPECT_TRUE(!!yin.error());
  1941. }
  1942. //
  1943. // Test error handling reading built-in Hex32 type
  1944. //
  1945. LLVM_YAML_IS_SEQUENCE_VECTOR(Hex32)
  1946. TEST(YAMLIO, TestReadBuiltInTypesHex32Error) {
  1947. std::vector<Hex32> seq;
  1948. Input yin("---\n"
  1949. "- 0x0012\n"
  1950. "- 0xFEFF0000\n"
  1951. "- 0x1234556789\n"
  1952. "...\n",
  1953. /*Ctxt=*/nullptr,
  1954. suppressErrorMessages);
  1955. yin >> seq;
  1956. EXPECT_TRUE(!!yin.error());
  1957. }
  1958. //
  1959. // Test error handling reading built-in Hex64 type
  1960. //
  1961. LLVM_YAML_IS_SEQUENCE_VECTOR(Hex64)
  1962. TEST(YAMLIO, TestReadBuiltInTypesHex64Error) {
  1963. std::vector<Hex64> seq;
  1964. Input yin("---\n"
  1965. "- 0x0012\n"
  1966. "- 0xFFEEDDCCBBAA9988\n"
  1967. "- 0x12345567890ABCDEF0\n"
  1968. "...\n",
  1969. /*Ctxt=*/nullptr,
  1970. suppressErrorMessages);
  1971. yin >> seq;
  1972. EXPECT_TRUE(!!yin.error());
  1973. }
  1974. TEST(YAMLIO, TestMalformedMapFailsGracefully) {
  1975. FooBar doc;
  1976. {
  1977. // We pass the suppressErrorMessages handler to handle the error
  1978. // message generated in the constructor of Input.
  1979. Input yin("{foo:3, bar: 5}", /*Ctxt=*/nullptr, suppressErrorMessages);
  1980. yin >> doc;
  1981. EXPECT_TRUE(!!yin.error());
  1982. }
  1983. {
  1984. Input yin("---\nfoo:3\nbar: 5\n...\n", /*Ctxt=*/nullptr, suppressErrorMessages);
  1985. yin >> doc;
  1986. EXPECT_TRUE(!!yin.error());
  1987. }
  1988. }
  1989. struct OptionalTest {
  1990. std::vector<int> Numbers;
  1991. };
  1992. struct OptionalTestSeq {
  1993. std::vector<OptionalTest> Tests;
  1994. };
  1995. LLVM_YAML_IS_SEQUENCE_VECTOR(OptionalTest)
  1996. namespace llvm {
  1997. namespace yaml {
  1998. template <>
  1999. struct MappingTraits<OptionalTest> {
  2000. static void mapping(IO& IO, OptionalTest &OT) {
  2001. IO.mapOptional("Numbers", OT.Numbers);
  2002. }
  2003. };
  2004. template <>
  2005. struct MappingTraits<OptionalTestSeq> {
  2006. static void mapping(IO &IO, OptionalTestSeq &OTS) {
  2007. IO.mapOptional("Tests", OTS.Tests);
  2008. }
  2009. };
  2010. }
  2011. }
  2012. TEST(YAMLIO, SequenceElideTest) {
  2013. // Test that writing out a purely optional structure with its fields set to
  2014. // default followed by other data is properly read back in.
  2015. OptionalTestSeq Seq;
  2016. OptionalTest One, Two, Three, Four;
  2017. int N[] = {1, 2, 3};
  2018. Three.Numbers.assign(N, N + 3);
  2019. Seq.Tests.push_back(One);
  2020. Seq.Tests.push_back(Two);
  2021. Seq.Tests.push_back(Three);
  2022. Seq.Tests.push_back(Four);
  2023. std::string intermediate;
  2024. {
  2025. llvm::raw_string_ostream ostr(intermediate);
  2026. Output yout(ostr);
  2027. yout << Seq;
  2028. }
  2029. Input yin(intermediate);
  2030. OptionalTestSeq Seq2;
  2031. yin >> Seq2;
  2032. EXPECT_FALSE(yin.error());
  2033. EXPECT_EQ(4UL, Seq2.Tests.size());
  2034. EXPECT_TRUE(Seq2.Tests[0].Numbers.empty());
  2035. EXPECT_TRUE(Seq2.Tests[1].Numbers.empty());
  2036. EXPECT_EQ(1, Seq2.Tests[2].Numbers[0]);
  2037. EXPECT_EQ(2, Seq2.Tests[2].Numbers[1]);
  2038. EXPECT_EQ(3, Seq2.Tests[2].Numbers[2]);
  2039. EXPECT_TRUE(Seq2.Tests[3].Numbers.empty());
  2040. }
  2041. TEST(YAMLIO, TestEmptyStringFailsForMapWithRequiredFields) {
  2042. FooBar doc;
  2043. Input yin("");
  2044. yin >> doc;
  2045. EXPECT_TRUE(!!yin.error());
  2046. }
  2047. TEST(YAMLIO, TestEmptyStringSucceedsForMapWithOptionalFields) {
  2048. OptionalTest doc;
  2049. Input yin("");
  2050. yin >> doc;
  2051. EXPECT_FALSE(yin.error());
  2052. }
  2053. TEST(YAMLIO, TestEmptyStringSucceedsForSequence) {
  2054. std::vector<uint8_t> seq;
  2055. Input yin("", /*Ctxt=*/nullptr, suppressErrorMessages);
  2056. yin >> seq;
  2057. EXPECT_FALSE(yin.error());
  2058. EXPECT_TRUE(seq.empty());
  2059. }
  2060. struct FlowMap {
  2061. llvm::StringRef str1, str2, str3;
  2062. FlowMap(llvm::StringRef str1, llvm::StringRef str2, llvm::StringRef str3)
  2063. : str1(str1), str2(str2), str3(str3) {}
  2064. };
  2065. struct FlowSeq {
  2066. llvm::StringRef str;
  2067. FlowSeq(llvm::StringRef S) : str(S) {}
  2068. FlowSeq() = default;
  2069. };
  2070. namespace llvm {
  2071. namespace yaml {
  2072. template <>
  2073. struct MappingTraits<FlowMap> {
  2074. static void mapping(IO &io, FlowMap &fm) {
  2075. io.mapRequired("str1", fm.str1);
  2076. io.mapRequired("str2", fm.str2);
  2077. io.mapRequired("str3", fm.str3);
  2078. }
  2079. static const bool flow = true;
  2080. };
  2081. template <>
  2082. struct ScalarTraits<FlowSeq> {
  2083. static void output(const FlowSeq &value, void*, llvm::raw_ostream &out) {
  2084. out << value.str;
  2085. }
  2086. static StringRef input(StringRef scalar, void*, FlowSeq &value) {
  2087. value.str = scalar;
  2088. return "";
  2089. }
  2090. static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
  2091. };
  2092. }
  2093. }
  2094. LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FlowSeq)
  2095. TEST(YAMLIO, TestWrapFlow) {
  2096. std::string out;
  2097. llvm::raw_string_ostream ostr(out);
  2098. FlowMap Map("This is str1", "This is str2", "This is str3");
  2099. std::vector<FlowSeq> Seq;
  2100. Seq.emplace_back("This is str1");
  2101. Seq.emplace_back("This is str2");
  2102. Seq.emplace_back("This is str3");
  2103. {
  2104. // 20 is just bellow the total length of the first mapping field.
  2105. // We should wreap at every element.
  2106. Output yout(ostr, nullptr, 15);
  2107. yout << Map;
  2108. ostr.flush();
  2109. EXPECT_EQ(out,
  2110. "---\n"
  2111. "{ str1: This is str1, \n"
  2112. " str2: This is str2, \n"
  2113. " str3: This is str3 }\n"
  2114. "...\n");
  2115. out.clear();
  2116. yout << Seq;
  2117. ostr.flush();
  2118. EXPECT_EQ(out,
  2119. "---\n"
  2120. "[ This is str1, \n"
  2121. " This is str2, \n"
  2122. " This is str3 ]\n"
  2123. "...\n");
  2124. out.clear();
  2125. }
  2126. {
  2127. // 25 will allow the second field to be output on the first line.
  2128. Output yout(ostr, nullptr, 25);
  2129. yout << Map;
  2130. ostr.flush();
  2131. EXPECT_EQ(out,
  2132. "---\n"
  2133. "{ str1: This is str1, str2: This is str2, \n"
  2134. " str3: This is str3 }\n"
  2135. "...\n");
  2136. out.clear();
  2137. yout << Seq;
  2138. ostr.flush();
  2139. EXPECT_EQ(out,
  2140. "---\n"
  2141. "[ This is str1, This is str2, \n"
  2142. " This is str3 ]\n"
  2143. "...\n");
  2144. out.clear();
  2145. }
  2146. {
  2147. // 0 means no wrapping.
  2148. Output yout(ostr, nullptr, 0);
  2149. yout << Map;
  2150. ostr.flush();
  2151. EXPECT_EQ(out,
  2152. "---\n"
  2153. "{ str1: This is str1, str2: This is str2, str3: This is str3 }\n"
  2154. "...\n");
  2155. out.clear();
  2156. yout << Seq;
  2157. ostr.flush();
  2158. EXPECT_EQ(out,
  2159. "---\n"
  2160. "[ This is str1, This is str2, This is str3 ]\n"
  2161. "...\n");
  2162. out.clear();
  2163. }
  2164. }
  2165. struct MappingContext {
  2166. int A = 0;
  2167. };
  2168. struct SimpleMap {
  2169. int B = 0;
  2170. int C = 0;
  2171. };
  2172. struct NestedMap {
  2173. NestedMap(MappingContext &Context) : Context(Context) {}
  2174. SimpleMap Simple;
  2175. MappingContext &Context;
  2176. };
  2177. namespace llvm {
  2178. namespace yaml {
  2179. template <> struct MappingContextTraits<SimpleMap, MappingContext> {
  2180. static void mapping(IO &io, SimpleMap &sm, MappingContext &Context) {
  2181. io.mapRequired("B", sm.B);
  2182. io.mapRequired("C", sm.C);
  2183. ++Context.A;
  2184. io.mapRequired("Context", Context.A);
  2185. }
  2186. };
  2187. template <> struct MappingTraits<NestedMap> {
  2188. static void mapping(IO &io, NestedMap &nm) {
  2189. io.mapRequired("Simple", nm.Simple, nm.Context);
  2190. }
  2191. };
  2192. }
  2193. }
  2194. TEST(YAMLIO, TestMapWithContext) {
  2195. MappingContext Context;
  2196. NestedMap Nested(Context);
  2197. std::string out;
  2198. llvm::raw_string_ostream ostr(out);
  2199. Output yout(ostr, nullptr, 15);
  2200. yout << Nested;
  2201. ostr.flush();
  2202. EXPECT_EQ(1, Context.A);
  2203. EXPECT_EQ("---\n"
  2204. "Simple:\n"
  2205. " B: 0\n"
  2206. " C: 0\n"
  2207. " Context: 1\n"
  2208. "...\n",
  2209. out);
  2210. out.clear();
  2211. Nested.Simple.B = 2;
  2212. Nested.Simple.C = 3;
  2213. yout << Nested;
  2214. ostr.flush();
  2215. EXPECT_EQ(2, Context.A);
  2216. EXPECT_EQ("---\n"
  2217. "Simple:\n"
  2218. " B: 2\n"
  2219. " C: 3\n"
  2220. " Context: 2\n"
  2221. "...\n",
  2222. out);
  2223. out.clear();
  2224. }
  2225. LLVM_YAML_IS_STRING_MAP(int)
  2226. TEST(YAMLIO, TestCustomMapping) {
  2227. std::map<std::string, int> x;
  2228. std::string out;
  2229. llvm::raw_string_ostream ostr(out);
  2230. Output xout(ostr, nullptr, 0);
  2231. xout << x;
  2232. ostr.flush();
  2233. EXPECT_EQ("---\n"
  2234. "{}\n"
  2235. "...\n",
  2236. out);
  2237. x["foo"] = 1;
  2238. x["bar"] = 2;
  2239. out.clear();
  2240. xout << x;
  2241. ostr.flush();
  2242. EXPECT_EQ("---\n"
  2243. "bar: 2\n"
  2244. "foo: 1\n"
  2245. "...\n",
  2246. out);
  2247. Input yin(out);
  2248. std::map<std::string, int> y;
  2249. yin >> y;
  2250. EXPECT_EQ(2ul, y.size());
  2251. EXPECT_EQ(1, y["foo"]);
  2252. EXPECT_EQ(2, y["bar"]);
  2253. }
  2254. LLVM_YAML_IS_STRING_MAP(FooBar)
  2255. TEST(YAMLIO, TestCustomMappingStruct) {
  2256. std::map<std::string, FooBar> x;
  2257. x["foo"].foo = 1;
  2258. x["foo"].bar = 2;
  2259. x["bar"].foo = 3;
  2260. x["bar"].bar = 4;
  2261. std::string out;
  2262. llvm::raw_string_ostream ostr(out);
  2263. Output xout(ostr, nullptr, 0);
  2264. xout << x;
  2265. ostr.flush();
  2266. EXPECT_EQ("---\n"
  2267. "bar:\n"
  2268. " foo: 3\n"
  2269. " bar: 4\n"
  2270. "foo:\n"
  2271. " foo: 1\n"
  2272. " bar: 2\n"
  2273. "...\n",
  2274. out);
  2275. Input yin(out);
  2276. std::map<std::string, FooBar> y;
  2277. yin >> y;
  2278. EXPECT_EQ(2ul, y.size());
  2279. EXPECT_EQ(1, y["foo"].foo);
  2280. EXPECT_EQ(2, y["foo"].bar);
  2281. EXPECT_EQ(3, y["bar"].foo);
  2282. EXPECT_EQ(4, y["bar"].bar);
  2283. }
  2284. struct FooBarMapMap {
  2285. std::map<std::string, FooBar> fbm;
  2286. };
  2287. namespace llvm {
  2288. namespace yaml {
  2289. template <> struct MappingTraits<FooBarMapMap> {
  2290. static void mapping(IO &io, FooBarMapMap &x) {
  2291. io.mapRequired("fbm", x.fbm);
  2292. }
  2293. };
  2294. }
  2295. }
  2296. TEST(YAMLIO, TestEmptyMapWrite) {
  2297. FooBarMapMap cont;
  2298. std::string str;
  2299. llvm::raw_string_ostream OS(str);
  2300. Output yout(OS);
  2301. yout << cont;
  2302. EXPECT_EQ(OS.str(), "---\nfbm: {}\n...\n");
  2303. }
  2304. TEST(YAMLIO, TestEmptySequenceWrite) {
  2305. FooBarContainer cont;
  2306. std::string str;
  2307. llvm::raw_string_ostream OS(str);
  2308. Output yout(OS);
  2309. yout << cont;
  2310. EXPECT_EQ(OS.str(), "---\nfbs: []\n...\n");
  2311. }
  2312. static void TestEscaped(llvm::StringRef Input, llvm::StringRef Expected) {
  2313. std::string out;
  2314. llvm::raw_string_ostream ostr(out);
  2315. Output xout(ostr, nullptr, 0);
  2316. llvm::yaml::EmptyContext Ctx;
  2317. yamlize(xout, Input, true, Ctx);
  2318. ostr.flush();
  2319. // Make a separate StringRef so we get nice byte-by-byte output.
  2320. llvm::StringRef Got(out);
  2321. EXPECT_EQ(Expected, Got);
  2322. }
  2323. TEST(YAMLIO, TestEscaped) {
  2324. // Single quote
  2325. TestEscaped("@abc@", "'@abc@'");
  2326. // No quote
  2327. TestEscaped("abc", "abc");
  2328. // Forward slash quoted
  2329. TestEscaped("abc/", "'abc/'");
  2330. // Double quote non-printable
  2331. TestEscaped("\01@abc@", "\"\\x01@abc@\"");
  2332. // Double quote inside single quote
  2333. TestEscaped("abc\"fdf", "'abc\"fdf'");
  2334. // Double quote inside double quote
  2335. TestEscaped("\01bc\"fdf", "\"\\x01bc\\\"fdf\"");
  2336. // Single quote inside single quote
  2337. TestEscaped("abc'fdf", "'abc''fdf'");
  2338. // UTF8
  2339. TestEscaped("/*параметр*/", "\"/*параметр*/\"");
  2340. // UTF8 with single quote inside double quote
  2341. TestEscaped("parameter 'параметр' is unused",
  2342. "\"parameter 'параметр' is unused\"");
  2343. // String with embedded non-printable multibyte UTF-8 sequence (U+200B
  2344. // zero-width space). The thing to test here is that we emit a
  2345. // unicode-scalar level escape like \uNNNN (at the YAML level), and don't
  2346. // just pass the UTF-8 byte sequence through as with quoted printables.
  2347. {
  2348. const unsigned char foobar[10] = {'f', 'o', 'o',
  2349. 0xE2, 0x80, 0x8B, // UTF-8 of U+200B
  2350. 'b', 'a', 'r',
  2351. 0x0};
  2352. TestEscaped((char const *)foobar, "\"foo\\u200Bbar\"");
  2353. }
  2354. }
  2355. TEST(YAMLIO, Numeric) {
  2356. EXPECT_TRUE(isNumeric(".inf"));
  2357. EXPECT_TRUE(isNumeric(".INF"));
  2358. EXPECT_TRUE(isNumeric(".Inf"));
  2359. EXPECT_TRUE(isNumeric("-.inf"));
  2360. EXPECT_TRUE(isNumeric("+.inf"));
  2361. EXPECT_TRUE(isNumeric(".nan"));
  2362. EXPECT_TRUE(isNumeric(".NaN"));
  2363. EXPECT_TRUE(isNumeric(".NAN"));
  2364. EXPECT_TRUE(isNumeric("0"));
  2365. EXPECT_TRUE(isNumeric("0."));
  2366. EXPECT_TRUE(isNumeric("0.0"));
  2367. EXPECT_TRUE(isNumeric("-0.0"));
  2368. EXPECT_TRUE(isNumeric("+0.0"));
  2369. EXPECT_TRUE(isNumeric("12345"));
  2370. EXPECT_TRUE(isNumeric("012345"));
  2371. EXPECT_TRUE(isNumeric("+12.0"));
  2372. EXPECT_TRUE(isNumeric(".5"));
  2373. EXPECT_TRUE(isNumeric("+.5"));
  2374. EXPECT_TRUE(isNumeric("-1.0"));
  2375. EXPECT_TRUE(isNumeric("2.3e4"));
  2376. EXPECT_TRUE(isNumeric("-2E+05"));
  2377. EXPECT_TRUE(isNumeric("+12e03"));
  2378. EXPECT_TRUE(isNumeric("6.8523015e+5"));
  2379. EXPECT_TRUE(isNumeric("1.e+1"));
  2380. EXPECT_TRUE(isNumeric(".0e+1"));
  2381. EXPECT_TRUE(isNumeric("0x2aF3"));
  2382. EXPECT_TRUE(isNumeric("0o01234567"));
  2383. EXPECT_FALSE(isNumeric("not a number"));
  2384. EXPECT_FALSE(isNumeric("."));
  2385. EXPECT_FALSE(isNumeric(".e+1"));
  2386. EXPECT_FALSE(isNumeric(".1e"));
  2387. EXPECT_FALSE(isNumeric(".1e+"));
  2388. EXPECT_FALSE(isNumeric(".1e++1"));
  2389. EXPECT_FALSE(isNumeric("ABCD"));
  2390. EXPECT_FALSE(isNumeric("+0x2AF3"));
  2391. EXPECT_FALSE(isNumeric("-0x2AF3"));
  2392. EXPECT_FALSE(isNumeric("0x2AF3Z"));
  2393. EXPECT_FALSE(isNumeric("0o012345678"));
  2394. EXPECT_FALSE(isNumeric("0xZ"));
  2395. EXPECT_FALSE(isNumeric("-0o012345678"));
  2396. EXPECT_FALSE(isNumeric("000003A8229434B839616A25C16B0291F77A438B"));
  2397. EXPECT_FALSE(isNumeric(""));
  2398. EXPECT_FALSE(isNumeric("."));
  2399. EXPECT_FALSE(isNumeric(".e+1"));
  2400. EXPECT_FALSE(isNumeric(".e+"));
  2401. EXPECT_FALSE(isNumeric(".e"));
  2402. EXPECT_FALSE(isNumeric("e1"));
  2403. // Deprecated formats: as for YAML 1.2 specification, the following are not
  2404. // valid numbers anymore:
  2405. //
  2406. // * Sexagecimal numbers
  2407. // * Decimal numbers with comma s the delimiter
  2408. // * "inf", "nan" without '.' prefix
  2409. EXPECT_FALSE(isNumeric("3:25:45"));
  2410. EXPECT_FALSE(isNumeric("+12,345"));
  2411. EXPECT_FALSE(isNumeric("-inf"));
  2412. EXPECT_FALSE(isNumeric("1,230.15"));
  2413. }
  2414. //===----------------------------------------------------------------------===//
  2415. // Test PolymorphicTraits and TaggedScalarTraits
  2416. //===----------------------------------------------------------------------===//
  2417. struct Poly {
  2418. enum NodeKind {
  2419. NK_Scalar,
  2420. NK_Seq,
  2421. NK_Map,
  2422. } Kind;
  2423. Poly(NodeKind Kind) : Kind(Kind) {}
  2424. virtual ~Poly() = default;
  2425. NodeKind getKind() const { return Kind; }
  2426. };
  2427. struct Scalar : Poly {
  2428. enum ScalarKind {
  2429. SK_Unknown,
  2430. SK_Double,
  2431. SK_Bool,
  2432. } SKind;
  2433. union {
  2434. double DoubleValue;
  2435. bool BoolValue;
  2436. };
  2437. Scalar() : Poly(NK_Scalar), SKind(SK_Unknown) {}
  2438. Scalar(double DoubleValue)
  2439. : Poly(NK_Scalar), SKind(SK_Double), DoubleValue(DoubleValue) {}
  2440. Scalar(bool BoolValue)
  2441. : Poly(NK_Scalar), SKind(SK_Bool), BoolValue(BoolValue) {}
  2442. static bool classof(const Poly *N) { return N->getKind() == NK_Scalar; }
  2443. };
  2444. struct Seq : Poly, std::vector<std::unique_ptr<Poly>> {
  2445. Seq() : Poly(NK_Seq) {}
  2446. static bool classof(const Poly *N) { return N->getKind() == NK_Seq; }
  2447. };
  2448. struct Map : Poly, llvm::StringMap<std::unique_ptr<Poly>> {
  2449. Map() : Poly(NK_Map) {}
  2450. static bool classof(const Poly *N) { return N->getKind() == NK_Map; }
  2451. };
  2452. namespace llvm {
  2453. namespace yaml {
  2454. template <> struct PolymorphicTraits<std::unique_ptr<Poly>> {
  2455. static NodeKind getKind(const std::unique_ptr<Poly> &N) {
  2456. if (isa<Scalar>(*N))
  2457. return NodeKind::Scalar;
  2458. if (isa<Seq>(*N))
  2459. return NodeKind::Sequence;
  2460. if (isa<Map>(*N))
  2461. return NodeKind::Map;
  2462. llvm_unreachable("unsupported node type");
  2463. }
  2464. static Scalar &getAsScalar(std::unique_ptr<Poly> &N) {
  2465. if (!N || !isa<Scalar>(*N))
  2466. N = std::make_unique<Scalar>();
  2467. return *cast<Scalar>(N.get());
  2468. }
  2469. static Seq &getAsSequence(std::unique_ptr<Poly> &N) {
  2470. if (!N || !isa<Seq>(*N))
  2471. N = std::make_unique<Seq>();
  2472. return *cast<Seq>(N.get());
  2473. }
  2474. static Map &getAsMap(std::unique_ptr<Poly> &N) {
  2475. if (!N || !isa<Map>(*N))
  2476. N = std::make_unique<Map>();
  2477. return *cast<Map>(N.get());
  2478. }
  2479. };
  2480. template <> struct TaggedScalarTraits<Scalar> {
  2481. static void output(const Scalar &S, void *Ctxt, raw_ostream &ScalarOS,
  2482. raw_ostream &TagOS) {
  2483. switch (S.SKind) {
  2484. case Scalar::SK_Unknown:
  2485. report_fatal_error("output unknown scalar");
  2486. break;
  2487. case Scalar::SK_Double:
  2488. TagOS << "!double";
  2489. ScalarTraits<double>::output(S.DoubleValue, Ctxt, ScalarOS);
  2490. break;
  2491. case Scalar::SK_Bool:
  2492. TagOS << "!bool";
  2493. ScalarTraits<bool>::output(S.BoolValue, Ctxt, ScalarOS);
  2494. break;
  2495. }
  2496. }
  2497. static StringRef input(StringRef ScalarStr, StringRef Tag, void *Ctxt,
  2498. Scalar &S) {
  2499. S.SKind = StringSwitch<Scalar::ScalarKind>(Tag)
  2500. .Case("!double", Scalar::SK_Double)
  2501. .Case("!bool", Scalar::SK_Bool)
  2502. .Default(Scalar::SK_Unknown);
  2503. switch (S.SKind) {
  2504. case Scalar::SK_Unknown:
  2505. return StringRef("unknown scalar tag");
  2506. case Scalar::SK_Double:
  2507. return ScalarTraits<double>::input(ScalarStr, Ctxt, S.DoubleValue);
  2508. case Scalar::SK_Bool:
  2509. return ScalarTraits<bool>::input(ScalarStr, Ctxt, S.BoolValue);
  2510. }
  2511. llvm_unreachable("unknown scalar kind");
  2512. }
  2513. static QuotingType mustQuote(const Scalar &S, StringRef Str) {
  2514. switch (S.SKind) {
  2515. case Scalar::SK_Unknown:
  2516. report_fatal_error("quote unknown scalar");
  2517. case Scalar::SK_Double:
  2518. return ScalarTraits<double>::mustQuote(Str);
  2519. case Scalar::SK_Bool:
  2520. return ScalarTraits<bool>::mustQuote(Str);
  2521. }
  2522. llvm_unreachable("unknown scalar kind");
  2523. }
  2524. };
  2525. template <> struct CustomMappingTraits<Map> {
  2526. static void inputOne(IO &IO, StringRef Key, Map &M) {
  2527. IO.mapRequired(Key.str().c_str(), M[Key]);
  2528. }
  2529. static void output(IO &IO, Map &M) {
  2530. for (auto &N : M)
  2531. IO.mapRequired(N.getKey().str().c_str(), N.getValue());
  2532. }
  2533. };
  2534. template <> struct SequenceTraits<Seq> {
  2535. static size_t size(IO &IO, Seq &A) { return A.size(); }
  2536. static std::unique_ptr<Poly> &element(IO &IO, Seq &A, size_t Index) {
  2537. if (Index >= A.size())
  2538. A.resize(Index + 1);
  2539. return A[Index];
  2540. }
  2541. };
  2542. } // namespace yaml
  2543. } // namespace llvm
  2544. TEST(YAMLIO, TestReadWritePolymorphicScalar) {
  2545. std::string intermediate;
  2546. std::unique_ptr<Poly> node = std::make_unique<Scalar>(true);
  2547. llvm::raw_string_ostream ostr(intermediate);
  2548. Output yout(ostr);
  2549. #ifdef GTEST_HAS_DEATH_TEST
  2550. #ifndef NDEBUG
  2551. EXPECT_DEATH(yout << node, "plain scalar documents are not supported");
  2552. #endif
  2553. #endif
  2554. }
  2555. TEST(YAMLIO, TestReadWritePolymorphicSeq) {
  2556. std::string intermediate;
  2557. {
  2558. auto seq = std::make_unique<Seq>();
  2559. seq->push_back(std::make_unique<Scalar>(true));
  2560. seq->push_back(std::make_unique<Scalar>(1.0));
  2561. auto node = llvm::unique_dyn_cast<Poly>(seq);
  2562. llvm::raw_string_ostream ostr(intermediate);
  2563. Output yout(ostr);
  2564. yout << node;
  2565. }
  2566. {
  2567. Input yin(intermediate);
  2568. std::unique_ptr<Poly> node;
  2569. yin >> node;
  2570. EXPECT_FALSE(yin.error());
  2571. auto seq = llvm::dyn_cast<Seq>(node.get());
  2572. ASSERT_TRUE(seq);
  2573. ASSERT_EQ(seq->size(), 2u);
  2574. auto first = llvm::dyn_cast<Scalar>((*seq)[0].get());
  2575. ASSERT_TRUE(first);
  2576. EXPECT_EQ(first->SKind, Scalar::SK_Bool);
  2577. EXPECT_TRUE(first->BoolValue);
  2578. auto second = llvm::dyn_cast<Scalar>((*seq)[1].get());
  2579. ASSERT_TRUE(second);
  2580. EXPECT_EQ(second->SKind, Scalar::SK_Double);
  2581. EXPECT_EQ(second->DoubleValue, 1.0);
  2582. }
  2583. }
  2584. TEST(YAMLIO, TestReadWritePolymorphicMap) {
  2585. std::string intermediate;
  2586. {
  2587. auto map = std::make_unique<Map>();
  2588. (*map)["foo"] = std::make_unique<Scalar>(false);
  2589. (*map)["bar"] = std::make_unique<Scalar>(2.0);
  2590. std::unique_ptr<Poly> node = llvm::unique_dyn_cast<Poly>(map);
  2591. llvm::raw_string_ostream ostr(intermediate);
  2592. Output yout(ostr);
  2593. yout << node;
  2594. }
  2595. {
  2596. Input yin(intermediate);
  2597. std::unique_ptr<Poly> node;
  2598. yin >> node;
  2599. EXPECT_FALSE(yin.error());
  2600. auto map = llvm::dyn_cast<Map>(node.get());
  2601. ASSERT_TRUE(map);
  2602. auto foo = llvm::dyn_cast<Scalar>((*map)["foo"].get());
  2603. ASSERT_TRUE(foo);
  2604. EXPECT_EQ(foo->SKind, Scalar::SK_Bool);
  2605. EXPECT_FALSE(foo->BoolValue);
  2606. auto bar = llvm::dyn_cast<Scalar>((*map)["bar"].get());
  2607. ASSERT_TRUE(bar);
  2608. EXPECT_EQ(bar->SKind, Scalar::SK_Double);
  2609. EXPECT_EQ(bar->DoubleValue, 2.0);
  2610. }
  2611. }