123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- /*
- Language: C
- Category: common, system
- Website: https://en.wikipedia.org/wiki/C_(programming_language)
- */
- /** @type LanguageFn */
- function c(hljs) {
- const regex = hljs.regex;
- // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does
- // not include such support nor can we be sure all the grammars depending
- // on it would desire this behavior
- const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', { contains: [ { begin: /\\\n/ } ] });
- const DECLTYPE_AUTO_RE = 'decltype\\(auto\\)';
- const NAMESPACE_RE = '[a-zA-Z_]\\w*::';
- const TEMPLATE_ARGUMENT_RE = '<[^<>]+>';
- const FUNCTION_TYPE_RE = '('
- + DECLTYPE_AUTO_RE + '|'
- + regex.optional(NAMESPACE_RE)
- + '[a-zA-Z_]\\w*' + regex.optional(TEMPLATE_ARGUMENT_RE)
- + ')';
- const TYPES = {
- className: 'type',
- variants: [
- { begin: '\\b[a-z\\d_]*_t\\b' },
- { match: /\batomic_[a-z]{3,6}\b/ }
- ]
- };
- // https://en.cppreference.com/w/cpp/language/escape
- // \\ \x \xFF \u2837 \u00323747 \374
- const CHARACTER_ESCAPES = '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)';
- const STRINGS = {
- className: 'string',
- variants: [
- {
- begin: '(u8?|U|L)?"',
- end: '"',
- illegal: '\\n',
- contains: [ hljs.BACKSLASH_ESCAPE ]
- },
- {
- begin: '(u8?|U|L)?\'(' + CHARACTER_ESCAPES + "|.)",
- end: '\'',
- illegal: '.'
- },
- hljs.END_SAME_AS_BEGIN({
- begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,
- end: /\)([^()\\ ]{0,16})"/
- })
- ]
- };
- const NUMBERS = {
- className: 'number',
- variants: [
- { begin: '\\b(0b[01\']+)' },
- { begin: '(-?)\\b([\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)' },
- { begin: '(-?)(\\b0[xX][a-fA-F0-9\']+|(\\b[\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)([eE][-+]?[\\d\']+)?)' }
- ],
- relevance: 0
- };
- const PREPROCESSOR = {
- className: 'meta',
- begin: /#\s*[a-z]+\b/,
- end: /$/,
- keywords: { keyword:
- 'if else elif endif define undef warning error line '
- + 'pragma _Pragma ifdef ifndef elifdef elifndef include' },
- contains: [
- {
- begin: /\\\n/,
- relevance: 0
- },
- hljs.inherit(STRINGS, { className: 'string' }),
- {
- className: 'string',
- begin: /<.*?>/
- },
- C_LINE_COMMENT_MODE,
- hljs.C_BLOCK_COMMENT_MODE
- ]
- };
- const TITLE_MODE = {
- className: 'title',
- begin: regex.optional(NAMESPACE_RE) + hljs.IDENT_RE,
- relevance: 0
- };
- const FUNCTION_TITLE = regex.optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\s*\\(';
- const C_KEYWORDS = [
- "asm",
- "auto",
- "break",
- "case",
- "continue",
- "default",
- "do",
- "else",
- "enum",
- "extern",
- "for",
- "fortran",
- "goto",
- "if",
- "inline",
- "register",
- "restrict",
- "return",
- "sizeof",
- "typeof",
- "typeof_unqual",
- "struct",
- "switch",
- "typedef",
- "union",
- "volatile",
- "while",
- "_Alignas",
- "_Alignof",
- "_Atomic",
- "_Generic",
- "_Noreturn",
- "_Static_assert",
- "_Thread_local",
- // aliases
- "alignas",
- "alignof",
- "noreturn",
- "static_assert",
- "thread_local",
- // not a C keyword but is, for all intents and purposes, treated exactly like one.
- "_Pragma"
- ];
- const C_TYPES = [
- "float",
- "double",
- "signed",
- "unsigned",
- "int",
- "short",
- "long",
- "char",
- "void",
- "_Bool",
- "_BitInt",
- "_Complex",
- "_Imaginary",
- "_Decimal32",
- "_Decimal64",
- "_Decimal96",
- "_Decimal128",
- "_Decimal64x",
- "_Decimal128x",
- "_Float16",
- "_Float32",
- "_Float64",
- "_Float128",
- "_Float32x",
- "_Float64x",
- "_Float128x",
- // modifiers
- "const",
- "static",
- "constexpr",
- // aliases
- "complex",
- "bool",
- "imaginary"
- ];
- const KEYWORDS = {
- keyword: C_KEYWORDS,
- type: C_TYPES,
- literal: 'true false NULL',
- // TODO: apply hinting work similar to what was done in cpp.js
- built_in: 'std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream '
- + 'auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set '
- + 'unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos '
- + 'asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp '
- + 'fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper '
- + 'isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow '
- + 'printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp '
- + 'strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan '
- + 'vfprintf vprintf vsprintf endl initializer_list unique_ptr',
- };
- const EXPRESSION_CONTAINS = [
- PREPROCESSOR,
- TYPES,
- C_LINE_COMMENT_MODE,
- hljs.C_BLOCK_COMMENT_MODE,
- NUMBERS,
- STRINGS
- ];
- const EXPRESSION_CONTEXT = {
- // This mode covers expression context where we can't expect a function
- // definition and shouldn't highlight anything that looks like one:
- // `return some()`, `else if()`, `(x*sum(1, 2))`
- variants: [
- {
- begin: /=/,
- end: /;/
- },
- {
- begin: /\(/,
- end: /\)/
- },
- {
- beginKeywords: 'new throw return else',
- end: /;/
- }
- ],
- keywords: KEYWORDS,
- contains: EXPRESSION_CONTAINS.concat([
- {
- begin: /\(/,
- end: /\)/,
- keywords: KEYWORDS,
- contains: EXPRESSION_CONTAINS.concat([ 'self' ]),
- relevance: 0
- }
- ]),
- relevance: 0
- };
- const FUNCTION_DECLARATION = {
- begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE,
- returnBegin: true,
- end: /[{;=]/,
- excludeEnd: true,
- keywords: KEYWORDS,
- illegal: /[^\w\s\*&:<>.]/,
- contains: [
- { // to prevent it from being confused as the function title
- begin: DECLTYPE_AUTO_RE,
- keywords: KEYWORDS,
- relevance: 0
- },
- {
- begin: FUNCTION_TITLE,
- returnBegin: true,
- contains: [ hljs.inherit(TITLE_MODE, { className: "title.function" }) ],
- relevance: 0
- },
- // allow for multiple declarations, e.g.:
- // extern void f(int), g(char);
- {
- relevance: 0,
- match: /,/
- },
- {
- className: 'params',
- begin: /\(/,
- end: /\)/,
- keywords: KEYWORDS,
- relevance: 0,
- contains: [
- C_LINE_COMMENT_MODE,
- hljs.C_BLOCK_COMMENT_MODE,
- STRINGS,
- NUMBERS,
- TYPES,
- // Count matching parentheses.
- {
- begin: /\(/,
- end: /\)/,
- keywords: KEYWORDS,
- relevance: 0,
- contains: [
- 'self',
- C_LINE_COMMENT_MODE,
- hljs.C_BLOCK_COMMENT_MODE,
- STRINGS,
- NUMBERS,
- TYPES
- ]
- }
- ]
- },
- TYPES,
- C_LINE_COMMENT_MODE,
- hljs.C_BLOCK_COMMENT_MODE,
- PREPROCESSOR
- ]
- };
- return {
- name: "C",
- aliases: [ 'h' ],
- keywords: KEYWORDS,
- // Until differentiations are added between `c` and `cpp`, `c` will
- // not be auto-detected to avoid auto-detect conflicts between C and C++
- disableAutodetect: true,
- illegal: '</',
- contains: [].concat(
- EXPRESSION_CONTEXT,
- FUNCTION_DECLARATION,
- EXPRESSION_CONTAINS,
- [
- PREPROCESSOR,
- {
- begin: hljs.IDENT_RE + '::',
- keywords: KEYWORDS
- },
- {
- className: 'class',
- beginKeywords: 'enum class struct union',
- end: /[{;:<>=]/,
- contains: [
- { beginKeywords: "final class struct" },
- hljs.TITLE_MODE
- ]
- }
- ]),
- exports: {
- preprocessor: PREPROCESSOR,
- strings: STRINGS,
- keywords: KEYWORDS
- }
- };
- }
- export { c as default };
|