lectures.alex.balgavy.eu

Lecture notes from university.
git clone git://git.alex.balgavy.eu/lectures.alex.balgavy.eu.git
Log | Files | Refs | Submodules

C.sublime-syntax (47936B)


      1 %YAML 1.2
      2 ---
      3 # http://www.sublimetext.com/docs/3/syntax.html
      4 name: C
      5 file_extensions:
      6   - c
      7   - h
      8 first_line_match: "-[*]-( Mode:)? C -[*]-"
      9 scope: source.c
     10 
     11 variables:
     12   # number exponents
     13   dec_exponent: '(?:[eE][-+]??\d+)'
     14   hex_exponent: '(?:[pP][-+]??\d+)'
     15 
     16   # number suffixes
     17   dec_suffix: '[a-zA-Z_][[:alnum:]_]*'
     18   hex_suffix: '[g-zG-Z_][[:alnum:]_]*'
     19   integer_suffix: '[lL]{1,2}[uU]?|[uU][lL]{0,2}'
     20 
     21   identifier: \b[[:alpha:]_][[:alnum:]_]*\b # upper and lowercase
     22   macro_identifier: \b[[:upper:]_][[:upper:][:digit:]_]{2,}\b # only uppercase, at least 3 chars
     23   control_keywords: 'break|case|continue|default|do|else|for|goto|if|_Pragma|return|switch|while'
     24   basic_types: 'asm|__asm__|auto|bool|_Bool|char|_Complex|double|float|_Imaginary|int|long|short|signed|unsigned|void'
     25   before_tag: 'struct|union|enum'
     26   microsoft_types: '__int8|__int16|__int32|__int64'
     27   windows_types: 'APIENTRY|ATOM|BOOL|BOOLEAN|BYTE|CALLBACK|CCHAR|CHAR|COLORREF|CONST|DWORD|DWORDLONG|DWORD_PTR|DWORD32|DWORD64|FLOAT|HACCEL|HALF_PTR|HANDLE|HBITMAP|HBRUSH|HCOLORSPACE|HCONV|HCONVLIST|HCURSOR|HDC|HDDEDATA|HDESK|HDROP|HDWP|HENHMETAFILE|HFILE|HFONT|HGDIOBJ|HGLOBAL|HHOOK|HICON|HINSTANCE|HKEY|HKL|HLOCAL|HMENU|HMETAFILE|HMODULE|HMONITOR|HPALETTE|HPEN|HRESULT|HRGN|HRSRC|HSZ|HWINSTA|HWND|INT|INT_PTR|INT8|INT16|INT32|INT64|LANGID|LCID|LCTYPE|LGRPID|LONG|LONGLONG|LONG_PTR|LONG32|LONG64|LPARAM|LPBOOL|LPBYTE|LPCOLORREF|LPCSTR|LPCTSTR|LPCVOID|LPCWSTR|LPDWORD|LPHANDLE|LPINT|LPLONG|LPSTR|LPTSTR|LPVOID|LPWORD|LPWSTR|LRESULT|PBOOL|PBOOLEAN|PBYTE|PCHAR|PCSTR|PCTSTR|PCWSTR|PDWORD|PDWORDLONG|PDWORD_PTR|PDWORD32|PDWORD64|PFLOAT|PHALF_PTR|PHANDLE|PHKEY|PINT|PINT_PTR|PINT8|PINT16|PINT32|PINT64|PLCID|PLONG|PLONGLONG|PLONG_PTR|PLONG32|PLONG64|POINTER_32|POINTER_64|POINTER_SIGNED|POINTER_UNSIGNED|PSHORT|PSIZE_T|PSSIZE_T|PSTR|PTBYTE|PTCHAR|PTSTR|PUCHAR|PUHALF_PTR|PUINT|PUINT_PTR|PUINT8|PUINT16|PUINT32|PUINT64|PULONG|PULONGLONG|PULONG_PTR|PULONG32|PULONG64|PUSHORT|PVOID|PWCHAR|PWORD|PWSTR|QWORD|SC_HANDLE|SC_LOCK|SERVICE_STATUS_HANDLE|SHORT|SIZE_T|SSIZE_T|TBYTE|TCHAR|UCHAR|UHALF_PTR|UINT|UINT_PTR|UINT8|UINT16|UINT32|UINT64|ULONG|ULONGLONG|ULONG_PTR|ULONG32|ULONG64|UNICODE_STRING|USHORT|USN|VOID|WCHAR|WINAPI|WORD|WPARAM'
     28   stdint: 'int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t|int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t|uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t|uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t|uintmax_t|uintmax_t'
     29   declspec: '__declspec\(\s*\w+(?:\([^)]+\))?\s*\)'
     30   storage_classes: 'static|extern|register|{{declspec}}'
     31   type_qualifier: 'const|volatile'
     32   compiler_directive: 'inline|restrict|__restrict__|__restrict'
     33   modifiers: '{{storage_classes}}|{{type_qualifier}}|{{compiler_directive}}'
     34   non_func_keywords: 'if|for|switch|while|decltype|sizeof|__declspec|__attribute__'
     35 
     36 contexts:
     37   main:
     38     - include: preprocessor-global
     39     - include: global
     40 
     41   #############################################################################
     42   # Reusable contexts
     43   #
     44   # The follow contexts are currently constructed to be reused in the C++
     45   # syntax. They are specifically constructed to not push into sub-contexts,
     46   # which ensures that C++ code isn't accidentally lexed as plain C. They also
     47   # should not use the {{identifier}} variable since that is different for C++.
     48   #############################################################################
     49 
     50   comments:
     51     - match: ^/\* =(\s*.*?)\s*= \*/$\n?
     52       scope: comment.block.c
     53       captures:
     54         1: meta.toc-list.banner.block.c
     55     - match: /\*
     56       scope: punctuation.definition.comment.c
     57       push:
     58         - meta_scope: comment.block.c
     59         - match: \*/
     60           scope: punctuation.definition.comment.c
     61           pop: true
     62         - match: ^\s*(\*)(?!/)
     63           captures:
     64             1: punctuation.definition.comment.c
     65     - match: \*/(?!\*)
     66       scope: invalid.illegal.stray-comment-end.c
     67     - match: ^// =(\s*.*?)\s*=\s*$\n?
     68       scope: comment.line.banner.c
     69       captures:
     70         1: meta.toc-list.banner.line.c
     71     - match: //
     72       scope: punctuation.definition.comment.c
     73       push:
     74         - meta_scope: comment.line.double-slash.c
     75         - match: '(\\)$\n'
     76           captures:
     77             1: punctuation.separator.continuation.c
     78         - match: \n
     79           pop: true
     80 
     81   strings:
     82     - match: '(L|u8|u|U)?(")'
     83       captures:
     84         1: storage.type.string.c
     85         2: punctuation.definition.string.begin.c
     86       push:
     87         - meta_scope: string.quoted.double.c
     88         - match: '"'
     89           scope: punctuation.definition.string.end.c
     90           pop: true
     91         - include: string_escaped_char
     92         - include: string_placeholder
     93     - match: "(L|u8|u|U)?(')"
     94       captures:
     95         1: storage.type.string.c
     96         2: punctuation.definition.string.begin.c
     97       push:
     98         - meta_scope: string.quoted.single.c
     99         - match: "'"
    100           scope: punctuation.definition.string.end.c
    101           pop: true
    102         - include: string_escaped_char
    103 
    104   string_escaped_char:
    105     - match: '(\\)$\n'
    106       captures:
    107         1: punctuation.separator.continuation.c
    108     - match: \\(?:\\|[abefnrtv\'"?]|[0-3][0-9]{0,2}|[4-7][0-9]?|x[a-fA-F0-9]+|u[a-fA-F0-9]{4}|U[a-fA-F0-9]{8})
    109       scope: constant.character.escape.c
    110     - match: \\.
    111       scope: invalid.illegal.unknown-escape.c
    112 
    113   string_placeholder:
    114     - match: |-
    115         (?x)%
    116           (\d+\$)?                                      # field (argument #)
    117           [#0\- +']*                                    # flags
    118           [,;:_]?                                       # separator character (AltiVec)
    119           ((-?\d+)|\*(-?\d+\$)?)?                       # minimum field width
    120           (\.((-?\d+)|\*(-?\d+\$)?)?)?                  # precision
    121           (hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)?          # length modifier
    122           (\[[^\]]+\]|[am]s|[diouxXDOUeEfFgGaACcSspn%]) # conversion type
    123       scope: constant.other.placeholder.c
    124 
    125   keywords:
    126     - match: \bbreak\b
    127       scope: keyword.control.flow.break.c
    128     - match: \bcontinue\b
    129       scope: keyword.control.flow.continue.c
    130     - match: \bgoto\b
    131       scope: keyword.control.flow.goto.c
    132     - match: \breturn\b
    133       scope: keyword.control.flow.return.c
    134     - match: \b({{control_keywords}})\b
    135       scope: keyword.control.c
    136     - match: \bsizeof\b
    137       scope: keyword.operator.word.c
    138 
    139   modifiers:
    140     - match: \b({{modifiers}})\b
    141       scope: storage.modifier.c
    142 
    143   variables:
    144     - match: '\bg[A-Z]\w*\b'
    145       scope: variable.other.readwrite.global.mac-classic.c
    146     - match: '\bs[A-Z]\w*\b'
    147       scope: variable.other.readwrite.static.mac-classic.c
    148 
    149   constants:
    150     - match: \b(__func__|NULL|true|false|TRUE|FALSE)\b
    151       scope: constant.language.c
    152     - match: \b(__FILE__|__FUNCTION__|__LINE__)\b
    153       scope: support.constant.c
    154     # common C constant naming idiom -- kConstantVariable
    155     - match: '\bk[A-Z]\w*\b'
    156       scope: constant.other.variable.mac-classic.c
    157     - match: \b(noErr|kNilOptions|kInvalidID|kVariableLengthArray)\b
    158       scope: support.constant.mac-classic.c
    159 
    160   c99:
    161     - match: \b(hypot(f|l)?|s(scanf|ystem|nprintf|ca(nf|lb(n(f|l)?|ln(f|l)?))|i(n(h(f|l)?|f|l)?|gn(al|bit))|tr(s(tr|pn)|nc(py|at|mp)|c(spn|hr|oll|py|at|mp)|to(imax|d|u(l(l)?|max)|k|f|l(d|l)?)|error|pbrk|ftime|len|rchr|xfrm)|printf|et(jmp|vbuf|locale|buf)|qrt(f|l)?|w(scanf|printf)|rand)|n(e(arbyint(f|l)?|xt(toward(f|l)?|after(f|l)?))|an(f|l)?)|c(s(in(h(f|l)?|f|l)?|qrt(f|l)?)|cos(h(f)?|f|l)?|imag(f|l)?|t(ime|an(h(f|l)?|f|l)?)|o(s(h(f|l)?|f|l)?|nj(f|l)?|pysign(f|l)?)|p(ow(f|l)?|roj(f|l)?)|e(il(f|l)?|xp(f|l)?)|l(o(ck|g(f|l)?)|earerr)|a(sin(h(f|l)?|f|l)?|cos(h(f|l)?|f|l)?|tan(h(f|l)?|f|l)?|lloc|rg(f|l)?|bs(f|l)?)|real(f|l)?|brt(f|l)?)|t(ime|o(upper|lower)|an(h(f|l)?|f|l)?|runc(f|l)?|gamma(f|l)?|mp(nam|file))|i(s(space|n(ormal|an)|cntrl|inf|digit|u(nordered|pper)|p(unct|rint)|finite|w(space|c(ntrl|type)|digit|upper|p(unct|rint)|lower|al(num|pha)|graph|xdigit|blank)|l(ower|ess(equal|greater)?)|al(num|pha)|gr(eater(equal)?|aph)|xdigit|blank)|logb(f|l)?|max(div|abs))|di(v|fftime)|_Exit|unget(c|wc)|p(ow(f|l)?|ut(s|c(har)?|wc(har)?)|error|rintf)|e(rf(c(f|l)?|f|l)?|x(it|p(2(f|l)?|f|l|m1(f|l)?)?))|v(s(scanf|nprintf|canf|printf|w(scanf|printf))|printf|f(scanf|printf|w(scanf|printf))|w(scanf|printf)|a_(start|copy|end|arg))|qsort|f(s(canf|e(tpos|ek))|close|tell|open|dim(f|l)?|p(classify|ut(s|c|w(s|c))|rintf)|e(holdexcept|set(e(nv|xceptflag)|round)|clearexcept|testexcept|of|updateenv|r(aiseexcept|ror)|get(e(nv|xceptflag)|round))|flush|w(scanf|ide|printf|rite)|loor(f|l)?|abs(f|l)?|get(s|c|pos|w(s|c))|re(open|e|ad|xp(f|l)?)|m(in(f|l)?|od(f|l)?|a(f|l|x(f|l)?)?))|l(d(iv|exp(f|l)?)|o(ngjmp|cal(time|econv)|g(1(p(f|l)?|0(f|l)?)|2(f|l)?|f|l|b(f|l)?)?)|abs|l(div|abs|r(int(f|l)?|ound(f|l)?))|r(int(f|l)?|ound(f|l)?)|gamma(f|l)?)|w(scanf|c(s(s(tr|pn)|nc(py|at|mp)|c(spn|hr|oll|py|at|mp)|to(imax|d|u(l(l)?|max)|k|f|l(d|l)?|mbs)|pbrk|ftime|len|r(chr|tombs)|xfrm)|to(b|mb)|rtomb)|printf|mem(set|c(hr|py|mp)|move))|a(s(sert|ctime|in(h(f|l)?|f|l)?)|cos(h(f|l)?|f|l)?|t(o(i|f|l(l)?)|exit|an(h(f|l)?|2(f|l)?|f|l)?)|b(s|ort))|g(et(s|c(har)?|env|wc(har)?)|mtime)|r(int(f|l)?|ound(f|l)?|e(name|alloc|wind|m(ove|quo(f|l)?|ainder(f|l)?))|a(nd|ise))|b(search|towc)|m(odf(f|l)?|em(set|c(hr|py|mp)|move)|ktime|alloc|b(s(init|towcs|rtowcs)|towc|len|r(towc|len))))\b
    162       scope: support.function.C99.c
    163 
    164   types:
    165     - match: \b({{basic_types}}|{{before_tag}})\b
    166       scope: storage.type.c
    167     - match: \b(u_char|u_short|u_int|u_long|ushort|uint|u_quad_t|quad_t|qaddr_t|caddr_t|daddr_t|dev_t|fixpt_t|blkcnt_t|blksize_t|gid_t|in_addr_t|in_port_t|ino_t|key_t|mode_t|nlink_t|id_t|pid_t|off_t|segsz_t|swblk_t|uid_t|id_t|clock_t|size_t|ssize_t|time_t|useconds_t|suseconds_t|ptrdiff_t)\b
    168       scope: support.type.sys-types.c
    169     - match: \b(pthread_attr_t|pthread_cond_t|pthread_condattr_t|pthread_mutex_t|pthread_mutexattr_t|pthread_once_t|pthread_rwlock_t|pthread_rwlockattr_t|pthread_t|pthread_key_t)\b
    170       scope: support.type.pthread.c
    171     - match: \b({{stdint}})\b
    172       scope: support.type.stdint.c
    173     - match: '\b({{microsoft_types}})\b'
    174       scope: support.type.microsoft.c
    175     - match: '\b({{windows_types}})\b'
    176       scope: support.type.windows.c
    177     - match: \b(AbsoluteTime|Boolean|Byte|ByteCount|ByteOffset|BytePtr|CompTimeValue|ConstLogicalAddress|ConstStrFileNameParam|ConstStringPtr|Duration|Fixed|FixedPtr|Float32|Float32Point|Float64|Float80|Float96|FourCharCode|Fract|FractPtr|Handle|ItemCount|LogicalAddress|OptionBits|OSErr|OSStatus|OSType|OSTypePtr|PhysicalAddress|ProcessSerialNumber|ProcessSerialNumberPtr|ProcHandle|Ptr|ResType|ResTypePtr|ShortFixed|ShortFixedPtr|SignedByte|SInt16|SInt32|SInt64|SInt8|Size|StrFileName|StringHandle|StringPtr|TimeBase|TimeRecord|TimeScale|TimeValue|TimeValue64|UInt16|UInt32|UInt64|UInt8|UniChar|UniCharCount|UniCharCountPtr|UniCharPtr|UnicodeScalarValue|UniversalProcHandle|UniversalProcPtr|UnsignedFixed|UnsignedFixedPtr|UnsignedWide|UTF16Char|UTF32Char|UTF8Char)\b
    178       scope: support.type.mac-classic.c
    179 
    180   numbers:
    181     # https://en.cppreference.com/w/c/language/floating_constant
    182 
    183     # decimal floats
    184     - match: |-
    185         (?x:
    186           \b\d+
    187           (?:
    188             (?: (\.) (?: \d+ {{dec_exponent}}? | {{dec_exponent}} | (?=[^.])) | {{dec_exponent}} )
    189             (?: ([fFlL])\b | ({{dec_suffix}})? ) | ([fF])\b
    190           )
    191           | (\.) \d+ {{dec_exponent}}? (?: ([fFlL])\b | ({{dec_suffix}})? )
    192         )
    193       scope: constant.numeric.float.decimal.c
    194       captures:
    195         1: punctuation.separator.decimal.c
    196         2: storage.type.numeric.c
    197         3: invalid.illegal.numeric.suffix.c
    198         4: storage.type.numeric.c
    199         5: punctuation.separator.decimal.c
    200         6: storage.type.numeric.c
    201         7: invalid.illegal.numeric.suffix.c
    202     # hexadecimal float (C99)
    203     - match: \b0[xX](?=[[:alnum:].]+?[pP])
    204       scope: punctuation.definition.numeric.base.c
    205       push:
    206         - meta_include_prototype: false
    207         - meta_scope: constant.numeric.float.hexadecimal.c
    208         - match: '{{hex_exponent}}\b'
    209           pop: true
    210         - match: \.
    211           scope: punctuation.separator.decimal.c
    212         - match: \H
    213           scope: invalid.illegal.numeric.digit.c
    214 
    215     # https://en.cppreference.com/w/c/language/integer_constant
    216 
    217     # hexadecimal integer
    218     - match: \b0[xX]
    219       scope: punctuation.definition.numeric.base.c
    220       push:
    221         - meta_include_prototype: false
    222         - meta_scope: constant.numeric.integer.hexadecimal.c
    223         - include: hexadecimal-suffix
    224     # octal integer
    225     - match: \b0(?=\d)
    226       scope: punctuation.definition.numeric.base.c
    227       push:
    228         - meta_include_prototype: false
    229         - meta_scope: constant.numeric.integer.octal.c
    230         - match: '[89]'
    231           scope: invalid.illegal.numeric.digit.c
    232         - include: decimal-suffix
    233     # decimal integer
    234     - match: \b\d+
    235       push:
    236         - meta_include_prototype: false
    237         - meta_scope: constant.numeric.integer.decimal.c
    238         - include: decimal-suffix
    239 
    240   decimal-suffix:
    241     - match: (?:{{integer_suffix}})?\b
    242       scope: storage.type.numeric.c
    243       pop: true
    244     - match: '{{dec_suffix}}'
    245       scope: invalid.illegal.numeric.suffix.c
    246       pop: true
    247 
    248   hexadecimal-suffix:
    249     - match: (?:{{integer_suffix}})?\b
    250       scope: storage.type.numeric.c
    251       pop: true
    252     - match: '{{hex_suffix}}'
    253       scope: invalid.illegal.numeric.suffix.c
    254       pop: true
    255 
    256   operators:
    257     - match: (?:\+\+|--)
    258       scope: keyword.operator.arithmetic.c
    259     - match: '->'
    260       scope: punctuation.accessor.c
    261     - match: \+\=|-\=|\*\=|/\=|%\=|&\=|\|\=|\^\=|>>\=|<<\=
    262       scope: keyword.operator.assignment.augmented.c
    263     - match: <<|>>|&&|\|\|
    264       scope: keyword.operator.arithmetic.c
    265     - match: <\=|>\=|\=\=|<|>|\!\=
    266       scope: keyword.operator.comparison.c
    267     - match: \+|\-|/|%|\||\^|~|!
    268       scope: keyword.operator.arithmetic.c
    269     # These two operator can be both arithmetic and pointer/address related
    270     - match: \*|&
    271       scope: keyword.operator.c
    272     - match: \=
    273       scope: keyword.operator.assignment.c
    274     # Negative lookahead prevents match :: when included in C++
    275     - match: '\?|:(?!:)'
    276       scope: keyword.operator.ternary.c
    277     - match: '\.\.\.'
    278       scope: keyword.operator.variadic.c
    279 
    280   access-illegal:
    281     - match: \.\.(?!\.)
    282       scope: invalid.illegal.syntax.c
    283 
    284   access:
    285     - match: '(\.)({{identifier}})(?!\s*\()'
    286       captures:
    287         1: punctuation.accessor.c
    288         2: variable.other.member.c
    289     - include: access-illegal
    290     - match: \.(?!\.)
    291       scope: punctuation.accessor.c
    292 
    293   label:
    294     - match: '^\s*((?!default){{identifier}})(:)(?!:)'
    295       captures:
    296         1: entity.name.label.c
    297         2: punctuation.separator.c
    298 
    299   preprocessor-disabled:
    300     - match: ^\s*(#\s*if(n?def)?)\b
    301       captures:
    302         1: meta.preprocessor.c
    303       push:
    304         - match: ^\s*(#\s*endif)\b
    305           captures:
    306             1: meta.preprocessor.c
    307           pop: true
    308         - include: preprocessor-disabled
    309         - include: pragma-mark
    310     - include: pragma-mark
    311 
    312   preprocessor-line-continuation:
    313     - match: '(\\)$\n'
    314       captures:
    315         1: punctuation.separator.continuation.c
    316     - match: \\(\s+?)$
    317       captures:
    318         1: invalid.illegal.space-after-continuation.c
    319 
    320   preprocessor-line-ending:
    321     - match: $\n
    322       pop: true
    323 
    324   # Comment handling in preprocessor directives are complicated by the fact
    325   # that a single-line comment will normally consume the newline to prevent
    326   # completions from being presented to the user. Additionally, a multi-line
    327   # comment without a line continuation ends at the newline.
    328   preprocessor-comments:
    329     - match: /\*
    330       scope: punctuation.definition.comment.c
    331       push:
    332         - meta_scope: comment.block.c
    333         - match: '\\$\n'
    334           scope: punctuation.separator.continuation.c
    335         - match: \*/
    336           scope: punctuation.definition.comment.c
    337           pop: true
    338     - match: //
    339       scope: punctuation.definition.comment.c
    340       push:
    341         - meta_scope: comment.line.double-slash.c
    342         - match: '(\\)$\n'
    343           captures:
    344             1: punctuation.separator.continuation.c
    345           pop: true
    346         - match: (?=\n)
    347           pop: true
    348 
    349   pragma-mark:
    350     - match: ^\s*((#\s*pragma\s+mark)\s+(.*))
    351       scope: meta.section.c
    352       captures:
    353         1: meta.preprocessor.c
    354         2: keyword.control.import.pragma.c
    355         3: meta.toc-list.pragma-mark.c
    356 
    357   # Used by "inc" snippets to prevent double ##include
    358   incomplete-inc:
    359     - match: '^\s*(#i(nc?)?)\b\s*'
    360       scope: meta.preprocessor.incomplete.c
    361 
    362   #############################################################################
    363   # The following are C-specific scopes that should not be reused. This is
    364   # because they push into subcontexts and use variables that are C-specific.
    365   #############################################################################
    366 
    367   global:
    368     - include: early-expressions
    369     - match: '^\s*(?=\w+)'
    370       push: global-modifier
    371     - include: late-expressions
    372 
    373   statements:
    374     - include: preprocessor-statements
    375     - include: label
    376     - include: expressions
    377 
    378   expressions:
    379     - include: early-expressions
    380     - include: late-expressions
    381 
    382   early-expressions:
    383     - include: preprocessor-expressions
    384     - include: comments
    385     - include: case-default
    386     - include: typedef
    387     - include: keywords-parens
    388     - include: keywords
    389     - include: numbers
    390     - include: operators
    391     - include: strings
    392     - include: parens
    393     - include: brackets
    394     - include: block
    395     - include: variables
    396     - include: constants
    397     - include: access
    398     - match: ','
    399       scope: punctuation.separator.c
    400     - match: '\)|\}'
    401       scope: invalid.illegal.stray-bracket-end.c
    402 
    403   late-expressions:
    404     - include: modifiers-parens
    405     - include: modifiers
    406     - include: types
    407     - include: function-call
    408     - match: ';'
    409       scope: punctuation.terminator.c
    410 
    411   ## C-specific contexts
    412 
    413   global-modifier:
    414     - include: comments
    415     - include: modifiers-parens
    416     - include: modifiers
    417     - match: '(?=\S)'
    418       set: global-type
    419 
    420   global-type:
    421     - include: comments
    422     - match: \*
    423       scope: keyword.operator.c
    424     - match: |-
    425         (?x:
    426           ({{before_tag}})
    427           \s+
    428           (?=
    429             {{identifier}}
    430             (\s+{{identifier}}(?!\s*[{=;])|\s*\*+)
    431           )
    432         )
    433       captures:
    434         1: storage.type.c
    435       set: global-maybe-function
    436     # The previous match handles return types of struct/enum/etc from a func,
    437     # there this one exits the context to allow matching an actual struct/union
    438     - match: '(?=\b({{before_tag}})\b)'
    439       set: data-structures
    440     - match: '(?=\b({{control_keywords}})\b)'
    441       pop: true
    442     - match: '(?=\s)'
    443       set: global-maybe-function
    444     # Allow a macro call
    445     - match: '({{identifier}})\s*(\()(?=[^\)]+\))'
    446       captures:
    447         1: variable.function.c
    448         2: meta.group.c punctuation.section.group.begin.c
    449       push:
    450         - meta_scope: meta.function-call.c
    451         - meta_content_scope: meta.group.c
    452         - match: '\)'
    453           scope: meta.group.c punctuation.section.group.end.c
    454           pop: true
    455         - include: expressions
    456     - match: (?={{identifier}}\s*\()
    457       set:
    458         - include: function-call
    459         - match: ''
    460           pop: true
    461     - include: types
    462     - match: '{{identifier}}'
    463     - match: (?=\W)
    464       pop: true
    465 
    466   global-maybe-function:
    467     - include: comments
    468     # Consume pointer info, macros and any type info that was offset by macros
    469     - match: \*
    470       scope: keyword.operator.c
    471     - include: types
    472     - include: modifiers-parens
    473     - include: modifiers
    474     # All uppercase identifier just before a newline is most likely a macro
    475     - match: '[[:upper:][:digit:]_]+\s*$'
    476     # Identifier that is not the function name - likely a macro
    477     - match: '{{identifier}}(?!\s*(\(|$))'
    478     # Real function definition
    479     - match: '{{identifier}}(?=\s*(\(|$))'
    480       scope: meta.function.c entity.name.function.c
    481       set: function-definition-params
    482     - match: '(?=\S)'
    483       pop: true
    484 
    485   function-definition-params:
    486     - meta_content_scope: meta.function.c
    487     - include: comments
    488     - match: '(?=\()'
    489       set:
    490         - match: \(
    491           scope: meta.function.parameters.c meta.group.c punctuation.section.group.begin.c
    492           set:
    493             - meta_content_scope: meta.function.parameters.c meta.group.c
    494             - match : \)
    495               scope: punctuation.section.group.end.c
    496               set: function-definition-continue
    497             - match: '\bvoid\b'
    498               scope: storage.type.c
    499             - match: '{{identifier}}(?=\s*(\[|,|\)))'
    500               scope: variable.parameter.c
    501             - include: expressions
    502             - include: preprocessor-line-continuation
    503     - match: (?=\S)
    504       pop: true
    505 
    506   function-definition-continue:
    507     - meta_content_scope: meta.function.c
    508     - include: comments
    509     - match: '(?=;)'
    510       pop: true
    511     - match: \b(const|final|noexcept|override)\b
    512       scope: storage.modifier.c
    513     - match: '(?=\{)'
    514       set: function-definition-body
    515     - match: '(?=\S)'
    516       pop: true
    517 
    518   function-definition-body:
    519     - meta_content_scope: meta.function.c
    520     - match: '\{'
    521       scope: meta.block.c punctuation.section.block.begin.c
    522       set:
    523         - meta_content_scope: meta.function.c meta.block.c
    524         - match: '\}'
    525           scope: meta.function.c meta.block.c punctuation.section.block.end.c
    526           pop: true
    527         - match: (?=^\s*#\s*(elif|else|endif)\b)
    528           pop: true
    529         - match: '(?=({{before_tag}})([^(;]+$|.*\{))'
    530           push: data-structures
    531         - include: statements
    532 
    533   data-structures:
    534     # Detect variable type definitions using struct/enum/union followed by a tag
    535     - match: '\b({{before_tag}})(?=\s+{{identifier}}\s+{{identifier}}\s*[=;\[])'
    536       scope: storage.type.c
    537     - match: '\bstruct\b'
    538       scope: storage.type.c
    539       set: data-structures-struct-definition
    540     - match: '\benum\b'
    541       scope: storage.type.c
    542       set: data-structures-enum-definition
    543     - match: '\bunion\b'
    544       scope: storage.type.c
    545       set: data-structures-union-definition
    546     - match: '(?=\S)'
    547       pop: true
    548 
    549   data-structures-struct-definition:
    550     - meta_scope: meta.struct.c
    551     - include: data-structures-definition-common-begin
    552     - include: data-structures-definition-common-macro
    553     - match: '{{identifier}}(?=\s*;)'
    554       scope: entity.name.struct.forward-decl.c
    555     - match: '{{identifier}}'
    556       scope: entity.name.struct.c
    557       set: data-structures-struct-definition-after-name
    558     - include: data-structures-struct-definition-block-start
    559     - match: '(?=;)'
    560       pop: true
    561 
    562   data-structures-struct-definition-after-name:
    563     - meta_scope: meta.struct.c
    564     - include: data-structures-definition-common-begin
    565     - match: '(?=;)'
    566       pop: true
    567     - include: data-structures-struct-definition-block-start
    568 
    569   data-structures-struct-definition-block-start:
    570     - match: '\{'
    571       scope: meta.block.c punctuation.section.block.begin.c
    572       set:
    573         - meta_content_scope: meta.struct.c meta.block.c
    574         - match: '\}'
    575           scope: meta.struct.c meta.block.c punctuation.section.block.end.c
    576           pop: true
    577         - include: data-structures-body
    578 
    579   data-structures-enum-definition:
    580     - meta_scope: meta.enum.c
    581     - include: data-structures-definition-common-begin
    582     - include: data-structures-definition-common-macro
    583     - match: '{{identifier}}(?=\s*;)'
    584       scope: entity.name.enum.forward-decl.c
    585     - match: '{{identifier}}'
    586       scope: entity.name.enum.c
    587       set: data-structures-enum-definition-after-name
    588     - include: data-structures-enum-definition-block-start
    589     - match: '(?=;)'
    590       pop: true
    591 
    592   data-structures-enum-definition-after-name:
    593     - meta_scope: meta.enum.c
    594     - include: data-structures-definition-common-begin
    595     - match: '(?=;)'
    596       pop: true
    597     - include: data-structures-enum-definition-block-start
    598 
    599   data-structures-enum-definition-block-start:
    600     - match: '\{'
    601       scope: meta.block.c punctuation.section.block.begin.c
    602       set:
    603         - meta_content_scope: meta.enum.c meta.block.c
    604         # Enums don't support methods so we have a simplified body
    605         - match: '\}'
    606           scope: meta.enum.c meta.block.c punctuation.section.block.end.c
    607           pop: true
    608         - include: data-structures-body
    609 
    610   data-structures-union-definition:
    611     - meta_scope: meta.union.c
    612     - include: data-structures-definition-common-begin
    613     - include: data-structures-definition-common-macro
    614     - match: '{{identifier}}(?=\s*;)'
    615       scope: entity.name.union.forward-decl.c
    616     - match: '{{identifier}}'
    617       scope: entity.name.union.c
    618       set: data-structures-union-definition-after-name
    619     - include: data-structures-union-definition-block-start
    620     - match: '(?=;)'
    621       pop: true
    622 
    623   data-structures-union-definition-after-name:
    624     - meta_scope: meta.union.c
    625     - include: data-structures-definition-common-begin
    626     - match: '(?=;)'
    627       pop: true
    628     - include: data-structures-union-definition-block-start
    629 
    630   data-structures-union-definition-block-start:
    631     - match: '\{'
    632       scope: meta.block.c punctuation.section.block.begin.c
    633       set:
    634         - meta_content_scope: meta.union.c meta.block.c
    635         - match: '\}'
    636           scope: meta.union.c meta.block.c punctuation.section.block.end.c
    637           pop: true
    638         - include: data-structures-body
    639 
    640   data-structures-definition-common-begin:
    641     - include: comments
    642     - match: '(?=\b(?:{{before_tag}}|{{control_keywords}})\b)'
    643       pop: true
    644     - include: modifiers-parens
    645     - include: modifiers
    646 
    647   data-structures-definition-common-macro:
    648     # Handle macros so they aren't matched as the class name
    649     - match: '\b[[:upper:][:digit:]_]+\b(?!\s*($|\{))'
    650 
    651   data-structures-definition-common-end:
    652     - match: '(?=;)'
    653       pop: true
    654 
    655   data-structures-body:
    656     - include: preprocessor-data-structures
    657     - match: '(?={{before_tag}})'
    658       push: data-structures
    659     - include: expressions
    660 
    661   block:
    662     - match: '\{'
    663       scope: punctuation.section.block.begin.c
    664       push:
    665         - meta_scope: meta.block.c
    666         - match: (?=^\s*#\s*(elif|else|endif)\b)
    667           pop: true
    668         - match: '\}'
    669           scope: punctuation.section.block.end.c
    670           pop: true
    671         - include: statements
    672 
    673   parens:
    674     - match: \(
    675       scope: punctuation.section.group.begin.c
    676       push:
    677         - meta_scope: meta.group.c
    678         - match: \)
    679           scope: punctuation.section.group.end.c
    680           pop: true
    681         - include: expressions
    682 
    683   brackets:
    684     - match: \[
    685       scope: punctuation.section.brackets.begin.c
    686       push:
    687         - meta_scope: meta.brackets.c
    688         - match: \]
    689           scope: punctuation.section.brackets.end.c
    690           pop: true
    691         - include: expressions
    692 
    693   case-default:
    694     - match: '\b(default|case)\b'
    695       scope: keyword.control.c
    696       push:
    697         - match: ':'
    698           scope: punctuation.separator.c
    699           pop: true
    700         - include: expressions
    701 
    702   modifiers-parens:
    703     - match: \b(__attribute__)\s*(\(\()
    704       captures:
    705         1: storage.modifier.c
    706         2: meta.group.c punctuation.section.group.begin.c
    707       push :
    708         - meta_scope: meta.attribute.c
    709         - meta_content_scope: meta.group.c
    710         - include: parens
    711         - include: strings
    712         - match: \)\)
    713           scope: meta.group.c punctuation.section.group.end.c
    714           pop: true
    715     - match: \b(__declspec)(\()
    716       captures:
    717         1: storage.modifier.c
    718         2: meta.group.c punctuation.section.group.begin.c
    719       push:
    720         - meta_content_scope: meta.group.c
    721         - match: '\)'
    722           scope: meta.group.c punctuation.section.group.end.c
    723           pop: true
    724         - match: '\b(align|allocate|code_seg|deprecated|property|uuid)\b\s*(\()'
    725           captures:
    726             1: storage.modifier.c
    727             2: meta.group.c punctuation.section.group.begin.c
    728           push:
    729             - meta_content_scope: meta.group.c
    730             - match: '\)'
    731               scope: meta.group.c punctuation.section.group.end.c
    732               pop: true
    733             - include: numbers
    734             - include: strings
    735             - match: \b(get|put)\b
    736               scope: variable.parameter.c
    737             - match: ','
    738               scope: punctuation.separator.c
    739             - match: '='
    740               scope: keyword.operator.assignment.c
    741         - match: '\b(appdomain|deprecated|dllimport|dllexport|jintrinsic|naked|noalias|noinline|noreturn|nothrow|novtable|process|restrict|safebuffers|selectany|thread)\b'
    742           scope: constant.other.c
    743 
    744   keywords-parens:
    745     - match: '\b(sizeof)\b\s*(\()'
    746       captures:
    747         1: keyword.operator.word.c
    748         2: meta.group.c punctuation.section.group.begin.c
    749       push:
    750         - meta_content_scope: meta.group.c
    751         - match: '\)'
    752           scope: meta.group.c punctuation.section.group.end.c
    753           pop: true
    754         - include: expressions
    755 
    756   typedef:
    757     - match: \btypedef\b
    758       scope: storage.type.c
    759       push:
    760         - match: ({{identifier}})?\s*(?=;)
    761           captures:
    762             1: entity.name.type.typedef.c
    763           pop: true
    764         - match: \b(struct)\s+({{identifier}})
    765           captures:
    766             1: storage.type.c
    767         - include: expressions
    768 
    769   function-call:
    770     - match: (?={{identifier}}\s*\()
    771       push:
    772         - meta_content_scope: meta.function-call.c
    773         - include: c99
    774         - match: '{{identifier}}'
    775           scope: variable.function.c
    776         - match: '\('
    777           scope: meta.group.c punctuation.section.group.begin.c
    778           set:
    779             - meta_content_scope: meta.function-call.c meta.group.c
    780             - match : \)
    781               scope: meta.function-call.c meta.group.c punctuation.section.group.end.c
    782               pop: true
    783             - include: expressions
    784 
    785   ## Preprocessor for data-structures
    786 
    787   preprocessor-data-structures:
    788     - include: preprocessor-rule-enabled-data-structures
    789     - include: preprocessor-rule-disabled-data-structures
    790 
    791   preprocessor-rule-disabled-data-structures:
    792     - match: ^\s*((#if)\s+(0))\b
    793       captures:
    794         1: meta.preprocessor.c
    795         2: keyword.control.import.c
    796         3: constant.numeric.integer.decimal.c
    797       push:
    798         - match: ^\s*(#\s*endif)\b
    799           captures:
    800             1: meta.preprocessor.c keyword.control.import.c
    801           pop: true
    802         - match: ^\s*(#\s*else)\b
    803           captures:
    804             1: meta.preprocessor.c keyword.control.import.else.c
    805           push:
    806             - match: (?=^\s*#\s*endif\b)
    807               pop: true
    808             - include: negated-block
    809             - include: data-structures-body
    810         - match: ""
    811           push:
    812             - meta_scope: comment.block.preprocessor.if-branch.c
    813             - match: (?=^\s*#\s*(else|endif)\b)
    814               pop: true
    815             - include: preprocessor-disabled
    816 
    817   preprocessor-rule-enabled-data-structures:
    818     - match: ^\s*((#if)\s+(0*1))\b
    819       captures:
    820         1: meta.preprocessor.c
    821         2: keyword.control.import.c
    822         3: constant.numeric.integer.decimal.c
    823       push:
    824         - match: ^\s*(#\s*endif)\b
    825           captures:
    826             1: meta.preprocessor.c keyword.control.import.c
    827           pop: true
    828         - match: ^\s*(#\s*else)\b
    829           captures:
    830             1: meta.preprocessor.c keyword.control.import.else.c
    831           push:
    832             - meta_content_scope: comment.block.preprocessor.else-branch.c
    833             - match: (?=^\s*#\s*endif\b)
    834               pop: true
    835             - include: preprocessor-disabled
    836         - match: ""
    837           push:
    838             - match: (?=^\s*#\s*(else|endif)\b)
    839               pop: true
    840             - include: negated-block
    841             - include: data-structures-body
    842 
    843   ## Preprocessor for global
    844 
    845   preprocessor-global:
    846     - include: preprocessor-rule-enabled-global
    847     - include: preprocessor-rule-disabled-global
    848     - include: preprocessor-rule-other-global
    849 
    850   preprocessor-statements:
    851     - include: preprocessor-rule-enabled-statements
    852     - include: preprocessor-rule-disabled-statements
    853     - include: preprocessor-rule-other-statements
    854 
    855   preprocessor-expressions:
    856     - include: incomplete-inc
    857     - include: preprocessor-macro-define
    858     - include: pragma-mark
    859     - include: preprocessor-other
    860 
    861   preprocessor-rule-disabled-global:
    862     - match: ^\s*((#if)\s+(0))\b
    863       captures:
    864         1: meta.preprocessor.c
    865         2: keyword.control.import.c
    866         3: constant.numeric.integer.decimal.c
    867       push:
    868         - match: ^\s*(#\s*endif)\b
    869           captures:
    870             1: meta.preprocessor.c keyword.control.import.c
    871           pop: true
    872         - match: ^\s*(#\s*else)\b
    873           captures:
    874             1: meta.preprocessor.c keyword.control.import.else.c
    875           push:
    876             - match: (?=^\s*#\s*endif\b)
    877               pop: true
    878             - include: preprocessor-global
    879             - include: negated-block
    880             - include: global
    881         - match: ""
    882           push:
    883             - meta_scope: comment.block.preprocessor.if-branch.c
    884             - match: (?=^\s*#\s*(else|endif)\b)
    885               pop: true
    886             - include: preprocessor-disabled
    887 
    888   preprocessor-rule-enabled-global:
    889     - match: ^\s*((#if)\s+(0*1))\b
    890       captures:
    891         1: meta.preprocessor.c
    892         2: keyword.control.import.c
    893         3: constant.numeric.integer.decimal.c
    894       push:
    895         - match: ^\s*(#\s*endif)\b
    896           captures:
    897             1: meta.preprocessor.c keyword.control.import.c
    898           pop: true
    899         - match: ^\s*(#\s*else)\b
    900           captures:
    901             1: meta.preprocessor.c keyword.control.import.else.c
    902           push:
    903             - meta_content_scope: comment.block.preprocessor.else-branch.c
    904             - match: (?=^\s*#\s*endif\b)
    905               pop: true
    906             - include: preprocessor-disabled
    907         - match: ""
    908           push:
    909             - match: (?=^\s*#\s*(else|endif)\b)
    910               pop: true
    911             - include: preprocessor-global
    912             - include: negated-block
    913             - include: global
    914 
    915   preprocessor-rule-other-global:
    916     - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b
    917       captures:
    918         1: keyword.control.import.c
    919       push:
    920         - meta_scope: meta.preprocessor.c
    921         - include: preprocessor-line-continuation
    922         - include: preprocessor-comments
    923         - match: \bdefined\b
    924           scope: keyword.control.c
    925         # Enter a new scope where all elif/else branches have their
    926         # contexts popped by a subsequent elif/else/endif. This ensures that
    927         # preprocessor branches don't push multiple meta.block scopes on
    928         # the stack, thus messing up the "global" context's detection of
    929         # functions.
    930         - match: $\n
    931           set: preprocessor-if-branch-global
    932 
    933   # These gymnastics here ensure that we are properly handling scope even
    934   # when the preprocessor is used to create different scope beginnings, such
    935   # as a different if/while condition
    936   preprocessor-if-branch-global:
    937     - match: ^\s*(#\s*endif)\b
    938       captures:
    939         1: meta.preprocessor.c keyword.control.import.c
    940       pop: true
    941     - match: (?=^\s*#\s*(elif|else)\b)
    942       push: preprocessor-elif-else-branch-global
    943     - match: \{
    944       scope: punctuation.section.block.begin.c
    945       set: preprocessor-block-if-branch-global
    946     - include: preprocessor-global
    947     - include: negated-block
    948     - include: global
    949 
    950   preprocessor-block-if-branch-global:
    951     - meta_scope: meta.block.c
    952     - match: ^\s*(#\s*endif)\b
    953       captures:
    954         1: meta.preprocessor.c keyword.control.import.c
    955       set: preprocessor-block-finish-global
    956     - match: (?=^\s*#\s*(elif|else)\b)
    957       push: preprocessor-elif-else-branch-global
    958     - match: \}
    959       scope: punctuation.section.block.end.c
    960       set: preprocessor-if-branch-global
    961     - include: statements
    962 
    963   preprocessor-block-finish-global:
    964     - meta_scope: meta.block.c
    965     - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b
    966       captures:
    967         1: meta.preprocessor.c keyword.control.import.c
    968       set: preprocessor-block-finish-if-branch-global
    969     - match: \}
    970       scope: punctuation.section.block.end.c
    971       pop: true
    972     - include: statements
    973 
    974   preprocessor-block-finish-if-branch-global:
    975     - match: ^\s*(#\s*endif)\b
    976       captures:
    977         1: meta.preprocessor.c keyword.control.import.c
    978       pop: true
    979     - match: \}
    980       scope: punctuation.section.block.end.c
    981       set: preprocessor-if-branch-global
    982     - include: statements
    983 
    984   preprocessor-elif-else-branch-global:
    985     - match: (?=^\s*#\s*endif\b)
    986       pop: true
    987     - include: negated-block
    988     - include: preprocessor-global
    989     - include: global
    990 
    991   ## Preprocessor for statements
    992 
    993   preprocessor-rule-disabled-statements:
    994     - match: ^\s*((#if)\s+(0))\b
    995       captures:
    996         1: meta.preprocessor.c
    997         2: keyword.control.import.c
    998         3: constant.numeric.integer.decimal.c
    999       push:
   1000         - match: ^\s*(#\s*endif)\b
   1001           captures:
   1002             1: meta.preprocessor.c keyword.control.import.c
   1003           pop: true
   1004         - match: ^\s*(#\s*else)\b
   1005           captures:
   1006             1: meta.preprocessor.c keyword.control.import.else.c
   1007           push:
   1008             - match: (?=^\s*#\s*endif\b)
   1009               pop: true
   1010             - include: negated-block
   1011             - include: statements
   1012         - match: ""
   1013           push:
   1014             - meta_scope: comment.block.preprocessor.if-branch.c
   1015             - match: (?=^\s*#\s*(else|endif)\b)
   1016               pop: true
   1017             - include: preprocessor-disabled
   1018 
   1019   preprocessor-rule-enabled-statements:
   1020     - match: ^\s*((#if)\s+(0*1))\b
   1021       captures:
   1022         1: meta.preprocessor.c
   1023         2: keyword.control.import.c
   1024         3: constant.numeric.integer.decimal.c
   1025       push:
   1026         - match: ^\s*(#\s*endif)\b
   1027           captures:
   1028             1: meta.preprocessor.c keyword.control.import.c
   1029           pop: true
   1030         - match: ^\s*(#\s*else)\b
   1031           captures:
   1032             1: meta.preprocessor.c keyword.control.import.else.c
   1033           push:
   1034             - meta_content_scope: comment.block.preprocessor.else-branch.c
   1035             - match: (?=^\s*#\s*endif\b)
   1036               pop: true
   1037             - include: preprocessor-disabled
   1038         - match: ""
   1039           push:
   1040             - match: (?=^\s*#\s*(else|endif)\b)
   1041               pop: true
   1042             - include: negated-block
   1043             - include: statements
   1044 
   1045   preprocessor-rule-other-statements:
   1046     - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b
   1047       captures:
   1048         1: keyword.control.import.c
   1049       push:
   1050         - meta_scope: meta.preprocessor.c
   1051         - include: preprocessor-line-continuation
   1052         - include: preprocessor-comments
   1053         - match: \bdefined\b
   1054           scope: keyword.control.c
   1055         # Enter a new scope where all elif/else branches have their
   1056         # contexts popped by a subsequent elif/else/endif. This ensures that
   1057         # preprocessor branches don't push multiple meta.block scopes on
   1058         # the stack, thus messing up the "global" context's detection of
   1059         # functions.
   1060         - match: $\n
   1061           set: preprocessor-if-branch-statements
   1062 
   1063   # These gymnastics here ensure that we are properly handling scope even
   1064   # when the preprocessor is used to create different scope beginnings, such
   1065   # as a different if/while condition
   1066   preprocessor-if-branch-statements:
   1067     - match: ^\s*(#\s*endif)\b
   1068       captures:
   1069         1: meta.preprocessor.c keyword.control.import.c
   1070       pop: true
   1071     - match: (?=^\s*#\s*(elif|else)\b)
   1072       push: preprocessor-elif-else-branch-statements
   1073     - match: \{
   1074       scope: punctuation.section.block.begin.c
   1075       set: preprocessor-block-if-branch-statements
   1076     - match: (?=(?!{{non_func_keywords}}){{identifier}}\s*\()
   1077       set: preprocessor-if-branch-function-call
   1078     - include: negated-block
   1079     - include: statements
   1080 
   1081   preprocessor-if-branch-function-call:
   1082     - meta_content_scope: meta.function-call.c
   1083     - include: c99
   1084     - match: '{{identifier}}'
   1085       scope: variable.function.c
   1086     - match: '\('
   1087       scope: meta.group.c punctuation.section.group.begin.c
   1088       set: preprocessor-if-branch-function-call-arguments
   1089 
   1090   preprocessor-if-branch-function-call-arguments:
   1091     - meta_content_scope: meta.function-call.c meta.group.c
   1092     - match : \)
   1093       scope: meta.function-call.c meta.group.c punctuation.section.group.end.c
   1094       set: preprocessor-if-branch-statements
   1095     - match: ^\s*(#\s*(?:elif|else))\b
   1096       captures:
   1097         1: meta.preprocessor.c keyword.control.import.c
   1098       set: preprocessor-if-branch-statements
   1099     - match: ^\s*(#\s*endif)\b
   1100       captures:
   1101         1: meta.preprocessor.c keyword.control.import.c
   1102       set: preprocessor-if-branch-function-call-arguments-finish
   1103     - include: expressions
   1104 
   1105   preprocessor-if-branch-function-call-arguments-finish:
   1106     - meta_content_scope: meta.function-call.c meta.group.c
   1107     - match: \)
   1108       scope: meta.function-call.c meta.group.c punctuation.section.group.end.c
   1109       pop: true
   1110     - include: expressions
   1111 
   1112   preprocessor-block-if-branch-statements:
   1113     - meta_scope: meta.block.c
   1114     - match: ^\s*(#\s*endif)\b
   1115       captures:
   1116         1: meta.preprocessor.c keyword.control.import.c
   1117       set: preprocessor-block-finish-statements
   1118     - match: (?=^\s*#\s*(elif|else)\b)
   1119       push: preprocessor-elif-else-branch-statements
   1120     - match: \}
   1121       scope: punctuation.section.block.end.c
   1122       set: preprocessor-if-branch-statements
   1123     - include: statements
   1124 
   1125   preprocessor-block-finish-statements:
   1126     - meta_scope: meta.block.c
   1127     - match: ^\s*(#\s*(?:if|ifdef|ifndef))\b
   1128       captures:
   1129         1: meta.preprocessor.c keyword.control.import.c
   1130       set: preprocessor-block-finish-if-branch-statements
   1131     - match: \}
   1132       scope: punctuation.section.block.end.c
   1133       pop: true
   1134     - include: statements
   1135 
   1136   preprocessor-block-finish-if-branch-statements:
   1137     - match: ^\s*(#\s*endif)\b
   1138       captures:
   1139         1: meta.preprocessor.c keyword.control.import.c
   1140       pop: true
   1141     - match: \}
   1142       scope: punctuation.section.block.end.c
   1143       set: preprocessor-if-branch-statements
   1144     - include: statements
   1145 
   1146   preprocessor-elif-else-branch-statements:
   1147     - match: (?=^\s*#\s*endif\b)
   1148       pop: true
   1149     - include: negated-block
   1150     - include: statements
   1151 
   1152   ## Preprocessor other
   1153 
   1154   negated-block:
   1155     - match: '\}'
   1156       scope: punctuation.section.block.end.c
   1157       push:
   1158         - match: '\{'
   1159           scope: punctuation.section.block.begin.c
   1160           pop: true
   1161         - match: (?=^\s*#\s*(elif|else|endif)\b)
   1162           pop: true
   1163         - include: statements
   1164 
   1165   preprocessor-macro-define:
   1166     - match: ^\s*(#\s*define)\b
   1167       captures:
   1168         1: meta.preprocessor.macro.c keyword.control.import.define.c
   1169       push:
   1170         - meta_content_scope: meta.preprocessor.macro.c
   1171         - include: preprocessor-line-continuation
   1172         - include: preprocessor-line-ending
   1173         - include: preprocessor-comments
   1174         - match: '({{identifier}})(?=\()'
   1175           scope: entity.name.function.preprocessor.c
   1176           set:
   1177             - match: '\('
   1178               scope: punctuation.section.group.begin.c
   1179               set: preprocessor-macro-params
   1180         - match: '{{identifier}}'
   1181           scope: entity.name.constant.preprocessor.c
   1182           set: preprocessor-macro-definition
   1183 
   1184   preprocessor-macro-params:
   1185     - meta_scope: meta.preprocessor.macro.parameters.c meta.group.c
   1186     - match: '{{identifier}}'
   1187       scope: variable.parameter.c
   1188     - match: \)
   1189       scope: punctuation.section.group.end.c
   1190       set: preprocessor-macro-definition
   1191     - match: ','
   1192       scope: punctuation.separator.c
   1193       push:
   1194         - match: '{{identifier}}'
   1195           scope: variable.parameter.c
   1196           pop: true
   1197         - include: preprocessor-line-continuation
   1198         - include: preprocessor-comments
   1199         - match: '\.\.\.'
   1200           scope: keyword.operator.variadic.c
   1201         - match: '(?=\))'
   1202           pop: true
   1203         - match: (/\*).*(\*/)
   1204           scope: comment.block.c
   1205           captures:
   1206             1: punctuation.definition.comment.c
   1207             2: punctuation.definition.comment.c
   1208         - match: '\S+'
   1209           scope: invalid.illegal.unexpected-character.c
   1210     - include: preprocessor-line-continuation
   1211     - include: preprocessor-comments
   1212     - match: '\.\.\.'
   1213       scope: keyword.operator.variadic.c
   1214     - match: (/\*).*(\*/)
   1215       scope: comment.block.c
   1216       captures:
   1217         1: punctuation.definition.comment.c
   1218         2: punctuation.definition.comment.c
   1219     - match: $\n
   1220       scope: invalid.illegal.unexpected-end-of-line.c
   1221 
   1222   preprocessor-macro-definition:
   1223     - meta_content_scope: meta.preprocessor.macro.c
   1224     - include: preprocessor-line-continuation
   1225     - include: preprocessor-line-ending
   1226     - include: preprocessor-comments
   1227     # Don't define blocks in define statements
   1228     - match: '\{'
   1229       scope: punctuation.section.block.begin.c
   1230     - match: '\}'
   1231       scope: punctuation.section.block.end.c
   1232     - include: expressions
   1233 
   1234   preprocessor-practical-workarounds:
   1235     - include: preprocessor-convention-ignore-uppercase-ident-lines
   1236     - include: preprocessor-convention-ignore-uppercase-calls-without-semicolon
   1237 
   1238   preprocessor-convention-ignore-uppercase-ident-lines:
   1239     - match: ^(\s*{{macro_identifier}})+\s*$
   1240       scope: meta.assumed-macro.c
   1241       push:
   1242         # It's possible that we are dealing with a function return type on its own line, and the
   1243         # name of the function is on the subsequent line.
   1244         - match: \s*({{identifier}})(?=\s*\()
   1245           captures:
   1246             1: meta.function.c entity.name.function.c
   1247           set: function-definition-params
   1248         - match: ^
   1249           pop: true
   1250 
   1251 
   1252   preprocessor-convention-ignore-uppercase-calls-without-semicolon:
   1253     - match: ^\s*({{macro_identifier}})\s*(\()(?=[^)]*\)\s*$)
   1254       captures:
   1255         1: variable.function.assumed-macro.c
   1256         2: punctuation.section.group.begin.c
   1257       push:
   1258         - meta_scope: meta.assumed-macro.c
   1259         - match: \)
   1260           scope: punctuation.section.group.end.c
   1261           pop: true
   1262         - include: expressions
   1263 
   1264   preprocessor-other:
   1265     - match: ^\s*(#\s*(?:if|ifdef|ifndef|elif|else|line|pragma|undef))\b
   1266       captures:
   1267         1: keyword.control.import.c
   1268       push:
   1269         - meta_scope: meta.preprocessor.c
   1270         - include: preprocessor-line-continuation
   1271         - include: preprocessor-line-ending
   1272         - include: preprocessor-comments
   1273         - match: \bdefined\b
   1274           scope: keyword.control.c
   1275     - match: ^\s*(#\s*endif)\b
   1276       captures:
   1277         1: meta.preprocessor.c keyword.control.import.c
   1278     - match: ^\s*(#\s*(?:error|warning))\b
   1279       captures:
   1280         1: keyword.control.import.error.c
   1281       push:
   1282         - meta_scope: meta.preprocessor.diagnostic.c
   1283         - include: preprocessor-line-continuation
   1284         - include: preprocessor-line-ending
   1285         - include: preprocessor-comments
   1286         - include: strings
   1287         - match: '\S+'
   1288           scope: string.unquoted.c
   1289     - match: ^\s*(#\s*(?:include|include_next|import))\b
   1290       captures:
   1291         1: keyword.control.import.include.c
   1292       push:
   1293         - meta_scope: meta.preprocessor.include.c
   1294         - include: preprocessor-line-continuation
   1295         - include: preprocessor-line-ending
   1296         - include: preprocessor-comments
   1297         - match: '"'
   1298           scope: punctuation.definition.string.begin.c
   1299           push:
   1300             - meta_scope: string.quoted.double.include.c
   1301             - match: '"'
   1302               scope: punctuation.definition.string.end.c
   1303               pop: true
   1304         - match: <
   1305           scope: punctuation.definition.string.begin.c
   1306           push:
   1307             - meta_scope: string.quoted.other.lt-gt.include.c
   1308             - match: ">"
   1309               scope: punctuation.definition.string.end.c
   1310               pop: true
   1311     - include: preprocessor-practical-workarounds