📄 syntax.c
字号:
for (; i < len; ++i) { while (i < len && bj_isspace( text[i] )) attr[i++] = col; if (i == len) break; this = text[i]; next = (i+1 < len) ? text[i+1] : '\0'; /* * Search for the end of the comment. */ if (in_comment) { attr[i] = col; com_len = match_comment( info->comend[com_num], text, i, len ); if (com_len) { while (--com_len != 0) attr[++i] = col; in_comment = FALSE; col = syntax_color[(in_prepro) ? COL_PREPRO : COL_NORMAL]; } continue; } /* * Search for the end of the string. */ if (in_string) { attr[i] = col; if (info->escape && this == info->escape) attr[++i] = col; else if (this == info->strend) { in_string = FALSE; col = syntax_color[(in_prepro) ? COL_PREPRO : COL_NORMAL]; } continue; } /* * Search for the end of a character literal/string. */ if (in_character) { if (char_count && ++count > info->charnum) { col = syntax_color[COL_BAD]; memset( attr+start, col, i - start ); } attr[i] = col; if (info->escape && this == info->escape) attr[++i] = col; else if (this == info->charend) { in_character = FALSE; col = syntax_color[(in_prepro) ? COL_PREPRO : COL_NORMAL]; } continue; } /* * If it's a line comment, everything from here is a comment. */ if (info->comment[0][0]) { if (match_comment( info->comment[0], text, i, len ) || (info->comment[1][0] && match_comment( info->comment[1], text, i, len ))) { col = syntax_color[COL_COMMENT]; memset( attr+i, col, len - i ); return( col ); } } /* * Start of a multi-line comment? */ if (info->comstart[0][0]) { com_num = 0; com_bit = 0; com_len = match_comment( info->comstart[0], text, i, len ); if (!com_len && info->comstart[1][0]) { com_num = 1; com_bit = COM_NUMBER; com_len = match_comment( info->comstart[1], text, i, len ); } if (com_len) { col = syntax_color[COL_COMMENT]; in_comment = TRUE; --i; do { attr[++i] = col; } while (--com_len != 0); continue; } } /* * Start of a string? */ if (info->strstart && this == info->strstart) { if (!in_prepro) col = syntax_color[COL_STRING]; attr[i] = col; in_string = TRUE; start = i; continue; } /* * Start of a character literal/string? */ if (info->charstart && this == info->charstart) { if (!in_prepro) col = syntax_color[COL_CHARACTER]; attr[i] = col; in_character = TRUE; start = i; if (char_count) { count = 1; if (++i < len) { attr[i] = col; if (info->escape && text[i] == info->escape) attr[++i] = col; } } continue; } /* * Check for a keyword or function */ if (info->identifier[this] & ID_STARTWORD) { start = i; count = 0; do word[count++] = text[i++]; while (i < len && (info->identifier[text[i]] & ID_INWORD)); word[count] = '\0'; if (!in_prepro) keyword = is_keyword( syntax, word, TRUE ); else keyword = NULL; /* * A keyword has been found. * jmh 980814: allow color 0 to remove inherited keywords. */ if (keyword != NULL && *keyword != 0) col = *keyword; /* * Check for a function. */ else { while (i < len && bj_isspace( text[i] )) ++i, ++count; if (!in_prepro && info->function && i < len && text[i] == info->function) col = syntax_color[COL_FUNCTION]; } memset( attr+start, col, count ); col = syntax_color[(in_prepro) ? COL_PREPRO : COL_NORMAL]; --i; continue; } this = bj_tolower( this ); /* case insensitive for numbers */ next = bj_tolower( next ); base = 0; /* * Test for a binary prefix. */ if (info->binary[0] == PREFIX && this == info->binary[1] && (!info->binary[2] || next == info->binary[2])) { base = ID_BINARY; col = syntax_color[COL_BINARY]; start = i++; if (info->binary[2]) ++i; /* * Test for a hexadecimal prefix. This is before octal so C can recog- * nize "0x" before "0". */ } else if (info->hex[0] == PREFIX && this == info->hex[1] && (!info->hex[2] || next == info->hex[2])) { base = ID_HEX; col = syntax_color[COL_HEX]; start = i++; if (info->hex[2]) ++i; /* * Test for an octal prefix. */ } else if (info->octal[0] == PREFIX && this == info->octal[1] && (!info->octal[2] || next == info->octal[2])) { base = ID_OCTAL; col = syntax_color[COL_OCTAL]; start = i++; if (info->octal[2]) ++i; /* * Try all the bases, see if there's a suffix. */ } else if (bj_isdigit( this )) { base = ID_DIGIT; col = syntax_color[COL_INTEGER]; start = i; } /* * Now verify the number. * jmh 991026: ignore exponents if 'e' is in_number (ie. binary). */ if (base) { test_real: while (i < len && (info->identifier[this = text[i]] & base)) { if (base & ID_DIGIT) { if ((this == 'e' || this == 'E') && !(info->identifier[this] & ID_BINARY)) { if (i+1 < len && (text[i+1] == '-' || text[i+1] == '+')) ++i; if (base & ID_EXPONENT) col = 0; else base |= ID_EXPONENT; } else if (info->identifier[this] & ID_BINARY) base |= ID_BINARY; else if (info->identifier[this] & ID_OCTAL) base |= ID_OCTAL; else if (info->identifier[this] & ID_DECIMAL) base |= ID_DECIMAL; else if (info->identifier[this] & ID_HEX) base |= ID_HEX; } ++i; } /* * Test for a decimal point or exponent. I've complicated the point * test somewhat, because two points in a row makes a symbol (eg. * Pascal's range). I've used the next character rather than the * previous so I can keep the real part. If I have 2.3..4 using a * previous test, the first point turns on real, the second point * makes it bad, the third point turns off the second point, which * would also turn off the first point, causing the number to be an * integer. Using the next character avoids this, at the expense of a * funny-looking condition. If the next character is a point then it's * a symbol, but if there is no next character, it's a point. */ if (i < len && ((this == '.' && !(i+1 < len && text[i+1] == '.')) || this == 'e' || this == 'E')) { if (this == '.') { if (base & ID_REAL) col = 0; else /* * Add the decimal numbers to get around that damn annoying * leading octal 0, which makes 0.89 bad. */ base |= ID_POINT | ID_DECIMAL; } else { if (i+1 < len && (text[i+1] == '-' || text[i+1] == '+')) ++i; if (base & ID_EXPONENT) col = 0; else base |= ID_EXPONENT; } ++i; goto test_real; } /* * If I haven't got a prefix, test for a suffix. */ if (base & ID_DIGIT) { int num_start = i; /* * Go back at most two characters to test for suffixes. This allows * assembly's binary "b" suffix, rather than hex's "b" digit. eg. * "100b" is good binary, not bad hex. It's not perfect, as it will * allow other hex digits - "123b" is bad (decimal digits), but * "1ab" is good, because I turn off the hex digit test so "100b" * will be recognized as good. Sigh. * 991026: "1ba" is good if radix 16 is used, so only test two * characters if necessary. */ count = 2; test_suffix: /* Dear, oh dear, two gotos in the one function. */ this = (i < len) ? bj_tolower( text[i] ) : '\0'; next = (i+1 < len) ? bj_tolower( text[i+1] ) : '\0'; /* * Test for a binary suffix. */ if (info->binary[0] == SUFFIX && (info->binary[2] || count > 0) && this == info->binary[1] && (!info->binary[2] || next == info->binary[2])) { ++i; if (info->binary[2]) ++i; if ((base & (ID_OCTAL | ID_DECIMAL)) || ((base & ID_HEX) && count == 2)) col = 0; else col = syntax_color[COL_BINARY]; /* * Test for an octal suffix. */ } else if (info->octal[0] == SUFFIX && (info->octal[2] || count > 0) && this == info->octal[1] && (!info->octal[2] || next == info->octal[2])) { ++i; if (info->octal[2]) ++i; if ((base & ID_DECIMAL) || ((base & ID_HEX) && count == 2)) col = 0; else col = syntax_color[COL_OCTAL]; /* * Test for a hexadecimal suffix. */ } else if (info->hex[0] == SUFFIX && (info->hex[2] || count > 0) && this == info->hex[1] && (!info->hex[2] || next == info->hex[2])) { ++i; if (info->hex[2]) ++i; /* * There's no base greater than hex, so don't bother testing it. */ col = syntax_color[COL_HEX]; /* * There's no suffix and no prefix, so there are two possibilities: * it's a bad number; or the suffix was treated as a hex digit. Go * back a character and try again. */ } else { if (!bj_isdigit( text[i-1] ) && count > 0) { --count; --i; goto test_suffix; } /* * I still didn't recognize anything, so go back to where I was. */ i = num_start; /* * Now I know there is no prefix and no suffix. If there were * hex digits, it's a bad number. */ if (base & ID_HEX) col = 0; } /* * If I have a prefix without any following digits, it's bad. Unless * that prefix is a one-character digit (damn C's prefixes). */ } else { if (i-1 == start) { /* a one-character prefix */ if (((base & ID_BINARY) && bj_isdigit( info->binary[1] )) || ((base & ID_OCTAL ) && bj_isdigit( info->octal[1] )) || ((base & ID_HEX ) && bj_isdigit( info->hex[1] ))) col = syntax_color[COL_INTEGER]; else col = 0; /* * Either a one-character prefix with one digit, or a two-character * prefix with no digits. Let's assume that two-character prefixes * are not both digits. */ } else if (i-2 == start) { if (((base & ID_BINARY) && info->binary[2] ) || ((base & ID_OCTAL ) && info->octal[2] ) || ((base & ID_HEX ) && info->hex[2] )) col = 0; } } /* * If the number is bad, leave it that way, but if it is real, use that * color i
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -