1998-04-24 19:18:08 +04:00
/* editor syntax highlighting.
Copyright ( C ) 1996 , 1997 , 1998 the Free Software Foundation
Authors : 1998 Paul Sheer
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA . */
# include <config.h>
# ifdef MIDNIGHT
# include "edit.h"
# else
# include "coolwidget.h"
# endif
# if !defined(MIDNIGHT) || defined(HAVE_SYNTAXH)
int option_syntax_highlighting = 1 ;
/* these three functions are called from the outside */
void edit_load_syntax ( WEdit * edit , char * * names , char * type ) ;
void edit_free_syntax_rules ( WEdit * edit ) ;
void edit_get_syntax_color ( WEdit * edit , long byte_index , int * fg , int * bg ) ;
static void * syntax_malloc ( size_t x )
{
void * p ;
p = malloc ( x ) ;
memset ( p , 0 , x ) ;
return p ;
}
# define syntax_free(x) {if(x){free(x);(x)=0;}}
static int compare_word_to_right ( WEdit * edit , long i , char * text , char * whole_left , char * whole_right , int line_start )
{
char * p ;
1998-04-29 05:15:19 +04:00
int c , j ;
1998-04-24 19:18:08 +04:00
if ( ! * text )
return 0 ;
c = edit_get_byte ( edit , i - 1 ) ;
if ( line_start )
if ( c ! = ' \n ' )
return 0 ;
if ( whole_left )
if ( strchr ( whole_left , c ) )
return 0 ;
for ( p = text ; * p ; p + + , i + + ) {
1998-04-29 05:15:19 +04:00
switch ( * p ) {
case ' \001 ' :
1998-04-24 19:18:08 +04:00
p + + ;
for ( ; ; ) {
c = edit_get_byte ( edit , i ) ;
1998-04-29 05:15:19 +04:00
if ( c = = * p )
break ;
1998-04-24 19:18:08 +04:00
if ( c = = ' \n ' )
return 0 ;
1998-04-29 05:15:19 +04:00
i + + ;
}
break ;
case ' \002 ' :
p + + ;
for ( ; ; ) {
c = edit_get_byte ( edit , i ) ;
1998-04-24 19:18:08 +04:00
if ( c = = * p )
break ;
1998-04-29 05:15:19 +04:00
if ( c = = ' \n ' | | c = = ' \t ' | | c = = ' ' )
return 0 ;
1998-04-24 19:18:08 +04:00
i + + ;
}
1998-04-29 05:15:19 +04:00
break ;
case ' \003 ' :
p + + ;
#if 0
c = edit_get_byte ( edit , i + + ) ;
for ( j = 0 ; p [ j ] ! = ' \003 ' ; j + + )
if ( c = = p [ j ] )
goto found_char1 ;
return 0 ;
found_char1 :
# endif
for ( ; ; i + + ) {
c = edit_get_byte ( edit , i ) ;
for ( j = 0 ; p [ j ] ! = ' \003 ' ; j + + )
if ( c = = p [ j ] )
goto found_char2 ;
break ;
found_char2 :
}
i - - ;
while ( * p ! = ' \003 ' )
p + + ;
break ;
#if 0
case ' \004 ' :
p + + ;
c = edit_get_byte ( edit , i + + ) ;
for ( j = 0 ; p [ j ] ! = ' \004 ' ; j + + )
if ( c = = p [ j ] )
return 0 ;
for ( ; ; i + + ) {
c = edit_get_byte ( edit , i ) ;
for ( j = 0 ; p [ j ] ! = ' \004 ' ; j + + )
if ( c = = p [ j ] )
goto found_char4 ;
continue ;
found_char4 :
break ;
}
i - - ;
while ( * p ! = ' \004 ' )
p + + ;
break ;
# endif
default :
1998-04-24 19:18:08 +04:00
if ( * p ! = edit_get_byte ( edit , i ) )
return 0 ;
}
}
if ( whole_right )
if ( strchr ( whole_right , edit_get_byte ( edit , i ) ) )
return 0 ;
return 1 ;
}
static int compare_word_to_left ( WEdit * edit , long i , char * text , char * whole_left , char * whole_right , int line_start )
{
char * p ;
1998-04-29 05:15:19 +04:00
int c , j ;
#if 0
int d ;
# endif
1998-04-24 19:18:08 +04:00
if ( ! * text )
return 0 ;
if ( whole_right )
if ( strchr ( whole_right , edit_get_byte ( edit , i + 1 ) ) )
return 0 ;
for ( p = text + strlen ( text ) - 1 ; ( unsigned long ) p > = ( unsigned long ) text ; p - - , i - - ) {
1998-04-29 05:15:19 +04:00
switch ( * p ) {
case ' \001 ' :
1998-04-24 19:18:08 +04:00
p - - ;
for ( ; ; ) {
c = edit_get_byte ( edit , i ) ;
1998-04-29 05:15:19 +04:00
if ( c = = * p )
break ;
1998-04-24 19:18:08 +04:00
if ( c = = ' \n ' )
return 0 ;
1998-04-29 05:15:19 +04:00
i - - ;
}
break ;
case ' \002 ' :
p - - ;
for ( ; ; ) {
c = edit_get_byte ( edit , i ) ;
1998-04-24 19:18:08 +04:00
if ( c = = * p )
break ;
1998-04-29 05:15:19 +04:00
if ( c = = ' \n ' | | c = = ' \t ' | | c = = ' ' )
return 0 ;
1998-04-24 19:18:08 +04:00
i - - ;
}
1998-04-29 05:15:19 +04:00
break ;
case ' \003 ' :
while ( * ( - - p ) ! = ' \003 ' ) ;
p + + ;
#if 0
c = edit_get_byte ( edit , i - - ) ;
for ( j = 0 ; p [ j ] ! = ' \003 ' ; j + + )
if ( c = = p [ j ] )
goto found_char1 ;
return 0 ;
found_char1 :
# endif
for ( ; ; i - - ) {
c = edit_get_byte ( edit , i ) ;
for ( j = 0 ; p [ j ] ! = ' \003 ' ; j + + )
if ( c = = p [ j ] )
goto found_char2 ;
break ;
found_char2 :
}
i + + ;
p - - ;
break ;
#if 0
case ' \004 ' :
while ( * ( - - p ) ! = ' \004 ' ) ;
d = * p ;
p + + ;
c = edit_get_byte ( edit , i - - ) ;
for ( j = 0 ; p [ j ] ! = ' \004 ' ; j + + )
if ( c = = p [ j ] )
return 0 ;
for ( ; ; i - - ) {
c = edit_get_byte ( edit , i ) ;
for ( j = 0 ; p [ j ] ! = ' \004 ' ; j + + )
if ( c = = p [ j ] | | c = = ' \n ' | | c = = d )
goto found_char4 ;
continue ;
found_char4 :
break ;
}
i + + ;
p - - ;
break ;
# endif
default :
1998-04-24 19:18:08 +04:00
if ( * p ! = edit_get_byte ( edit , i ) )
return 0 ;
}
}
c = edit_get_byte ( edit , i ) ;
if ( line_start )
if ( c ! = ' \n ' )
return 0 ;
if ( whole_left )
if ( strchr ( whole_left , c ) )
return 0 ;
return 1 ;
}
#if 0
1998-04-29 05:15:19 +04:00
# define debug_printf(x,y) fprintf(stderr,x,y)
1998-04-24 19:18:08 +04:00
# else
# define debug_printf(x,y)
# endif
1998-05-01 13:32:43 +04:00
static inline unsigned long apply_rules_going_right ( WEdit * edit , long i , unsigned long rule )
1998-04-24 19:18:08 +04:00
{
struct context_rule * r ;
int context , keyword , c1 , c2 ;
1998-04-29 05:15:19 +04:00
int found_right = 0 , found_left = 0 ;
int done = 0 ;
1998-04-24 19:18:08 +04:00
unsigned long border ;
context = ( rule & RULE_CONTEXT ) > > RULE_CONTEXT_SHIFT ;
keyword = ( rule & RULE_WORD ) > > RULE_WORD_SHIFT ;
border = rule & ( RULE_ON_LEFT_BORDER | RULE_ON_RIGHT_BORDER ) ;
c1 = edit_get_byte ( edit , i - 1 ) ;
c2 = edit_get_byte ( edit , i ) ;
1998-05-01 13:32:43 +04:00
if ( ! c2 | | ! c1 )
return rule ;
1998-04-24 19:18:08 +04:00
debug_printf ( " %c-> " , c1 ) ;
debug_printf ( " %c " , c2 ) ;
1998-04-29 05:15:19 +04:00
/* check to turn off a keyword */
if ( keyword ) {
struct key_word * k ;
k = edit - > rules [ context ] - > keyword [ keyword ] ;
if ( k - > last = = c1 & & compare_word_to_left ( edit , i - 1 , k - > keyword , k - > whole_word_chars_left , k - > whole_word_chars_right , k - > line_start ) ) {
keyword = 0 ;
debug_printf ( " keyword=%d " , keyword ) ;
}
}
debug_printf ( " border=%s " , border ? ( ( border & RULE_ON_LEFT_BORDER ) ? " left " : " right " ) : " off " ) ;
1998-04-24 19:18:08 +04:00
/* check to turn off a context */
if ( context & & ! keyword ) {
r = edit - > rules [ context ] ;
1998-04-29 05:15:19 +04:00
if ( r - > first_right = = c2 & & compare_word_to_right ( edit , i , r - > right , r - > whole_word_chars_left , r - > whole_word_chars_right , r - > line_start_right ) \
& & ! ( rule & RULE_ON_RIGHT_BORDER ) ) {
debug_printf ( " A:3 " , 0 ) ;
found_right = 1 ;
1998-04-24 19:18:08 +04:00
border = RULE_ON_RIGHT_BORDER ;
if ( r - > between_delimiters ) {
context = 0 ;
keyword = 0 ;
}
1998-04-29 05:15:19 +04:00
} else if ( ! found_left ) {
if ( r - > last_right = = c1 & & compare_word_to_left ( edit , i - 1 , r - > right , r - > whole_word_chars_left , r - > whole_word_chars_right , r - > line_start_right ) \
& & ( rule & RULE_ON_RIGHT_BORDER ) ) {
/* always turn off a context at 4 */
debug_printf ( " A:4 " , 0 ) ;
found_left = 1 ;
border = 0 ;
1998-04-24 19:18:08 +04:00
context = 0 ;
1998-04-29 05:15:19 +04:00
keyword = 0 ;
} else if ( r - > last_left = = c1 & & compare_word_to_left ( edit , i - 1 , r - > left , r - > whole_word_chars_left , r - > whole_word_chars_right , r - > line_start_left ) \
& & ( rule & RULE_ON_LEFT_BORDER ) ) {
/* never turn off a context at 2 */
debug_printf ( " A:2 " , 0 ) ;
found_left = 1 ;
border = 0 ;
1998-04-24 19:18:08 +04:00
keyword = 0 ;
}
}
}
debug_printf ( " \n " , 0 ) ;
/* check to turn on a context */
if ( ! context & & ! keyword ) {
int count ;
1998-04-29 05:15:19 +04:00
for ( count = 1 ; edit - > rules [ count ] & & ! done ; count + + ) {
1998-04-24 19:18:08 +04:00
r = edit - > rules [ count ] ;
1998-04-29 05:15:19 +04:00
if ( ! found_left ) {
if ( r - > last_right = = c1 & & compare_word_to_left ( edit , i - 1 , r - > right , r - > whole_word_chars_left , r - > whole_word_chars_right , r - > line_start_right ) \
& & ( rule & RULE_ON_RIGHT_BORDER ) ) {
debug_printf ( " B:4 count=%d " , count ) ;
found_left = 1 ;
border = 0 ;
context = 0 ;
} else if ( r - > last_left = = c1 & & compare_word_to_left ( edit , i - 1 , r - > left , r - > whole_word_chars_left , r - > whole_word_chars_right , r - > line_start_left ) \
& & ( rule & RULE_ON_LEFT_BORDER ) ) {
debug_printf ( " B:2 " , 0 ) ;
found_left = 1 ;
border = 0 ;
1998-04-24 19:18:08 +04:00
if ( r - > between_delimiters ) {
context = count ;
debug_printf ( " context=%d " , context ) ;
keyword = 0 ;
1998-04-29 05:15:19 +04:00
if ( r - > first_right = = c2 & & compare_word_to_right ( edit , i , r - > right , r - > whole_word_chars_left , r - > whole_word_chars_right , r - > line_start_right ) ) {
debug_printf ( " B:3 " , 0 ) ;
found_right = 1 ;
border = RULE_ON_RIGHT_BORDER ;
context = 0 ;
keyword = 0 ;
}
}
break ;
}
}
if ( ! found_right ) {
if ( r - > first_left = = c2 & & compare_word_to_right ( edit , i , r - > left , r - > whole_word_chars_left , r - > whole_word_chars_right , r - > line_start_left ) ) {
debug_printf ( " B:1 " , 0 ) ;
found_right = 1 ;
border = RULE_ON_LEFT_BORDER ;
if ( ! r - > between_delimiters ) {
context = count ;
debug_printf ( " context=%d " , context ) ;
keyword = 0 ;
1998-04-24 19:18:08 +04:00
}
break ;
}
}
}
}
/* check to turn on a keyword */
if ( ! keyword ) {
1998-04-25 15:52:29 +04:00
char * p ;
p = ( r = edit - > rules [ context ] ) - > keyword_first_chars ;
while ( ( p = strchr ( p + 1 , c2 ) ) ) {
1998-04-24 19:18:08 +04:00
struct key_word * k ;
1998-04-25 15:52:29 +04:00
int count ;
count = ( unsigned long ) p - ( unsigned long ) r - > keyword_first_chars ;
1998-04-24 19:18:08 +04:00
k = r - > keyword [ count ] ;
1998-04-25 15:52:29 +04:00
if ( compare_word_to_right ( edit , i , k - > keyword , k - > whole_word_chars_left , k - > whole_word_chars_right , k - > line_start ) ) {
keyword = count ;
debug_printf ( " keyword=%d " , keyword ) ;
break ;
}
1998-04-24 19:18:08 +04:00
}
}
debug_printf ( " border=%s " , border ? ( ( border & RULE_ON_LEFT_BORDER ) ? " left " : " right " ) : " off " ) ;
debug_printf ( " keyword=%d " , keyword ) ;
1998-04-29 05:15:19 +04:00
debug_printf ( " %d# \n \n " , context ) ;
1998-04-24 19:18:08 +04:00
return ( context < < RULE_CONTEXT_SHIFT ) | ( keyword < < RULE_WORD_SHIFT ) | border ;
}
static inline int resolve_left_delim ( WEdit * edit , long i , struct context_rule * r , int s )
{
int c , count ;
if ( ! r - > conflicts )
return s ;
for ( ; ; ) {
c = edit_get_byte ( edit , i ) ;
if ( c = = ' \n ' )
break ;
for ( count = 1 ; r - > conflicts [ count ] ; count + + ) {
struct context_rule * p ;
p = edit - > rules [ r - > conflicts [ count ] ] ;
if ( ! p )
break ;
if ( p - > first_left = = c & & r - > between_delimiters = = p - > between_delimiters & & compare_word_to_right ( edit , i , p - > left , p - > whole_word_chars_left , r - > whole_word_chars_right , p - > line_start_left ) )
return r - > conflicts [ count ] ;
}
i - - ;
}
return 0 ;
}
1998-05-01 13:32:43 +04:00
static inline unsigned long apply_rules_going_left ( WEdit * edit , long i , unsigned long rule )
1998-04-24 19:18:08 +04:00
{
struct context_rule * r ;
1998-04-29 05:15:19 +04:00
int context , keyword , c2 , c1 ;
int found_left = 0 , found_right = 0 ;
int done = 0 ;
1998-04-24 19:18:08 +04:00
unsigned long border ;
context = ( rule & RULE_CONTEXT ) > > RULE_CONTEXT_SHIFT ;
keyword = ( rule & RULE_WORD ) > > RULE_WORD_SHIFT ;
1998-04-29 05:15:19 +04:00
border = rule & ( RULE_ON_RIGHT_BORDER | RULE_ON_LEFT_BORDER ) ;
1998-04-24 19:18:08 +04:00
c1 = edit_get_byte ( edit , i ) ;
c2 = edit_get_byte ( edit , i + 1 ) ;
1998-05-01 13:32:43 +04:00
if ( ! c2 | | ! c1 )
return rule ;
1998-04-24 19:18:08 +04:00
1998-04-29 05:15:19 +04:00
debug_printf ( " %c-> " , c2 ) ;
debug_printf ( " %c " , c1 ) ;
/* check to turn off a keyword */
if ( keyword ) {
struct key_word * k ;
k = edit - > rules [ context ] - > keyword [ keyword ] ;
if ( k - > first = = c2 & & compare_word_to_right ( edit , i + 1 , k - > keyword , k - > whole_word_chars_right , k - > whole_word_chars_left , k - > line_start ) ) {
keyword = 0 ;
debug_printf ( " keyword=%d " , keyword ) ;
}
}
debug_printf ( " border=%s " , border ? ( ( border & RULE_ON_RIGHT_BORDER ) ? " right " : " left " ) : " off " ) ;
1998-04-24 19:18:08 +04:00
/* check to turn off a context */
if ( context & & ! keyword ) {
r = edit - > rules [ context ] ;
1998-04-29 05:15:19 +04:00
if ( r - > last_left = = c1 & & compare_word_to_left ( edit , i , r - > left , r - > whole_word_chars_right , r - > whole_word_chars_left , r - > line_start_left ) \
& & ! ( rule & RULE_ON_LEFT_BORDER ) ) {
debug_printf ( " A:2 " , 0 ) ;
found_left = 1 ;
1998-04-24 19:18:08 +04:00
border = RULE_ON_LEFT_BORDER ;
if ( r - > between_delimiters ) {
context = 0 ;
keyword = 0 ;
}
1998-04-29 05:15:19 +04:00
} else if ( ! found_right ) {
if ( r - > first_left = = c2 & & compare_word_to_right ( edit , i + 1 , r - > left , r - > whole_word_chars_right , r - > whole_word_chars_left , r - > line_start_left ) \
& & ( rule & RULE_ON_LEFT_BORDER ) ) {
/* always turn off a context at 4 */
debug_printf ( " A:1 " , 0 ) ;
found_right = 1 ;
border = 0 ;
context = 0 ;
keyword = 0 ;
} else if ( r - > first_right = = c2 & & compare_word_to_right ( edit , i + 1 , r - > right , r - > whole_word_chars_right , r - > whole_word_chars_left , r - > line_start_right ) \
& & ( rule & RULE_ON_RIGHT_BORDER ) ) {
/* never turn off a context at 2 */
debug_printf ( " A:3 " , 0 ) ;
found_right = 1 ;
border = 0 ;
1998-04-24 19:18:08 +04:00
keyword = 0 ;
}
1998-04-29 05:15:19 +04:00
}
1998-04-24 19:18:08 +04:00
}
debug_printf ( " \n " , 0 ) ;
/* check to turn on a context */
if ( ! context & & ! keyword ) {
int count ;
1998-04-29 05:15:19 +04:00
for ( count = 1 ; edit - > rules [ count ] & & ! done ; count + + ) {
1998-04-24 19:18:08 +04:00
r = edit - > rules [ count ] ;
1998-04-29 05:15:19 +04:00
if ( ! found_right ) {
if ( r - > first_left = = c2 & & compare_word_to_right ( edit , i + 1 , r - > left , r - > whole_word_chars_right , r - > whole_word_chars_left , r - > line_start_left ) \
& & ( rule & RULE_ON_LEFT_BORDER ) ) {
debug_printf ( " B:1 count=%d " , count ) ;
found_right = 1 ;
border = 0 ;
context = 0 ;
} else if ( r - > first_right = = c2 & & compare_word_to_right ( edit , i + 1 , r - > right , r - > whole_word_chars_right , r - > whole_word_chars_left , r - > line_start_right ) \
& & ( rule & RULE_ON_RIGHT_BORDER ) ) {
if ( ! ( c2 = = ' \n ' & & r - > single_char ) ) {
debug_printf ( " B:3 " , 0 ) ;
found_right = 1 ;
border = 0 ;
if ( r - > between_delimiters ) {
context = resolve_left_delim ( edit , i , r , count ) ;
1998-04-24 19:18:08 +04:00
debug_printf ( " context=%d " , context ) ;
1998-04-29 05:15:19 +04:00
keyword = 0 ;
if ( r - > last_left = = c1 & & compare_word_to_left ( edit , i , r - > left , r - > whole_word_chars_right , r - > whole_word_chars_left , r - > line_start_left ) ) {
debug_printf ( " B:2 " , 0 ) ;
found_left = 1 ;
border = RULE_ON_LEFT_BORDER ;
context = 0 ;
keyword = 0 ;
}
1998-04-24 19:18:08 +04:00
}
1998-04-29 05:15:19 +04:00
break ;
}
}
}
if ( ! found_left ) {
if ( r - > last_right = = c1 & & compare_word_to_left ( edit , i , r - > right , r - > whole_word_chars_right , r - > whole_word_chars_left , r - > line_start_right ) ) {
if ( ! ( c1 = = ' \n ' & & r - > single_char ) ) {
debug_printf ( " B:4 " , 0 ) ;
found_left = 1 ;
border = RULE_ON_RIGHT_BORDER ;
if ( ! r - > between_delimiters )
context = resolve_left_delim ( edit , i - 1 , r , count ) ;
keyword = 0 ;
break ;
}
}
1998-04-24 19:18:08 +04:00
}
}
}
/* check to turn on a keyword */
if ( ! keyword ) {
1998-04-25 15:52:29 +04:00
char * p ;
p = ( r = edit - > rules [ context ] ) - > keyword_last_chars ;
while ( ( p = strchr ( p + 1 , c1 ) ) ) {
1998-04-24 19:18:08 +04:00
struct key_word * k ;
1998-04-25 15:52:29 +04:00
int count ;
count = ( unsigned long ) p - ( unsigned long ) r - > keyword_last_chars ;
1998-04-24 19:18:08 +04:00
k = r - > keyword [ count ] ;
1998-04-29 05:15:19 +04:00
if ( compare_word_to_left ( edit , i , k - > keyword , k - > whole_word_chars_right , k - > whole_word_chars_left , k - > line_start ) ) {
1998-04-24 19:18:08 +04:00
keyword = count ;
debug_printf ( " keyword=%d " , keyword ) ;
break ;
}
}
}
1998-04-29 05:15:19 +04:00
debug_printf ( " border=%s " , border ? ( ( border & RULE_ON_RIGHT_BORDER ) ? " right " : " left " ) : " off " ) ;
debug_printf ( " keyword=%d " , keyword ) ;
1998-04-24 19:18:08 +04:00
1998-04-29 05:15:19 +04:00
debug_printf ( " %d# \n \n " , context ) ;
1998-04-24 19:18:08 +04:00
return ( context < < RULE_CONTEXT_SHIFT ) | ( keyword < < RULE_WORD_SHIFT ) | border ;
}
1998-04-29 05:15:19 +04:00
1998-04-24 19:18:08 +04:00
static unsigned long edit_get_rule ( WEdit * edit , long byte_index )
{
long i ;
if ( byte_index < 0 ) {
edit - > last_get_rule = - 1 ;
edit - > rule = 0 ;
return 0 ;
}
1998-04-29 05:15:19 +04:00
#if 0
if ( byte_index < edit - > last_get_rule_start_display ) {
/* this is for optimisation */
for ( i = edit - > last_get_rule_start_display - 1 ; i > = byte_index ; i - - )
edit - > rule_start_display = apply_rules_going_left ( edit , i , edit - > rule_start_display ) ;
edit - > last_get_rule_start_display = byte_index ;
edit - > rule = edit - > rule_start_display ;
} else
# endif
1998-04-24 19:18:08 +04:00
if ( byte_index > edit - > last_get_rule ) {
for ( i = edit - > last_get_rule + 1 ; i < = byte_index ; i + + )
edit - > rule = apply_rules_going_right ( edit , i , edit - > rule ) ;
} else if ( byte_index < edit - > last_get_rule ) {
for ( i = edit - > last_get_rule - 1 ; i > = byte_index ; i - - )
edit - > rule = apply_rules_going_left ( edit , i , edit - > rule ) ;
}
edit - > last_get_rule = byte_index ;
return edit - > rule ;
}
static void translate_rule_to_color ( WEdit * edit , unsigned long rule , int * fg , int * bg )
{
struct key_word * k ;
k = edit - > rules [ ( rule & RULE_CONTEXT ) > > RULE_CONTEXT_SHIFT ] - > keyword [ ( rule & RULE_WORD ) > > RULE_WORD_SHIFT ] ;
* bg = k - > bg ;
* fg = k - > fg ;
}
void edit_get_syntax_color ( WEdit * edit , long byte_index , int * fg , int * bg )
{
unsigned long rule ;
if ( ! edit - > rules | | byte_index > = edit - > last_byte | | ! option_syntax_highlighting ) {
# ifdef MIDNIGHT
* fg = NORMAL_COLOR ;
# else
* fg = NO_COLOR ;
* bg = NO_COLOR ;
# endif
} else {
rule = edit_get_rule ( edit , byte_index ) ;
translate_rule_to_color ( edit , rule , fg , bg ) ;
}
}
/*
Returns 0 on error / eof or a count of the number of bytes read
including the newline . Result must be free ' d .
*/
static int read_one_line ( char * * line , FILE * f )
{
char * p ;
int len = 256 , c , r = 0 , i = 0 ;
p = syntax_malloc ( len ) ;
for ( ; ; ) {
c = fgetc ( f ) ;
if ( c = = - 1 ) {
r = 0 ;
break ;
} else if ( c = = ' \n ' ) {
r = i + 1 ; /* extra 1 for the newline just read */
break ;
} else {
if ( i > = len - 1 ) {
char * q ;
q = syntax_malloc ( len * 2 ) ;
memcpy ( q , p , len ) ;
syntax_free ( p ) ;
p = q ;
len * = 2 ;
}
p [ i + + ] = c ;
}
}
p [ i ] = 0 ;
* line = p ;
return r ;
}
static char * strdup_convert ( char * s )
{
1998-04-29 05:15:19 +04:00
#if 0
int e = 0 ;
# endif
1998-04-24 19:18:08 +04:00
char * r , * p ;
p = r = strdup ( s ) ;
while ( * s ) {
switch ( * s ) {
case ' \\ ' :
s + + ;
switch ( * s ) {
case ' n ' :
* p = ' \n ' ;
break ;
case ' r ' :
* p = ' \r ' ;
break ;
case ' t ' :
* p = ' \t ' ;
break ;
case ' s ' :
* p = ' ' ;
break ;
case ' * ' :
* p = ' * ' ;
break ;
case ' \\ ' :
* p = ' \\ ' ;
break ;
1998-04-29 05:15:19 +04:00
case ' [ ' :
case ' ] ' :
if ( ( unsigned long ) p = = ( unsigned long ) r | | strlen ( s ) = = 1 )
* p = * s ;
else {
#if 0
if ( ! strncmp ( s , " [^ " , 2 ) ) {
* p = ' \004 ' ;
e = 1 ;
s + + ;
} else {
if ( e )
* p = ' \004 ' ;
else
# endif
* p = ' \003 ' ;
#if 0
e = 0 ;
}
# endif
}
break ;
1998-04-24 19:18:08 +04:00
default :
* p = * s ;
break ;
}
break ;
case ' * ' :
1998-04-29 05:15:19 +04:00
/* a * or + at the beginning or end of the line must be interpreted literally */
1998-04-24 19:18:08 +04:00
if ( ( unsigned long ) p = = ( unsigned long ) r | | strlen ( s ) = = 1 )
* p = ' * ' ;
else
* p = ' \001 ' ;
break ;
1998-04-29 05:15:19 +04:00
case ' + ' :
if ( ( unsigned long ) p = = ( unsigned long ) r | | strlen ( s ) = = 1 )
* p = ' + ' ;
else
* p = ' \002 ' ;
break ;
1998-04-24 19:18:08 +04:00
default :
* p = * s ;
break ;
}
s + + ;
p + + ;
}
* p = 0 ;
return r ;
}
# define whiteness(x) ((x) == '\t' || (x) == '\n' || (x) == ' ')
static void get_args ( char * l , char * * args , int * argc )
{
* argc = 0 ;
l - - ;
for ( ; ; ) {
char * p ;
for ( p = l + 1 ; * p & & whiteness ( * p ) ; p + + ) ;
if ( ! * p )
break ;
for ( l = p + 1 ; * l & & ! whiteness ( * l ) ; l + + ) ;
* l = ' \0 ' ;
* args = strdup_convert ( p ) ;
( * argc ) + + ;
args + + ;
}
* args = 0 ;
}
static void free_args ( char * * args )
{
while ( * args ) {
syntax_free ( * args ) ;
* args = 0 ;
args + + ;
}
}
# define check_a {if(!*a){result=line;break;}}
# define check_not_a {if(*a){result=line;break;}}
# ifdef MIDNIGHT
1998-04-29 05:15:19 +04:00
1998-04-24 19:18:08 +04:00
int try_alloc_color_pair ( char * fg , char * bg ) ;
1998-04-29 05:15:19 +04:00
int this_try_alloc_color_pair ( char * fg , char * bg )
{
char f [ 80 ] , b [ 80 ] , * p ;
if ( fg ) {
strcpy ( f , fg ) ;
p = strchr ( f , ' / ' ) ;
if ( p )
* p = ' \0 ' ;
fg = f ;
}
if ( bg ) {
strcpy ( b , bg ) ;
p = strchr ( b , ' / ' ) ;
if ( p )
* p = ' \0 ' ;
bg = b ;
}
return try_alloc_color_pair ( fg , bg ) ;
}
# else
int this_allocate_color ( char * fg )
{
char * p ;
if ( ! fg )
return allocate_color ( 0 ) ;
p = strchr ( fg , ' / ' ) ;
if ( ! p )
return allocate_color ( fg ) ;
return allocate_color ( p + 1 ) ;
}
1998-04-24 19:18:08 +04:00
# endif
/* returns line number on error */
static int edit_read_syntax_rules ( WEdit * edit , FILE * f )
{
char * fg , * bg ;
char whole_right [ 256 ] ;
char whole_left [ 256 ] ;
char * args [ 1024 ] , * l = 0 ;
int line = 0 ;
struct context_rule * * r , * c ;
int num_words = - 1 , num_contexts = - 1 ;
int argc , result = 0 ;
int i , j ;
args [ 0 ] = 0 ;
1998-04-29 05:15:19 +04:00
strcpy ( whole_left , " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890 " ) ;
strcpy ( whole_right , " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890 " ) ;
1998-04-24 19:18:08 +04:00
r = edit - > rules = syntax_malloc ( 256 * sizeof ( struct context_rule * ) ) ;
for ( ; ; ) {
char * * a ;
line + + ;
if ( ! read_one_line ( & l , f ) )
break ;
get_args ( l , args , & argc ) ;
a = args + 1 ;
if ( ! args [ 0 ] ) {
/* do nothing */
} else if ( ! strcmp ( args [ 0 ] , " wholechars " ) ) {
check_a ;
if ( ! strcmp ( * a , " left " ) ) {
a + + ;
strcpy ( whole_left , * a ) ;
} else if ( ! strcmp ( * a , " right " ) ) {
a + + ;
strcpy ( whole_right , * a ) ;
} else {
strcpy ( whole_left , * a ) ;
strcpy ( whole_right , * a ) ;
}
a + + ;
check_not_a ;
} else if ( ! strcmp ( args [ 0 ] , " context " ) ) {
check_a ;
if ( num_contexts = = - 1 ) {
if ( strcmp ( * a , " default " ) ) { /* first context is the default */
* a = 0 ;
check_a ;
}
a + + ;
c = r [ 0 ] = syntax_malloc ( sizeof ( struct context_rule ) ) ;
c - > left = strdup ( " " ) ;
c - > right = strdup ( " " ) ;
num_contexts = 0 ;
} else {
c = r [ num_contexts ] = syntax_malloc ( sizeof ( struct context_rule ) ) ;
if ( ! strcmp ( * a , " exclusive " ) ) {
a + + ;
c - > between_delimiters = 1 ;
}
check_a ;
if ( ! strcmp ( * a , " whole " ) ) {
a + + ;
c - > whole_word_chars_left = strdup ( whole_left ) ;
c - > whole_word_chars_right = strdup ( whole_right ) ;
} else if ( ! strcmp ( * a , " wholeleft " ) ) {
a + + ;
c - > whole_word_chars_left = strdup ( whole_left ) ;
} else if ( ! strcmp ( * a , " wholeright " ) ) {
a + + ;
c - > whole_word_chars_right = strdup ( whole_right ) ;
}
check_a ;
if ( ! strcmp ( * a , " linestart " ) ) {
a + + ;
c - > line_start_left = 1 ;
}
check_a ;
c - > left = strdup ( * a + + ) ;
check_a ;
if ( ! strcmp ( * a , " linestart " ) ) {
a + + ;
c - > line_start_right = 1 ;
}
check_a ;
c - > right = strdup ( * a + + ) ;
c - > last_left = c - > left [ strlen ( c - > left ) - 1 ] ;
c - > last_right = c - > right [ strlen ( c - > right ) - 1 ] ;
c - > first_left = * c - > left ;
c - > first_right = * c - > right ;
c - > single_char = ( strlen ( c - > right ) = = 1 ) ;
}
c - > keyword = syntax_malloc ( 1024 * sizeof ( struct key_word * ) ) ;
num_words = 1 ;
c - > keyword [ 0 ] = syntax_malloc ( sizeof ( struct key_word ) ) ;
fg = * a ;
if ( * a )
a + + ;
bg = * a ;
if ( * a )
a + + ;
# ifdef MIDNIGHT
1998-04-29 05:15:19 +04:00
c - > keyword [ 0 ] - > fg = this_try_alloc_color_pair ( fg , bg ) ;
1998-04-24 19:18:08 +04:00
# else
1998-04-29 05:15:19 +04:00
c - > keyword [ 0 ] - > fg = this_allocate_color ( fg ) ;
c - > keyword [ 0 ] - > bg = this_allocate_color ( bg ) ;
1998-04-24 19:18:08 +04:00
# endif
c - > keyword [ 0 ] - > keyword = strdup ( " " ) ;
check_not_a ;
num_contexts + + ;
} else if ( ! strcmp ( args [ 0 ] , " keyword " ) ) {
struct key_word * k ;
if ( num_words = = - 1 )
* a = 0 ;
check_a ;
k = r [ num_contexts - 1 ] - > keyword [ num_words ] = syntax_malloc ( sizeof ( struct key_word ) ) ;
if ( ! strcmp ( * a , " whole " ) ) {
a + + ;
k - > whole_word_chars_left = strdup ( whole_left ) ;
k - > whole_word_chars_right = strdup ( whole_right ) ;
} else if ( ! strcmp ( * a , " wholeleft " ) ) {
a + + ;
k - > whole_word_chars_left = strdup ( whole_left ) ;
} else if ( ! strcmp ( * a , " wholeright " ) ) {
a + + ;
k - > whole_word_chars_right = strdup ( whole_right ) ;
}
check_a ;
if ( ! strcmp ( * a , " linestart " ) ) {
a + + ;
k - > line_start = 1 ;
}
check_a ;
if ( ! strcmp ( * a , " whole " ) ) {
* a = 0 ;
check_a ;
}
k - > keyword = strdup ( * a + + ) ;
k - > last = k - > keyword [ strlen ( k - > keyword ) - 1 ] ;
k - > first = * k - > keyword ;
fg = * a ;
if ( * a )
a + + ;
bg = * a ;
if ( * a )
a + + ;
# ifdef MIDNIGHT
1998-04-29 05:15:19 +04:00
k - > fg = this_try_alloc_color_pair ( fg , bg ) ;
1998-04-24 19:18:08 +04:00
# else
1998-04-29 05:15:19 +04:00
k - > fg = this_allocate_color ( fg ) ;
k - > bg = this_allocate_color ( bg ) ;
1998-04-24 19:18:08 +04:00
# endif
check_not_a ;
num_words + + ;
} else if ( ! strncmp ( args [ 0 ] , " # " , 1 ) ) {
/* do nothing for comment */
} else if ( ! strcmp ( args [ 0 ] , " file " ) ) {
break ;
} else { /* anything else is an error */
* a = 0 ;
check_a ;
}
free_args ( args ) ;
syntax_free ( l ) ;
}
free_args ( args ) ;
syntax_free ( l ) ;
if ( result )
return result ;
if ( num_contexts = = - 1 ) {
result = line ;
return result ;
}
for ( i = 1 ; edit - > rules [ i ] ; i + + ) {
for ( j = i + 1 ; edit - > rules [ j ] ; j + + ) {
if ( strstr ( edit - > rules [ j ] - > right , edit - > rules [ i ] - > right ) & & strcmp ( edit - > rules [ i ] - > right , " \n " ) ) {
unsigned char * s ;
if ( ! edit - > rules [ i ] - > conflicts )
edit - > rules [ i ] - > conflicts = syntax_malloc ( sizeof ( unsigned char ) * 260 ) ;
s = edit - > rules [ i ] - > conflicts ;
s [ strlen ( ( char * ) s ) ] = ( unsigned char ) j ;
}
}
}
1998-04-25 15:52:29 +04:00
{
char first_chars [ 1024 ] , * p ;
char last_chars [ 1024 ] , * q ;
for ( i = 0 ; edit - > rules [ i ] ; i + + ) {
c = edit - > rules [ i ] ;
p = first_chars ;
q = last_chars ;
* p + + = ( char ) 1 ;
* q + + = ( char ) 1 ;
for ( j = 1 ; c - > keyword [ j ] ; j + + ) {
* p + + = c - > keyword [ j ] - > first ;
* q + + = c - > keyword [ j ] - > last ;
}
* p = ' \0 ' ;
* q = ' \0 ' ;
c - > keyword_first_chars = strdup ( first_chars ) ;
c - > keyword_last_chars = strdup ( last_chars ) ;
}
}
1998-04-24 19:18:08 +04:00
return result ;
}
void ( * syntax_change_callback ) ( CWidget * ) = 0 ;
void edit_set_syntax_change_callback ( void ( * callback ) ( CWidget * ) )
{
syntax_change_callback = callback ;
}
void edit_free_syntax_rules ( WEdit * edit )
{
int i , j ;
if ( ! edit )
return ;
if ( ! edit - > rules )
return ;
syntax_free ( edit - > syntax_type ) ;
if ( syntax_change_callback )
# ifdef MIDNIGHT
( * syntax_change_callback ) ( & edit - > widget ) ;
# else
( * syntax_change_callback ) ( edit - > widget ) ;
# endif
for ( i = 0 ; edit - > rules [ i ] ; i + + ) {
if ( edit - > rules [ i ] - > keyword ) {
for ( j = 0 ; edit - > rules [ i ] - > keyword [ j ] ; j + + ) {
syntax_free ( edit - > rules [ i ] - > keyword [ j ] - > keyword ) ;
syntax_free ( edit - > rules [ i ] - > keyword [ j ] - > whole_word_chars_left ) ;
syntax_free ( edit - > rules [ i ] - > keyword [ j ] - > whole_word_chars_right ) ;
syntax_free ( edit - > rules [ i ] - > keyword [ j ] ) ;
}
}
syntax_free ( edit - > rules [ i ] - > conflicts ) ;
syntax_free ( edit - > rules [ i ] - > left ) ;
syntax_free ( edit - > rules [ i ] - > right ) ;
syntax_free ( edit - > rules [ i ] - > whole_word_chars_left ) ;
syntax_free ( edit - > rules [ i ] - > whole_word_chars_right ) ;
syntax_free ( edit - > rules [ i ] - > keyword ) ;
1998-04-25 15:52:29 +04:00
syntax_free ( edit - > rules [ i ] - > keyword_first_chars ) ;
syntax_free ( edit - > rules [ i ] - > keyword_last_chars ) ;
1998-04-24 19:18:08 +04:00
syntax_free ( edit - > rules [ i ] ) ;
}
syntax_free ( edit - > rules ) ;
}
1998-04-29 05:15:19 +04:00
# define CURRENT_SYNTAX_RULES_VERSION "19"
1998-04-24 19:18:08 +04:00
char * syntax_text =
1998-04-29 05:15:19 +04:00
" # syntax rules version " CURRENT_SYNTAX_RULES_VERSION " \n "
1998-04-24 19:18:08 +04:00
" # Allowable colors for mc are \n "
1998-04-29 05:15:19 +04:00
" # (after the slash is a Cooledit color, 0-26 or any of the X colors in rgb.txt) \n "
1998-04-24 19:18:08 +04:00
" # black \n "
" # red \n "
" # green \n "
" # brown \n "
" # blue \n "
" # magenta \n "
" # cyan \n "
" # lightgray \n "
" # gray \n "
" # brightred \n "
" # brightgreen \n "
" # yellow \n "
" # brightblue \n "
" # brightmagenta \n "
" # brightcyan \n "
" # white \n "
" \n "
1998-04-29 05:15:19 +04:00
" ############################################################################### \n "
" file .. \\ * \\ \\ .([chC]|CC|cxx|cc|cpp|CPP|CXX)$ C/C \\ + \\ + \\ sProgram \n "
1998-04-24 19:18:08 +04:00
" context default \n "
1998-04-29 05:15:19 +04:00
" keyword whole auto yellow/24 \n "
" keyword whole break yellow/24 \n "
" keyword whole case yellow/24 \n "
" keyword whole char yellow/24 \n "
" keyword whole const yellow/24 \n "
" keyword whole continue yellow/24 \n "
" keyword whole default yellow/24 \n "
" keyword whole do yellow/24 \n "
" keyword whole double yellow/24 \n "
" keyword whole else yellow/24 \n "
" keyword whole enum yellow/24 \n "
" keyword whole extern yellow/24 \n "
" keyword whole float yellow/24 \n "
" keyword whole for yellow/24 \n "
" keyword whole goto yellow/24 \n "
" keyword whole if yellow/24 \n "
" keyword whole int yellow/24 \n "
" keyword whole long yellow/24 \n "
" keyword whole register yellow/24 \n "
" keyword whole return yellow/24 \n "
" keyword whole short yellow/24 \n "
" keyword whole signed yellow/24 \n "
" keyword whole sizeof yellow/24 \n "
" keyword whole static yellow/24 \n "
" keyword whole struct yellow/24 \n "
" keyword whole switch yellow/24 \n "
" keyword whole typedef yellow/24 \n "
" keyword whole union yellow/24 \n "
" keyword whole unsigned yellow/24 \n "
" keyword whole void yellow/24 \n "
" keyword whole volatile yellow/24 \n "
" keyword whole while yellow/24 \n "
" keyword whole asm yellow/24 \n "
" keyword whole catch yellow/24 \n "
" keyword whole class yellow/24 \n "
" keyword whole friend yellow/24 \n "
" keyword whole delete yellow/24 \n "
" keyword whole inline yellow/24 \n "
" keyword whole new yellow/24 \n "
" keyword whole operator yellow/24 \n "
" keyword whole private yellow/24 \n "
" keyword whole protected yellow/24 \n "
" keyword whole public yellow/24 \n "
" keyword whole this yellow/24 \n "
" keyword whole throw yellow/24 \n "
" keyword whole template yellow/24 \n "
" keyword whole try yellow/24 \n "
" keyword whole virtual yellow/24 \n "
" keyword whole bool yellow/24 \n "
" keyword whole const_cast yellow/24 \n "
" keyword whole dynamic_cast yellow/24 \n "
" keyword whole explicit yellow/24 \n "
" keyword whole false yellow/24 \n "
" keyword whole mutable yellow/24 \n "
" keyword whole namespace yellow/24 \n "
" keyword whole reinterpret_cast yellow/24 \n "
" keyword whole static_cast yellow/24 \n "
" keyword whole true yellow/24 \n "
" keyword whole typeid yellow/24 \n "
" keyword whole typename yellow/24 \n "
" keyword whole using yellow/24 \n "
" keyword whole wchar_t yellow/24 \n "
" keyword whole ... yellow/24 \n "
" keyword ' \\ s' brightgreen/16 \n "
" keyword '+' brightgreen/16 \n "
" keyword > yellow/24 \n "
" keyword < yellow/24 \n "
" keyword \\ + yellow/24 \n "
" keyword - yellow/24 \n "
" keyword \\ * yellow/24 \n "
" keyword / yellow/24 \n "
" keyword % yellow/24 \n "
" keyword = yellow/24 \n "
" keyword != yellow/24 \n "
" keyword == yellow/24 \n "
" keyword { brightcyan/14 \n "
" keyword } brightcyan/14 \n "
" keyword ( brightcyan/15 \n "
" keyword ) brightcyan/15 \n "
" keyword [ brightcyan/14 \n "
" keyword ] brightcyan/14 \n "
" keyword , brightcyan/14 \n "
" keyword : brightcyan/14 \n "
" keyword ; brightmagenta/19 \n "
" context / \\ * \\ */ brown/22 \n "
" context linestart # \\ n brightred/18 \n "
" keyword \\ \\ \\ n yellow/24 \n "
" keyword / \\ ** \\ */ brown/22 \n "
" keyword \" + \" red/19 \n "
" keyword <+> red/19 \n "
" context \" \" green/6 \n "
" keyword \\ \\ \" brightgreen/16 \n "
" keyword %% brightgreen/16 \n "
" keyword % \\ [#0 \\ s- \\ +, \\ ] \\ [0123456789 \\ ] \\ [. \\ ] \\ [0123456789 \\ ] \\ [L \\ ]e brightgreen/16 \n "
" keyword % \\ [#0 \\ s- \\ +, \\ ] \\ [0123456789 \\ ] \\ [. \\ ] \\ [0123456789 \\ ] \\ [L \\ ]E brightgreen/16 \n "
" keyword % \\ [#0 \\ s- \\ +, \\ ] \\ [0123456789 \\ ] \\ [. \\ ] \\ [0123456789 \\ ] \\ [L \\ ]f brightgreen/16 \n "
" keyword % \\ [#0 \\ s- \\ +, \\ ] \\ [0123456789 \\ ] \\ [. \\ ] \\ [0123456789 \\ ] \\ [L \\ ]g brightgreen/16 \n "
" keyword % \\ [#0 \\ s- \\ +, \\ ] \\ [0123456789 \\ ] \\ [. \\ ] \\ [0123456789 \\ ] \\ [L \\ ]G brightgreen/16 \n "
" keyword % \\ [0 \\ s- \\ +, \\ ] \\ [0123456789 \\ ] \\ [. \\ ] \\ [0123456789 \\ ] \\ [hl \\ ]d brightgreen/16 \n "
" keyword % \\ [0 \\ s- \\ +, \\ ] \\ [0123456789 \\ ] \\ [. \\ ] \\ [0123456789 \\ ] \\ [hl \\ ]i brightgreen/16 \n "
" keyword % \\ [#0 \\ s- \\ +, \\ ] \\ [0123456789 \\ ] \\ [. \\ ] \\ [0123456789 \\ ] \\ [hl \\ ]o brightgreen/16 \n "
" keyword % \\ [0 \\ s- \\ +, \\ ] \\ [0123456789 \\ ] \\ [. \\ ] \\ [0123456789 \\ ] \\ [hl \\ ]u brightgreen/16 \n "
" keyword % \\ [#0 \\ s- \\ +, \\ ] \\ [0123456789 \\ ] \\ [. \\ ] \\ [0123456789 \\ ] \\ [hl \\ ]x brightgreen/16 \n "
" keyword % \\ [#0 \\ s- \\ +, \\ ] \\ [0123456789 \\ ] \\ [. \\ ] \\ [0123456789 \\ ] \\ [hl \\ ]X brightgreen/16 \n "
" keyword % \\ [hl \\ ]n brightgreen/16 \n "
" keyword % \\ [. \\ ] \\ [0123456789 \\ ]s brightgreen/16 \n "
" keyword %[*] brightgreen/16 \n "
" keyword %c brightgreen/16 \n "
" keyword \\ \\ \\ \\ brightgreen/16 \n "
" \n "
" ############################################################################### \n "
" file . \\ *ChangeLog$ GNU \\ sDistribution \\ sChangeLog \\ sFile \n "
" \n "
" context default \n "
" keyword \\ s+() brightmagenta/23 \n "
" keyword \\ t+() brightmagenta/23 \n "
" \n "
" context linestart \\ t \\ * : brightcyan/17 \n "
" context linestart \\ s \\ s \\ s \\ s \\ s \\ s \\ s \\ s \\ * : brightcyan/17 \n "
" \n "
" context linestart 19+-+ \\ s \\ n yellow/24 \n "
" keyword <+@+> brightred/19 \n "
" context linestart 20+-+ \\ s \\ n yellow/24 \n "
" keyword <+@+> brightred/19 \n "
" context linestart Mon \\ s+ \\ s+ \\ s+ \\ s \\ n yellow/24 \n "
" keyword <+@+> brightred/19 \n "
" context linestart Tue \\ s+ \\ s+ \\ s+ \\ s \\ n yellow/24 \n "
" keyword <+@+> brightred/19 \n "
" context linestart Wed \\ s+ \\ s+ \\ s+ \\ s \\ n yellow/24 \n "
" keyword <+@+> brightred/19 \n "
" context linestart Thu \\ s+ \\ s+ \\ s+ \\ s \\ n yellow/24 \n "
" keyword <+@+> brightred/19 \n "
" context linestart Fri \\ s+ \\ s+ \\ s+ \\ s \\ n yellow/24 \n "
" keyword <+@+> brightred/19 \n "
" context linestart Sat \\ s+ \\ s+ \\ s+ \\ s \\ n yellow/24 \n "
" keyword <+@+> brightred/19 \n "
" context linestart Sun \\ s+ \\ s+ \\ s+ \\ s \\ n yellow/24 \n "
" keyword <+@+> brightred/19 \n "
" \n "
" \n "
" ############################################################################### \n "
" file . \\ *Makefile[ \\ \\ \\ .a-z] \\ *$ Makefile \n "
" \n "
1998-04-24 19:18:08 +04:00
" context default \n "
1998-04-29 05:15:19 +04:00
" keyword $(*) yellow/24 \n "
" keyword ${*} brightgreen/16 \n "
" keyword whole linestart include magenta \n "
" keyword whole linestart endif magenta \n "
" keyword whole linestart ifeq magenta \n "
" keyword whole linestart ifneq magenta \n "
" keyword whole linestart else magenta \n "
" keyword linestart \\ t lightgray/13 red \n "
" keyword whole .PHONY white/25 \n "
" keyword whole .NOEXPORT white/25 \n "
" keyword = white/25 \n "
" keyword : yellow/24 \n "
" keyword \\ \\ \\ n yellow/24 \n "
" # this handles strange cases like @something@@somethingelse@ properly \n "
" keyword whole @+@ brightmagenta/23 black/0 \n "
" keyword @+@ brightmagenta/23 black/0 \n "
" \n "
" context linestart # \\ n brown/22 \n "
" keyword whole @+@ brightmagenta/23 black/0 \n "
" keyword @+@ brightmagenta/23 black/0 \n "
" \n "
" context exclusive = \\ n brightcyan/17 \n "
" keyword \\ \\ \\ n yellow/24 \n "
" keyword $(*) yellow/24 \n "
" keyword ${*} brightgreen/16 \n "
" keyword linestart \\ t lightgray/13 red \n "
" keyword whole @+@ brightmagenta/23 black/0 \n "
" keyword @+@ brightmagenta/23 black/0 \n "
" \n "
" context exclusive linestart \\ t \\ n \n "
" keyword \\ \\ \\ n yellow/24 \n "
" keyword $(*) yellow/24 \n "
" keyword ${*} brightgreen/16 \n "
" keyword linestart \\ t lightgray/13 red \n "
" keyword whole @+@ brightmagenta/23 black/0 \n "
" keyword @+@ brightmagenta/23 black/0 \n "
" \n "
1998-04-24 19:18:08 +04:00
" file \\ . \\ * Help \\ ssupport \\ sother \\ sfile \\ stypes \n "
" context default \n "
" file \\ . \\ * by \\ scoding \\ srules \\ sin \\ s~/.cedit/syntax. \n "
" context default \n "
" file \\ . \\ * See \\ sman/syntax \\ sin \\ sthe \\ ssource \\ sdistribution \n "
" context default \n "
" file \\ . \\ * and \\ sconsult \\ sthe \\ sman \\ spage. \n "
" context default \n " ;
1998-04-29 05:15:19 +04:00
FILE * upgrade_syntax_file ( char * syntax_file )
{
FILE * f ;
char line [ 80 ] ;
f = fopen ( syntax_file , " r " ) ;
if ( ! f ) {
f = fopen ( syntax_file , " w " ) ;
if ( ! f )
return 0 ;
fprintf ( f , " %s " , syntax_text ) ;
fclose ( f ) ;
return fopen ( syntax_file , " r " ) ;
}
memset ( line , 0 , 79 ) ;
fread ( line , 80 , 1 , f ) ;
if ( ! strstr ( line , " syntax rules version " ) ) {
goto rename_rule_file ;
} else {
char * p ;
p = strstr ( line , " version " ) + strlen ( " version " ) + 1 ;
if ( atoi ( p ) < atoi ( CURRENT_SYNTAX_RULES_VERSION ) ) {
char s [ 1024 ] ;
rename_rule_file :
strcpy ( s , syntax_file ) ;
strcat ( s , " .OLD " ) ;
unlink ( s ) ;
rename ( syntax_file , s ) ;
unlink ( syntax_file ) ; /* might rename() fail ? */
# ifdef MIDNIGHT
edit_message_dialog ( " Load Syntax Rules " , " Your syntax rule file is outdated \n A new rule file is being installed. \n Your old rule file has been saved with a .OLD extension. " ) ;
# else
CMessageDialog ( 0 , 20 , 20 , 0 , " Load Syntax Rules " , " Your syntax rule file is outdated \n A new rule file is being installed. \n Your old rule file has been saved with a .OLD extension. " ) ;
1998-04-24 19:18:08 +04:00
# endif
1998-04-29 05:15:19 +04:00
return upgrade_syntax_file ( syntax_file ) ;
} else {
rewind ( f ) ;
return ( f ) ;
}
}
return 0 ; /* not reached */
}
1998-04-24 19:18:08 +04:00
/* returns -1 on file error, line number on error in file syntax */
static int edit_read_syntax_file ( WEdit * edit , char * * names , char * syntax_file , char * editor_file , char * type )
{
FILE * f ;
regex_t r ;
regmatch_t pmatch [ 1 ] ;
char * args [ 1024 ] , * l ;
int line = 0 ;
int argc ;
int result = 0 ;
int count = 0 ;
1998-04-29 05:15:19 +04:00
f = upgrade_syntax_file ( syntax_file ) ;
if ( ! f )
return - 1 ;
1998-04-24 19:18:08 +04:00
args [ 0 ] = 0 ;
for ( ; ; ) {
line + + ;
if ( ! read_one_line ( & l , f ) )
break ;
get_args ( l , args , & argc ) ;
if ( ! args [ 0 ] ) {
} else if ( ! strcmp ( args [ 0 ] , " file " ) ) {
if ( ! args [ 1 ] | | ! args [ 2 ] ) {
result = line ;
break ;
}
if ( regcomp ( & r , args [ 1 ] , REG_EXTENDED ) ) {
result = line ;
break ;
}
if ( names ) {
names [ count + + ] = strdup ( args [ 2 ] ) ;
names [ count ] = 0 ;
} else if ( type ) {
if ( ! strcmp ( type , args [ 2 ] ) )
goto found_type ;
} else if ( editor_file & & edit ) {
if ( ! regexec ( & r , editor_file , 1 , pmatch , 0 ) ) {
int line_error ;
found_type :
line_error = edit_read_syntax_rules ( edit , f ) ;
if ( line_error )
result = line + line_error ;
else {
syntax_free ( edit - > syntax_type ) ;
edit - > syntax_type = strdup ( args [ 2 ] ) ;
if ( syntax_change_callback )
# ifdef MIDNIGHT
( * syntax_change_callback ) ( & edit - > widget ) ;
# else
( * syntax_change_callback ) ( edit - > widget ) ;
# endif
1998-05-01 13:32:43 +04:00
/* if there are no rules then turn off syntax highlighting for speed */
if ( ! edit - > rules [ 1 ] )
if ( ! edit - > rules [ 0 ] - > keyword [ 1 ] )
edit_free_syntax_rules ( edit ) ;
1998-04-24 19:18:08 +04:00
}
break ;
}
}
}
free_args ( args ) ;
syntax_free ( l ) ;
}
free_args ( args ) ;
syntax_free ( l ) ;
fclose ( f ) ;
return result ;
}
/* loads rules into edit struct. one of edit or names must be zero. if
edit is zero , a list of types will be stored into name . type may be zero
in which case the type will be selected according to the filename . */
void edit_load_syntax ( WEdit * edit , char * * names , char * type )
{
int r ;
char * f ;
edit_free_syntax_rules ( edit ) ;
# ifdef MIDNIGHT
if ( ! SLtt_Use_Ansi_Colors )
return ;
# endif
if ( edit ) {
if ( ! edit - > filename )
return ;
1998-04-29 05:15:19 +04:00
if ( ! * edit - > filename & & ! type )
1998-04-24 19:18:08 +04:00
return ;
}
f = catstrs ( home_dir , SYNTAX_FILE , 0 ) ;
r = edit_read_syntax_file ( edit , names , f , edit ? edit - > filename : 0 , type ) ;
if ( r = = - 1 ) {
edit_free_syntax_rules ( edit ) ;
edit_error_dialog ( _ ( " Load syntax file " ) , _ ( " File access error " ) ) ;
return ;
}
if ( r ) {
char s [ 80 ] ;
edit_free_syntax_rules ( edit ) ;
sprintf ( s , _ ( " Syntax error in file %s on line %d " ) , f , r ) ;
edit_error_dialog ( _ ( " Load syntax file " ) , s ) ;
return ;
}
}
# else
int option_syntax_highlighting = 0 ;
void edit_load_syntax ( WEdit * edit , char * * names , char * type )
{
return ;
}
void edit_free_syntax_rules ( WEdit * edit )
{
return ;
}
void edit_get_syntax_color ( WEdit * edit , long byte_index , int * fg , int * bg )
{
* fg = NORMAL_COLOR ;
}
# endif /* !defined(MIDNIGHT) || defined(HAVE_SYNTAXH) */