File: make.rb

package info (click to toggle)
ruby-rouge 4.7.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,844 kB
  • sloc: ruby: 38,489; sed: 2,071; perl: 152; makefile: 8
file content (148 lines) | stat: -rw-r--r-- 4,106 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# -*- coding: utf-8 -*- #
# frozen_string_literal: true

module Rouge
  module Lexers
    class Make < RegexLexer
      title "Make"
      desc "Makefile syntax"
      tag 'make'
      aliases 'makefile', 'mf', 'gnumake', 'bsdmake'
      filenames '*.make', '*.mak', '*.mk', 'Makefile', 'makefile', 'Makefile.*', 'GNUmakefile', '*,fe1'
      mimetypes 'text/x-makefile'

      def self.functions
        @functions ||= %w(
          abspath addprefix addsuffix and basename call dir error eval file
          filter filter-out findstring firstword flavor foreach if join lastword
          notdir or origin patsubst realpath shell sort strip subst suffix value
          warning wildcard word wordlist words
        )
      end

      def initialize(opts={})
        super
        @shell = Shell.new(opts)
      end

      start { @shell.reset! }

      state :root do
        rule %r/\s+/, Text

        rule %r/#.*?\n/, Comment

        rule %r/([-s]?include)((?:[\t ]+[^\t\n #]+)+)/ do
          groups Keyword, Literal::String::Other
        end

        rule %r/((?:ifn?def|ifn?eq|unexport)\b)([\t ]+)([^#\n]+)/ do
          groups Keyword, Text, Name::Variable
        end

        rule %r/(else\b)([\t ]+)((?:ifn?def|ifn?eq)\b)([\t ]+)([^#\n]+)/ do
          groups Keyword, Text, Keyword, Text, Name::Variable
        end

        rule %r/(?:else|endif|endef|endfor)[\t ]*(?=[#\n])/, Keyword

        rule %r/(export)([\t ]+)(?=[\w\${}()\t -]+\n)/ do
          groups Keyword, Text
          push :export
        end

        rule %r/export[\t ]+/, Keyword

        # assignment
        rule %r/(override\b)*([\t ]*)([\w${}().-]+)([\t ]*)([!?:+]?=)/m do |m|
          groups Name::Builtin, Text, Name::Variable, Text, Operator
          push :shell_line
        end

        rule %r/"(\\\\|\\.|[^"\\])*"/, Str::Double
        rule %r/'(\\\\|\\.|[^'\\])*'/, Str::Single
        rule %r/([^\n:]+)(:+)([ \t]*)/ do
          groups Name::Label, Operator, Text
          push :block_header
        end

        rule %r/(override\b)*([\t ])*(define)([\t ]+)([^#\n]+)/ do
          groups Name::Builtin, Text, Keyword, Text, Name::Variable
        end

        rule %r/(\$[({])([\t ]*)(#{Make.functions.join('|')})([\t ]+)/m do
          groups Name::Function, Text, Name::Builtin, Text
          push :shell_expr
        end
      end

      state :export do
        rule %r/[\w\${}()-]/, Name::Variable
        rule %r/\n/, Text, :pop!
        rule %r/[\t ]+/, Text
      end

      state :block_header do
        rule %r/[^,\\\n#]+/, Name::Function
        rule %r/,/, Punctuation
        rule %r/#.*?/, Comment
        rule %r/\\\n/, Text
        rule %r/\\./, Text
        rule %r/\n/ do
          token Text
          goto :block_body
        end
      end

      state :block_body do
        rule %r/(ifn?def|ifn?eq)([\t ]+)([^#\n]+)(#.*)?(\n)/ do
          groups Keyword, Text, Name::Variable, Comment, Text
        end

        rule %r/(else|endif)([\t ]*)(#.*)?(\n)/ do
          groups Keyword, Text, Comment, Text
        end

        rule %r/(\t[\t ]*)([@-]?)/ do
          groups Text, Punctuation
          push :shell_line
        end

        rule(//) { @shell.reset!; pop! }
      end

      state :shell do
        # macro interpolation
        rule %r/[\$]{1,2}[({]/, Punctuation, :macro_expr

        # function invocation
        rule %r/(\$[({])([\t ]*)(#{Make.functions.join('|')})([\t ]+)/m do
          groups Punctuation, Text, Name::Builtin, Text
          push :shell_expr
        end

        rule(/\\./m) { delegate @shell }
        stop = /[\$]{1,2}\(|[\$]{1,2}\{|\(|\)|\}|\\|$/
        rule(/.+?(?=#{stop})/m) { delegate @shell }
        rule(stop) { delegate @shell }
      end

      state :macro_expr do
        rule %r/[)}]/, Punctuation, :pop!
        rule %r/\n/, Text, :pop!
        mixin :shell
      end

      state :shell_expr do
        rule(/[({]/) { delegate @shell; push }
        rule %r/[)}]/, Punctuation, :pop!
        mixin :shell
      end

      state :shell_line do
        rule %r/\n/, Text, :pop!
        mixin :shell
      end
    end
  end
end