bitbake.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. """
  2. pygments.lexers.bitbake
  3. ~~~~~~~~~~~~~~~~~~~~~~~
  4. Lexer for BitBake recipes, classes, includes and configuration files
  5. used by the Yocto Project / OpenEmbedded build system.
  6. :copyright: Copyright 2006-present by the Pygments team, see AUTHORS.
  7. :license: BSD, see LICENSE for details.
  8. """
  9. import re
  10. from pygments.lexer import RegexLexer, bygroups, include, using, words
  11. from pygments.lexers.python import PythonLexer
  12. from pygments.lexers.shell import BashLexer
  13. from pygments.token import Comment, Keyword, Name, Operator, Punctuation, \
  14. String, Text, Whitespace
  15. __all__ = ['BitBakeLexer']
  16. # A bare BitBake identifier (variable, function or flag name). Allows the
  17. # characters used by OE-Core variable names (digits, ``-``, ``.``, ``+``).
  18. _IDENT = r'[A-Za-z_][A-Za-z0-9_\-.+]*'
  19. # Optional OE override chain such as ``:append``, ``:remove``, ``:class-target``
  20. # or ``:${PN}-doc``. Anchored so it only consumes ``:foo`` runs and never
  21. # eats the leading ``:`` of the ``:=`` assignment operator.
  22. _OVERRIDE = r'(?::[A-Za-z0-9_\-.+${}]+)*'
  23. # All BitBake variable assignment operators, ordered so that the longer
  24. # operators win the regex alternation.
  25. _ASSIGN = r'(?:\?\?=|\?=|:=|\+=|=\+|\.=|=\.|=)'
  26. class BitBakeLexer(RegexLexer):
  27. """
  28. Lexer for BitBake recipes, classes, includes and configuration files
  29. used by the Yocto Project and OpenEmbedded build system.
  30. """
  31. name = 'BitBake'
  32. url = 'https://docs.yoctoproject.org/bitbake/'
  33. aliases = ['bitbake']
  34. filenames = ['*.bbclass', '*.bbappend']
  35. mimetypes = ['text/x-bitbake']
  36. version_added = '2.21'
  37. flags = re.MULTILINE
  38. tokens = {
  39. 'root': [
  40. (r'[ \t]+', Whitespace),
  41. (r'\n', Whitespace),
  42. (r'#.*$', Comment.Single),
  43. # ``python [name]() { ... }`` blocks (also ``fakeroot python``).
  44. # Must be tried before the generic shell function rule so the
  45. # ``python`` keyword is not mistaken for a shell function name.
  46. (r'(^(?:fakeroot[ \t]+)?)(python)((?:[ \t]+' + _IDENT + r')?)'
  47. r'([ \t]*\([ \t]*\)[ \t]*)(\{[ \t]*\n)'
  48. r'((?:.*\n)*?)'
  49. r'(^\}[ \t]*$)',
  50. bygroups(Keyword.Type, Keyword, Name.Function, Text,
  51. Punctuation, using(PythonLexer), Punctuation)),
  52. # Shell task bodies: ``[fakeroot ]name[:override]() { ... }``.
  53. (r'(^(?:fakeroot[ \t]+)?)(' + _IDENT + r')(' + _OVERRIDE + r')'
  54. r'([ \t]*\([ \t]*\)[ \t]*)(\{[ \t]*\n)'
  55. r'((?:.*\n)*?)'
  56. r'(^\}[ \t]*$)',
  57. bygroups(Keyword.Type, Name.Function, Name.Decorator, Text,
  58. Punctuation, using(BashLexer), Punctuation)),
  59. # Top-level python ``def`` blocks; the body is any run of
  60. # indented or blank lines following the signature.
  61. (r'^def[ \t]+' + _IDENT + r'[ \t]*\([^)]*\)[ \t]*:[ \t]*\n'
  62. r'(?:[ \t]+.*\n|\n)+',
  63. using(PythonLexer)),
  64. # ``inherit`` / ``inherit_defer`` / ``include`` / ``include_all`` /
  65. # ``require`` directives. Longer keywords are listed first so the
  66. # regex alternation does not match the shorter prefix.
  67. (r'^(inherit_defer|inherit|include_all|include|require)\b',
  68. Keyword.Namespace, 'include-line'),
  69. # ``addtask`` / ``deltask`` / ``addhandler`` / ``EXPORT_FUNCTIONS``.
  70. (r'^(addtask|deltask|addhandler|EXPORT_FUNCTIONS)\b',
  71. Keyword, 'statement'),
  72. # ``VAR[flag] = "value"`` (varflag assignment).
  73. (r'^(' + _IDENT + r')(\[)(' + _IDENT + r')(\])([ \t]*)('
  74. + _ASSIGN + r')',
  75. bygroups(Name.Variable, Punctuation, Name.Attribute,
  76. Punctuation, Whitespace, Operator),
  77. 'value'),
  78. # ``[export ]VAR[:override...] OP "value"`` assignments.
  79. (r'^(export[ \t]+)?(' + _IDENT + r')(' + _OVERRIDE + r')'
  80. r'([ \t]*)(' + _ASSIGN + r')',
  81. bygroups(Keyword.Type, Name.Variable, Name.Decorator,
  82. Whitespace, Operator),
  83. 'value'),
  84. # Anything else: consume runs of "boring" characters in one
  85. # token, then fall back to a single character if needed.
  86. (r'[^\s#${}\[\]:=+?.@\\"\']+', Text),
  87. (r'.', Text),
  88. ],
  89. 'include-line': [
  90. (r'[ \t]+', Whitespace),
  91. (r'\\\n', Text),
  92. (r'\n', Whitespace, '#pop'),
  93. include('interp'),
  94. (r'[^\s$]+', String),
  95. ],
  96. 'statement': [
  97. (r'[ \t]+', Whitespace),
  98. (r'\\\n', Text),
  99. (r'\n', Whitespace, '#pop'),
  100. (words(('after', 'before'), suffix=r'\b'), Keyword),
  101. include('interp'),
  102. (r'[^\s$\\]+', Name),
  103. ],
  104. 'value': [
  105. (r'[ \t]+', Whitespace),
  106. (r'\\\n', String.Escape),
  107. (r'\n', Whitespace, '#pop'),
  108. (r'"', String.Double, 'string-double'),
  109. (r"'", String.Single, 'string-single'),
  110. include('interp'),
  111. (r'[^\s"\'$\\]+', String),
  112. ],
  113. 'string-double': [
  114. (r'\\\n', String.Escape),
  115. (r'\\.', String.Escape),
  116. (r'"', String.Double, '#pop'),
  117. include('interp'),
  118. (r'[^"\\$]+', String.Double),
  119. ],
  120. 'string-single': [
  121. (r'\\\n', String.Escape),
  122. (r'\\.', String.Escape),
  123. (r"'", String.Single, '#pop'),
  124. include('interp'),
  125. (r"[^'\\$]+", String.Single),
  126. ],
  127. 'interp': [
  128. # ``${@ python expression }`` evaluated by BitBake at parse time.
  129. (r'\$\{@', String.Interpol, 'py-interp'),
  130. # ``${VAR}`` variable expansion.
  131. (r'(\$\{)([A-Za-z0-9_\-:.+/]+)(\})',
  132. bygroups(String.Interpol, Name.Variable, String.Interpol)),
  133. ],
  134. 'py-interp': [
  135. (r'\}', String.Interpol, '#pop'),
  136. (r'[^}]+', using(PythonLexer)),
  137. ],
  138. }