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

📄 syntax.c

📁 一个开源著名的TDE编辑器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                        info->strnewl = TRUE;                     else {                        residue = parse_token( residue, key );                        if (strlen( key ) != 1 || bj_isalnum( *key )) {                           ERRORLINE( syntax7, key );                        } else                           info->strspan = *key;                     }                  }               }            }            break;         case SHL_CHARACTER:            if (info->identifier[U( *key )] & ID_STARTWORD)               add_keyword_list( syntax, key_no, key, residue );            else {               if (strlen( key ) > 2) {                  ERRORLINE( syntax8a, key );               } else {                  /*                   * Characters are the same as strings, but they also have a                   * length limit.                   */                  if (key[1] == '\0') {                     info->charstart = key[0];                     number = parse_token( residue, key );                     if (*key && key[1] == '\0' && !bj_isdigit( *key ) ) {                        info->charend = key[0];                        residue = number;                     } else                        info->charend = info->charstart;                  } else {                     info->charstart = key[0];                     info->charend   = key[1];                  }                  for (;;) {                     residue = parse_token( residue, key );                     if (*key == '\0' || *key == ';')                        break;                     if (bj_isdigit( *key )) {                        info->charnum = atoi( key );                        if (info->charnum)                           ++info->charnum;   /* add one for closing quote */                        continue;                     }                     key_no = search( key, valid_string, 1 );                     if (key_no == ERROR) {                        ERRORLINE( syntax5, key );                        continue;                     }                     if (key_no == SHL_NEWLINE)                        info->charnewl = TRUE;                     else {                        residue = parse_token( residue, key );                        if (strlen( key ) != 1 || bj_isalnum( *key )) {                           ERRORLINE( syntax7, key );                        } else                           info->charspan = *key;                     }                  }               }            }            break;         case SHL_MENU:         {            const char* errmsg = new_user_menu( residue, key, TRUE );            if (errmsg != NULL) {               ERRORLINE( errmsg, key );            }            break;         }         case SHL_INFLATETABS:            key_no = search( key, valid_tabs, 2 );            if (key_no == ERROR) {               ERRORLINE( config16, key );               continue;            }            syntax->inflate_tabs = key_no;            break;         case SHL_PTABSIZE :         case SHL_LTABSIZE :            i = atoi( key );            if (i > MAX_TAB_SIZE || i < 1) {               ERRORLINE( config8, key );               continue;            }            if (key_no == SHL_PTABSIZE)               syntax->ptab_size = i;            else               syntax->ltab_size = i;            break;         case SHL_KEYWORD:         case SHL_NORMAL:         case SHL_BAD:         case SHL_SYMBOL:         case SHL_INTEGER:         case SHL_REAL:         default:            add_keyword_list( syntax, key_no, key, residue );      }   }}#undef U/* * Name:    add_keyword_list * Purpose: add a line of keywords to the syntax highlighting info * Passed:  syntax:  syntax structure containing the keywords *          color:   color of the keywords *          key:     first keyword *          residue: rest of the keywords */void add_keyword_list( LANGUAGE *syntax, int color, char *key, char *residue ){   if (color >= 256)      color = syntax_color[color - 256];   while (*key != '\0' && !out_of_memory) {      add_keyword( syntax, key, color );      residue = parse_token( residue, key );   }}/* * Name:    add_keyword * Purpose: update the keyword list * Passed:  syntax: syntax structure containing the keywords *          key:    keyword *          color:  color of the keyword * Notes:   uses a hash table based on the first two characters. *          The first character is the color, the rest is the word itself. */void add_keyword( LANGUAGE *syntax, char *key, int color ){text_ptr keyword;int  hash;text_ptr *hashed;int  i;int  len;int  rc = OK;   /*    * Add the keyword if it doesn't already exist.    */   if ((keyword = is_keyword( syntax, key, FALSE )) == NULL) {      len = strlen( key ) + 1;      keyword = (text_ptr)my_malloc( len + 1, &rc );      if (rc == OK) {         my_memcpy( keyword+1, key, len );         hash = KWHASH( key );         /*          * Create a bigger array.          */         if (syntax->keyword[hash]) {            /*             * Find the number of words already allocated.             */            for (i = 0; syntax->keyword[hash][i]; ++i) ;            hashed = (text_ptr *)my_malloc( (i+2) * sizeof(text_ptr), &rc );            if (rc == OK) {               for (; i >= 0; --i)                  hashed[i+1] = syntax->keyword[hash][i];               my_free( syntax->keyword[hash] );            }         } else {            /*             * Start a new list.             */            hashed = (text_ptr *)my_malloc( 2 * sizeof(text_ptr), &rc );            if (rc == OK)               hashed[1] = NULL;         }         if (hashed == NULL)            my_free( keyword );         else {            syntax->keyword[hash]    = hashed;            syntax->keyword[hash][0] = keyword;         }      }      if (rc == ERROR) {         /*          * out of memory          */         error( WARNING, prompt_line, main4 );         out_of_memory = TRUE;         return;      }   }   keyword[0] = color;}/* * Name:    is_keyword * Purpose: determine if a string is a keyword * Passed:  syntax: pointer to the syntax info *          word:   string to test *          parent: TRUE to scan the parent language's keywords. * Returns: pointer to the keyword if it exists, NULL otherwise */text_ptr is_keyword( LANGUAGE *syntax, char *word, int parent ){int hash;int i;   hash = KWHASH( word );   if (syntax->keyword[hash] != NULL)      for (i = 0; syntax->keyword[hash][i]; ++i)         if (!my_strcmp( syntax->keyword[hash][i]+1, (text_ptr)word ))            return( syntax->keyword[hash][i] );   return( (parent && syntax->parent) ?           is_keyword( syntax->parent, word, parent ) : NULL );}/* * Name:    syntax_init_colors * Purpose: set the colors for the syntax highlighting components * Passed:  fp: file pointer of syntax file * Notes:   goes back to the start of the file, reads the colors, and *           restores the file position. * 990421:  modified to use the new parse_color() function. */void syntax_init_colors( FILE *fp ){long pos;                       /* current position in the file */unsigned old_line;              /* current line number of the file */char *color;int  key;char col[1042];int  color_no;const char *errmsg = NULL;   pos = ftell( fp );   rewind( fp );   old_line = line_no;   line_no  = 0;   for (;;) {      key = syntax_read_line( fp, &color );      if (key == SHL_LANGUAGE)         break;      if ((key > SHL_SYMBOL || key < SHL_NORMAL) && key != SHL_BACKGROUND)         errmsg = syntax3;      else {         color_no = parse_color( &color, col, prompt_line, config6a );         if (color_no != ERROR) {            if (key == SHL_BACKGROUND) {               color_no >>= 4;               background = color_no & 15;            } else               syntax_color[key - 256] = color_no;         }      }      if (errmsg != NULL) {         ERRORLINE( errmsg, col );         errmsg = NULL;      }   }   fseek( fp, pos, SEEK_SET );   line_no = old_line;}/* * Name:    syntax_init_lines * Purpose: set the initial line flags for syntax highlighting * Passed:  file: pointer to the file to be initialized * * 060915:  set the tab settings. */void syntax_init_lines( file_infos *file ){syntax_info *syntax;line_list_ptr ll;   /*    * No point doing this if the file doesn't have highlighting.    */   if (file->syntax != NULL) {      syntax = file->syntax->info;      ll     = file->line_list->next;      while (ll->len != EOF) {         syntax_check( ll, syntax );         ll = ll->next;      }      if (g_option.tab_size == -1) {         if (file->syntax->inflate_tabs != ERROR)            file->inflate_tabs = file->syntax->inflate_tabs;         if (file->syntax->ptab_size)            file->ptab_size = file->syntax->ptab_size;      }      if (file->syntax->ltab_size)         file->ltab_size = file->syntax->ltab_size;   }}/* * Name:    match_comment * Purpose: determine if the line contains a comment * Author:  Jason Hood * Date:    November 23, 2001 * Passed:  comment:  comment to test *          line:     line to test against *          pos:      position in line to start test *          len:      length of line * Returns: length of the comment, or 0 if no match * Notes:   comment should exist (ie. be at least one character). */static int  match_comment( text_ptr comment, text_ptr line, int pos, int len ){text_ptr start = comment;   line += pos;   len -= pos;   while (*comment == *line++  &&  *++comment  &&  --len);   if (*comment == '\0')      return( (int)(comment - start) );   return( 0 );}/* * Name:    syntax_check * Purpose: determine the syntax highlighting flags for a line * Passed:  line:   line to test *          syntax: language to test against * Notes:   The previous line must have the right flags. * * This function is used to determine what type of line a line is. It enables * us to jump to any part of the file, without the need to backtrack to see if * we're in a comment or string, like Elvis does. As such, it's only required * for the stuff that uses multiple lines, namely comments, strings, characters * and some preprocessors (like C). However, if these start and finish in the * one line, there's no need to type them, since they have no effect on * subsequent lines. * * Comments (COM), strings (STR) and characters (CHR) consist of three * components: _START, _WHOLE and _END. _START means it begins somewhere on the * line and extends to the end of the line; _WHOLE means the entire line is * occupied; _END means it continues from the beginning of the line, but stops * somewhere. _START and _WHOLE are used to "inherit" the new line type from * the previous line. _WHOLE and _END are used to indicate that this line is * still (partly) a comment, string or character, for display purposes (ie. * syntax_attr()) - which is the whole point of doing this typing. * * Strings and characters also have START_VALID, WHOLE_VALID and END_VALID * values, which indicates if it is actually legally allowed to span multiple * lines. (Note that they always do span lines, they never stop at eol, like * some versions of BASIC allowed.) * * Preprocessor is a little different, since it always occupies the whole line, * but can still have the above components. So it has PREPRO to indicate that * the line is a preprocessor, and _START and _END components to indicate the * first and last lines of the preprocessor. The new line will be PREPRO if the * last line was PREPRO, but not PREPRO_END. PREPRO_START is used in * syntax_attr() to indicate that we should still test for preprocessor, so * leading blanks will be done in normal, and preprocessor will be recognized * before comment (with Pascal's {$ and shell scripts' #!, for example). * * jmh 030411: fixed bug with spanning (this wasn't set correctly). */void syntax_check( line_list_ptr line, syntax_info *syntax ){text_ptr ll;int  len;long old_type;          /* type of the previous line */long type;              /* type of this line */int  in_comment;int  in_string;int  in_character;int  in_prepro;text_t this, next;int  com_len, com_num;long com_bit;int  i;

⌨️ 快捷键说明

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