YAMLIOTest.cpp 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196
  1. //===- unittest/Support/YAMLIOTest.cpp ------------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/ADT/SmallString.h"
  10. #include "llvm/ADT/Twine.h"
  11. #include "llvm/Support/Casting.h"
  12. #include "llvm/Support/Format.h"
  13. #include "llvm/Support/YAMLTraits.h"
  14. #include "gtest/gtest.h"
  15. using llvm::yaml::Input;
  16. using llvm::yaml::Output;
  17. using llvm::yaml::IO;
  18. using llvm::yaml::MappingTraits;
  19. using llvm::yaml::MappingNormalization;
  20. using llvm::yaml::ScalarTraits;
  21. using llvm::yaml::Hex8;
  22. using llvm::yaml::Hex16;
  23. using llvm::yaml::Hex32;
  24. using llvm::yaml::Hex64;
  25. static void suppressErrorMessages(const llvm::SMDiagnostic &, void *) {
  26. }
  27. //===----------------------------------------------------------------------===//
  28. // Test MappingTraits
  29. //===----------------------------------------------------------------------===//
  30. struct FooBar {
  31. int foo;
  32. int bar;
  33. };
  34. typedef std::vector<FooBar> FooBarSequence;
  35. LLVM_YAML_IS_SEQUENCE_VECTOR(FooBar)
  36. struct FooBarContainer {
  37. FooBarSequence fbs;
  38. };
  39. namespace llvm {
  40. namespace yaml {
  41. template <>
  42. struct MappingTraits<FooBar> {
  43. static void mapping(IO &io, FooBar& fb) {
  44. io.mapRequired("foo", fb.foo);
  45. io.mapRequired("bar", fb.bar);
  46. }
  47. };
  48. template <> struct MappingTraits<FooBarContainer> {
  49. static void mapping(IO &io, FooBarContainer &fb) {
  50. io.mapRequired("fbs", fb.fbs);
  51. }
  52. };
  53. }
  54. }
  55. //
  56. // Test the reading of a yaml mapping
  57. //
  58. TEST(YAMLIO, TestMapRead) {
  59. FooBar doc;
  60. {
  61. Input yin("---\nfoo: 3\nbar: 5\n...\n");
  62. yin >> doc;
  63. EXPECT_FALSE(yin.error());
  64. EXPECT_EQ(doc.foo, 3);
  65. EXPECT_EQ(doc.bar, 5);
  66. }
  67. {
  68. Input yin("{foo: 3, bar: 5}");
  69. yin >> doc;
  70. EXPECT_FALSE(yin.error());
  71. EXPECT_EQ(doc.foo, 3);
  72. EXPECT_EQ(doc.bar, 5);
  73. }
  74. }
  75. TEST(YAMLIO, TestMalformedMapRead) {
  76. FooBar doc;
  77. Input yin("{foo: 3; bar: 5}", nullptr, suppressErrorMessages);
  78. yin >> doc;
  79. EXPECT_TRUE(!!yin.error());
  80. }
  81. //
  82. // Test the reading of a yaml sequence of mappings
  83. //
  84. TEST(YAMLIO, TestSequenceMapRead) {
  85. FooBarSequence seq;
  86. Input yin("---\n - foo: 3\n bar: 5\n - foo: 7\n bar: 9\n...\n");
  87. yin >> seq;
  88. EXPECT_FALSE(yin.error());
  89. EXPECT_EQ(seq.size(), 2UL);
  90. FooBar& map1 = seq[0];
  91. FooBar& map2 = seq[1];
  92. EXPECT_EQ(map1.foo, 3);
  93. EXPECT_EQ(map1.bar, 5);
  94. EXPECT_EQ(map2.foo, 7);
  95. EXPECT_EQ(map2.bar, 9);
  96. }
  97. //
  98. // Test the reading of a map containing a yaml sequence of mappings
  99. //
  100. TEST(YAMLIO, TestContainerSequenceMapRead) {
  101. {
  102. FooBarContainer cont;
  103. Input yin2("---\nfbs:\n - foo: 3\n bar: 5\n - foo: 7\n bar: 9\n...\n");
  104. yin2 >> cont;
  105. EXPECT_FALSE(yin2.error());
  106. EXPECT_EQ(cont.fbs.size(), 2UL);
  107. EXPECT_EQ(cont.fbs[0].foo, 3);
  108. EXPECT_EQ(cont.fbs[0].bar, 5);
  109. EXPECT_EQ(cont.fbs[1].foo, 7);
  110. EXPECT_EQ(cont.fbs[1].bar, 9);
  111. }
  112. {
  113. FooBarContainer cont;
  114. Input yin("---\nfbs:\n...\n");
  115. yin >> cont;
  116. // Okay: Empty node represents an empty array.
  117. EXPECT_FALSE(yin.error());
  118. EXPECT_EQ(cont.fbs.size(), 0UL);
  119. }
  120. {
  121. FooBarContainer cont;
  122. Input yin("---\nfbs: !!null null\n...\n");
  123. yin >> cont;
  124. // Okay: null represents an empty array.
  125. EXPECT_FALSE(yin.error());
  126. EXPECT_EQ(cont.fbs.size(), 0UL);
  127. }
  128. {
  129. FooBarContainer cont;
  130. Input yin("---\nfbs: ~\n...\n");
  131. yin >> cont;
  132. // Okay: null represents an empty array.
  133. EXPECT_FALSE(yin.error());
  134. EXPECT_EQ(cont.fbs.size(), 0UL);
  135. }
  136. {
  137. FooBarContainer cont;
  138. Input yin("---\nfbs: null\n...\n");
  139. yin >> cont;
  140. // Okay: null represents an empty array.
  141. EXPECT_FALSE(yin.error());
  142. EXPECT_EQ(cont.fbs.size(), 0UL);
  143. }
  144. }
  145. //
  146. // Test the reading of a map containing a malformed yaml sequence
  147. //
  148. TEST(YAMLIO, TestMalformedContainerSequenceMapRead) {
  149. {
  150. FooBarContainer cont;
  151. Input yin("---\nfbs:\n foo: 3\n bar: 5\n...\n", nullptr,
  152. suppressErrorMessages);
  153. yin >> cont;
  154. // Error: fbs is not a sequence.
  155. EXPECT_TRUE(!!yin.error());
  156. EXPECT_EQ(cont.fbs.size(), 0UL);
  157. }
  158. {
  159. FooBarContainer cont;
  160. Input yin("---\nfbs: 'scalar'\n...\n", nullptr, suppressErrorMessages);
  161. yin >> cont;
  162. // This should be an error.
  163. EXPECT_TRUE(!!yin.error());
  164. EXPECT_EQ(cont.fbs.size(), 0UL);
  165. }
  166. }
  167. //
  168. // Test writing then reading back a sequence of mappings
  169. //
  170. TEST(YAMLIO, TestSequenceMapWriteAndRead) {
  171. std::string intermediate;
  172. {
  173. FooBar entry1;
  174. entry1.foo = 10;
  175. entry1.bar = -3;
  176. FooBar entry2;
  177. entry2.foo = 257;
  178. entry2.bar = 0;
  179. FooBarSequence seq;
  180. seq.push_back(entry1);
  181. seq.push_back(entry2);
  182. llvm::raw_string_ostream ostr(intermediate);
  183. Output yout(ostr);
  184. yout << seq;
  185. }
  186. {
  187. Input yin(intermediate);
  188. FooBarSequence seq2;
  189. yin >> seq2;
  190. EXPECT_FALSE(yin.error());
  191. EXPECT_EQ(seq2.size(), 2UL);
  192. FooBar& map1 = seq2[0];
  193. FooBar& map2 = seq2[1];
  194. EXPECT_EQ(map1.foo, 10);
  195. EXPECT_EQ(map1.bar, -3);
  196. EXPECT_EQ(map2.foo, 257);
  197. EXPECT_EQ(map2.bar, 0);
  198. }
  199. }
  200. //===----------------------------------------------------------------------===//
  201. // Test built-in types
  202. //===----------------------------------------------------------------------===//
  203. struct BuiltInTypes {
  204. llvm::StringRef str;
  205. std::string stdstr;
  206. uint64_t u64;
  207. uint32_t u32;
  208. uint16_t u16;
  209. uint8_t u8;
  210. bool b;
  211. int64_t s64;
  212. int32_t s32;
  213. int16_t s16;
  214. int8_t s8;
  215. float f;
  216. double d;
  217. Hex8 h8;
  218. Hex16 h16;
  219. Hex32 h32;
  220. Hex64 h64;
  221. };
  222. namespace llvm {
  223. namespace yaml {
  224. template <>
  225. struct MappingTraits<BuiltInTypes> {
  226. static void mapping(IO &io, BuiltInTypes& bt) {
  227. io.mapRequired("str", bt.str);
  228. io.mapRequired("stdstr", bt.stdstr);
  229. io.mapRequired("u64", bt.u64);
  230. io.mapRequired("u32", bt.u32);
  231. io.mapRequired("u16", bt.u16);
  232. io.mapRequired("u8", bt.u8);
  233. io.mapRequired("b", bt.b);
  234. io.mapRequired("s64", bt.s64);
  235. io.mapRequired("s32", bt.s32);
  236. io.mapRequired("s16", bt.s16);
  237. io.mapRequired("s8", bt.s8);
  238. io.mapRequired("f", bt.f);
  239. io.mapRequired("d", bt.d);
  240. io.mapRequired("h8", bt.h8);
  241. io.mapRequired("h16", bt.h16);
  242. io.mapRequired("h32", bt.h32);
  243. io.mapRequired("h64", bt.h64);
  244. }
  245. };
  246. }
  247. }
  248. //
  249. // Test the reading of all built-in scalar conversions
  250. //
  251. TEST(YAMLIO, TestReadBuiltInTypes) {
  252. BuiltInTypes map;
  253. Input yin("---\n"
  254. "str: hello there\n"
  255. "stdstr: hello where?\n"
  256. "u64: 5000000000\n"
  257. "u32: 4000000000\n"
  258. "u16: 65000\n"
  259. "u8: 255\n"
  260. "b: false\n"
  261. "s64: -5000000000\n"
  262. "s32: -2000000000\n"
  263. "s16: -32000\n"
  264. "s8: -127\n"
  265. "f: 137.125\n"
  266. "d: -2.8625\n"
  267. "h8: 0xFF\n"
  268. "h16: 0x8765\n"
  269. "h32: 0xFEDCBA98\n"
  270. "h64: 0xFEDCBA9876543210\n"
  271. "...\n");
  272. yin >> map;
  273. EXPECT_FALSE(yin.error());
  274. EXPECT_TRUE(map.str.equals("hello there"));
  275. EXPECT_TRUE(map.stdstr == "hello where?");
  276. EXPECT_EQ(map.u64, 5000000000ULL);
  277. EXPECT_EQ(map.u32, 4000000000U);
  278. EXPECT_EQ(map.u16, 65000);
  279. EXPECT_EQ(map.u8, 255);
  280. EXPECT_EQ(map.b, false);
  281. EXPECT_EQ(map.s64, -5000000000LL);
  282. EXPECT_EQ(map.s32, -2000000000L);
  283. EXPECT_EQ(map.s16, -32000);
  284. EXPECT_EQ(map.s8, -127);
  285. EXPECT_EQ(map.f, 137.125);
  286. EXPECT_EQ(map.d, -2.8625);
  287. EXPECT_EQ(map.h8, Hex8(255));
  288. EXPECT_EQ(map.h16, Hex16(0x8765));
  289. EXPECT_EQ(map.h32, Hex32(0xFEDCBA98));
  290. EXPECT_EQ(map.h64, Hex64(0xFEDCBA9876543210LL));
  291. }
  292. //
  293. // Test writing then reading back all built-in scalar types
  294. //
  295. TEST(YAMLIO, TestReadWriteBuiltInTypes) {
  296. std::string intermediate;
  297. {
  298. BuiltInTypes map;
  299. map.str = "one two";
  300. map.stdstr = "three four";
  301. map.u64 = 6000000000ULL;
  302. map.u32 = 3000000000U;
  303. map.u16 = 50000;
  304. map.u8 = 254;
  305. map.b = true;
  306. map.s64 = -6000000000LL;
  307. map.s32 = -2000000000;
  308. map.s16 = -32000;
  309. map.s8 = -128;
  310. map.f = 3.25;
  311. map.d = -2.8625;
  312. map.h8 = 254;
  313. map.h16 = 50000;
  314. map.h32 = 3000000000U;
  315. map.h64 = 6000000000LL;
  316. llvm::raw_string_ostream ostr(intermediate);
  317. Output yout(ostr);
  318. yout << map;
  319. }
  320. {
  321. Input yin(intermediate);
  322. BuiltInTypes map;
  323. yin >> map;
  324. EXPECT_FALSE(yin.error());
  325. EXPECT_TRUE(map.str.equals("one two"));
  326. EXPECT_TRUE(map.stdstr == "three four");
  327. EXPECT_EQ(map.u64, 6000000000ULL);
  328. EXPECT_EQ(map.u32, 3000000000U);
  329. EXPECT_EQ(map.u16, 50000);
  330. EXPECT_EQ(map.u8, 254);
  331. EXPECT_EQ(map.b, true);
  332. EXPECT_EQ(map.s64, -6000000000LL);
  333. EXPECT_EQ(map.s32, -2000000000L);
  334. EXPECT_EQ(map.s16, -32000);
  335. EXPECT_EQ(map.s8, -128);
  336. EXPECT_EQ(map.f, 3.25);
  337. EXPECT_EQ(map.d, -2.8625);
  338. EXPECT_EQ(map.h8, Hex8(254));
  339. EXPECT_EQ(map.h16, Hex16(50000));
  340. EXPECT_EQ(map.h32, Hex32(3000000000U));
  341. EXPECT_EQ(map.h64, Hex64(6000000000LL));
  342. }
  343. }
  344. struct StringTypes {
  345. llvm::StringRef str1;
  346. llvm::StringRef str2;
  347. llvm::StringRef str3;
  348. llvm::StringRef str4;
  349. llvm::StringRef str5;
  350. llvm::StringRef str6;
  351. llvm::StringRef str7;
  352. llvm::StringRef str8;
  353. llvm::StringRef str9;
  354. llvm::StringRef str10;
  355. llvm::StringRef str11;
  356. std::string stdstr1;
  357. std::string stdstr2;
  358. std::string stdstr3;
  359. std::string stdstr4;
  360. std::string stdstr5;
  361. std::string stdstr6;
  362. std::string stdstr7;
  363. std::string stdstr8;
  364. std::string stdstr9;
  365. std::string stdstr10;
  366. std::string stdstr11;
  367. };
  368. namespace llvm {
  369. namespace yaml {
  370. template <>
  371. struct MappingTraits<StringTypes> {
  372. static void mapping(IO &io, StringTypes& st) {
  373. io.mapRequired("str1", st.str1);
  374. io.mapRequired("str2", st.str2);
  375. io.mapRequired("str3", st.str3);
  376. io.mapRequired("str4", st.str4);
  377. io.mapRequired("str5", st.str5);
  378. io.mapRequired("str6", st.str6);
  379. io.mapRequired("str7", st.str7);
  380. io.mapRequired("str8", st.str8);
  381. io.mapRequired("str9", st.str9);
  382. io.mapRequired("str10", st.str10);
  383. io.mapRequired("str11", st.str11);
  384. io.mapRequired("stdstr1", st.stdstr1);
  385. io.mapRequired("stdstr2", st.stdstr2);
  386. io.mapRequired("stdstr3", st.stdstr3);
  387. io.mapRequired("stdstr4", st.stdstr4);
  388. io.mapRequired("stdstr5", st.stdstr5);
  389. io.mapRequired("stdstr6", st.stdstr6);
  390. io.mapRequired("stdstr7", st.stdstr7);
  391. io.mapRequired("stdstr8", st.stdstr8);
  392. io.mapRequired("stdstr9", st.stdstr9);
  393. io.mapRequired("stdstr10", st.stdstr10);
  394. io.mapRequired("stdstr11", st.stdstr11);
  395. }
  396. };
  397. }
  398. }
  399. TEST(YAMLIO, TestReadWriteStringTypes) {
  400. std::string intermediate;
  401. {
  402. StringTypes map;
  403. map.str1 = "'aaa";
  404. map.str2 = "\"bbb";
  405. map.str3 = "`ccc";
  406. map.str4 = "@ddd";
  407. map.str5 = "";
  408. map.str6 = "0000000004000000";
  409. map.str7 = "true";
  410. map.str8 = "FALSE";
  411. map.str9 = "~";
  412. map.str10 = "0.2e20";
  413. map.str11 = "0x30";
  414. map.stdstr1 = "'eee";
  415. map.stdstr2 = "\"fff";
  416. map.stdstr3 = "`ggg";
  417. map.stdstr4 = "@hhh";
  418. map.stdstr5 = "";
  419. map.stdstr6 = "0000000004000000";
  420. map.stdstr7 = "true";
  421. map.stdstr8 = "FALSE";
  422. map.stdstr9 = "~";
  423. map.stdstr10 = "0.2e20";
  424. map.stdstr11 = "0x30";
  425. llvm::raw_string_ostream ostr(intermediate);
  426. Output yout(ostr);
  427. yout << map;
  428. }
  429. llvm::StringRef flowOut(intermediate);
  430. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'''aaa"));
  431. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'\"bbb'"));
  432. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'`ccc'"));
  433. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'@ddd'"));
  434. EXPECT_NE(llvm::StringRef::npos, flowOut.find("''\n"));
  435. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0000000004000000'\n"));
  436. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'true'\n"));
  437. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'FALSE'\n"));
  438. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'~'\n"));
  439. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0.2e20'\n"));
  440. EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0x30'\n"));
  441. EXPECT_NE(std::string::npos, flowOut.find("'''eee"));
  442. EXPECT_NE(std::string::npos, flowOut.find("'\"fff'"));
  443. EXPECT_NE(std::string::npos, flowOut.find("'`ggg'"));
  444. EXPECT_NE(std::string::npos, flowOut.find("'@hhh'"));
  445. EXPECT_NE(std::string::npos, flowOut.find("''\n"));
  446. EXPECT_NE(std::string::npos, flowOut.find("'0000000004000000'\n"));
  447. {
  448. Input yin(intermediate);
  449. StringTypes map;
  450. yin >> map;
  451. EXPECT_FALSE(yin.error());
  452. EXPECT_TRUE(map.str1.equals("'aaa"));
  453. EXPECT_TRUE(map.str2.equals("\"bbb"));
  454. EXPECT_TRUE(map.str3.equals("`ccc"));
  455. EXPECT_TRUE(map.str4.equals("@ddd"));
  456. EXPECT_TRUE(map.str5.equals(""));
  457. EXPECT_TRUE(map.str6.equals("0000000004000000"));
  458. EXPECT_TRUE(map.stdstr1 == "'eee");
  459. EXPECT_TRUE(map.stdstr2 == "\"fff");
  460. EXPECT_TRUE(map.stdstr3 == "`ggg");
  461. EXPECT_TRUE(map.stdstr4 == "@hhh");
  462. EXPECT_TRUE(map.stdstr5 == "");
  463. EXPECT_TRUE(map.stdstr6 == "0000000004000000");
  464. }
  465. }
  466. //===----------------------------------------------------------------------===//
  467. // Test ScalarEnumerationTraits
  468. //===----------------------------------------------------------------------===//
  469. enum Colors {
  470. cRed,
  471. cBlue,
  472. cGreen,
  473. cYellow
  474. };
  475. struct ColorMap {
  476. Colors c1;
  477. Colors c2;
  478. Colors c3;
  479. Colors c4;
  480. Colors c5;
  481. Colors c6;
  482. };
  483. namespace llvm {
  484. namespace yaml {
  485. template <>
  486. struct ScalarEnumerationTraits<Colors> {
  487. static void enumeration(IO &io, Colors &value) {
  488. io.enumCase(value, "red", cRed);
  489. io.enumCase(value, "blue", cBlue);
  490. io.enumCase(value, "green", cGreen);
  491. io.enumCase(value, "yellow",cYellow);
  492. }
  493. };
  494. template <>
  495. struct MappingTraits<ColorMap> {
  496. static void mapping(IO &io, ColorMap& c) {
  497. io.mapRequired("c1", c.c1);
  498. io.mapRequired("c2", c.c2);
  499. io.mapRequired("c3", c.c3);
  500. io.mapOptional("c4", c.c4, cBlue); // supplies default
  501. io.mapOptional("c5", c.c5, cYellow); // supplies default
  502. io.mapOptional("c6", c.c6, cRed); // supplies default
  503. }
  504. };
  505. }
  506. }
  507. //
  508. // Test reading enumerated scalars
  509. //
  510. TEST(YAMLIO, TestEnumRead) {
  511. ColorMap map;
  512. Input yin("---\n"
  513. "c1: blue\n"
  514. "c2: red\n"
  515. "c3: green\n"
  516. "c5: yellow\n"
  517. "...\n");
  518. yin >> map;
  519. EXPECT_FALSE(yin.error());
  520. EXPECT_EQ(cBlue, map.c1);
  521. EXPECT_EQ(cRed, map.c2);
  522. EXPECT_EQ(cGreen, map.c3);
  523. EXPECT_EQ(cBlue, map.c4); // tests default
  524. EXPECT_EQ(cYellow,map.c5); // tests overridden
  525. EXPECT_EQ(cRed, map.c6); // tests default
  526. }
  527. //===----------------------------------------------------------------------===//
  528. // Test ScalarBitSetTraits
  529. //===----------------------------------------------------------------------===//
  530. enum MyFlags {
  531. flagNone = 0,
  532. flagBig = 1 << 0,
  533. flagFlat = 1 << 1,
  534. flagRound = 1 << 2,
  535. flagPointy = 1 << 3
  536. };
  537. inline MyFlags operator|(MyFlags a, MyFlags b) {
  538. return static_cast<MyFlags>(
  539. static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
  540. }
  541. struct FlagsMap {
  542. MyFlags f1;
  543. MyFlags f2;
  544. MyFlags f3;
  545. MyFlags f4;
  546. };
  547. namespace llvm {
  548. namespace yaml {
  549. template <>
  550. struct ScalarBitSetTraits<MyFlags> {
  551. static void bitset(IO &io, MyFlags &value) {
  552. io.bitSetCase(value, "big", flagBig);
  553. io.bitSetCase(value, "flat", flagFlat);
  554. io.bitSetCase(value, "round", flagRound);
  555. io.bitSetCase(value, "pointy",flagPointy);
  556. }
  557. };
  558. template <>
  559. struct MappingTraits<FlagsMap> {
  560. static void mapping(IO &io, FlagsMap& c) {
  561. io.mapRequired("f1", c.f1);
  562. io.mapRequired("f2", c.f2);
  563. io.mapRequired("f3", c.f3);
  564. io.mapOptional("f4", c.f4, MyFlags(flagRound));
  565. }
  566. };
  567. }
  568. }
  569. //
  570. // Test reading flow sequence representing bit-mask values
  571. //
  572. TEST(YAMLIO, TestFlagsRead) {
  573. FlagsMap map;
  574. Input yin("---\n"
  575. "f1: [ big ]\n"
  576. "f2: [ round, flat ]\n"
  577. "f3: []\n"
  578. "...\n");
  579. yin >> map;
  580. EXPECT_FALSE(yin.error());
  581. EXPECT_EQ(flagBig, map.f1);
  582. EXPECT_EQ(flagRound|flagFlat, map.f2);
  583. EXPECT_EQ(flagNone, map.f3); // check empty set
  584. EXPECT_EQ(flagRound, map.f4); // check optional key
  585. }
  586. //
  587. // Test writing then reading back bit-mask values
  588. //
  589. TEST(YAMLIO, TestReadWriteFlags) {
  590. std::string intermediate;
  591. {
  592. FlagsMap map;
  593. map.f1 = flagBig;
  594. map.f2 = flagRound | flagFlat;
  595. map.f3 = flagNone;
  596. map.f4 = flagNone;
  597. llvm::raw_string_ostream ostr(intermediate);
  598. Output yout(ostr);
  599. yout << map;
  600. }
  601. {
  602. Input yin(intermediate);
  603. FlagsMap map2;
  604. yin >> map2;
  605. EXPECT_FALSE(yin.error());
  606. EXPECT_EQ(flagBig, map2.f1);
  607. EXPECT_EQ(flagRound|flagFlat, map2.f2);
  608. EXPECT_EQ(flagNone, map2.f3);
  609. //EXPECT_EQ(flagRound, map2.f4); // check optional key
  610. }
  611. }
  612. //===----------------------------------------------------------------------===//
  613. // Test ScalarTraits
  614. //===----------------------------------------------------------------------===//
  615. struct MyCustomType {
  616. int length;
  617. int width;
  618. };
  619. struct MyCustomTypeMap {
  620. MyCustomType f1;
  621. MyCustomType f2;
  622. int f3;
  623. };
  624. namespace llvm {
  625. namespace yaml {
  626. template <>
  627. struct MappingTraits<MyCustomTypeMap> {
  628. static void mapping(IO &io, MyCustomTypeMap& s) {
  629. io.mapRequired("f1", s.f1);
  630. io.mapRequired("f2", s.f2);
  631. io.mapRequired("f3", s.f3);
  632. }
  633. };
  634. // MyCustomType is formatted as a yaml scalar. A value of
  635. // {length=3, width=4} would be represented in yaml as "3 by 4".
  636. template<>
  637. struct ScalarTraits<MyCustomType> {
  638. static void output(const MyCustomType &value, void* ctxt, llvm::raw_ostream &out) {
  639. out << llvm::format("%d by %d", value.length, value.width);
  640. }
  641. static StringRef input(StringRef scalar, void* ctxt, MyCustomType &value) {
  642. size_t byStart = scalar.find("by");
  643. if ( byStart != StringRef::npos ) {
  644. StringRef lenStr = scalar.slice(0, byStart);
  645. lenStr = lenStr.rtrim();
  646. if ( lenStr.getAsInteger(0, value.length) ) {
  647. return "malformed length";
  648. }
  649. StringRef widthStr = scalar.drop_front(byStart+2);
  650. widthStr = widthStr.ltrim();
  651. if ( widthStr.getAsInteger(0, value.width) ) {
  652. return "malformed width";
  653. }
  654. return StringRef();
  655. }
  656. else {
  657. return "malformed by";
  658. }
  659. }
  660. static bool mustQuote(StringRef) { return true; }
  661. };
  662. }
  663. }
  664. //
  665. // Test writing then reading back custom values
  666. //
  667. TEST(YAMLIO, TestReadWriteMyCustomType) {
  668. std::string intermediate;
  669. {
  670. MyCustomTypeMap map;
  671. map.f1.length = 1;
  672. map.f1.width = 4;
  673. map.f2.length = 100;
  674. map.f2.width = 400;
  675. map.f3 = 10;
  676. llvm::raw_string_ostream ostr(intermediate);
  677. Output yout(ostr);
  678. yout << map;
  679. }
  680. {
  681. Input yin(intermediate);
  682. MyCustomTypeMap map2;
  683. yin >> map2;
  684. EXPECT_FALSE(yin.error());
  685. EXPECT_EQ(1, map2.f1.length);
  686. EXPECT_EQ(4, map2.f1.width);
  687. EXPECT_EQ(100, map2.f2.length);
  688. EXPECT_EQ(400, map2.f2.width);
  689. EXPECT_EQ(10, map2.f3);
  690. }
  691. }
  692. //===----------------------------------------------------------------------===//
  693. // Test BlockScalarTraits
  694. //===----------------------------------------------------------------------===//
  695. struct MultilineStringType {
  696. std::string str;
  697. };
  698. struct MultilineStringTypeMap {
  699. MultilineStringType name;
  700. MultilineStringType description;
  701. MultilineStringType ingredients;
  702. MultilineStringType recipes;
  703. MultilineStringType warningLabels;
  704. MultilineStringType documentation;
  705. int price;
  706. };
  707. namespace llvm {
  708. namespace yaml {
  709. template <>
  710. struct MappingTraits<MultilineStringTypeMap> {
  711. static void mapping(IO &io, MultilineStringTypeMap& s) {
  712. io.mapRequired("name", s.name);
  713. io.mapRequired("description", s.description);
  714. io.mapRequired("ingredients", s.ingredients);
  715. io.mapRequired("recipes", s.recipes);
  716. io.mapRequired("warningLabels", s.warningLabels);
  717. io.mapRequired("documentation", s.documentation);
  718. io.mapRequired("price", s.price);
  719. }
  720. };
  721. // MultilineStringType is formatted as a yaml block literal scalar. A value of
  722. // "Hello\nWorld" would be represented in yaml as
  723. // |
  724. // Hello
  725. // World
  726. template <>
  727. struct BlockScalarTraits<MultilineStringType> {
  728. static void output(const MultilineStringType &value, void *ctxt,
  729. llvm::raw_ostream &out) {
  730. out << value.str;
  731. }
  732. static StringRef input(StringRef scalar, void *ctxt,
  733. MultilineStringType &value) {
  734. value.str = scalar.str();
  735. return StringRef();
  736. }
  737. };
  738. }
  739. }
  740. LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MultilineStringType)
  741. //
  742. // Test writing then reading back custom values
  743. //
  744. TEST(YAMLIO, TestReadWriteMultilineStringType) {
  745. std::string intermediate;
  746. {
  747. MultilineStringTypeMap map;
  748. map.name.str = "An Item";
  749. map.description.str = "Hello\nWorld";
  750. map.ingredients.str = "SubItem 1\nSub Item 2\n\nSub Item 3\n";
  751. map.recipes.str = "\n\nTest 1\n\n\n";
  752. map.warningLabels.str = "";
  753. map.documentation.str = "\n\n";
  754. map.price = 350;
  755. llvm::raw_string_ostream ostr(intermediate);
  756. Output yout(ostr);
  757. yout << map;
  758. }
  759. {
  760. Input yin(intermediate);
  761. MultilineStringTypeMap map2;
  762. yin >> map2;
  763. EXPECT_FALSE(yin.error());
  764. EXPECT_EQ(map2.name.str, "An Item\n");
  765. EXPECT_EQ(map2.description.str, "Hello\nWorld\n");
  766. EXPECT_EQ(map2.ingredients.str, "SubItem 1\nSub Item 2\n\nSub Item 3\n");
  767. EXPECT_EQ(map2.recipes.str, "\n\nTest 1\n");
  768. EXPECT_TRUE(map2.warningLabels.str.empty());
  769. EXPECT_TRUE(map2.documentation.str.empty());
  770. EXPECT_EQ(map2.price, 350);
  771. }
  772. }
  773. //
  774. // Test writing then reading back custom values
  775. //
  776. TEST(YAMLIO, TestReadWriteBlockScalarDocuments) {
  777. std::string intermediate;
  778. {
  779. std::vector<MultilineStringType> documents;
  780. MultilineStringType doc;
  781. doc.str = "Hello\nWorld";
  782. documents.push_back(doc);
  783. llvm::raw_string_ostream ostr(intermediate);
  784. Output yout(ostr);
  785. yout << documents;
  786. // Verify that the block scalar header was written out on the same line
  787. // as the document marker.
  788. EXPECT_NE(llvm::StringRef::npos, llvm::StringRef(ostr.str()).find("--- |"));
  789. }
  790. {
  791. Input yin(intermediate);
  792. std::vector<MultilineStringType> documents2;
  793. yin >> documents2;
  794. EXPECT_FALSE(yin.error());
  795. EXPECT_EQ(documents2.size(), size_t(1));
  796. EXPECT_EQ(documents2[0].str, "Hello\nWorld\n");
  797. }
  798. }
  799. TEST(YAMLIO, TestReadWriteBlockScalarValue) {
  800. std::string intermediate;
  801. {
  802. MultilineStringType doc;
  803. doc.str = "Just a block\nscalar doc";
  804. llvm::raw_string_ostream ostr(intermediate);
  805. Output yout(ostr);
  806. yout << doc;
  807. }
  808. {
  809. Input yin(intermediate);
  810. MultilineStringType doc;
  811. yin >> doc;
  812. EXPECT_FALSE(yin.error());
  813. EXPECT_EQ(doc.str, "Just a block\nscalar doc\n");
  814. }
  815. }
  816. //===----------------------------------------------------------------------===//
  817. // Test flow sequences
  818. //===----------------------------------------------------------------------===//
  819. LLVM_YAML_STRONG_TYPEDEF(int, MyNumber)
  820. LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(MyNumber)
  821. LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::StringRef)
  822. namespace llvm {
  823. namespace yaml {
  824. template<>
  825. struct ScalarTraits<MyNumber> {
  826. static void output(const MyNumber &value, void *, llvm::raw_ostream &out) {
  827. out << value;
  828. }
  829. static StringRef input(StringRef scalar, void *, MyNumber &value) {
  830. long long n;
  831. if ( getAsSignedInteger(scalar, 0, n) )
  832. return "invalid number";
  833. value = n;
  834. return StringRef();
  835. }
  836. static bool mustQuote(StringRef) { return false; }
  837. };
  838. }
  839. }
  840. struct NameAndNumbers {
  841. llvm::StringRef name;
  842. std::vector<llvm::StringRef> strings;
  843. std::vector<MyNumber> single;
  844. std::vector<MyNumber> numbers;
  845. };
  846. namespace llvm {
  847. namespace yaml {
  848. template <>
  849. struct MappingTraits<NameAndNumbers> {
  850. static void mapping(IO &io, NameAndNumbers& nn) {
  851. io.mapRequired("name", nn.name);
  852. io.mapRequired("strings", nn.strings);
  853. io.mapRequired("single", nn.single);
  854. io.mapRequired("numbers", nn.numbers);
  855. }
  856. };
  857. }
  858. }
  859. typedef std::vector<MyNumber> MyNumberFlowSequence;
  860. LLVM_YAML_IS_SEQUENCE_VECTOR(MyNumberFlowSequence)
  861. struct NameAndNumbersFlow {
  862. llvm::StringRef name;
  863. std::vector<MyNumberFlowSequence> sequenceOfNumbers;
  864. };
  865. namespace llvm {
  866. namespace yaml {
  867. template <>
  868. struct MappingTraits<NameAndNumbersFlow> {
  869. static void mapping(IO &io, NameAndNumbersFlow& nn) {
  870. io.mapRequired("name", nn.name);
  871. io.mapRequired("sequenceOfNumbers", nn.sequenceOfNumbers);
  872. }
  873. };
  874. }
  875. }
  876. //
  877. // Test writing then reading back custom values
  878. //
  879. TEST(YAMLIO, TestReadWriteMyFlowSequence) {
  880. std::string intermediate;
  881. {
  882. NameAndNumbers map;
  883. map.name = "hello";
  884. map.strings.push_back(llvm::StringRef("one"));
  885. map.strings.push_back(llvm::StringRef("two"));
  886. map.single.push_back(1);
  887. map.numbers.push_back(10);
  888. map.numbers.push_back(-30);
  889. map.numbers.push_back(1024);
  890. llvm::raw_string_ostream ostr(intermediate);
  891. Output yout(ostr);
  892. yout << map;
  893. // Verify sequences were written in flow style
  894. ostr.flush();
  895. llvm::StringRef flowOut(intermediate);
  896. EXPECT_NE(llvm::StringRef::npos, flowOut.find("one, two"));
  897. EXPECT_NE(llvm::StringRef::npos, flowOut.find("10, -30, 1024"));
  898. }
  899. {
  900. Input yin(intermediate);
  901. NameAndNumbers map2;
  902. yin >> map2;
  903. EXPECT_FALSE(yin.error());
  904. EXPECT_TRUE(map2.name.equals("hello"));
  905. EXPECT_EQ(map2.strings.size(), 2UL);
  906. EXPECT_TRUE(map2.strings[0].equals("one"));
  907. EXPECT_TRUE(map2.strings[1].equals("two"));
  908. EXPECT_EQ(map2.single.size(), 1UL);
  909. EXPECT_EQ(1, map2.single[0]);
  910. EXPECT_EQ(map2.numbers.size(), 3UL);
  911. EXPECT_EQ(10, map2.numbers[0]);
  912. EXPECT_EQ(-30, map2.numbers[1]);
  913. EXPECT_EQ(1024, map2.numbers[2]);
  914. }
  915. }
  916. //
  917. // Test writing then reading back a sequence of flow sequences.
  918. //
  919. TEST(YAMLIO, TestReadWriteSequenceOfMyFlowSequence) {
  920. std::string intermediate;
  921. {
  922. NameAndNumbersFlow map;
  923. map.name = "hello";
  924. MyNumberFlowSequence single = { 0 };
  925. MyNumberFlowSequence numbers = { 12, 1, -512 };
  926. map.sequenceOfNumbers.push_back(single);
  927. map.sequenceOfNumbers.push_back(numbers);
  928. map.sequenceOfNumbers.push_back(MyNumberFlowSequence());
  929. llvm::raw_string_ostream ostr(intermediate);
  930. Output yout(ostr);
  931. yout << map;
  932. // Verify sequences were written in flow style
  933. // and that the parent sequence used '-'.
  934. ostr.flush();
  935. llvm::StringRef flowOut(intermediate);
  936. EXPECT_NE(llvm::StringRef::npos, flowOut.find("- [ 0 ]"));
  937. EXPECT_NE(llvm::StringRef::npos, flowOut.find("- [ 12, 1, -512 ]"));
  938. EXPECT_NE(llvm::StringRef::npos, flowOut.find("- [ ]"));
  939. }
  940. {
  941. Input yin(intermediate);
  942. NameAndNumbersFlow map2;
  943. yin >> map2;
  944. EXPECT_FALSE(yin.error());
  945. EXPECT_TRUE(map2.name.equals("hello"));
  946. EXPECT_EQ(map2.sequenceOfNumbers.size(), 3UL);
  947. EXPECT_EQ(map2.sequenceOfNumbers[0].size(), 1UL);
  948. EXPECT_EQ(0, map2.sequenceOfNumbers[0][0]);
  949. EXPECT_EQ(map2.sequenceOfNumbers[1].size(), 3UL);
  950. EXPECT_EQ(12, map2.sequenceOfNumbers[1][0]);
  951. EXPECT_EQ(1, map2.sequenceOfNumbers[1][1]);
  952. EXPECT_EQ(-512, map2.sequenceOfNumbers[1][2]);
  953. EXPECT_TRUE(map2.sequenceOfNumbers[2].empty());
  954. }
  955. }
  956. //===----------------------------------------------------------------------===//
  957. // Test normalizing/denormalizing
  958. //===----------------------------------------------------------------------===//
  959. LLVM_YAML_STRONG_TYPEDEF(uint32_t, TotalSeconds)
  960. typedef std::vector<TotalSeconds> SecondsSequence;
  961. LLVM_YAML_IS_SEQUENCE_VECTOR(TotalSeconds)
  962. namespace llvm {
  963. namespace yaml {
  964. template <>
  965. struct MappingTraits<TotalSeconds> {
  966. class NormalizedSeconds {
  967. public:
  968. NormalizedSeconds(IO &io)
  969. : hours(0), minutes(0), seconds(0) {
  970. }
  971. NormalizedSeconds(IO &, TotalSeconds &secs)
  972. : hours(secs/3600),
  973. minutes((secs - (hours*3600))/60),
  974. seconds(secs % 60) {
  975. }
  976. TotalSeconds denormalize(IO &) {
  977. return TotalSeconds(hours*3600 + minutes*60 + seconds);
  978. }
  979. uint32_t hours;
  980. uint8_t minutes;
  981. uint8_t seconds;
  982. };
  983. static void mapping(IO &io, TotalSeconds &secs) {
  984. MappingNormalization<NormalizedSeconds, TotalSeconds> keys(io, secs);
  985. io.mapOptional("hours", keys->hours, (uint32_t)0);
  986. io.mapOptional("minutes", keys->minutes, (uint8_t)0);
  987. io.mapRequired("seconds", keys->seconds);
  988. }
  989. };
  990. }
  991. }
  992. //
  993. // Test the reading of a yaml sequence of mappings
  994. //
  995. TEST(YAMLIO, TestReadMySecondsSequence) {
  996. SecondsSequence seq;
  997. Input yin("---\n - hours: 1\n seconds: 5\n - seconds: 59\n...\n");
  998. yin >> seq;
  999. EXPECT_FALSE(yin.error());
  1000. EXPECT_EQ(seq.size(), 2UL);
  1001. EXPECT_EQ(seq[0], 3605U);
  1002. EXPECT_EQ(seq[1], 59U);
  1003. }
  1004. //
  1005. // Test writing then reading back custom values
  1006. //
  1007. TEST(YAMLIO, TestReadWriteMySecondsSequence) {
  1008. std::string intermediate;
  1009. {
  1010. SecondsSequence seq;
  1011. seq.push_back(4000);
  1012. seq.push_back(500);
  1013. seq.push_back(59);
  1014. llvm::raw_string_ostream ostr(intermediate);
  1015. Output yout(ostr);
  1016. yout << seq;
  1017. }
  1018. {
  1019. Input yin(intermediate);
  1020. SecondsSequence seq2;
  1021. yin >> seq2;
  1022. EXPECT_FALSE(yin.error());
  1023. EXPECT_EQ(seq2.size(), 3UL);
  1024. EXPECT_EQ(seq2[0], 4000U);
  1025. EXPECT_EQ(seq2[1], 500U);
  1026. EXPECT_EQ(seq2[2], 59U);
  1027. }
  1028. }
  1029. //===----------------------------------------------------------------------===//
  1030. // Test dynamic typing
  1031. //===----------------------------------------------------------------------===//
  1032. enum AFlags {
  1033. a1,
  1034. a2,
  1035. a3
  1036. };
  1037. enum BFlags {
  1038. b1,
  1039. b2,
  1040. b3
  1041. };
  1042. enum Kind {
  1043. kindA,
  1044. kindB
  1045. };
  1046. struct KindAndFlags {
  1047. KindAndFlags() : kind(kindA), flags(0) { }
  1048. KindAndFlags(Kind k, uint32_t f) : kind(k), flags(f) { }
  1049. Kind kind;
  1050. uint32_t flags;
  1051. };
  1052. typedef std::vector<KindAndFlags> KindAndFlagsSequence;
  1053. LLVM_YAML_IS_SEQUENCE_VECTOR(KindAndFlags)
  1054. namespace llvm {
  1055. namespace yaml {
  1056. template <>
  1057. struct ScalarEnumerationTraits<AFlags> {
  1058. static void enumeration(IO &io, AFlags &value) {
  1059. io.enumCase(value, "a1", a1);
  1060. io.enumCase(value, "a2", a2);
  1061. io.enumCase(value, "a3", a3);
  1062. }
  1063. };
  1064. template <>
  1065. struct ScalarEnumerationTraits<BFlags> {
  1066. static void enumeration(IO &io, BFlags &value) {
  1067. io.enumCase(value, "b1", b1);
  1068. io.enumCase(value, "b2", b2);
  1069. io.enumCase(value, "b3", b3);
  1070. }
  1071. };
  1072. template <>
  1073. struct ScalarEnumerationTraits<Kind> {
  1074. static void enumeration(IO &io, Kind &value) {
  1075. io.enumCase(value, "A", kindA);
  1076. io.enumCase(value, "B", kindB);
  1077. }
  1078. };
  1079. template <>
  1080. struct MappingTraits<KindAndFlags> {
  1081. static void mapping(IO &io, KindAndFlags& kf) {
  1082. io.mapRequired("kind", kf.kind);
  1083. // Type of "flags" field varies depending on "kind" field.
  1084. // Use memcpy here to avoid breaking strict aliasing rules.
  1085. if (kf.kind == kindA) {
  1086. AFlags aflags = static_cast<AFlags>(kf.flags);
  1087. io.mapRequired("flags", aflags);
  1088. kf.flags = aflags;
  1089. } else {
  1090. BFlags bflags = static_cast<BFlags>(kf.flags);
  1091. io.mapRequired("flags", bflags);
  1092. kf.flags = bflags;
  1093. }
  1094. }
  1095. };
  1096. }
  1097. }
  1098. //
  1099. // Test the reading of a yaml sequence dynamic types
  1100. //
  1101. TEST(YAMLIO, TestReadKindAndFlagsSequence) {
  1102. KindAndFlagsSequence seq;
  1103. Input yin("---\n - kind: A\n flags: a2\n - kind: B\n flags: b1\n...\n");
  1104. yin >> seq;
  1105. EXPECT_FALSE(yin.error());
  1106. EXPECT_EQ(seq.size(), 2UL);
  1107. EXPECT_EQ(seq[0].kind, kindA);
  1108. EXPECT_EQ(seq[0].flags, (uint32_t)a2);
  1109. EXPECT_EQ(seq[1].kind, kindB);
  1110. EXPECT_EQ(seq[1].flags, (uint32_t)b1);
  1111. }
  1112. //
  1113. // Test writing then reading back dynamic types
  1114. //
  1115. TEST(YAMLIO, TestReadWriteKindAndFlagsSequence) {
  1116. std::string intermediate;
  1117. {
  1118. KindAndFlagsSequence seq;
  1119. seq.push_back(KindAndFlags(kindA,a1));
  1120. seq.push_back(KindAndFlags(kindB,b1));
  1121. seq.push_back(KindAndFlags(kindA,a2));
  1122. seq.push_back(KindAndFlags(kindB,b2));
  1123. seq.push_back(KindAndFlags(kindA,a3));
  1124. llvm::raw_string_ostream ostr(intermediate);
  1125. Output yout(ostr);
  1126. yout << seq;
  1127. }
  1128. {
  1129. Input yin(intermediate);
  1130. KindAndFlagsSequence seq2;
  1131. yin >> seq2;
  1132. EXPECT_FALSE(yin.error());
  1133. EXPECT_EQ(seq2.size(), 5UL);
  1134. EXPECT_EQ(seq2[0].kind, kindA);
  1135. EXPECT_EQ(seq2[0].flags, (uint32_t)a1);
  1136. EXPECT_EQ(seq2[1].kind, kindB);
  1137. EXPECT_EQ(seq2[1].flags, (uint32_t)b1);
  1138. EXPECT_EQ(seq2[2].kind, kindA);
  1139. EXPECT_EQ(seq2[2].flags, (uint32_t)a2);
  1140. EXPECT_EQ(seq2[3].kind, kindB);
  1141. EXPECT_EQ(seq2[3].flags, (uint32_t)b2);
  1142. EXPECT_EQ(seq2[4].kind, kindA);
  1143. EXPECT_EQ(seq2[4].flags, (uint32_t)a3);
  1144. }
  1145. }
  1146. //===----------------------------------------------------------------------===//
  1147. // Test document list
  1148. //===----------------------------------------------------------------------===//
  1149. struct FooBarMap {
  1150. int foo;
  1151. int bar;
  1152. };
  1153. typedef std::vector<FooBarMap> FooBarMapDocumentList;
  1154. LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(FooBarMap)
  1155. namespace llvm {
  1156. namespace yaml {
  1157. template <>
  1158. struct MappingTraits<FooBarMap> {
  1159. static void mapping(IO &io, FooBarMap& fb) {
  1160. io.mapRequired("foo", fb.foo);
  1161. io.mapRequired("bar", fb.bar);
  1162. }
  1163. };
  1164. }
  1165. }
  1166. //
  1167. // Test the reading of a yaml mapping
  1168. //
  1169. TEST(YAMLIO, TestDocRead) {
  1170. FooBarMap doc;
  1171. Input yin("---\nfoo: 3\nbar: 5\n...\n");
  1172. yin >> doc;
  1173. EXPECT_FALSE(yin.error());
  1174. EXPECT_EQ(doc.foo, 3);
  1175. EXPECT_EQ(doc.bar,5);
  1176. }
  1177. //
  1178. // Test writing then reading back a sequence of mappings
  1179. //
  1180. TEST(YAMLIO, TestSequenceDocListWriteAndRead) {
  1181. std::string intermediate;
  1182. {
  1183. FooBarMap doc1;
  1184. doc1.foo = 10;
  1185. doc1.bar = -3;
  1186. FooBarMap doc2;
  1187. doc2.foo = 257;
  1188. doc2.bar = 0;
  1189. std::vector<FooBarMap> docList;
  1190. docList.push_back(doc1);
  1191. docList.push_back(doc2);
  1192. llvm::raw_string_ostream ostr(intermediate);
  1193. Output yout(ostr);
  1194. yout << docList;
  1195. }
  1196. {
  1197. Input yin(intermediate);
  1198. std::vector<FooBarMap> docList2;
  1199. yin >> docList2;
  1200. EXPECT_FALSE(yin.error());
  1201. EXPECT_EQ(docList2.size(), 2UL);
  1202. FooBarMap& map1 = docList2[0];
  1203. FooBarMap& map2 = docList2[1];
  1204. EXPECT_EQ(map1.foo, 10);
  1205. EXPECT_EQ(map1.bar, -3);
  1206. EXPECT_EQ(map2.foo, 257);
  1207. EXPECT_EQ(map2.bar, 0);
  1208. }
  1209. }
  1210. //===----------------------------------------------------------------------===//
  1211. // Test document tags
  1212. //===----------------------------------------------------------------------===//
  1213. struct MyDouble {
  1214. MyDouble() : value(0.0) { }
  1215. MyDouble(double x) : value(x) { }
  1216. double value;
  1217. };
  1218. LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyDouble)
  1219. namespace llvm {
  1220. namespace yaml {
  1221. template <>
  1222. struct MappingTraits<MyDouble> {
  1223. static void mapping(IO &io, MyDouble &d) {
  1224. if (io.mapTag("!decimal", true)) {
  1225. mappingDecimal(io, d);
  1226. } else if (io.mapTag("!fraction")) {
  1227. mappingFraction(io, d);
  1228. }
  1229. }
  1230. static void mappingDecimal(IO &io, MyDouble &d) {
  1231. io.mapRequired("value", d.value);
  1232. }
  1233. static void mappingFraction(IO &io, MyDouble &d) {
  1234. double num, denom;
  1235. io.mapRequired("numerator", num);
  1236. io.mapRequired("denominator", denom);
  1237. // convert fraction to double
  1238. d.value = num/denom;
  1239. }
  1240. };
  1241. }
  1242. }
  1243. //
  1244. // Test the reading of two different tagged yaml documents.
  1245. //
  1246. TEST(YAMLIO, TestTaggedDocuments) {
  1247. std::vector<MyDouble> docList;
  1248. Input yin("--- !decimal\nvalue: 3.0\n"
  1249. "--- !fraction\nnumerator: 9.0\ndenominator: 2\n...\n");
  1250. yin >> docList;
  1251. EXPECT_FALSE(yin.error());
  1252. EXPECT_EQ(docList.size(), 2UL);
  1253. EXPECT_EQ(docList[0].value, 3.0);
  1254. EXPECT_EQ(docList[1].value, 4.5);
  1255. }
  1256. //
  1257. // Test writing then reading back tagged documents
  1258. //
  1259. TEST(YAMLIO, TestTaggedDocumentsWriteAndRead) {
  1260. std::string intermediate;
  1261. {
  1262. MyDouble a(10.25);
  1263. MyDouble b(-3.75);
  1264. std::vector<MyDouble> docList;
  1265. docList.push_back(a);
  1266. docList.push_back(b);
  1267. llvm::raw_string_ostream ostr(intermediate);
  1268. Output yout(ostr);
  1269. yout << docList;
  1270. }
  1271. {
  1272. Input yin(intermediate);
  1273. std::vector<MyDouble> docList2;
  1274. yin >> docList2;
  1275. EXPECT_FALSE(yin.error());
  1276. EXPECT_EQ(docList2.size(), 2UL);
  1277. EXPECT_EQ(docList2[0].value, 10.25);
  1278. EXPECT_EQ(docList2[1].value, -3.75);
  1279. }
  1280. }
  1281. //===----------------------------------------------------------------------===//
  1282. // Test mapping validation
  1283. //===----------------------------------------------------------------------===//
  1284. struct MyValidation {
  1285. double value;
  1286. };
  1287. LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyValidation)
  1288. namespace llvm {
  1289. namespace yaml {
  1290. template <>
  1291. struct MappingTraits<MyValidation> {
  1292. static void mapping(IO &io, MyValidation &d) {
  1293. io.mapRequired("value", d.value);
  1294. }
  1295. static StringRef validate(IO &io, MyValidation &d) {
  1296. if (d.value < 0)
  1297. return "negative value";
  1298. return StringRef();
  1299. }
  1300. };
  1301. }
  1302. }
  1303. //
  1304. // Test that validate() is called and complains about the negative value.
  1305. //
  1306. TEST(YAMLIO, TestValidatingInput) {
  1307. std::vector<MyValidation> docList;
  1308. Input yin("--- \nvalue: 3.0\n"
  1309. "--- \nvalue: -1.0\n...\n",
  1310. nullptr, suppressErrorMessages);
  1311. yin >> docList;
  1312. EXPECT_TRUE(!!yin.error());
  1313. }
  1314. //===----------------------------------------------------------------------===//
  1315. // Test flow mapping
  1316. //===----------------------------------------------------------------------===//
  1317. struct FlowFooBar {
  1318. int foo;
  1319. int bar;
  1320. FlowFooBar() : foo(0), bar(0) {}
  1321. FlowFooBar(int foo, int bar) : foo(foo), bar(bar) {}
  1322. };
  1323. typedef std::vector<FlowFooBar> FlowFooBarSequence;
  1324. LLVM_YAML_IS_SEQUENCE_VECTOR(FlowFooBar)
  1325. struct FlowFooBarDoc {
  1326. FlowFooBar attribute;
  1327. FlowFooBarSequence seq;
  1328. };
  1329. namespace llvm {
  1330. namespace yaml {
  1331. template <>
  1332. struct MappingTraits<FlowFooBar> {
  1333. static void mapping(IO &io, FlowFooBar &fb) {
  1334. io.mapRequired("foo", fb.foo);
  1335. io.mapRequired("bar", fb.bar);
  1336. }
  1337. static const bool flow = true;
  1338. };
  1339. template <>
  1340. struct MappingTraits<FlowFooBarDoc> {
  1341. static void mapping(IO &io, FlowFooBarDoc &fb) {
  1342. io.mapRequired("attribute", fb.attribute);
  1343. io.mapRequired("seq", fb.seq);
  1344. }
  1345. };
  1346. }
  1347. }
  1348. //
  1349. // Test writing then reading back custom mappings
  1350. //
  1351. TEST(YAMLIO, TestReadWriteMyFlowMapping) {
  1352. std::string intermediate;
  1353. {
  1354. FlowFooBarDoc doc;
  1355. doc.attribute = FlowFooBar(42, 907);
  1356. doc.seq.push_back(FlowFooBar(1, 2));
  1357. doc.seq.push_back(FlowFooBar(0, 0));
  1358. doc.seq.push_back(FlowFooBar(-1, 1024));
  1359. llvm::raw_string_ostream ostr(intermediate);
  1360. Output yout(ostr);
  1361. yout << doc;
  1362. // Verify that mappings were written in flow style
  1363. ostr.flush();
  1364. llvm::StringRef flowOut(intermediate);
  1365. EXPECT_NE(llvm::StringRef::npos, flowOut.find("{ foo: 42, bar: 907 }"));
  1366. EXPECT_NE(llvm::StringRef::npos, flowOut.find("- { foo: 1, bar: 2 }"));
  1367. EXPECT_NE(llvm::StringRef::npos, flowOut.find("- { foo: 0, bar: 0 }"));
  1368. EXPECT_NE(llvm::StringRef::npos, flowOut.find("- { foo: -1, bar: 1024 }"));
  1369. }
  1370. {
  1371. Input yin(intermediate);
  1372. FlowFooBarDoc doc2;
  1373. yin >> doc2;
  1374. EXPECT_FALSE(yin.error());
  1375. EXPECT_EQ(doc2.attribute.foo, 42);
  1376. EXPECT_EQ(doc2.attribute.bar, 907);
  1377. EXPECT_EQ(doc2.seq.size(), 3UL);
  1378. EXPECT_EQ(doc2.seq[0].foo, 1);
  1379. EXPECT_EQ(doc2.seq[0].bar, 2);
  1380. EXPECT_EQ(doc2.seq[1].foo, 0);
  1381. EXPECT_EQ(doc2.seq[1].bar, 0);
  1382. EXPECT_EQ(doc2.seq[2].foo, -1);
  1383. EXPECT_EQ(doc2.seq[2].bar, 1024);
  1384. }
  1385. }
  1386. //===----------------------------------------------------------------------===//
  1387. // Test error handling
  1388. //===----------------------------------------------------------------------===//
  1389. //
  1390. // Test error handling of unknown enumerated scalar
  1391. //
  1392. TEST(YAMLIO, TestColorsReadError) {
  1393. ColorMap map;
  1394. Input yin("---\n"
  1395. "c1: blue\n"
  1396. "c2: purple\n"
  1397. "c3: green\n"
  1398. "...\n",
  1399. /*Ctxt=*/nullptr,
  1400. suppressErrorMessages);
  1401. yin >> map;
  1402. EXPECT_TRUE(!!yin.error());
  1403. }
  1404. //
  1405. // Test error handling of flow sequence with unknown value
  1406. //
  1407. TEST(YAMLIO, TestFlagsReadError) {
  1408. FlagsMap map;
  1409. Input yin("---\n"
  1410. "f1: [ big ]\n"
  1411. "f2: [ round, hollow ]\n"
  1412. "f3: []\n"
  1413. "...\n",
  1414. /*Ctxt=*/nullptr,
  1415. suppressErrorMessages);
  1416. yin >> map;
  1417. EXPECT_TRUE(!!yin.error());
  1418. }
  1419. //
  1420. // Test error handling reading built-in uint8_t type
  1421. //
  1422. LLVM_YAML_IS_SEQUENCE_VECTOR(uint8_t)
  1423. TEST(YAMLIO, TestReadBuiltInTypesUint8Error) {
  1424. std::vector<uint8_t> seq;
  1425. Input yin("---\n"
  1426. "- 255\n"
  1427. "- 0\n"
  1428. "- 257\n"
  1429. "...\n",
  1430. /*Ctxt=*/nullptr,
  1431. suppressErrorMessages);
  1432. yin >> seq;
  1433. EXPECT_TRUE(!!yin.error());
  1434. }
  1435. //
  1436. // Test error handling reading built-in uint16_t type
  1437. //
  1438. LLVM_YAML_IS_SEQUENCE_VECTOR(uint16_t)
  1439. TEST(YAMLIO, TestReadBuiltInTypesUint16Error) {
  1440. std::vector<uint16_t> seq;
  1441. Input yin("---\n"
  1442. "- 65535\n"
  1443. "- 0\n"
  1444. "- 66000\n"
  1445. "...\n",
  1446. /*Ctxt=*/nullptr,
  1447. suppressErrorMessages);
  1448. yin >> seq;
  1449. EXPECT_TRUE(!!yin.error());
  1450. }
  1451. //
  1452. // Test error handling reading built-in uint32_t type
  1453. //
  1454. LLVM_YAML_IS_SEQUENCE_VECTOR(uint32_t)
  1455. TEST(YAMLIO, TestReadBuiltInTypesUint32Error) {
  1456. std::vector<uint32_t> seq;
  1457. Input yin("---\n"
  1458. "- 4000000000\n"
  1459. "- 0\n"
  1460. "- 5000000000\n"
  1461. "...\n",
  1462. /*Ctxt=*/nullptr,
  1463. suppressErrorMessages);
  1464. yin >> seq;
  1465. EXPECT_TRUE(!!yin.error());
  1466. }
  1467. //
  1468. // Test error handling reading built-in uint64_t type
  1469. //
  1470. LLVM_YAML_IS_SEQUENCE_VECTOR(uint64_t)
  1471. TEST(YAMLIO, TestReadBuiltInTypesUint64Error) {
  1472. std::vector<uint64_t> seq;
  1473. Input yin("---\n"
  1474. "- 18446744073709551615\n"
  1475. "- 0\n"
  1476. "- 19446744073709551615\n"
  1477. "...\n",
  1478. /*Ctxt=*/nullptr,
  1479. suppressErrorMessages);
  1480. yin >> seq;
  1481. EXPECT_TRUE(!!yin.error());
  1482. }
  1483. //
  1484. // Test error handling reading built-in int8_t type
  1485. //
  1486. LLVM_YAML_IS_SEQUENCE_VECTOR(int8_t)
  1487. TEST(YAMLIO, TestReadBuiltInTypesint8OverError) {
  1488. std::vector<int8_t> seq;
  1489. Input yin("---\n"
  1490. "- -128\n"
  1491. "- 0\n"
  1492. "- 127\n"
  1493. "- 128\n"
  1494. "...\n",
  1495. /*Ctxt=*/nullptr,
  1496. suppressErrorMessages);
  1497. yin >> seq;
  1498. EXPECT_TRUE(!!yin.error());
  1499. }
  1500. //
  1501. // Test error handling reading built-in int8_t type
  1502. //
  1503. TEST(YAMLIO, TestReadBuiltInTypesint8UnderError) {
  1504. std::vector<int8_t> seq;
  1505. Input yin("---\n"
  1506. "- -128\n"
  1507. "- 0\n"
  1508. "- 127\n"
  1509. "- -129\n"
  1510. "...\n",
  1511. /*Ctxt=*/nullptr,
  1512. suppressErrorMessages);
  1513. yin >> seq;
  1514. EXPECT_TRUE(!!yin.error());
  1515. }
  1516. //
  1517. // Test error handling reading built-in int16_t type
  1518. //
  1519. LLVM_YAML_IS_SEQUENCE_VECTOR(int16_t)
  1520. TEST(YAMLIO, TestReadBuiltInTypesint16UnderError) {
  1521. std::vector<int16_t> seq;
  1522. Input yin("---\n"
  1523. "- 32767\n"
  1524. "- 0\n"
  1525. "- -32768\n"
  1526. "- -32769\n"
  1527. "...\n",
  1528. /*Ctxt=*/nullptr,
  1529. suppressErrorMessages);
  1530. yin >> seq;
  1531. EXPECT_TRUE(!!yin.error());
  1532. }
  1533. //
  1534. // Test error handling reading built-in int16_t type
  1535. //
  1536. TEST(YAMLIO, TestReadBuiltInTypesint16OverError) {
  1537. std::vector<int16_t> seq;
  1538. Input yin("---\n"
  1539. "- 32767\n"
  1540. "- 0\n"
  1541. "- -32768\n"
  1542. "- 32768\n"
  1543. "...\n",
  1544. /*Ctxt=*/nullptr,
  1545. suppressErrorMessages);
  1546. yin >> seq;
  1547. EXPECT_TRUE(!!yin.error());
  1548. }
  1549. //
  1550. // Test error handling reading built-in int32_t type
  1551. //
  1552. LLVM_YAML_IS_SEQUENCE_VECTOR(int32_t)
  1553. TEST(YAMLIO, TestReadBuiltInTypesint32UnderError) {
  1554. std::vector<int32_t> seq;
  1555. Input yin("---\n"
  1556. "- 2147483647\n"
  1557. "- 0\n"
  1558. "- -2147483648\n"
  1559. "- -2147483649\n"
  1560. "...\n",
  1561. /*Ctxt=*/nullptr,
  1562. suppressErrorMessages);
  1563. yin >> seq;
  1564. EXPECT_TRUE(!!yin.error());
  1565. }
  1566. //
  1567. // Test error handling reading built-in int32_t type
  1568. //
  1569. TEST(YAMLIO, TestReadBuiltInTypesint32OverError) {
  1570. std::vector<int32_t> seq;
  1571. Input yin("---\n"
  1572. "- 2147483647\n"
  1573. "- 0\n"
  1574. "- -2147483648\n"
  1575. "- 2147483649\n"
  1576. "...\n",
  1577. /*Ctxt=*/nullptr,
  1578. suppressErrorMessages);
  1579. yin >> seq;
  1580. EXPECT_TRUE(!!yin.error());
  1581. }
  1582. //
  1583. // Test error handling reading built-in int64_t type
  1584. //
  1585. LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t)
  1586. TEST(YAMLIO, TestReadBuiltInTypesint64UnderError) {
  1587. std::vector<int64_t> seq;
  1588. Input yin("---\n"
  1589. "- -9223372036854775808\n"
  1590. "- 0\n"
  1591. "- 9223372036854775807\n"
  1592. "- -9223372036854775809\n"
  1593. "...\n",
  1594. /*Ctxt=*/nullptr,
  1595. suppressErrorMessages);
  1596. yin >> seq;
  1597. EXPECT_TRUE(!!yin.error());
  1598. }
  1599. //
  1600. // Test error handling reading built-in int64_t type
  1601. //
  1602. TEST(YAMLIO, TestReadBuiltInTypesint64OverError) {
  1603. std::vector<int64_t> seq;
  1604. Input yin("---\n"
  1605. "- -9223372036854775808\n"
  1606. "- 0\n"
  1607. "- 9223372036854775807\n"
  1608. "- 9223372036854775809\n"
  1609. "...\n",
  1610. /*Ctxt=*/nullptr,
  1611. suppressErrorMessages);
  1612. yin >> seq;
  1613. EXPECT_TRUE(!!yin.error());
  1614. }
  1615. //
  1616. // Test error handling reading built-in float type
  1617. //
  1618. LLVM_YAML_IS_SEQUENCE_VECTOR(float)
  1619. TEST(YAMLIO, TestReadBuiltInTypesFloatError) {
  1620. std::vector<float> seq;
  1621. Input yin("---\n"
  1622. "- 0.0\n"
  1623. "- 1000.1\n"
  1624. "- -123.456\n"
  1625. "- 1.2.3\n"
  1626. "...\n",
  1627. /*Ctxt=*/nullptr,
  1628. suppressErrorMessages);
  1629. yin >> seq;
  1630. EXPECT_TRUE(!!yin.error());
  1631. }
  1632. //
  1633. // Test error handling reading built-in float type
  1634. //
  1635. LLVM_YAML_IS_SEQUENCE_VECTOR(double)
  1636. TEST(YAMLIO, TestReadBuiltInTypesDoubleError) {
  1637. std::vector<double> seq;
  1638. Input yin("---\n"
  1639. "- 0.0\n"
  1640. "- 1000.1\n"
  1641. "- -123.456\n"
  1642. "- 1.2.3\n"
  1643. "...\n",
  1644. /*Ctxt=*/nullptr,
  1645. suppressErrorMessages);
  1646. yin >> seq;
  1647. EXPECT_TRUE(!!yin.error());
  1648. }
  1649. //
  1650. // Test error handling reading built-in Hex8 type
  1651. //
  1652. LLVM_YAML_IS_SEQUENCE_VECTOR(Hex8)
  1653. TEST(YAMLIO, TestReadBuiltInTypesHex8Error) {
  1654. std::vector<Hex8> seq;
  1655. Input yin("---\n"
  1656. "- 0x12\n"
  1657. "- 0xFE\n"
  1658. "- 0x123\n"
  1659. "...\n",
  1660. /*Ctxt=*/nullptr,
  1661. suppressErrorMessages);
  1662. yin >> seq;
  1663. EXPECT_TRUE(!!yin.error());
  1664. }
  1665. //
  1666. // Test error handling reading built-in Hex16 type
  1667. //
  1668. LLVM_YAML_IS_SEQUENCE_VECTOR(Hex16)
  1669. TEST(YAMLIO, TestReadBuiltInTypesHex16Error) {
  1670. std::vector<Hex16> seq;
  1671. Input yin("---\n"
  1672. "- 0x0012\n"
  1673. "- 0xFEFF\n"
  1674. "- 0x12345\n"
  1675. "...\n",
  1676. /*Ctxt=*/nullptr,
  1677. suppressErrorMessages);
  1678. yin >> seq;
  1679. EXPECT_TRUE(!!yin.error());
  1680. }
  1681. //
  1682. // Test error handling reading built-in Hex32 type
  1683. //
  1684. LLVM_YAML_IS_SEQUENCE_VECTOR(Hex32)
  1685. TEST(YAMLIO, TestReadBuiltInTypesHex32Error) {
  1686. std::vector<Hex32> seq;
  1687. Input yin("---\n"
  1688. "- 0x0012\n"
  1689. "- 0xFEFF0000\n"
  1690. "- 0x1234556789\n"
  1691. "...\n",
  1692. /*Ctxt=*/nullptr,
  1693. suppressErrorMessages);
  1694. yin >> seq;
  1695. EXPECT_TRUE(!!yin.error());
  1696. }
  1697. //
  1698. // Test error handling reading built-in Hex64 type
  1699. //
  1700. LLVM_YAML_IS_SEQUENCE_VECTOR(Hex64)
  1701. TEST(YAMLIO, TestReadBuiltInTypesHex64Error) {
  1702. std::vector<Hex64> seq;
  1703. Input yin("---\n"
  1704. "- 0x0012\n"
  1705. "- 0xFFEEDDCCBBAA9988\n"
  1706. "- 0x12345567890ABCDEF0\n"
  1707. "...\n",
  1708. /*Ctxt=*/nullptr,
  1709. suppressErrorMessages);
  1710. yin >> seq;
  1711. EXPECT_TRUE(!!yin.error());
  1712. }
  1713. TEST(YAMLIO, TestMalformedMapFailsGracefully) {
  1714. FooBar doc;
  1715. {
  1716. // We pass the suppressErrorMessages handler to handle the error
  1717. // message generated in the constructor of Input.
  1718. Input yin("{foo:3, bar: 5}", /*Ctxt=*/nullptr, suppressErrorMessages);
  1719. yin >> doc;
  1720. EXPECT_TRUE(!!yin.error());
  1721. }
  1722. {
  1723. Input yin("---\nfoo:3\nbar: 5\n...\n", /*Ctxt=*/nullptr, suppressErrorMessages);
  1724. yin >> doc;
  1725. EXPECT_TRUE(!!yin.error());
  1726. }
  1727. }
  1728. struct OptionalTest {
  1729. std::vector<int> Numbers;
  1730. };
  1731. struct OptionalTestSeq {
  1732. std::vector<OptionalTest> Tests;
  1733. };
  1734. LLVM_YAML_IS_SEQUENCE_VECTOR(OptionalTest)
  1735. namespace llvm {
  1736. namespace yaml {
  1737. template <>
  1738. struct MappingTraits<OptionalTest> {
  1739. static void mapping(IO& IO, OptionalTest &OT) {
  1740. IO.mapOptional("Numbers", OT.Numbers);
  1741. }
  1742. };
  1743. template <>
  1744. struct MappingTraits<OptionalTestSeq> {
  1745. static void mapping(IO &IO, OptionalTestSeq &OTS) {
  1746. IO.mapOptional("Tests", OTS.Tests);
  1747. }
  1748. };
  1749. }
  1750. }
  1751. TEST(YAMLIO, SequenceElideTest) {
  1752. // Test that writing out a purely optional structure with its fields set to
  1753. // default followed by other data is properly read back in.
  1754. OptionalTestSeq Seq;
  1755. OptionalTest One, Two, Three, Four;
  1756. int N[] = {1, 2, 3};
  1757. Three.Numbers.assign(N, N + 3);
  1758. Seq.Tests.push_back(One);
  1759. Seq.Tests.push_back(Two);
  1760. Seq.Tests.push_back(Three);
  1761. Seq.Tests.push_back(Four);
  1762. std::string intermediate;
  1763. {
  1764. llvm::raw_string_ostream ostr(intermediate);
  1765. Output yout(ostr);
  1766. yout << Seq;
  1767. }
  1768. Input yin(intermediate);
  1769. OptionalTestSeq Seq2;
  1770. yin >> Seq2;
  1771. EXPECT_FALSE(yin.error());
  1772. EXPECT_EQ(4UL, Seq2.Tests.size());
  1773. EXPECT_TRUE(Seq2.Tests[0].Numbers.empty());
  1774. EXPECT_TRUE(Seq2.Tests[1].Numbers.empty());
  1775. EXPECT_EQ(1, Seq2.Tests[2].Numbers[0]);
  1776. EXPECT_EQ(2, Seq2.Tests[2].Numbers[1]);
  1777. EXPECT_EQ(3, Seq2.Tests[2].Numbers[2]);
  1778. EXPECT_TRUE(Seq2.Tests[3].Numbers.empty());
  1779. }
  1780. TEST(YAMLIO, TestEmptyStringFailsForMapWithRequiredFields) {
  1781. FooBar doc;
  1782. Input yin("");
  1783. yin >> doc;
  1784. EXPECT_TRUE(!!yin.error());
  1785. }
  1786. TEST(YAMLIO, TestEmptyStringSucceedsForMapWithOptionalFields) {
  1787. OptionalTest doc;
  1788. Input yin("");
  1789. yin >> doc;
  1790. EXPECT_FALSE(yin.error());
  1791. }
  1792. TEST(YAMLIO, TestEmptyStringSucceedsForSequence) {
  1793. std::vector<uint8_t> seq;
  1794. Input yin("", /*Ctxt=*/nullptr, suppressErrorMessages);
  1795. yin >> seq;
  1796. EXPECT_FALSE(yin.error());
  1797. EXPECT_TRUE(seq.empty());
  1798. }
  1799. struct FlowMap {
  1800. llvm::StringRef str1, str2, str3;
  1801. FlowMap(llvm::StringRef str1, llvm::StringRef str2, llvm::StringRef str3)
  1802. : str1(str1), str2(str2), str3(str3) {}
  1803. };
  1804. struct FlowSeq {
  1805. llvm::StringRef str;
  1806. FlowSeq(llvm::StringRef S) : str(S) {}
  1807. FlowSeq() = default;
  1808. };
  1809. namespace llvm {
  1810. namespace yaml {
  1811. template <>
  1812. struct MappingTraits<FlowMap> {
  1813. static void mapping(IO &io, FlowMap &fm) {
  1814. io.mapRequired("str1", fm.str1);
  1815. io.mapRequired("str2", fm.str2);
  1816. io.mapRequired("str3", fm.str3);
  1817. }
  1818. static const bool flow = true;
  1819. };
  1820. template <>
  1821. struct ScalarTraits<FlowSeq> {
  1822. static void output(const FlowSeq &value, void*, llvm::raw_ostream &out) {
  1823. out << value.str;
  1824. }
  1825. static StringRef input(StringRef scalar, void*, FlowSeq &value) {
  1826. value.str = scalar;
  1827. return "";
  1828. }
  1829. static bool mustQuote(StringRef S) { return false; }
  1830. };
  1831. }
  1832. }
  1833. LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FlowSeq)
  1834. TEST(YAMLIO, TestWrapFlow) {
  1835. std::string out;
  1836. llvm::raw_string_ostream ostr(out);
  1837. FlowMap Map("This is str1", "This is str2", "This is str3");
  1838. std::vector<FlowSeq> Seq;
  1839. Seq.emplace_back("This is str1");
  1840. Seq.emplace_back("This is str2");
  1841. Seq.emplace_back("This is str3");
  1842. {
  1843. // 20 is just bellow the total length of the first mapping field.
  1844. // We should wreap at every element.
  1845. Output yout(ostr, nullptr, 15);
  1846. yout << Map;
  1847. ostr.flush();
  1848. EXPECT_EQ(out,
  1849. "---\n"
  1850. "{ str1: This is str1, \n"
  1851. " str2: This is str2, \n"
  1852. " str3: This is str3 }\n"
  1853. "...\n");
  1854. out.clear();
  1855. yout << Seq;
  1856. ostr.flush();
  1857. EXPECT_EQ(out,
  1858. "---\n"
  1859. "[ This is str1, \n"
  1860. " This is str2, \n"
  1861. " This is str3 ]\n"
  1862. "...\n");
  1863. out.clear();
  1864. }
  1865. {
  1866. // 25 will allow the second field to be output on the first line.
  1867. Output yout(ostr, nullptr, 25);
  1868. yout << Map;
  1869. ostr.flush();
  1870. EXPECT_EQ(out,
  1871. "---\n"
  1872. "{ str1: This is str1, str2: This is str2, \n"
  1873. " str3: This is str3 }\n"
  1874. "...\n");
  1875. out.clear();
  1876. yout << Seq;
  1877. ostr.flush();
  1878. EXPECT_EQ(out,
  1879. "---\n"
  1880. "[ This is str1, This is str2, \n"
  1881. " This is str3 ]\n"
  1882. "...\n");
  1883. out.clear();
  1884. }
  1885. {
  1886. // 0 means no wrapping.
  1887. Output yout(ostr, nullptr, 0);
  1888. yout << Map;
  1889. ostr.flush();
  1890. EXPECT_EQ(out,
  1891. "---\n"
  1892. "{ str1: This is str1, str2: This is str2, str3: This is str3 }\n"
  1893. "...\n");
  1894. out.clear();
  1895. yout << Seq;
  1896. ostr.flush();
  1897. EXPECT_EQ(out,
  1898. "---\n"
  1899. "[ This is str1, This is str2, This is str3 ]\n"
  1900. "...\n");
  1901. out.clear();
  1902. }
  1903. }