File indexing completed on 2025-05-12 09:08:10
0001 #ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
0002 #define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
0003
0004 #if defined(_MSC_VER) || \
0005 (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
0006 (__GNUC__ >= 4))
0007 #pragma once
0008 #endif
0009
0010 #include "setting.h"
0011 #include "ATOOLS/YAML/yaml-cpp/emitterdef.h"
0012 #include "ATOOLS/YAML/yaml-cpp/emittermanip.h"
0013
0014 #include <cassert>
0015 #include <memory>
0016 #include <stack>
0017 #include <stdexcept>
0018 #include <vector>
0019
0020 namespace SHERPA_YAML {
0021 struct FmtScope {
0022 enum value { Local, Global };
0023 };
0024 struct GroupType {
0025 enum value { NoType, Seq, Map };
0026 };
0027 struct FlowType {
0028 enum value { NoType, Flow, Block };
0029 };
0030
0031 class EmitterState {
0032 public:
0033 EmitterState();
0034 ~EmitterState();
0035
0036
0037 bool good() const { return m_isGood; }
0038 const std::string GetLastError() const { return m_lastError; }
0039 void SetError(const std::string& error) {
0040 m_isGood = false;
0041 m_lastError = error;
0042 }
0043
0044
0045 void SetAnchor();
0046 void SetAlias();
0047 void SetTag();
0048 void SetNonContent();
0049 void SetLongKey();
0050 void ForceFlow();
0051 void StartedDoc();
0052 void EndedDoc();
0053 void StartedScalar();
0054 void StartedGroup(GroupType::value type);
0055 void EndedGroup(GroupType::value type);
0056
0057 EmitterNodeType::value NextGroupType(GroupType::value type) const;
0058 EmitterNodeType::value CurGroupNodeType() const;
0059
0060 GroupType::value CurGroupType() const;
0061 FlowType::value CurGroupFlowType() const;
0062 std::size_t CurGroupIndent() const;
0063 std::size_t CurGroupChildCount() const;
0064 bool CurGroupLongKey() const;
0065
0066 std::size_t LastIndent() const;
0067 std::size_t CurIndent() const { return m_curIndent; }
0068 bool HasAnchor() const { return m_hasAnchor; }
0069 bool HasAlias() const { return m_hasAlias; }
0070 bool HasTag() const { return m_hasTag; }
0071 bool HasBegunNode() const {
0072 return m_hasAnchor || m_hasTag || m_hasNonContent;
0073 }
0074 bool HasBegunContent() const { return m_hasAnchor || m_hasTag; }
0075
0076 void ClearModifiedSettings();
0077 void RestoreGlobalModifiedSettings();
0078
0079
0080 void SetLocalValue(EMITTER_MANIP value);
0081
0082 bool SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope);
0083 EMITTER_MANIP GetOutputCharset() const { return m_charset.get(); }
0084
0085 bool SetStringFormat(EMITTER_MANIP value, FmtScope::value scope);
0086 EMITTER_MANIP GetStringFormat() const { return m_strFmt.get(); }
0087
0088 bool SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope);
0089 EMITTER_MANIP GetBoolFormat() const { return m_boolFmt.get(); }
0090
0091 bool SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope);
0092 EMITTER_MANIP GetBoolLengthFormat() const { return m_boolLengthFmt.get(); }
0093
0094 bool SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope);
0095 EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); }
0096
0097 bool SetNullFormat(EMITTER_MANIP value, FmtScope::value scope);
0098 EMITTER_MANIP GetNullFormat() const { return m_nullFmt.get(); }
0099
0100 bool SetIntFormat(EMITTER_MANIP value, FmtScope::value scope);
0101 EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); }
0102
0103 bool SetIndent(std::size_t value, FmtScope::value scope);
0104 std::size_t GetIndent() const { return m_indent.get(); }
0105
0106 bool SetPreCommentIndent(std::size_t value, FmtScope::value scope);
0107 std::size_t GetPreCommentIndent() const { return m_preCommentIndent.get(); }
0108 bool SetPostCommentIndent(std::size_t value, FmtScope::value scope);
0109 std::size_t GetPostCommentIndent() const { return m_postCommentIndent.get(); }
0110
0111 bool SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
0112 FmtScope::value scope);
0113 EMITTER_MANIP GetFlowType(GroupType::value groupType) const;
0114
0115 bool SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope);
0116 EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); }
0117
0118 bool SetFloatPrecision(std::size_t value, FmtScope::value scope);
0119 std::size_t GetFloatPrecision() const { return m_floatPrecision.get(); }
0120 bool SetDoublePrecision(std::size_t value, FmtScope::value scope);
0121 std::size_t GetDoublePrecision() const { return m_doublePrecision.get(); }
0122
0123 private:
0124 template <typename T>
0125 void _Set(Setting<T>& fmt, T value, FmtScope::value scope);
0126
0127 void StartedNode();
0128
0129 private:
0130
0131 bool m_isGood;
0132 std::string m_lastError;
0133
0134
0135 Setting<EMITTER_MANIP> m_charset;
0136 Setting<EMITTER_MANIP> m_strFmt;
0137 Setting<EMITTER_MANIP> m_boolFmt;
0138 Setting<EMITTER_MANIP> m_boolLengthFmt;
0139 Setting<EMITTER_MANIP> m_boolCaseFmt;
0140 Setting<EMITTER_MANIP> m_nullFmt;
0141 Setting<EMITTER_MANIP> m_intFmt;
0142 Setting<std::size_t> m_indent;
0143 Setting<std::size_t> m_preCommentIndent, m_postCommentIndent;
0144 Setting<EMITTER_MANIP> m_seqFmt;
0145 Setting<EMITTER_MANIP> m_mapFmt;
0146 Setting<EMITTER_MANIP> m_mapKeyFmt;
0147 Setting<std::size_t> m_floatPrecision;
0148 Setting<std::size_t> m_doublePrecision;
0149
0150 SettingChanges m_modifiedSettings;
0151 SettingChanges m_globalModifiedSettings;
0152
0153 struct Group {
0154 explicit Group(GroupType::value type_)
0155 : type(type_),
0156 flowType{},
0157 indent(0),
0158 childCount(0),
0159 longKey(false),
0160 modifiedSettings{} {}
0161
0162 GroupType::value type;
0163 FlowType::value flowType;
0164 std::size_t indent;
0165 std::size_t childCount;
0166 bool longKey;
0167
0168 SettingChanges modifiedSettings;
0169
0170 EmitterNodeType::value NodeType() const {
0171 if (type == GroupType::Seq) {
0172 if (flowType == FlowType::Flow)
0173 return EmitterNodeType::FlowSeq;
0174 else
0175 return EmitterNodeType::BlockSeq;
0176 } else {
0177 if (flowType == FlowType::Flow)
0178 return EmitterNodeType::FlowMap;
0179 else
0180 return EmitterNodeType::BlockMap;
0181 }
0182
0183
0184 assert(false);
0185 return EmitterNodeType::NoType;
0186 }
0187 };
0188
0189 std::vector<std::unique_ptr<Group>> m_groups;
0190 std::size_t m_curIndent;
0191 bool m_hasAnchor;
0192 bool m_hasAlias;
0193 bool m_hasTag;
0194 bool m_hasNonContent;
0195 std::size_t m_docCount;
0196 };
0197
0198 template <typename T>
0199 void EmitterState::_Set(Setting<T>& fmt, T value, FmtScope::value scope) {
0200 switch (scope) {
0201 case FmtScope::Local:
0202 m_modifiedSettings.push(fmt.set(value));
0203 break;
0204 case FmtScope::Global:
0205 fmt.set(value);
0206 m_globalModifiedSettings.push(
0207 fmt.set(value));
0208
0209 break;
0210 default:
0211 assert(false);
0212 }
0213 }
0214 }
0215
0216 #endif