File indexing completed on 2024-05-12 15:50:06

0001 /*
0002     SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org>
0003     SPDX-FileCopyrightText: 2018 Christoph Cullmann <cullmann@kde.org>
0004 
0005     SPDX-License-Identifier: MIT
0006 */
0007 
0008 #include "state.h"
0009 #include "state_p.h"
0010 
0011 #include "context_p.h"
0012 
0013 #include <QStringList>
0014 
0015 using namespace KSyntaxHighlighting;
0016 
0017 StateData *StateData::get(State &state)
0018 {
0019     // create state data on demand, to make default state construction cheap
0020     if (!state.d) {
0021         state.d = new StateData();
0022     } else {
0023         state.d.detach();
0024     }
0025     return state.d.data();
0026 }
0027 
0028 bool StateData::isEmpty() const
0029 {
0030     return m_contextStack.isEmpty();
0031 }
0032 
0033 void StateData::clear()
0034 {
0035     m_contextStack.clear();
0036 }
0037 
0038 int StateData::size() const
0039 {
0040     return m_contextStack.size();
0041 }
0042 
0043 void StateData::push(Context *context, const QStringList &captures)
0044 {
0045     Q_ASSERT(context);
0046     m_contextStack.push_back(qMakePair(context, captures));
0047 }
0048 
0049 bool StateData::pop(int popCount)
0050 {
0051     // nop if nothing to pop
0052     if (popCount <= 0) {
0053         return true;
0054     }
0055 
0056     // keep the initial context alive in any case
0057     Q_ASSERT(!isEmpty());
0058     const bool initialContextSurvived = m_contextStack.size() > popCount;
0059     m_contextStack.resize(std::max(1, int(m_contextStack.size()) - popCount));
0060     return initialContextSurvived;
0061 }
0062 
0063 Context *StateData::topContext() const
0064 {
0065     Q_ASSERT(!isEmpty());
0066     return m_contextStack.last().first;
0067 }
0068 
0069 const QStringList &StateData::topCaptures() const
0070 {
0071     Q_ASSERT(!isEmpty());
0072     return m_contextStack.last().second;
0073 }
0074 
0075 State::State()
0076 {
0077 }
0078 
0079 State::State(const State &other)
0080     : d(other.d)
0081 {
0082 }
0083 
0084 State::~State()
0085 {
0086 }
0087 
0088 State &State::operator=(const State &other)
0089 {
0090     d = other.d;
0091     return *this;
0092 }
0093 
0094 bool State::operator==(const State &other) const
0095 {
0096     // use pointer equal as shortcut for shared states
0097     return (d == other.d) || (d && other.d && d->m_contextStack == other.d->m_contextStack && d->m_defId == other.d->m_defId);
0098 }
0099 
0100 bool State::operator!=(const State &other) const
0101 {
0102     return !(*this == other);
0103 }
0104 
0105 bool State::indentationBasedFoldingEnabled() const
0106 {
0107     if (!d || d->m_contextStack.isEmpty()) {
0108         return false;
0109     }
0110     return d->m_contextStack.last().first->indentationBasedFoldingEnabled();
0111 }