| """ |
| pygments.lexers.make |
| ~~~~~~~~~~~~~~~~~~~~ |
| |
| Lexers for Makefiles and similar. |
| |
| :copyright: Copyright 2006-2023 by the Pygments team, see AUTHORS. |
| :license: BSD, see LICENSE for details. |
| """ |
| |
| import re |
| |
| from pygments.lexer import Lexer, RegexLexer, include, bygroups, \ |
| do_insertions, using |
| from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ |
| Punctuation, Whitespace |
| from pygments.lexers.shell import BashLexer |
| |
| __all__ = ['MakefileLexer', 'BaseMakefileLexer', 'CMakeLexer'] |
| |
| |
| class MakefileLexer(Lexer): |
| """ |
| Lexer for BSD and GNU make extensions (lenient enough to handle both in |
| the same file even). |
| |
| *Rewritten in Pygments 0.10.* |
| """ |
| |
| name = 'Makefile' |
| aliases = ['make', 'makefile', 'mf', 'bsdmake'] |
| filenames = ['*.mak', '*.mk', 'Makefile', 'makefile', 'Makefile.*', 'GNUmakefile'] |
| mimetypes = ['text/x-makefile'] |
| |
| r_special = re.compile( |
| r'^(?:' |
| # BSD Make |
| r'\.\s*(include|undef|error|warning|if|else|elif|endif|for|endfor)|' |
| # GNU Make |
| r'\s*(ifeq|ifneq|ifdef|ifndef|else|endif|-?include|define|endef|:|vpath)|' |
| # GNU Automake |
| r'\s*(if|else|endif))(?=\s)') |
| r_comment = re.compile(r'^\s*@?#') |
| |
| def get_tokens_unprocessed(self, text): |
| ins = [] |
| lines = text.splitlines(keepends=True) |
| done = '' |
| lex = BaseMakefileLexer(**self.options) |
| backslashflag = False |
| for line in lines: |
| if self.r_special.match(line) or backslashflag: |
| ins.append((len(done), [(0, Comment.Preproc, line)])) |
| backslashflag = line.strip().endswith('\\') |
| elif self.r_comment.match(line): |
| ins.append((len(done), [(0, Comment, line)])) |
| else: |
| done += line |
| yield from do_insertions(ins, lex.get_tokens_unprocessed(done)) |
| |
| def analyse_text(text): |
| # Many makefiles have $(BIG_CAPS) style variables |
| if re.search(r'\$\([A-Z_]+\)', text): |
| return 0.1 |
| |
| |
| class BaseMakefileLexer(RegexLexer): |
| """ |
| Lexer for simple Makefiles (no preprocessing). |
| |
| .. versionadded:: 0.10 |
| """ |
| |
| name = 'Base Makefile' |
| aliases = ['basemake'] |
| filenames = [] |
| mimetypes = [] |
| |
| tokens = { |
| 'root': [ |
| # recipes (need to allow spaces because of expandtabs) |
| (r'^(?:[\t ]+.*\n|\n)+', using(BashLexer)), |
| # special variables |
| (r'\$[<@$+%?|*]', Keyword), |
| (r'\s+', Whitespace), |
| (r'#.*?\n', Comment), |
| (r'((?:un)?export)(\s+)(?=[\w${}\t -]+\n)', |
| bygroups(Keyword, Whitespace), 'export'), |
| (r'(?:un)?export\s+', Keyword), |
| # assignment |
| (r'([\w${}().-]+)(\s*)([!?:+]?=)([ \t]*)((?:.*\\\n)+|.*\n)', |
| bygroups( |
| Name.Variable, Whitespace, Operator, Whitespace, |
| using(BashLexer))), |
| # strings |
| (r'"(\\\\|\\[^\\]|[^"\\])*"', String.Double), |
| (r"'(\\\\|\\[^\\]|[^'\\])*'", String.Single), |
| # targets |
| (r'([^\n:]+)(:+)([ \t]*)', bygroups( |
| Name.Function, Operator, Whitespace), |
| 'block-header'), |
| # expansions |
| (r'\$\(', Keyword, 'expansion'), |
| ], |
| 'expansion': [ |
| (r'[^\w$().-]+', Text), |
| (r'[\w.-]+', Name.Variable), |
| (r'\$', Keyword), |
| (r'\(', Keyword, '#push'), |
| (r'\)', Keyword, '#pop'), |
| ], |
| 'export': [ |
| (r'[\w${}-]+', Name.Variable), |
| (r'\n', Text, '#pop'), |
| (r'\s+', Whitespace), |
| ], |
| 'block-header': [ |
| (r'[,|]', Punctuation), |
| (r'#.*?\n', Comment, '#pop'), |
| (r'\\\n', Text), # line continuation |
| (r'\$\(', Keyword, 'expansion'), |
| (r'[a-zA-Z_]+', Name), |
| (r'\n', Whitespace, '#pop'), |
| (r'.', Text), |
| ], |
| } |
| |
| |
| class CMakeLexer(RegexLexer): |
| """ |
| Lexer for CMake files. |
| |
| .. versionadded:: 1.2 |
| """ |
| name = 'CMake' |
| url = 'https://cmake.org/documentation/' |
| aliases = ['cmake'] |
| filenames = ['*.cmake', 'CMakeLists.txt'] |
| mimetypes = ['text/x-cmake'] |
| |
| tokens = { |
| 'root': [ |
| # (r'(ADD_CUSTOM_COMMAND|ADD_CUSTOM_TARGET|ADD_DEFINITIONS|' |
| # r'ADD_DEPENDENCIES|ADD_EXECUTABLE|ADD_LIBRARY|ADD_SUBDIRECTORY|' |
| # r'ADD_TEST|AUX_SOURCE_DIRECTORY|BUILD_COMMAND|BUILD_NAME|' |
| # r'CMAKE_MINIMUM_REQUIRED|CONFIGURE_FILE|CREATE_TEST_SOURCELIST|' |
| # r'ELSE|ELSEIF|ENABLE_LANGUAGE|ENABLE_TESTING|ENDFOREACH|' |
| # r'ENDFUNCTION|ENDIF|ENDMACRO|ENDWHILE|EXEC_PROGRAM|' |
| # r'EXECUTE_PROCESS|EXPORT_LIBRARY_DEPENDENCIES|FILE|FIND_FILE|' |
| # r'FIND_LIBRARY|FIND_PACKAGE|FIND_PATH|FIND_PROGRAM|FLTK_WRAP_UI|' |
| # r'FOREACH|FUNCTION|GET_CMAKE_PROPERTY|GET_DIRECTORY_PROPERTY|' |
| # r'GET_FILENAME_COMPONENT|GET_SOURCE_FILE_PROPERTY|' |
| # r'GET_TARGET_PROPERTY|GET_TEST_PROPERTY|IF|INCLUDE|' |
| # r'INCLUDE_DIRECTORIES|INCLUDE_EXTERNAL_MSPROJECT|' |
| # r'INCLUDE_REGULAR_EXPRESSION|INSTALL|INSTALL_FILES|' |
| # r'INSTALL_PROGRAMS|INSTALL_TARGETS|LINK_DIRECTORIES|' |
| # r'LINK_LIBRARIES|LIST|LOAD_CACHE|LOAD_COMMAND|MACRO|' |
| # r'MAKE_DIRECTORY|MARK_AS_ADVANCED|MATH|MESSAGE|OPTION|' |
| # r'OUTPUT_REQUIRED_FILES|PROJECT|QT_WRAP_CPP|QT_WRAP_UI|REMOVE|' |
| # r'REMOVE_DEFINITIONS|SEPARATE_ARGUMENTS|SET|' |
| # r'SET_DIRECTORY_PROPERTIES|SET_SOURCE_FILES_PROPERTIES|' |
| # r'SET_TARGET_PROPERTIES|SET_TESTS_PROPERTIES|SITE_NAME|' |
| # r'SOURCE_GROUP|STRING|SUBDIR_DEPENDS|SUBDIRS|' |
| # r'TARGET_LINK_LIBRARIES|TRY_COMPILE|TRY_RUN|UNSET|' |
| # r'USE_MANGLED_MESA|UTILITY_SOURCE|VARIABLE_REQUIRES|' |
| # r'VTK_MAKE_INSTANTIATOR|VTK_WRAP_JAVA|VTK_WRAP_PYTHON|' |
| # r'VTK_WRAP_TCL|WHILE|WRITE_FILE|' |
| # r'COUNTARGS)\b', Name.Builtin, 'args'), |
| (r'\b(\w+)([ \t]*)(\()', bygroups(Name.Builtin, Whitespace, |
| Punctuation), 'args'), |
| include('keywords'), |
| include('ws') |
| ], |
| 'args': [ |
| (r'\(', Punctuation, '#push'), |
| (r'\)', Punctuation, '#pop'), |
| (r'(\$\{)(.+?)(\})', bygroups(Operator, Name.Variable, Operator)), |
| (r'(\$ENV\{)(.+?)(\})', bygroups(Operator, Name.Variable, Operator)), |
| (r'(\$<)(.+?)(>)', bygroups(Operator, Name.Variable, Operator)), |
| (r'(?s)".*?"', String.Double), |
| (r'\\\S+', String), |
| (r'[^)$"# \t\n]+', String), |
| (r'\n', Whitespace), # explicitly legal |
| include('keywords'), |
| include('ws') |
| ], |
| 'string': [ |
| |
| ], |
| 'keywords': [ |
| (r'\b(WIN32|UNIX|APPLE|CYGWIN|BORLAND|MINGW|MSVC|MSVC_IDE|MSVC60|' |
| r'MSVC70|MSVC71|MSVC80|MSVC90)\b', Keyword), |
| ], |
| 'ws': [ |
| (r'[ \t]+', Whitespace), |
| (r'#\[(?P<level>=*)\[[\w\W]*?\](?P=level)\]', Comment), |
| (r'#.*\n', Comment), |
| ] |
| } |
| |
| def analyse_text(text): |
| exp = ( |
| r'^[ \t]*CMAKE_MINIMUM_REQUIRED[ \t]*' |
| r'\([ \t]*VERSION[ \t]*\d+(\.\d+)*[ \t]*' |
| r'([ \t]FATAL_ERROR)?[ \t]*\)[ \t]*' |
| r'(#[^\n]*)?$' |
| ) |
| if re.search(exp, text, flags=re.MULTILINE | re.IGNORECASE): |
| return 0.8 |
| return 0.0 |