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

📄 syntax.c

📁 一个开源著名的TDE编辑器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      }      if (errmsg != NULL) {         key = ERROR;         if (!in_macro && line_no > error_no) {            ERRORLINE( errmsg, token );            error_no = line_no;         }      }   } while (key == ERROR);   return( key );}/* * Name:    add_language * Purpose: add a language to the list * Passed:  lang:   the language to add *          parent: parent language or NULL for no parent * Returns: pointer to new language on success; NULL on error (no memory) * * 980531:  added the defaults. */LANGUAGE *add_language( char *lang, LANGUAGE *parent ){LANGUAGE *new_lang;syntax_info *info = NULL;int  rc  = OK;int  len = strlen( lang );   new_lang = (LANGUAGE *)calloc( 1, sizeof(LANGUAGE) + len );   if (new_lang == NULL)      rc = ERROR;   else if (parent == NULL) {      info = (syntax_info *)calloc( 1, sizeof(syntax_info) );      if (info == NULL) {         rc = ERROR;         free( new_lang );      } else         new_lang->info = info;   } else {      new_lang->info   = parent->info;      new_lang->parent = parent;   }   if (rc == OK) {      new_lang->next = g_status.language_list;      g_status.language_list = new_lang;      memcpy( new_lang->name, lang, len + 1 );      new_lang->key_tree.key = 0x10000L;            /*       * Use config setting for tab mode if this is not set.       */      new_lang->inflate_tabs = ERROR;      if (info != NULL)         lang_defaults( info );   } else      /*       * out of memory       */      error( WARNING, prompt_line, main4 );   return( rc == OK ) ? new_lang : NULL;}/* * Name:    lang_defaults * Purpose: set default language information * Author:  Jason Hood * Date:    December 2, 2003 * Passed:  info:  information being set * Notes:   assumes info has been cleared on entry */static void lang_defaults( syntax_info *info ){int  j;   /*    * Characters have only one character (plus the closing quote character).    */   info->charnum = 2;   /*    * Case sensitive.    */   info->icase = MATCH;   /*    * Identifiers can start with a letter and contain letters and digits.    * Digits are set with their appropriate bases.    */   for (j = 0; j < 256; ++j) {      if (bj_isalpha( j ))         info->identifier[j] = ID_STARTWORD | ID_INWORD;      else if (bj_isdigit( j ))         info->identifier[j] = ID_INWORD | ID_DIGIT | ID_DECIMAL;      if (bj_isxdigit( j ))         info->identifier[j] |= ID_HEX | ID_DIGIT;   }   info->identifier[(int)'0'] |= ID_BINARY | ID_OCTAL;   info->identifier[(int)'1'] |= ID_BINARY | ID_OCTAL;   for (j = '2'; j < '8'; ++j)      info->identifier[j] |= ID_OCTAL;}/* * Name:    syntax_parse_file * Purpose: grab all the syntax highlighting info for a language * Passed:  fp:     file pointer of syntax file *          syntax: place to store the info * Notes:   reads from the current position till the next "language" or eof. *          Some components are either setting it, or using it as a color for *           a list of words (eg. "comment //", "comment rem"). If the first *           character can start a word, assume the latter. This also implies *           that startword should be done before keywords. * * 980531:  moved the defaults to add_language. * 990426:  turn in_macro off. * 990503:  added the U macro for consistent array referencing. * 011122:  expanded comments to four characters and allow two of each type. * 020623:  fixed a bug in recognizing the second line comment. */#define U( c ) (text_t)(c)void syntax_parse_file( FILE *fp, LANGUAGE *syntax ){syntax_info *info = syntax->info;char key[1042];                 /* buffer to hold any token that we parse */char *residue;                  /* pointer to next item in line, if it exists */int  key_no;                    /* index into key array */char *number;                   /* pointer to one of the bases */int  i, j;   for (;;) {      key_no = syntax_read_line( fp, &residue );      if (key_no == SHL_LANGUAGE || key_no == ERROR)         break;      if (key_no == SHL_MACRO) {         parse_line( line_in, prompt_line );         while (process_macro) {            if (syntax_read_line( fp, &residue ) == ERROR) {               /*                * Unexpected end of file.                * Tidy up the macro definition.                */               check_macro( mac );               error( WARNING, prompt_line, config26 );            } else               parse_macro( line_in, prompt_line );         }         in_macro = FALSE;         continue;      } else if (key_no == SHL_BACKGROUND) {         key_no = parse_color( &residue, key, prompt_line, config6a );         if (key_no != ERROR) {            key_no >>= 4;            background = key_no & 15;         }         continue;      }      residue = parse_token( residue, key );      switch (key_no) {         case SHL_PATTERN:            /*             * Setting is in the wrong place.             */            ERRORLINE( syntax5, key );            break;         case SHL_CASE:            key_no = search( key, case_modes, 1 );            if (key_no == ERROR) {               ERRORLINE( syntax6, key ); /* case setting not recognized */            } else {               info->icase = key_no;               sort.order_array = (key_no == MATCH) ? sort_order.match :                                                      sort_order.ignore;            }            break;         case SHL_ESCAPE:            if (strlen( key ) != 1 || bj_isalnum( *key )) {               ERRORLINE( syntax7, key ); /* expecting one non-alphanumeric */            } else               info->escape = *key;            break;         case SHL_STARTWORD:         case SHL_INWORD:            /*             * Allow a range using '-', provided it's not at the beginning             * or end of the key and the end-character is greater than the             * start-character.             */            key_no = (key_no == SHL_STARTWORD) ? ID_STARTWORD :                                                 ID_INWORD;            while (*key) {               for (i = 0; key[i]; ++i) {                  if (key[i] == '-' && (i != 0 && key[i+1] != '\0') &&                      U( key[i+1] ) > U( key[i-1] )) {                     ++i;                     for (j = U( key[i-2] ) + 1; j < U( key[i] ); ++j)                        info->identifier[j] |= key_no;                  }                  info->identifier[U( key[i] )] |= key_no;               }               residue = parse_token( residue, key );            }            break;         case SHL_INNUMBER:            /*             * Different from the above in that numbers are case insensitive,             * so transform both cases of a letter.             */            key_no = ID_DIGIT | ID_BINARY | ID_OCTAL | ID_DECIMAL | ID_HEX;            while (*key) {               for (i = 0; key[i]; ++i) {                  if (key[i] == '-' && (i != 0 && key[i+1] != '\0') &&                      U( key[i+1] ) > U( key[i-1] )) {                     ++i;                     for (j = U( key[i-2] + 1 ); j < U( key[i] ); ++j) {                        info->identifier[bj_tolower( j )] |= key_no;                        info->identifier[bj_toupper( j )] |= key_no;                     }                  }                  info->identifier[bj_tolower( key[i] )] |= key_no;                  info->identifier[bj_toupper( key[i] )] |= key_no;               }               residue = parse_token( residue, key );            }            break;         case SHL_COMMENT:            if (info->identifier[U( *key )] & ID_STARTWORD)               add_keyword_list( syntax, key_no, key, residue );            else {               if (strlen( key ) > 4) {                  ERRORLINE( syntax8b, key ); /*only one to four chars allowed*/               /*                * comment has two forms: "comment one" or "comment one two".                * The first is a line comment; the second is the start and end                * of a multi-line comment.                */               } else {                  char com[5];                  strcpy( com, key );                  parse_token( residue, key );                  if (*key) {                     if (strlen( key ) > 4) {                        ERRORLINE( syntax8b, key );                     } else if (info->comstart[1][0] != '\0') {                        ERRORLINE( syntax14a, key );                     } else {                        int com_num = (info->comstart[0][0] != '\0');                        strcpy( (char *)info->comstart[com_num], com );                        strcpy( (char *)info->comend[com_num], key );                     }                  } else if (info->comment[1][0] != '\0') {                     ERRORLINE( syntax14b, key );                  } else {                     int com_num = (info->comment[0][0] != '\0');                     strcpy( (char *)info->comment[com_num], com );                  }               }            }            break;         case SHL_FUNCTION:            if (info->identifier[U( *key )] & ID_STARTWORD)               add_keyword_list( syntax, key_no, key, residue );            else {               if (strlen( key ) > 1) {                  ERRORLINE( syntax9, key );    /* only one char allowed */               } else                  info->function = *key;            }            break;         case SHL_PREPRO:            if (info->identifier[U( *key )] & ID_STARTWORD)               add_keyword_list( syntax, key_no, key, residue );            else {               if (strlen( key ) > 2) {                  ERRORLINE( syntax8a, key );               } else {                  info->prepro[0] = key[0];                  info->prepro[1] = key[1];                  residue = parse_token( residue, key );                  if (*key && *key != ';') {                     if (search( key, valid_string, 1 ) != SHL_SPANLINE) {                        ERRORLINE( syntax5, key ); /* setting in wrong place */                     } else {                        parse_token( residue, key );                        if (strlen( key ) != 1 || bj_isalnum( *key )) {                           ERRORLINE( syntax7, key );                        } else                           info->prepspan = *key;                     }                  }               }            }            break;         case SHL_BINARY:         case SHL_OCTAL:         case SHL_HEX:            if ((info->identifier[U( *key )] & ID_STARTWORD) &&                (key[1] != '-' && key[2] != '-'))               add_keyword_list( syntax, key_no, key, residue );            else {               if (key_no == SHL_BINARY)                  number = (char *)info->binary;               else if (key_no == SHL_OCTAL)                  number = (char *)info->octal;               else                  number = (char *)info->hex;               /*                * The based numbers can have two forms: "base a[b]-" or                * "base -a[b]". The former specifies a one- or two-character                * prefix (eg. a[b]123); the latter is a suffix (123a[b]).                */               residue = key;               if (residue[0] == '-') {                  number[0] = SUFFIX;                  ++residue;               }               number[1] = bj_tolower( residue[0] );               if (residue[1] != '-') {                  number[2] = bj_tolower( residue[1] );                  ++residue;               }               if (residue[1] != '-' && number[0] != SUFFIX) {                  ERRORLINE( syntax10, key );   /* requires prefix or suffix */               } else if (residue[1] == '-') {                  if (number[0] == SUFFIX) {                     ERRORLINE( syntax11, key ); /* can't be prefix & suffix */                  } else                     number[0] = PREFIX;               }            }            break;         case SHL_STRING:            if (info->identifier[U( *key )] & ID_STARTWORD)               add_keyword_list( syntax, key_no, key, residue );            else {               if (strlen( key ) > 2) {                  ERRORLINE( syntax8a, key );               } else {                  /*                   * Strings can have three forms: "string a", "string ab" or                   * "string a b". The first indicates that the open and close                   * quote character are the same. The other two specify the                   * quote characters individually. Strings can also have                   * "newline" and "spanline a" (where "a" is non-alphanumeric)                   * modifiers.                   */                  if (key[1] == '\0') {                     info->strstart = key[0];                     number = parse_token( residue, key );                     if (key[0] != '\0' && key[1] == '\0') {                        info->strend = key[0];                        residue = number;                     } else                        info->strend = info->strstart;                  } else {                     info->strstart = key[0];                     info->strend   = key[1];                  }                  for (;;) {                     residue = parse_token( residue, key );                     if (*key == '\0' || *key == ';')                        break;                     key_no = search( key, valid_string, 1 );                     if (key_no == ERROR) {                        ERRORLINE( syntax5, key );                        continue;                     }                     if (key_no == SHL_NEWLINE)

⌨️ 快捷键说明

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