/ src / theme / languages / c.js
c.js
  1  /*! `c` grammar compiled for Highlight.js 11.10.0 */
  2    (function(){
  3      var hljsGrammar = (function () {
  4    'use strict';
  5  
  6    /*
  7    Language: C
  8    Category: common, system
  9    Website: https://en.wikipedia.org/wiki/C_(programming_language)
 10    */
 11  
 12    /** @type LanguageFn */
 13    function c(hljs) {
 14      const regex = hljs.regex;
 15      // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does
 16      // not include such support nor can we be sure all the grammars depending
 17      // on it would desire this behavior
 18      const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', { contains: [ { begin: /\\\n/ } ] });
 19      const DECLTYPE_AUTO_RE = 'decltype\\(auto\\)';
 20      const NAMESPACE_RE = '[a-zA-Z_]\\w*::';
 21      const TEMPLATE_ARGUMENT_RE = '<[^<>]+>';
 22      const FUNCTION_TYPE_RE = '('
 23        + DECLTYPE_AUTO_RE + '|'
 24        + regex.optional(NAMESPACE_RE)
 25        + '[a-zA-Z_]\\w*' + regex.optional(TEMPLATE_ARGUMENT_RE)
 26      + ')';
 27  
 28  
 29      const TYPES = {
 30        className: 'type',
 31        variants: [
 32          { begin: '\\b[a-z\\d_]*_t\\b' },
 33          { match: /\batomic_[a-z]{3,6}\b/ }
 34        ]
 35  
 36      };
 37  
 38      // https://en.cppreference.com/w/cpp/language/escape
 39      // \\ \x \xFF \u2837 \u00323747 \374
 40      const CHARACTER_ESCAPES = '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)';
 41      const STRINGS = {
 42        className: 'string',
 43        variants: [
 44          {
 45            begin: '(u8?|U|L)?"',
 46            end: '"',
 47            illegal: '\\n',
 48            contains: [ hljs.BACKSLASH_ESCAPE ]
 49          },
 50          {
 51            begin: '(u8?|U|L)?\'(' + CHARACTER_ESCAPES + "|.)",
 52            end: '\'',
 53            illegal: '.'
 54          },
 55          hljs.END_SAME_AS_BEGIN({
 56            begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,
 57            end: /\)([^()\\ ]{0,16})"/
 58          })
 59        ]
 60      };
 61  
 62      const NUMBERS = {
 63        className: 'number',
 64        variants: [
 65          { begin: '\\b(0b[01\']+)' },
 66          { begin: '(-?)\\b([\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)' },
 67          { begin: '(-?)(\\b0[xX][a-fA-F0-9\']+|(\\b[\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)([eE][-+]?[\\d\']+)?)' }
 68        ],
 69        relevance: 0
 70      };
 71  
 72      const PREPROCESSOR = {
 73        className: 'meta',
 74        begin: /#\s*[a-z]+\b/,
 75        end: /$/,
 76        keywords: { keyword:
 77            'if else elif endif define undef warning error line '
 78            + 'pragma _Pragma ifdef ifndef elifdef elifndef include' },
 79        contains: [
 80          {
 81            begin: /\\\n/,
 82            relevance: 0
 83          },
 84          hljs.inherit(STRINGS, { className: 'string' }),
 85          {
 86            className: 'string',
 87            begin: /<.*?>/
 88          },
 89          C_LINE_COMMENT_MODE,
 90          hljs.C_BLOCK_COMMENT_MODE
 91        ]
 92      };
 93  
 94      const TITLE_MODE = {
 95        className: 'title',
 96        begin: regex.optional(NAMESPACE_RE) + hljs.IDENT_RE,
 97        relevance: 0
 98      };
 99  
100      const FUNCTION_TITLE = regex.optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\s*\\(';
101  
102      const C_KEYWORDS = [
103        "asm",
104        "auto",
105        "break",
106        "case",
107        "continue",
108        "default",
109        "do",
110        "else",
111        "enum",
112        "extern",
113        "for",
114        "fortran",
115        "goto",
116        "if",
117        "inline",
118        "register",
119        "restrict",
120        "return",
121        "sizeof",
122        "typeof",
123        "typeof_unqual",
124        "struct",
125        "switch",
126        "typedef",
127        "union",
128        "volatile",
129        "while",
130        "_Alignas",
131        "_Alignof",
132        "_Atomic",
133        "_Generic",
134        "_Noreturn",
135        "_Static_assert",
136        "_Thread_local",
137        // aliases
138        "alignas",
139        "alignof",
140        "noreturn",
141        "static_assert",
142        "thread_local",
143        // not a C keyword but is, for all intents and purposes, treated exactly like one.
144        "_Pragma"
145      ];
146  
147      const C_TYPES = [
148        "float",
149        "double",
150        "signed",
151        "unsigned",
152        "int",
153        "short",
154        "long",
155        "char",
156        "void",
157        "_Bool",
158        "_BitInt",
159        "_Complex",
160        "_Imaginary",
161        "_Decimal32",
162        "_Decimal64",
163        "_Decimal96",
164        "_Decimal128",
165        "_Decimal64x",
166        "_Decimal128x",
167        "_Float16",
168        "_Float32",
169        "_Float64",
170        "_Float128",
171        "_Float32x",
172        "_Float64x",
173        "_Float128x",
174        // modifiers
175        "const",
176        "static",
177        "constexpr",
178        // aliases
179        "complex",
180        "bool",
181        "imaginary"
182      ];
183  
184      const KEYWORDS = {
185        keyword: C_KEYWORDS,
186        type: C_TYPES,
187        literal: 'true false NULL',
188        // TODO: apply hinting work similar to what was done in cpp.js
189        built_in: 'std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream '
190          + 'auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set '
191          + 'unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos '
192          + 'asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp '
193          + 'fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper '
194          + 'isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow '
195          + 'printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp '
196          + 'strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan '
197          + 'vfprintf vprintf vsprintf endl initializer_list unique_ptr',
198      };
199  
200      const EXPRESSION_CONTAINS = [
201        PREPROCESSOR,
202        TYPES,
203        C_LINE_COMMENT_MODE,
204        hljs.C_BLOCK_COMMENT_MODE,
205        NUMBERS,
206        STRINGS
207      ];
208  
209      const EXPRESSION_CONTEXT = {
210        // This mode covers expression context where we can't expect a function
211        // definition and shouldn't highlight anything that looks like one:
212        // `return some()`, `else if()`, `(x*sum(1, 2))`
213        variants: [
214          {
215            begin: /=/,
216            end: /;/
217          },
218          {
219            begin: /\(/,
220            end: /\)/
221          },
222          {
223            beginKeywords: 'new throw return else',
224            end: /;/
225          }
226        ],
227        keywords: KEYWORDS,
228        contains: EXPRESSION_CONTAINS.concat([
229          {
230            begin: /\(/,
231            end: /\)/,
232            keywords: KEYWORDS,
233            contains: EXPRESSION_CONTAINS.concat([ 'self' ]),
234            relevance: 0
235          }
236        ]),
237        relevance: 0
238      };
239  
240      const FUNCTION_DECLARATION = {
241        begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE,
242        returnBegin: true,
243        end: /[{;=]/,
244        excludeEnd: true,
245        keywords: KEYWORDS,
246        illegal: /[^\w\s\*&:<>.]/,
247        contains: [
248          { // to prevent it from being confused as the function title
249            begin: DECLTYPE_AUTO_RE,
250            keywords: KEYWORDS,
251            relevance: 0
252          },
253          {
254            begin: FUNCTION_TITLE,
255            returnBegin: true,
256            contains: [ hljs.inherit(TITLE_MODE, { className: "title.function" }) ],
257            relevance: 0
258          },
259          // allow for multiple declarations, e.g.:
260          // extern void f(int), g(char);
261          {
262            relevance: 0,
263            match: /,/
264          },
265          {
266            className: 'params',
267            begin: /\(/,
268            end: /\)/,
269            keywords: KEYWORDS,
270            relevance: 0,
271            contains: [
272              C_LINE_COMMENT_MODE,
273              hljs.C_BLOCK_COMMENT_MODE,
274              STRINGS,
275              NUMBERS,
276              TYPES,
277              // Count matching parentheses.
278              {
279                begin: /\(/,
280                end: /\)/,
281                keywords: KEYWORDS,
282                relevance: 0,
283                contains: [
284                  'self',
285                  C_LINE_COMMENT_MODE,
286                  hljs.C_BLOCK_COMMENT_MODE,
287                  STRINGS,
288                  NUMBERS,
289                  TYPES
290                ]
291              }
292            ]
293          },
294          TYPES,
295          C_LINE_COMMENT_MODE,
296          hljs.C_BLOCK_COMMENT_MODE,
297          PREPROCESSOR
298        ]
299      };
300  
301      return {
302        name: "C",
303        aliases: [ 'h' ],
304        keywords: KEYWORDS,
305        // Until differentiations are added between `c` and `cpp`, `c` will
306        // not be auto-detected to avoid auto-detect conflicts between C and C++
307        disableAutodetect: true,
308        illegal: '</',
309        contains: [].concat(
310          EXPRESSION_CONTEXT,
311          FUNCTION_DECLARATION,
312          EXPRESSION_CONTAINS,
313          [
314            PREPROCESSOR,
315            {
316              begin: hljs.IDENT_RE + '::',
317              keywords: KEYWORDS
318            },
319            {
320              className: 'class',
321              beginKeywords: 'enum class struct union',
322              end: /[{;:<>=]/,
323              contains: [
324                { beginKeywords: "final class struct" },
325                hljs.TITLE_MODE
326              ]
327            }
328          ]),
329        exports: {
330          preprocessor: PREPROCESSOR,
331          strings: STRINGS,
332          keywords: KEYWORDS
333        }
334      };
335    }
336  
337    return c;
338  
339  })();
340  
341      hljs.registerLanguage('c', hljsGrammar);
342    })();