text: /*============================================================================
    CMake - Cross Platform Makefile Generator
    Copyright 2015 Kitware, Inc., Gregor Jasny
  
    Distributed under the OSI-approved BSD License (the "License");
    see accompanying file Copyright.txt for details.
  
    This software is distributed WITHOUT ANY WARRANTY; without even the
    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    See the License for more information.
  ============================================================================*/
  
  #include "RegexExplorer.h"
  
  RegexExplorer::RegexExplorer(QWidget* p)
    : QDialog(p)
    , m_matched(false)
  {
    this->setupUi(this);
  
    for (int i = 1; i < cmsys::RegularExpression::NSUBEXP; ++i) {
      matchNumber->addItem(QString("Match %1").arg(QString::number(i)),
                           QVariant(i));
    }
    matchNumber->setCurrentIndex(0);
  }
  
  void RegexExplorer::setStatusColor(QWidget* widget, bool successful)
  {
    QColor color = successful ? QColor(0, 127, 0) : Qt::red;
  
    QPalette palette = widget->palette();
    palette.setColor(QPalette::Foreground, color);
    widget->setPalette(palette);
  }
  
  void RegexExplorer::on_regularExpression_textChanged(const QString& text)
  {
  #ifdef QT_NO_STL
    m_regex = text.toAscii().constData();
  #else
    m_regex = text.toStdString();
  #endif
  
    bool validExpression =
      stripEscapes(m_regex) && m_regexParser.compile(m_regex);
    if (!validExpression) {
      m_regexParser.set_invalid();
    }
  
    setStatusColor(labelRegexValid, validExpression);
  
    on_inputText_textChanged();
  }
  
  void RegexExplorer::on_inputText_textChanged()
  {
    if (m_regexParser.is_valid()) {
      QString plainText = inputText->toPlainText();
  #ifdef QT_NO_STL
      m_text = plainText.toAscii().constData();
  #else
      m_text = plainText.toStdString();
  #endif
      m_matched = m_regexParser.find(m_text);
    } else {
      m_matched = false;
    }
  
    setStatusColor(labelRegexMatch, m_matched);
  
    if (!m_matched) {
      clearMatch();
      return;
    }
  
  #ifdef QT_NO_STL
    QString matchText = m_regexParser.match(0).c_str();
  #else
    QString matchText = QString::fromStdString(m_regexParser.match(0));
  #endif
    match0->setPlainText(matchText);
  
    on_matchNumber_currentIndexChanged(matchNumber->currentIndex());
  }
  
  void RegexExplorer::on_matchNumber_currentIndexChanged(int index)
  {
    if (!m_matched) {
      return;
    }
  
    QVariant itemData = matchNumber->itemData(index);
    int idx = itemData.toInt();
  
    if (idx < 1 || idx >= cmsys::RegularExpression::NSUBEXP) {
      return;
    }
  
  #ifdef QT_NO_STL
    QString match = m_regexParser.match(idx).c_str();
  #else
    QString match = QString::fromStdString(m_regexParser.match(idx));
  #endif
    matchN->setPlainText(match);
  }
  
  void RegexExplorer::clearMatch()
  {
    match0->clear();
    matchN->clear();
  }
  
  bool RegexExplorer::stripEscapes(std::string& source)
  {
    const char* in = source.c_str();
  
    std::string result;
    result.reserve(source.size());
  
    for (char inc = *in; inc != '\0'; inc = *++in) {
      if (inc == '\\') {
        char nextc = in[1];
        if (nextc == 't') {
          result.append(1, '\t');
          in++;
        } else if (nextc == 'n') {
          result.append(1, '\n');
          in++;
        } else if (nextc == 't') {
          result.append(1, '\t');
          in++;
        } else if (isalnum(nextc) || nextc == '\0') {
          return false;
        } else {
          result.append(1, nextc);
          in++;
        }
      } else {
        result.append(1, inc);
      }
    }
  
    source = result;
    return true;
  }
  