The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

173 lines
4.5KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2020 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 6 End-User License
  8. Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
  9. End User License Agreement: www.juce.com/juce-6-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. XmlTokeniser::XmlTokeniser() {}
  21. XmlTokeniser::~XmlTokeniser() {}
  22. CodeEditorComponent::ColourScheme XmlTokeniser::getDefaultColourScheme()
  23. {
  24. struct Type
  25. {
  26. const char* name;
  27. uint32 colour;
  28. };
  29. const Type types[] =
  30. {
  31. { "Error", 0xffcc0000 },
  32. { "Comment", 0xff00aa00 },
  33. { "Keyword", 0xff0000cc },
  34. { "Operator", 0xff225500 },
  35. { "Identifier", 0xff000000 },
  36. { "String", 0xff990099 },
  37. { "Bracket", 0xff000055 },
  38. { "Punctuation", 0xff004400 },
  39. { "Preprocessor Text", 0xff660000 }
  40. };
  41. CodeEditorComponent::ColourScheme cs;
  42. for (auto& t : types)
  43. cs.set (t.name, Colour (t.colour));
  44. return cs;
  45. }
  46. template <typename Iterator>
  47. static void skipToEndOfXmlDTD (Iterator& source) noexcept
  48. {
  49. bool lastWasQuestionMark = false;
  50. for (;;)
  51. {
  52. auto c = source.nextChar();
  53. if (c == 0 || (c == '>' && lastWasQuestionMark))
  54. break;
  55. lastWasQuestionMark = (c == '?');
  56. }
  57. }
  58. template <typename Iterator>
  59. static void skipToEndOfXmlComment (Iterator& source) noexcept
  60. {
  61. juce_wchar last[2] = {};
  62. for (;;)
  63. {
  64. auto c = source.nextChar();
  65. if (c == 0 || (c == '>' && last[0] == '-' && last[1] == '-'))
  66. break;
  67. last[1] = last[0];
  68. last[0] = c;
  69. }
  70. }
  71. int XmlTokeniser::readNextToken (CodeDocument::Iterator& source)
  72. {
  73. source.skipWhitespace();
  74. auto firstChar = source.peekNextChar();
  75. switch (firstChar)
  76. {
  77. case 0: break;
  78. case '"':
  79. case '\'':
  80. CppTokeniserFunctions::skipQuotedString (source);
  81. return tokenType_string;
  82. case '<':
  83. {
  84. source.skip();
  85. source.skipWhitespace();
  86. auto nextChar = source.peekNextChar();
  87. if (nextChar == '?')
  88. {
  89. source.skip();
  90. skipToEndOfXmlDTD (source);
  91. return tokenType_preprocessor;
  92. }
  93. if (nextChar == '!')
  94. {
  95. source.skip();
  96. if (source.peekNextChar() == '-')
  97. {
  98. source.skip();
  99. if (source.peekNextChar() == '-')
  100. {
  101. skipToEndOfXmlComment (source);
  102. return tokenType_comment;
  103. }
  104. }
  105. }
  106. CppTokeniserFunctions::skipIfNextCharMatches (source, '/');
  107. CppTokeniserFunctions::parseIdentifier (source);
  108. source.skipWhitespace();
  109. CppTokeniserFunctions::skipIfNextCharMatches (source, '/');
  110. source.skipWhitespace();
  111. CppTokeniserFunctions::skipIfNextCharMatches (source, '>');
  112. return tokenType_keyword;
  113. }
  114. case '>':
  115. source.skip();
  116. return tokenType_keyword;
  117. case '/':
  118. source.skip();
  119. source.skipWhitespace();
  120. CppTokeniserFunctions::skipIfNextCharMatches (source, '>');
  121. return tokenType_keyword;
  122. case '=':
  123. case ':':
  124. source.skip();
  125. return tokenType_operator;
  126. default:
  127. if (CppTokeniserFunctions::isIdentifierStart (firstChar))
  128. CppTokeniserFunctions::parseIdentifier (source);
  129. source.skip();
  130. break;
  131. };
  132. return tokenType_identifier;
  133. }
  134. } // namespace juce