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.

167 lines
4.7KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. XmlTokeniser::XmlTokeniser() {}
  18. XmlTokeniser::~XmlTokeniser() {}
  19. CodeEditorComponent::ColourScheme XmlTokeniser::getDefaultColourScheme()
  20. {
  21. struct Type
  22. {
  23. const char* name;
  24. uint32 colour;
  25. };
  26. const Type types[] =
  27. {
  28. { "Error", 0xffcc0000 },
  29. { "Comment", 0xff00aa00 },
  30. { "Keyword", 0xff0000cc },
  31. { "Operator", 0xff225500 },
  32. { "Identifier", 0xff000000 },
  33. { "String", 0xff990099 },
  34. { "Bracket", 0xff000055 },
  35. { "Punctuation", 0xff004400 },
  36. { "Preprocessor Text", 0xff660000 }
  37. };
  38. CodeEditorComponent::ColourScheme cs;
  39. for (unsigned int i = 0; i < sizeof (types) / sizeof (types[0]); ++i) // (NB: numElementsInArray doesn't work here in GCC4.2)
  40. cs.set (types[i].name, Colour (types[i].colour));
  41. return cs;
  42. };
  43. template <typename Iterator>
  44. static void skipToEndOfXmlDTD (Iterator& source) noexcept
  45. {
  46. bool lastWasQuestionMark = false;
  47. for (;;)
  48. {
  49. const juce_wchar c = source.nextChar();
  50. if (c == 0 || (c == '>' && lastWasQuestionMark))
  51. break;
  52. lastWasQuestionMark = (c == '?');
  53. }
  54. }
  55. template <typename Iterator>
  56. static void skipToEndOfXmlComment (Iterator& source) noexcept
  57. {
  58. juce_wchar last[2] = { 0 };
  59. for (;;)
  60. {
  61. const juce_wchar c = source.nextChar();
  62. if (c == 0 || (c == '>' && last[0] == '-' && last[1] == '-'))
  63. break;
  64. last[1] = last[0];
  65. last[0] = c;
  66. }
  67. }
  68. int XmlTokeniser::readNextToken (CodeDocument::Iterator& source)
  69. {
  70. source.skipWhitespace();
  71. const juce_wchar firstChar = source.peekNextChar();
  72. switch (firstChar)
  73. {
  74. case 0: break;
  75. case '"':
  76. case '\'':
  77. CppTokeniserFunctions::skipQuotedString (source);
  78. return tokenType_string;
  79. case '<':
  80. {
  81. source.skip();
  82. source.skipWhitespace();
  83. const juce_wchar nextChar = source.peekNextChar();
  84. if (nextChar == '?')
  85. {
  86. source.skip();
  87. skipToEndOfXmlDTD (source);
  88. return tokenType_preprocessor;
  89. }
  90. if (nextChar == '!')
  91. {
  92. source.skip();
  93. if (source.peekNextChar() == '-')
  94. {
  95. source.skip();
  96. if (source.peekNextChar() == '-')
  97. {
  98. skipToEndOfXmlComment (source);
  99. return tokenType_comment;
  100. }
  101. }
  102. }
  103. CppTokeniserFunctions::skipIfNextCharMatches (source, '/');
  104. CppTokeniserFunctions::parseIdentifier (source);
  105. source.skipWhitespace();
  106. CppTokeniserFunctions::skipIfNextCharMatches (source, '/');
  107. source.skipWhitespace();
  108. CppTokeniserFunctions::skipIfNextCharMatches (source, '>');
  109. return tokenType_keyword;
  110. }
  111. case '>':
  112. source.skip();
  113. return tokenType_keyword;
  114. case '/':
  115. source.skip();
  116. source.skipWhitespace();
  117. CppTokeniserFunctions::skipIfNextCharMatches (source, '>');
  118. return tokenType_keyword;
  119. case '=':
  120. case ':':
  121. source.skip();
  122. return tokenType_operator;
  123. default:
  124. if (CppTokeniserFunctions::isIdentifierStart (firstChar))
  125. CppTokeniserFunctions::parseIdentifier (source);
  126. source.skip();
  127. break;
  128. };
  129. return tokenType_identifier;
  130. }