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.

174 lines
4.5KB

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