summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/rouge-4.5.2/lib/rouge/lexers/varnish.rb
blob: 07c0c67085b690fdf2c1ebb0abf80d50646bf454 (plain)
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# -*- coding: utf-8 -*- #
# frozen_string_literal: true

module Rouge
  module Lexers
    class Varnish < RegexLexer
      title 'VCL: Varnish Configuration Language'
      desc 'The configuration language for Varnish HTTP Cache (varnish-cache.org)'

      tag 'vcl'
      aliases 'varnishconf', 'varnish'
      filenames '*.vcl'
      mimetypes 'text/x-varnish', 'text/x-vcl'

      SPACE = '[ \f\n\r\t\v]+'

      # backend acl
      def self.keywords
        @keywords ||= Set.new %w[
          vcl set unset include import if else elseif elif elsif director probe
          backend acl

          declare local
          BOOL FLOAT INTEGER IP RTIME STRING TIME
        ]
      end

      def self.functions
        @functions ||= Set.new %w[
          ban call hash_data new regsub regsuball return rollback
          std.cache_req_body std.collect std.duration std.fileread std.healthy
          std.integer std.ip std.log std.port std.querysort std.random std.real
          std.real2time std.rollback std.set_ip_tos std.strstr std.syslog
          std.time std.time2integer std.time2real std.timestamp std.tolower
          std.toupper synth synthetic
        ]
      end

      def self.variables
        @variables ||= Set.new %w[
          bereq bereq.backend bereq.between_bytes_timeout bereq.connect_timeout
          bereq.first_byte_timeout bereq.method bereq.proto bereq.retries
          bereq.uncacheable bereq.url bereq.xid beresp beresp.age
          beresp.backend beresp.backend.ip beresp.backend.name beresp.do_esi
          beresp.do_gunzip beresp.do_gzip beresp.do_stream beresp.grace
          beresp.keep beresp.proto beresp.reason beresp.status
          beresp.storage_hint beresp.ttl beresp.uncacheable beresp.was_304
          client.identity client.ip local.ip now obj.age obj.grace obj.hits
          obj.keep obj.proto obj.reason obj.status obj.ttl obj.uncacheable
          remote.ip req req.backend_hint req.can_gzip req.esi req.esi_level
          req.hash_always_miss req.hash_ignore_busy req.method req.proto
          req.restarts req.ttl req.url req.xid resp resp.proto resp.reason
          resp.status server.hostname server.identity server.ip
        ]
      end

      # This is never used
      # def self.routines
      #   @routines ||= Set.new %w[
      #     backend_error backend_fetch backend_response purge deliver fini hash
      #     hit init miss pass pipe recv synth
      #   ]
      # end

      state :root do
        # long strings ({" ... "})
        rule %r/\{".*?"}/m, Str::Single

        # heredoc style long strings ({xyz"..."xyz})
        rule %r/\{(\w+)".*?"(\1)\}/m, Str::Single

        # comments
        rule %r'/\*.*?\*/'m, Comment::Multiline
        rule %r'(?://|#).*', Comment::Single

        rule %r/true|false/, Keyword::Constant

        # "wildcard variables"
        var_prefix = Regexp.union(%w(beresp bereq resp req obj))
        rule %r/(?:#{var_prefix})\.http\.[\w.-]+/ do
          token Name::Variable
        end

        # local variables (var.*)
        rule %r/(?:var)\.[\w.-]+/ do
          token Name::Variable
        end

        rule %r/(sub)(#{SPACE})([\w-]+)/ do
          groups Keyword, Text, Name::Function
        end

        # inline C (C{ ... }C)
        rule %r/C\{/ do
          token Comment::Preproc
          push :inline_c
        end

        rule %r/\.?[a-z_][\w.-]*/i do |m|
          next token Keyword if self.class.keywords.include? m[0]
          next token Name::Function if self.class.functions.include? m[0]
          next token Name::Variable if self.class.variables.include? m[0]
          token Text
        end

        ## for number literals

        decimal = %r/[0-9]+/
        hex = %r/[0-9a-f]+/i

        numeric = %r{
          (?:
            0x#{hex}
            (?:\.#{hex})?
            (?:p[+-]?#{hex})?
          )
          |
          (?:
            #{decimal}
            (?:\.#{decimal})?
            (?:e[+-]?#{decimal})?
          )
        }xi

        # duration literals
        duration_suffix = Regexp.union(%w(ms s m h d w y))
        rule %r/#{numeric}#{duration_suffix}/, Num::Other

        # numeric literals (integer / float)
        rule numeric do |m|
            case m[0]
            when /^#{decimal}$/
              token Num::Integer
            when /^0x#{hex}$/
              token Num::Integer
            else
              token Num::Float
            end
        end

        # standard strings
        rule %r/"/, Str::Double, :string

        rule %r'[&|+-]{2}|[<=>!*/+-]=|<<|>>|!~|[-+*/%><=!&|~]', Operator

        rule %r/[{}();.,]/, Punctuation

        rule %r/\r\n?|\n/, Text
        rule %r/./, Text
      end

      state :string do
        rule %r/"/, Str::Double, :pop!
        rule %r/\\[\\"nt]/, Str::Escape

        rule %r/\r\n?|\n/, Str::Double
        rule %r/./, Str::Double
      end

      state :inline_c do
        rule %r/}C/, Comment::Preproc, :pop!
        rule %r/.*?(?=}C)/m do
          delegate C
        end
      end
    end
  end
end