⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syntax.c

📁 一个开源著名的TDE编辑器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
   if (g_status.copied && line == g_status.buff_node) {      ll  = g_status.line_buff;      len = g_status.line_buff_len;   } else {      ll  = line->line;      len = line->len;   }   old_type     = line->prev->type;   in_prepro    = (old_type & PREPRO) && !(old_type & PREPRO_END);   in_comment   = ((old_type & (COM_START | COM_WHOLE)) != 0);   in_string    = ((old_type & (STR_START | STR_WHOLE)) != 0);   in_character = ((old_type & (CHR_START | CHR_WHOLE)) != 0);   type         = line->type & DIRTY; /* keep the dirty flag, clear the rest */   /*    * If this line continues the preprocessor then indicate as such.    */   if (in_prepro)      type |= PREPRO;   i = 0;   /*    * Skip leading blanks and test for preprocessor.    */   if (!in_prepro && !in_comment && !in_string && !in_character) {      for (; i < len && bj_isspace( ll[i] ); ++i) ;      this = (i   < len) ? ll[i]   : '\0';      next = (i+1 < len) ? ll[i+1] : '\0';      if (  syntax->prepro[0] && this == syntax->prepro[0] &&          (!syntax->prepro[1] || next == syntax->prepro[1])) {         type |= PREPRO | PREPRO_START;         in_prepro = TRUE;         ++i;         if (syntax->prepro[1])            ++i;      }   }   com_bit = old_type & COM_NUMBER;   com_num = (com_bit != 0);   for (; i < len; ++i) {      while (bj_isspace( ll[i] ) && ++i < len);      if (i == len)         break;      this = ll[i];      next = (i+1 < len) ? ll[i+1] : '\0';      /*       * Search for the end of the comment.       */      if (in_comment) {         com_len = match_comment( syntax->comend[com_num], ll, i, len );         if (com_len) {            if (type & COM_START)               type &= ~(COM_START | COM_NUMBER);            else               type |= COM_END | com_bit;            in_comment = FALSE;            i += com_len - 1;         }         continue;      }      /*       * Search for the end of the string.       */      if (in_string) {         if (syntax->escape && this == syntax->escape)            ++i;         else if (this == syntax->strend) {            if (type & STR_START)               type &= ~STR_START;            else {               type |= STR_END;               if (old_type & (START_VALID | WHOLE_VALID))                  type |= END_VALID;            }            in_string = FALSE;         }         continue;      }      /*       * Search for the end of a character literal/string.       */      if (in_character) {         if (syntax->escape && this == syntax->escape)            ++i;         else if (this == syntax->charend) {            if (type & CHR_START)               type &= ~CHR_START;            else {               type |= CHR_END;               if (old_type & (START_VALID | WHOLE_VALID))                  type |= END_VALID;            }            in_character = FALSE;         }         continue;      }      /*       * If it's a line comment, the rest of the line can be ignored.       */      if (syntax->comment[0][0]) {         if (match_comment( syntax->comment[0], ll, i, len ))            break;         if (syntax->comment[1][0]) {            if (match_comment( syntax->comment[1], ll, i, len ))               break;         }      }      /*       * Start of a multi-line comment?       */      if (syntax->comstart[0][0]) {         com_num = 0;         com_bit = 0;         com_len = match_comment( syntax->comstart[0], ll, i, len );         if (!com_len  &&  syntax->comstart[1][0]) {            com_num = 1;            com_bit = COM_NUMBER;            com_len = match_comment( syntax->comstart[1], ll, i, len );         }         if (com_len) {            type |= COM_START | com_bit;            in_comment = TRUE;            i += com_len - 1;            continue;         }      }      /*       * Start of a string?       */      if (syntax->strstart && this == syntax->strstart) {         type |= STR_START;         in_string = TRUE;         continue;      }      /*       * Start of a character literal/string?       */      if (syntax->charstart && this == syntax->charstart) {         type |= CHR_START;         in_character = TRUE;         if (syntax->charnum) {            ++i;            if (syntax->escape && next == syntax->escape)               ++i;         }         continue;      }      /*       * Skip all characters in identifiers and numbers. This is primarily so       * PERL's package naming will be correctly handled (eg. main'dumpvar is       * one word, not a word and the start of a string).       */      if (syntax->identifier[this] & (ID_STARTWORD | ID_DIGIT)) {         while (++i < len &&                (syntax->identifier[ll[i]] & (ID_INWORD | ID_DIGIT)));         --i;      }   }   /*    * If we finish in a comment/string/character, and it didn't start on this    * line, then it must occupy the whole line.    */   if (in_comment) {      if (!(type & COM_START))         type |= COM_WHOLE | com_bit;   } else if (in_string) {      if (!(type & STR_START))         type |= STR_WHOLE;   } else if (in_character) {      if (!(type & CHR_START))         type |= CHR_WHOLE;   }   /*    * Determine the validity of a spanning string/character.    */   this = (len) ? ll[len-1] : '\0';   if ((in_string &&       (syntax->strnewl || (syntax->strspan && this == syntax->strspan))) ||       (in_character &&       (syntax->charnewl || (syntax->charspan && this == syntax->charspan)))) {      if (type & (STR_START | CHR_START))         type |= START_VALID;      else if (old_type & (START_VALID | WHOLE_VALID))         type |= WHOLE_VALID;   }   /*    * Does the preprocessor stop here?    */   if (in_prepro && !in_string && !in_character)      if (in_comment || !syntax->prepspan || this != syntax->prepspan)         type |= PREPRO_END;   line->type = type;}/* * Name:    syntax_check_lines * Purpose: update a line's syntax flags and see if the change propagates * Passed:  line:   first line to check *          syntax: info to check against * Returns: the number of lines after this one that were changed. * Notes:   propagation occurs when something affects following lines, such as *           adding an opening multi-line comment. * jmh 980728: Changed return type to long from int. * jmh 980729: Test for eof. */long syntax_check_lines( line_list_ptr line, LANGUAGE *syntax ){syntax_info *info;long old_type, new_type;long count = -1;                        /* Don't count the first line */   if (syntax == NULL || line == NULL || line->len == EOF)      return 0;   info = syntax->info;   do {      old_type = line->type | DIRTY;    /* DIRTY is or'ed for the comparison */      syntax_check( line, info );      new_type = line->type | DIRTY;      ++count;      line = line->next;   } while (new_type != old_type  &&  line->len != EOF);   return( count );}/* * Name:    syntax_check_block * Purpose: check a number of lines * Author:  Jason Hood * Date:    July 29, 1998 * Passed:  br:     number of first line to check *          er:     number of last line *          line:   pointer to first line *          syntax: info to check against * Returns: none. * Notes:   Checks lines modified by block functions. *          br and er need not be actual line numbers, just a line range. * * jmh 031027: test for EOF. */void syntax_check_block( long br, long er, line_list_ptr line,                         LANGUAGE *syntax ){syntax_info *info;   if (syntax != NULL) {      info = syntax->info;      for (; br <= er  &&  line->len != EOF; ++br) {         syntax_check( line, info );         line = line->next;      }      if (line->len != EOF)         syntax_check_lines( line, syntax );   }}/* * Name:    syntax_attr * Purpose: determine the attributes (ie. colors) of a line * Passed:  line:   the line under consideration *          attr:   buffer to hold the attributes *          syntax: syntax highlighting info * Returns: attribute to use for the trailing blanks * Notes:   used by update_line(). *          attr should be at least as long as the line. *          The line should be detabbed. *          I've assumed that characters that can span lines don't have a *           length limit. Characters that have a limit must have at least one *           character. ie. the empty character string is not allowed (eg. ''). *           This allows Ada's apostrophe "'''" to work correctly. *          In rare circumstances, strings and characters that use escapes and *           span lines will fail. Eg. with C, \ is used to quote the next *           character and to continue the string on the next line. A string *           that ends like "string end \\" (where the terminating quote is *           actually eol) can be treated in two ways: a quoted \, which causes *           an unterminated string (BC3.1 does this, which is what I would *           expect); or as a continuing string, where the character to be *           quoted starts on the next line (this is what gcc 2.7.2.1 does). *           For simplicity, I do the latter. (Actually, gcc allows all lines *           to have continuing backslashes - including line comments.) *          The character limit could fail with the \nnn & \xnn escapes. *           Eg. if the limit is 2 (C, with 16-bit ints) then the legitimate *           character literal '\377' will register as 3 characters. (The *           supplied C and C++ limits are set to 4.) *          Everything in a preprocessor is in that color, except comments and *           bad items (currently strings, characters and numbers). *          attr should really be int (to be consistent), but char is a lot *           easier (in update_line()), and allows memset() to be used. * *          Note that _START can't be used to memset everything from here to *          the end, since there's no guarantee that this is the one to which *          the _START applies. eg: * *              "string"   "multi-line * *          If STR_START is used to memset and return, then it would do so at *          the `"string"' part, not the `"multi-line' part. *          Ask me how I know this. :) */int syntax_attr( text_ptr text, int len, long type,                 unsigned char *attr, LANGUAGE *syntax ){syntax_info *info;int  i;int  col = syntax_color[COL_NORMAL];int  in_comment;int  in_string;int  in_character;int  in_prepro;int  start = -1;        /* position where something started */int  count = 0;         /* number of characters in that something */int  char_count;        /* are we counting characters? */char word[1042];        /* Store a possible keyword */text_ptr keyword;int  base;              /* base for numbers */unsigned char this, next;int  com_len, com_num = 0;long com_bit;   info = syntax->info;   sort.order_array = (info->icase == MATCH) ? sort_order.match :                                               sort_order.ignore;   in_prepro    = (type & PREPRO) && !(type & PREPRO_START);   in_comment   = ((type & (COM_WHOLE | COM_END)) != 0);   in_string    = ((type & (STR_WHOLE | STR_END)) != 0);   in_character = ((type & (CHR_WHOLE | CHR_END)) != 0);   if (in_prepro)      col = syntax_color[COL_PREPRO];   if (in_comment) {      col = syntax_color[COL_COMMENT];      com_bit = type & COM_NUMBER;      com_num = (com_bit != 0);   } else if (in_string || in_character) {      if (type & (WHOLE_VALID | END_VALID)) {         if (!in_prepro)            col = syntax_color[in_string ? COL_STRING : COL_CHARACTER];      } else         col = syntax_color[COL_BAD];   }   if (type & (COM_WHOLE | STR_WHOLE | CHR_WHOLE)) {      memset( attr, col, len );      return( col );   }   char_count = (info->charnum && !(type & (CHR_WHOLE | CHR_END)));   i = 0;   /*    * Skip leading blanks and test for preprocessor.    */   if (!in_prepro && !in_comment && !in_string && !in_character) {      for (; i < len && bj_isspace( text[i] ); ++i)         attr[i] = col;      this = (i   < len) ? text[i]   : '\0';      next = (i+1 < len) ? text[i+1] : '\0';      if (  info->prepro[0] && this == info->prepro[0] &&          (!info->prepro[1] || next == info->prepro[1])) {         col = syntax_color[COL_PREPRO];         attr[i++] = col;         if (info->prepro[1])            attr[i++] = col;         in_prepro = TRUE;      }   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -