This is syntax.c in view mode; [Download] [Up]
/* * Copyright (c) 1995 John E. Davis (davis@space.mit.edu) * All Rights Reserved. */ #include <config.h> #include <stdio.h> #include "buffer.h" #include "screen.h" static unsigned short *Char_Syntax; static char **Keywords = NULL; /* array of keywords */ static int Keyword_Not_Case_Sensitive; void init_syntax_highlight (void) { Syntax_Table_Type *st = CBuf->syntax_table; Keywords = NULL; Mode_Has_Syntax_Highlight = 1; if (CBuf->coloring_style) return; if ((st == NULL) || (st == Default_Syntax_Table)) { Mode_Has_Syntax_Highlight = 0; return; } Char_Syntax = st->char_syntax; if (st->flags & SYNTAX_NOT_CASE_SENSITIVE) Keyword_Not_Case_Sensitive = 0x20; else Keyword_Not_Case_Sensitive = 0; Keywords = (char **) st->keywords; #if 0 i = 0; while (i < MAX_KEYWORD_LEN) { if (st->keywords[i]) { Keywords = st->keywords; break; } i++; } #endif } #ifdef COLOR_COLUMNS static void color_columns (register unsigned short *p, register unsigned short *pmax) { register unsigned char *color = CBuf->column_colors; if (color == NULL) return; while (p < pmax) { *p |= ((unsigned short) *color) << 8; p++; color++; } } #endif static int try_keyword (register unsigned short *q, int n, register char *t, unsigned short color) { unsigned short *p; while (*t) { p = q - n; if (Keyword_Not_Case_Sensitive == 0) { while ((p < q) && (*t == (char) *p)) { p++; t++; } } else while ((p < q) && (*t == (char) LOWER_CASE (*p))) { p++; t++; } if (p == q) { p = q - n; while (p < q) *p++ |= color; return 0; } /* alphabetical */ if (*t > ((char) *p | Keyword_Not_Case_Sensitive)) break; t += (int) (q - p); } return -1; } static unsigned short *highlight_word (unsigned short *p, unsigned short *pmax) { char **kwds; register unsigned short *q; int n; int i; unsigned short color; q = p; while ((q < pmax) && (Char_Syntax[*q] & WORD_SYNTAX)) q++; n = (int) (q - p); kwds = Keywords; if ((kwds == NULL) || (n > MAX_KEYWORD_LEN)) return q; for (i = 0; i < MAX_KEYWORD_TABLES; i++) { char *t; t = kwds[n - 1]; if (t != NULL) { color = (JKEY_COLOR + i) << 8; if (0 == try_keyword (q, n, t, color)) return q; } kwds += MAX_KEYWORD_LEN; } return q; } static unsigned short *highlight_string (unsigned short *p, unsigned short *pmax, unsigned char quote) { unsigned char ch; unsigned char q = (unsigned char) *p; *p++ |= JSTR_COLOR << 8; while (p < pmax) { ch = (unsigned char) *p; *p++ |= JSTR_COLOR << 8; if (ch == q) break; if ((ch == quote) && (p < pmax)) { *p++ |= JSTR_COLOR << 8; } } return p; } static unsigned short *highlight_number (unsigned short *p, unsigned short *pmax) { unsigned short *p1; unsigned char ch; ch = (unsigned char) *p; if (ch == '-') { p1 = p + 1; if ((p1 < p) && (Char_Syntax[*p1] & NUMBER_SYNTAX)) { *p |= JNUM_COLOR << 8; *p1 |= JNUM_COLOR << 8; p += 2; } else { *p |= JOP_COLOR << 8; return p + 1; } } while ((p < pmax) && (Char_Syntax[*p] & NUMBER_SYNTAX)) { *p++ |= JNUM_COLOR << 8; } return p; } static unsigned short *highlight_comment (unsigned short *p, unsigned short *pmax, Syntax_Table_Type *st) { int comment_type = st->flags; unsigned short *p1; unsigned char comment_end = st->comment_end; *p++ |= JCOM_COLOR << 8; if ((p < pmax) && (comment_type & MULTICHAR_TYPE)) *p++ |= JCOM_COLOR << 8; while (p < pmax) { if (*p == comment_end) { if ((comment_type & MULTICHAR_TYPE) == 0) { *p++ |= JCOM_COLOR << 8; break; } p1 = p + 1; if ((p1 < pmax) && (*p1 == st->comment_end2)) { *p |= JCOM_COLOR << 8; *p1 |= JCOM_COLOR << 8; p += 2; break; } } *p++ |= JCOM_COLOR << 8; } return p; } void syntax_highlight (register unsigned short *p, register unsigned short *pmax) { Syntax_Table_Type *st = CBuf->syntax_table; unsigned char ch; unsigned int flags; unsigned short *pmin, syntax, *p1; #ifdef COLOR_COLUMNS if (CBuf->coloring_style) { color_columns (p, pmax); return; } #endif /* Check for preprocessor character */ if (*p == st->preprocess) { /* I should only scan to a comment. But.... */ while (p < pmax) *p++ |= (JPREPROC_COLOR << 8); return; } flags = st->flags; /* Look for Fortran like comments. These are allowed to have any character * except a numeral at the beginning of a line. */ if ((flags & FORTRAN_TYPE) && ((*p != ' ') && ((*p > '9') || (*p < '0')))) { while (p < pmax) *p++ |= (JCOM_COLOR << 8); return; } /* Skip whitespace */ while ((p < pmax) && (*p == ' ')) p++; if (p == pmax) return; /* If we are looking at a '* ' combination, then this is considered to * be a C comment (like this line). */ if ((flags & C_COMMENT_TYPE) && (*p == '*')) { unsigned short *p1 = p + 1; while ((p1 < pmax) && (*p1 == '*')) p1++; if ((p1 == pmax) || (*p1 == ' ')) p = highlight_comment (p, pmax, st); } pmin = p; /* Now the preliminary stuff is done so do the hard part */ while (p < pmax) { syntax = Char_Syntax[*p]; if (syntax & WORD_SYNTAX) { if ((*p > '9') || (0 == (syntax & NUMBER_SYNTAX))) { p = highlight_word (p, pmax); continue; } } if (syntax == 0) { p++; continue; } if (syntax & DELIM_SYNTAX) { *p++ |= JDELIM_COLOR << 8; continue; } if (syntax & STRING_SYNTAX) { p = highlight_string (p, pmax, st->quote_char); continue; } if (syntax & COMMENT_SYNTAX) { p1 = p + 1; ch = *p; if (flags & MULTICHAR_TYPE) { if (p1 < pmax) { if ((ch == st->comment_beg) && (*p1 == st->comment_beg2)) { p = highlight_comment (p, pmax, st); continue; } if ((ch == st->comment_end) && (*p1 == st->comment_end2)) { /* Missed the beginning of it. So, start from the * beginning and comment the whole line, like this one */ p += 2; while (pmin < p) { *pmin = (JCOM_COLOR << 8) | (*pmin & 0xFF); pmin++; } continue; } /* Check for C++ */ if ((flags & C_COMMENT_TYPE) && (ch == '/') && (*p1 == ch)) { while (p < pmax) *p++ |= (JCOM_COLOR << 8); return; } } } else { if (flags & EOL_COMMENT_TYPE) { while (p < pmax) *p++ |= (JCOM_COLOR << 8); return; } if (ch == st->comment_beg) { p = highlight_comment (p, pmax, st); continue; } else if (ch == st->comment_end) { p++; while (pmin < p) { *pmin++ |= (JCOM_COLOR << 8); } continue; } } } /* comment syntax */ if (syntax & OP_SYNTAX) { *p++ |= JOP_COLOR << 8; continue; } if (syntax & NUMBER_SYNTAX) { p = highlight_number (p, pmax); continue; } if (syntax & HTML_START_SYNTAX) { *p++ |= JKEY_COLOR << 8; while (p < pmax) { if (Char_Syntax[*p] & HTML_END_SYNTAX) { *p++ |= JKEY_COLOR << 8; break; } *p++ |= JKEY_COLOR << 8; } continue; } if (syntax & HTML_END_SYNTAX) /* missed start from previous line */ { while (pmin < p) { *pmin = (JKEY_COLOR << 8) | (*pmin & 0xFF); pmin++; } *p++ |= JKEY_COLOR << 8; continue; } if ((syntax & OPEN_DELIM_SYNTAX) || (syntax & CLOSE_DELIM_SYNTAX)) { *p++ |= JDELIM_COLOR << 8; continue; } if ((syntax & QUOTE_SYNTAX) && (flags & TEX_LIKE_KEYWORDS)) { *p++ |= JKEY_COLOR << 8; if (p < pmax) { if (Char_Syntax[*p] & WORD_SYNTAX) { do { *p++ |= JKEY_COLOR << 8; } while ((p < pmax) && (Char_Syntax[*p] & WORD_SYNTAX)); } else *p++ |= JKEY_COLOR << 8; } continue; } /* Undefined. */ p++; } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.