The source code and dockerfile for the GSW2024 AI Lab.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

400 lines
9.8 KiB

2 months ago
  1. #include <limits>
  2. #include "emitterstate.h"
  3. #include "yaml-cpp/exceptions.h" // IWYU pragma: keep
  4. namespace YAML {
  5. EmitterState::EmitterState()
  6. : m_isGood(true),
  7. m_lastError{},
  8. // default global manipulators
  9. m_charset(EmitNonAscii),
  10. m_strFmt(Auto),
  11. m_boolFmt(TrueFalseBool),
  12. m_boolLengthFmt(LongBool),
  13. m_boolCaseFmt(LowerCase),
  14. m_nullFmt(TildeNull),
  15. m_intFmt(Dec),
  16. m_indent(2),
  17. m_preCommentIndent(2),
  18. m_postCommentIndent(1),
  19. m_seqFmt(Block),
  20. m_mapFmt(Block),
  21. m_mapKeyFmt(Auto),
  22. m_floatPrecision(std::numeric_limits<float>::max_digits10),
  23. m_doublePrecision(std::numeric_limits<double>::max_digits10),
  24. //
  25. m_modifiedSettings{},
  26. m_globalModifiedSettings{},
  27. m_groups{},
  28. m_curIndent(0),
  29. m_hasAnchor(false),
  30. m_hasAlias(false),
  31. m_hasTag(false),
  32. m_hasNonContent(false),
  33. m_docCount(0) {}
  34. EmitterState::~EmitterState() = default;
  35. // SetLocalValue
  36. // . We blindly tries to set all possible formatters to this value
  37. // . Only the ones that make sense will be accepted
  38. void EmitterState::SetLocalValue(EMITTER_MANIP value) {
  39. SetOutputCharset(value, FmtScope::Local);
  40. SetStringFormat(value, FmtScope::Local);
  41. SetBoolFormat(value, FmtScope::Local);
  42. SetBoolCaseFormat(value, FmtScope::Local);
  43. SetBoolLengthFormat(value, FmtScope::Local);
  44. SetNullFormat(value, FmtScope::Local);
  45. SetIntFormat(value, FmtScope::Local);
  46. SetFlowType(GroupType::Seq, value, FmtScope::Local);
  47. SetFlowType(GroupType::Map, value, FmtScope::Local);
  48. SetMapKeyFormat(value, FmtScope::Local);
  49. }
  50. void EmitterState::SetAnchor() { m_hasAnchor = true; }
  51. void EmitterState::SetAlias() { m_hasAlias = true; }
  52. void EmitterState::SetTag() { m_hasTag = true; }
  53. void EmitterState::SetNonContent() { m_hasNonContent = true; }
  54. void EmitterState::SetLongKey() {
  55. assert(!m_groups.empty());
  56. if (m_groups.empty()) {
  57. return;
  58. }
  59. assert(m_groups.back()->type == GroupType::Map);
  60. m_groups.back()->longKey = true;
  61. }
  62. void EmitterState::ForceFlow() {
  63. assert(!m_groups.empty());
  64. if (m_groups.empty()) {
  65. return;
  66. }
  67. m_groups.back()->flowType = FlowType::Flow;
  68. }
  69. void EmitterState::StartedNode() {
  70. if (m_groups.empty()) {
  71. m_docCount++;
  72. } else {
  73. m_groups.back()->childCount++;
  74. if (m_groups.back()->childCount % 2 == 0) {
  75. m_groups.back()->longKey = false;
  76. }
  77. }
  78. m_hasAnchor = false;
  79. m_hasAlias = false;
  80. m_hasTag = false;
  81. m_hasNonContent = false;
  82. }
  83. EmitterNodeType::value EmitterState::NextGroupType(
  84. GroupType::value type) const {
  85. if (type == GroupType::Seq) {
  86. if (GetFlowType(type) == Block)
  87. return EmitterNodeType::BlockSeq;
  88. return EmitterNodeType::FlowSeq;
  89. }
  90. if (GetFlowType(type) == Block)
  91. return EmitterNodeType::BlockMap;
  92. return EmitterNodeType::FlowMap;
  93. // can't happen
  94. assert(false);
  95. return EmitterNodeType::NoType;
  96. }
  97. void EmitterState::StartedDoc() {
  98. m_hasAnchor = false;
  99. m_hasTag = false;
  100. m_hasNonContent = false;
  101. }
  102. void EmitterState::EndedDoc() {
  103. m_hasAnchor = false;
  104. m_hasTag = false;
  105. m_hasNonContent = false;
  106. }
  107. void EmitterState::StartedScalar() {
  108. StartedNode();
  109. ClearModifiedSettings();
  110. }
  111. void EmitterState::StartedGroup(GroupType::value type) {
  112. StartedNode();
  113. const std::size_t lastGroupIndent =
  114. (m_groups.empty() ? 0 : m_groups.back()->indent);
  115. m_curIndent += lastGroupIndent;
  116. // TODO: Create move constructors for settings types to simplify transfer
  117. std::unique_ptr<Group> pGroup(new Group(type));
  118. // transfer settings (which last until this group is done)
  119. //
  120. // NB: if pGroup->modifiedSettings == m_modifiedSettings,
  121. // m_modifiedSettings is not changed!
  122. pGroup->modifiedSettings = std::move(m_modifiedSettings);
  123. // set up group
  124. if (GetFlowType(type) == Block) {
  125. pGroup->flowType = FlowType::Block;
  126. } else {
  127. pGroup->flowType = FlowType::Flow;
  128. }
  129. pGroup->indent = GetIndent();
  130. m_groups.push_back(std::move(pGroup));
  131. }
  132. void EmitterState::EndedGroup(GroupType::value type) {
  133. if (m_groups.empty()) {
  134. if (type == GroupType::Seq) {
  135. return SetError(ErrorMsg::UNEXPECTED_END_SEQ);
  136. }
  137. return SetError(ErrorMsg::UNEXPECTED_END_MAP);
  138. }
  139. if (m_hasTag) {
  140. SetError(ErrorMsg::INVALID_TAG);
  141. }
  142. if (m_hasAnchor) {
  143. SetError(ErrorMsg::INVALID_ANCHOR);
  144. }
  145. // get rid of the current group
  146. {
  147. std::unique_ptr<Group> pFinishedGroup = std::move(m_groups.back());
  148. m_groups.pop_back();
  149. if (pFinishedGroup->type != type) {
  150. return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
  151. }
  152. }
  153. // reset old settings
  154. std::size_t lastIndent = (m_groups.empty() ? 0 : m_groups.back()->indent);
  155. assert(m_curIndent >= lastIndent);
  156. m_curIndent -= lastIndent;
  157. // some global settings that we changed may have been overridden
  158. // by a local setting we just popped, so we need to restore them
  159. m_globalModifiedSettings.restore();
  160. ClearModifiedSettings();
  161. m_hasAnchor = false;
  162. m_hasTag = false;
  163. m_hasNonContent = false;
  164. }
  165. EmitterNodeType::value EmitterState::CurGroupNodeType() const {
  166. if (m_groups.empty()) {
  167. return EmitterNodeType::NoType;
  168. }
  169. return m_groups.back()->NodeType();
  170. }
  171. GroupType::value EmitterState::CurGroupType() const {
  172. return m_groups.empty() ? GroupType::NoType : m_groups.back()->type;
  173. }
  174. FlowType::value EmitterState::CurGroupFlowType() const {
  175. return m_groups.empty() ? FlowType::NoType : m_groups.back()->flowType;
  176. }
  177. std::size_t EmitterState::CurGroupIndent() const {
  178. return m_groups.empty() ? 0 : m_groups.back()->indent;
  179. }
  180. std::size_t EmitterState::CurGroupChildCount() const {
  181. return m_groups.empty() ? m_docCount : m_groups.back()->childCount;
  182. }
  183. bool EmitterState::CurGroupLongKey() const {
  184. return m_groups.empty() ? false : m_groups.back()->longKey;
  185. }
  186. std::size_t EmitterState::LastIndent() const {
  187. if (m_groups.size() <= 1) {
  188. return 0;
  189. }
  190. return m_curIndent - m_groups[m_groups.size() - 2]->indent;
  191. }
  192. void EmitterState::ClearModifiedSettings() { m_modifiedSettings.clear(); }
  193. void EmitterState::RestoreGlobalModifiedSettings() {
  194. m_globalModifiedSettings.restore();
  195. }
  196. bool EmitterState::SetOutputCharset(EMITTER_MANIP value,
  197. FmtScope::value scope) {
  198. switch (value) {
  199. case EmitNonAscii:
  200. case EscapeNonAscii:
  201. case EscapeAsJson:
  202. _Set(m_charset, value, scope);
  203. return true;
  204. default:
  205. return false;
  206. }
  207. }
  208. bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope) {
  209. switch (value) {
  210. case Auto:
  211. case SingleQuoted:
  212. case DoubleQuoted:
  213. case Literal:
  214. _Set(m_strFmt, value, scope);
  215. return true;
  216. default:
  217. return false;
  218. }
  219. }
  220. bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope) {
  221. switch (value) {
  222. case OnOffBool:
  223. case TrueFalseBool:
  224. case YesNoBool:
  225. _Set(m_boolFmt, value, scope);
  226. return true;
  227. default:
  228. return false;
  229. }
  230. }
  231. bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value,
  232. FmtScope::value scope) {
  233. switch (value) {
  234. case LongBool:
  235. case ShortBool:
  236. _Set(m_boolLengthFmt, value, scope);
  237. return true;
  238. default:
  239. return false;
  240. }
  241. }
  242. bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value,
  243. FmtScope::value scope) {
  244. switch (value) {
  245. case UpperCase:
  246. case LowerCase:
  247. case CamelCase:
  248. _Set(m_boolCaseFmt, value, scope);
  249. return true;
  250. default:
  251. return false;
  252. }
  253. }
  254. bool EmitterState::SetNullFormat(EMITTER_MANIP value, FmtScope::value scope) {
  255. switch (value) {
  256. case LowerNull:
  257. case UpperNull:
  258. case CamelNull:
  259. case TildeNull:
  260. _Set(m_nullFmt, value, scope);
  261. return true;
  262. default:
  263. return false;
  264. }
  265. }
  266. bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope) {
  267. switch (value) {
  268. case Dec:
  269. case Hex:
  270. case Oct:
  271. _Set(m_intFmt, value, scope);
  272. return true;
  273. default:
  274. return false;
  275. }
  276. }
  277. bool EmitterState::SetIndent(std::size_t value, FmtScope::value scope) {
  278. if (value <= 1)
  279. return false;
  280. _Set(m_indent, value, scope);
  281. return true;
  282. }
  283. bool EmitterState::SetPreCommentIndent(std::size_t value,
  284. FmtScope::value scope) {
  285. if (value == 0)
  286. return false;
  287. _Set(m_preCommentIndent, value, scope);
  288. return true;
  289. }
  290. bool EmitterState::SetPostCommentIndent(std::size_t value,
  291. FmtScope::value scope) {
  292. if (value == 0)
  293. return false;
  294. _Set(m_postCommentIndent, value, scope);
  295. return true;
  296. }
  297. bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
  298. FmtScope::value scope) {
  299. switch (value) {
  300. case Block:
  301. case Flow:
  302. _Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope);
  303. return true;
  304. default:
  305. return false;
  306. }
  307. }
  308. EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const {
  309. // force flow style if we're currently in a flow
  310. if (CurGroupFlowType() == FlowType::Flow)
  311. return Flow;
  312. // otherwise, go with what's asked of us
  313. return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get());
  314. }
  315. bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope) {
  316. switch (value) {
  317. case Auto:
  318. case LongKey:
  319. _Set(m_mapKeyFmt, value, scope);
  320. return true;
  321. default:
  322. return false;
  323. }
  324. }
  325. bool EmitterState::SetFloatPrecision(std::size_t value, FmtScope::value scope) {
  326. if (value > std::numeric_limits<float>::max_digits10)
  327. return false;
  328. _Set(m_floatPrecision, value, scope);
  329. return true;
  330. }
  331. bool EmitterState::SetDoublePrecision(std::size_t value,
  332. FmtScope::value scope) {
  333. if (value > std::numeric_limits<double>::max_digits10)
  334. return false;
  335. _Set(m_doublePrecision, value, scope);
  336. return true;
  337. }
  338. } // namespace YAML