RegexExplorer.cxx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "RegexExplorer.h"
  4. RegexExplorer::RegexExplorer(QWidget* p)
  5. : QDialog(p)
  6. , m_matched(false)
  7. {
  8. this->setupUi(this);
  9. for (int i = 1; i < cmsys::RegularExpressionMatch::NSUBEXP; ++i) {
  10. matchNumber->addItem(QString("Match %1").arg(QString::number(i)),
  11. QVariant(i));
  12. }
  13. matchNumber->setCurrentIndex(0);
  14. }
  15. void RegexExplorer::setStatusColor(QWidget* widget, bool successful)
  16. {
  17. QColor color = successful ? QColor(0, 127, 0) : Qt::red;
  18. QPalette palette = widget->palette();
  19. palette.setColor(QPalette::Foreground, color);
  20. widget->setPalette(palette);
  21. }
  22. void RegexExplorer::on_regularExpression_textChanged(const QString& text)
  23. {
  24. #ifdef QT_NO_STL
  25. m_regex = text.toAscii().constData();
  26. #else
  27. m_regex = text.toStdString();
  28. #endif
  29. bool validExpression =
  30. stripEscapes(m_regex) && m_regexParser.compile(m_regex);
  31. if (!validExpression) {
  32. m_regexParser.set_invalid();
  33. }
  34. setStatusColor(labelRegexValid, validExpression);
  35. on_inputText_textChanged();
  36. }
  37. void RegexExplorer::on_inputText_textChanged()
  38. {
  39. if (m_regexParser.is_valid()) {
  40. QString plainText = inputText->toPlainText();
  41. #ifdef QT_NO_STL
  42. m_text = plainText.toAscii().constData();
  43. #else
  44. m_text = plainText.toStdString();
  45. #endif
  46. m_matched = m_regexParser.find(m_text);
  47. } else {
  48. m_matched = false;
  49. }
  50. setStatusColor(labelRegexMatch, m_matched);
  51. if (!m_matched) {
  52. clearMatch();
  53. return;
  54. }
  55. std::string matchingText;
  56. if (matchAll->isChecked()) {
  57. const char* p = m_text.c_str();
  58. while (m_regexParser.find(p)) {
  59. std::string::size_type l = m_regexParser.start();
  60. std::string::size_type r = m_regexParser.end();
  61. if (r - l == 0) {
  62. // matched empty string
  63. clearMatch();
  64. return;
  65. }
  66. if (!matchingText.empty()) {
  67. matchingText += ";";
  68. }
  69. matchingText += std::string(p + l, r - l);
  70. p += r;
  71. }
  72. } else {
  73. matchingText = m_regexParser.match(0);
  74. }
  75. #ifdef QT_NO_STL
  76. QString matchText = matchingText.c_str();
  77. #else
  78. QString matchText = QString::fromStdString(matchingText);
  79. #endif
  80. match0->setPlainText(matchText);
  81. on_matchNumber_currentIndexChanged(matchNumber->currentIndex());
  82. }
  83. void RegexExplorer::on_matchNumber_currentIndexChanged(int index)
  84. {
  85. if (!m_matched) {
  86. return;
  87. }
  88. QVariant itemData = matchNumber->itemData(index);
  89. int idx = itemData.toInt();
  90. if (idx < 1 || idx >= cmsys::RegularExpressionMatch::NSUBEXP) {
  91. return;
  92. }
  93. #ifdef QT_NO_STL
  94. QString match = m_regexParser.match(idx).c_str();
  95. #else
  96. QString match = QString::fromStdString(m_regexParser.match(idx));
  97. #endif
  98. matchN->setPlainText(match);
  99. }
  100. void RegexExplorer::on_matchAll_toggled(bool checked)
  101. {
  102. Q_UNUSED(checked);
  103. on_inputText_textChanged();
  104. }
  105. void RegexExplorer::clearMatch()
  106. {
  107. m_matched = false;
  108. match0->clear();
  109. matchN->clear();
  110. }
  111. bool RegexExplorer::stripEscapes(std::string& source)
  112. {
  113. const char* in = source.c_str();
  114. std::string result;
  115. result.reserve(source.size());
  116. for (char inc = *in; inc != '\0'; inc = *++in) {
  117. if (inc == '\\') {
  118. char nextc = in[1];
  119. if (nextc == 't') {
  120. result.append(1, '\t');
  121. in++;
  122. } else if (nextc == 'n') {
  123. result.append(1, '\n');
  124. in++;
  125. } else if (nextc == 't') {
  126. result.append(1, '\t');
  127. in++;
  128. } else if (isalnum(nextc) || nextc == '\0') {
  129. return false;
  130. } else {
  131. result.append(1, nextc);
  132. in++;
  133. }
  134. } else {
  135. result.append(1, inc);
  136. }
  137. }
  138. source = result;
  139. return true;
  140. }