1 /* editor syntax highlighting.
3 Copyright (C) 1996, 1997, 1998 the Free Software Foundation
5 Authors: 1998 Paul Sheer
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
25 #include "coolwidget.h"
28 #if !defined(MIDNIGHT) || defined(HAVE_SYNTAXH)
30 int option_syntax_highlighting
= 1;
32 /* these three functions are called from the outside */
33 void edit_load_syntax (WEdit
* edit
, char **names
, char *type
);
34 void edit_free_syntax_rules (WEdit
* edit
);
35 void edit_get_syntax_color (WEdit
* edit
, long byte_index
, int *fg
, int *bg
);
37 static void *syntax_malloc (size_t x
)
45 #define syntax_free(x) {if(x){free(x);(x)=0;}}
47 static int compare_word_to_right (WEdit
* edit
, long i
, char *text
, char *whole_left
, char *whole_right
, int line_start
)
53 c
= edit_get_byte (edit
, i
- 1);
58 if (strchr (whole_left
, c
))
60 for (p
= text
; *p
; p
++, i
++) {
65 c
= edit_get_byte (edit
, i
);
76 c
= edit_get_byte (edit
, i
);
79 if (c
== '\n' || c
== '\t' || c
== ' ')
87 c
= edit_get_byte (edit
, i
++);
88 for (j
= 0; p
[j
] != '\003'; j
++)
95 c
= edit_get_byte (edit
, i
);
96 for (j
= 0; p
[j
] != '\003'; j
++)
109 c
= edit_get_byte (edit
, i
++);
110 for (j
= 0; p
[j
] != '\004'; j
++)
114 c
= edit_get_byte (edit
, i
);
115 for (j
= 0; p
[j
] != '\004'; j
++)
128 if (*p
!= edit_get_byte (edit
, i
))
133 if (strchr (whole_right
, edit_get_byte (edit
, i
)))
138 static int compare_word_to_left (WEdit
* edit
, long i
, char *text
, char *whole_left
, char *whole_right
, int line_start
)
148 if (strchr (whole_right
, edit_get_byte (edit
, i
+ 1)))
150 for (p
= text
+ strlen (text
) - 1; (unsigned long) p
>= (unsigned long) text
; p
--, i
--) {
155 c
= edit_get_byte (edit
, i
);
166 c
= edit_get_byte (edit
, i
);
169 if (c
== '\n' || c
== '\t' || c
== ' ')
175 while (*(--p
) != '\003');
178 c
= edit_get_byte (edit
, i
--);
179 for (j
= 0; p
[j
] != '\003'; j
++)
186 c
= edit_get_byte (edit
, i
);
187 for (j
= 0; p
[j
] != '\003'; j
++)
198 while (*(--p
) != '\004');
201 c
= edit_get_byte (edit
, i
--);
202 for (j
= 0; p
[j
] != '\004'; j
++)
206 c
= edit_get_byte (edit
, i
);
207 for (j
= 0; p
[j
] != '\004'; j
++)
208 if (c
== p
[j
] || c
== '\n' || c
== d
)
219 if (*p
!= edit_get_byte (edit
, i
))
223 c
= edit_get_byte (edit
, i
);
228 if (strchr (whole_left
, c
))
235 #define debug_printf(x,y) fprintf(stderr,x,y)
237 #define debug_printf(x,y)
240 static inline unsigned long apply_rules_going_right (WEdit
* edit
, long i
, unsigned long rule
)
242 struct context_rule
*r
;
243 int context
, contextchanged
= 0, keyword
, c1
, c2
;
244 int found_right
= 0, found_left
= 0, keyword_foundleft
= 0;
246 unsigned long border
;
247 context
= (rule
& RULE_CONTEXT
) >> RULE_CONTEXT_SHIFT
;
248 keyword
= (rule
& RULE_WORD
) >> RULE_WORD_SHIFT
;
249 border
= rule
& (RULE_ON_LEFT_BORDER
| RULE_ON_RIGHT_BORDER
);
250 c1
= edit_get_byte (edit
, i
- 1);
251 c2
= edit_get_byte (edit
, i
);
255 debug_printf ("%c->", c1
);
256 debug_printf ("%c ", c2
);
258 /* check to turn off a keyword */
261 k
= edit
->rules
[context
]->keyword
[keyword
];
264 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
)) {
266 keyword_foundleft
= 1;
267 debug_printf ("keyword=%d ", keyword
);
270 debug_printf ("border=%s ", border
? ((border
& RULE_ON_LEFT_BORDER
) ? "left" : "right") : "off");
272 /* check to turn off a context */
273 if (context
&& !keyword
) {
274 r
= edit
->rules
[context
];
275 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
) \
276 &&!(rule
& RULE_ON_RIGHT_BORDER
)) {
277 debug_printf ("A:3 ", 0);
279 border
= RULE_ON_RIGHT_BORDER
;
280 if (r
->between_delimiters
)
282 } else if (!found_left
) {
283 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
) \
284 &&(rule
& RULE_ON_RIGHT_BORDER
)) {
285 /* always turn off a context at 4 */
286 debug_printf ("A:4 ", 0);
289 if (!keyword_foundleft
)
291 } 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
) \
292 &&(rule
& RULE_ON_LEFT_BORDER
)) {
293 /* never turn off a context at 2 */
294 debug_printf ("A:2 ", 0);
300 debug_printf ("\n", 0);
302 /* check to turn on a keyword */
305 p
= (r
= edit
->rules
[context
])->keyword_first_chars
;
306 while ((p
= strchr (p
+ 1, c2
))) {
309 count
= (unsigned long) p
- (unsigned long) r
->keyword_first_chars
;
310 k
= r
->keyword
[count
];
311 if (compare_word_to_right (edit
, i
, k
->keyword
, k
->whole_word_chars_left
, k
->whole_word_chars_right
, k
->line_start
)) {
313 debug_printf ("keyword=%d ", keyword
);
318 /* check to turn on a context */
321 for (count
= 1; edit
->rules
[count
] && !done
; count
++) {
322 r
= edit
->rules
[count
];
324 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
) \
325 &&(rule
& RULE_ON_RIGHT_BORDER
)) {
326 debug_printf ("B:4 count=%d", count
);
332 } 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
) \
333 &&(rule
& RULE_ON_LEFT_BORDER
)) {
334 debug_printf ("B:2 ", 0);
337 if (r
->between_delimiters
) {
341 debug_printf ("context=%d ", context
);
342 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
)) {
343 debug_printf ("B:3 ", 0);
345 border
= RULE_ON_RIGHT_BORDER
;
353 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
)) {
354 debug_printf ("B:1 ", 0);
356 border
= RULE_ON_LEFT_BORDER
;
357 if (!r
->between_delimiters
) {
358 debug_printf ("context=%d ", context
);
367 if (!keyword
&& contextchanged
) {
369 p
= (r
= edit
->rules
[context
])->keyword_first_chars
;
370 while ((p
= strchr (p
+ 1, c2
))) {
373 coutner
= (unsigned long) p
- (unsigned long) r
->keyword_first_chars
;
374 k
= r
->keyword
[coutner
];
375 if (compare_word_to_right (edit
, i
, k
->keyword
, k
->whole_word_chars_left
, k
->whole_word_chars_right
, k
->line_start
)) {
377 debug_printf ("keyword=%d ", keyword
);
382 debug_printf ("border=%s ", border
? ((border
& RULE_ON_LEFT_BORDER
) ? "left" : "right") : "off");
383 debug_printf ("keyword=%d ", keyword
);
385 debug_printf (" %d#\n\n", context
);
387 return (context
<< RULE_CONTEXT_SHIFT
) | (keyword
<< RULE_WORD_SHIFT
) | border
;
390 static inline int resolve_left_delim (WEdit
* edit
, long i
, struct context_rule
*r
, int s
)
396 c
= edit_get_byte (edit
, i
);
399 for (count
= 1; r
->conflicts
[count
]; count
++) {
400 struct context_rule
*p
;
401 p
= edit
->rules
[r
->conflicts
[count
]];
404 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
))
405 return r
->conflicts
[count
];
412 static inline unsigned long apply_rules_going_left (WEdit
* edit
, long i
, unsigned long rule
)
414 struct context_rule
*r
;
415 int context
, contextchanged
= 0, keyword
, c2
, c1
;
416 int found_left
= 0, found_right
= 0, keyword_foundright
= 0;
418 unsigned long border
;
419 context
= (rule
& RULE_CONTEXT
) >> RULE_CONTEXT_SHIFT
;
420 keyword
= (rule
& RULE_WORD
) >> RULE_WORD_SHIFT
;
421 border
= rule
& (RULE_ON_RIGHT_BORDER
| RULE_ON_LEFT_BORDER
);
422 c1
= edit_get_byte (edit
, i
);
423 c2
= edit_get_byte (edit
, i
+ 1);
427 debug_printf ("%c->", c2
);
428 debug_printf ("%c ", c1
);
430 /* check to turn off a keyword */
433 k
= edit
->rules
[context
]->keyword
[keyword
];
436 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
)) || (c2
== '\n')) {
438 keyword_foundright
= 1;
439 debug_printf ("keyword=%d ", keyword
);
442 debug_printf ("border=%s ", border
? ((border
& RULE_ON_RIGHT_BORDER
) ? "right" : "left") : "off");
444 /* check to turn off a context */
445 if (context
&& !keyword
) {
446 r
= edit
->rules
[context
];
447 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
) \
448 &&!(rule
& RULE_ON_LEFT_BORDER
)) {
449 debug_printf ("A:2 ", 0);
451 border
= RULE_ON_LEFT_BORDER
;
452 if (r
->between_delimiters
)
454 } else if (!found_right
) {
455 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
) \
456 &&(rule
& RULE_ON_LEFT_BORDER
)) {
457 /* always turn off a context at 4 */
458 debug_printf ("A:1 ", 0);
461 if (!keyword_foundright
)
463 } 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
) \
464 &&(rule
& RULE_ON_RIGHT_BORDER
)) {
465 /* never turn off a context at 2 */
466 debug_printf ("A:3 ", 0);
472 debug_printf ("\n", 0);
474 /* check to turn on a keyword */
477 p
= (r
= edit
->rules
[context
])->keyword_last_chars
;
478 while ((p
= strchr (p
+ 1, c1
))) {
481 count
= (unsigned long) p
- (unsigned long) r
->keyword_last_chars
;
482 k
= r
->keyword
[count
];
483 if (compare_word_to_left (edit
, i
, k
->keyword
, k
->whole_word_chars_right
, k
->whole_word_chars_left
, k
->line_start
)) {
485 debug_printf ("keyword=%d ", keyword
);
490 /* check to turn on a context */
493 for (count
= 1; edit
->rules
[count
] && !done
; count
++) {
494 r
= edit
->rules
[count
];
496 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
) \
497 &&(rule
& RULE_ON_LEFT_BORDER
)) {
498 debug_printf ("B:1 count=%d", count
);
504 } 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
) \
505 &&(rule
& RULE_ON_RIGHT_BORDER
)) {
506 if (!(c2
== '\n' && r
->single_char
)) {
507 debug_printf ("B:3 ", 0);
510 if (r
->between_delimiters
) {
511 debug_printf ("context=%d ", context
);
512 context
= resolve_left_delim (edit
, i
, r
, count
);
515 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
)) {
516 debug_printf ("B:2 ", 0);
518 border
= RULE_ON_LEFT_BORDER
;
527 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
)) {
528 if (!(c1
== '\n' && r
->single_char
)) {
529 debug_printf ("B:4 ", 0);
531 border
= RULE_ON_RIGHT_BORDER
;
533 if (!r
->between_delimiters
)
534 context
= resolve_left_delim (edit
, i
- 1, r
, count
);
541 if (!keyword
&& contextchanged
) {
543 p
= (r
= edit
->rules
[context
])->keyword_last_chars
;
544 while ((p
= strchr (p
+ 1, c1
))) {
547 coutner
= (unsigned long) p
- (unsigned long) r
->keyword_last_chars
;
548 k
= r
->keyword
[coutner
];
549 if (compare_word_to_left (edit
, i
, k
->keyword
, k
->whole_word_chars_right
, k
->whole_word_chars_left
, k
->line_start
)) {
551 debug_printf ("keyword=%d ", keyword
);
556 debug_printf ("border=%s ", border
? ((border
& RULE_ON_RIGHT_BORDER
) ? "right" : "left") : "off");
557 debug_printf ("keyword=%d ", keyword
);
559 debug_printf (" %d#\n\n", context
);
561 return (context
<< RULE_CONTEXT_SHIFT
) | (keyword
<< RULE_WORD_SHIFT
) | border
;
565 static unsigned long edit_get_rule (WEdit
* edit
, long byte_index
)
568 if (byte_index
< 0) {
569 edit
->last_get_rule
= -1;
574 if (byte_index
< edit
->last_get_rule_start_display
) {
575 /* this is for optimisation */
576 for (i
= edit
->last_get_rule_start_display
- 1; i
>= byte_index
; i
--)
577 edit
->rule_start_display
= apply_rules_going_left (edit
, i
, edit
->rule_start_display
);
578 edit
->last_get_rule_start_display
= byte_index
;
579 edit
->rule
= edit
->rule_start_display
;
582 if (byte_index
> edit
->last_get_rule
) {
583 for (i
= edit
->last_get_rule
+ 1; i
<= byte_index
; i
++)
584 edit
->rule
= apply_rules_going_right (edit
, i
, edit
->rule
);
585 } else if (byte_index
< edit
->last_get_rule
) {
586 for (i
= edit
->last_get_rule
- 1; i
>= byte_index
; i
--)
587 edit
->rule
= apply_rules_going_left (edit
, i
, edit
->rule
);
589 edit
->last_get_rule
= byte_index
;
593 static void translate_rule_to_color (WEdit
* edit
, unsigned long rule
, int *fg
, int *bg
)
596 k
= edit
->rules
[(rule
& RULE_CONTEXT
) >> RULE_CONTEXT_SHIFT
]->keyword
[(rule
& RULE_WORD
) >> RULE_WORD_SHIFT
];
601 void edit_get_syntax_color (WEdit
* edit
, long byte_index
, int *fg
, int *bg
)
604 if (!edit
->rules
|| byte_index
>= edit
->last_byte
|| !option_syntax_highlighting
) {
612 rule
= edit_get_rule (edit
, byte_index
);
613 translate_rule_to_color (edit
, rule
, fg
, bg
);
619 Returns 0 on error/eof or a count of the number of bytes read
620 including the newline. Result must be free'd.
622 static int read_one_line (char **line
, FILE * f
)
625 int len
= 256, c
, r
= 0, i
= 0;
626 p
= syntax_malloc (len
);
632 } else if (c
== '\n') {
633 r
= i
+ 1; /* extra 1 for the newline just read */
638 q
= syntax_malloc (len
* 2);
652 static char *strdup_convert (char *s
)
684 if ((unsigned long) p
== (unsigned long) r
|| strlen (s
) == 1)
688 if (!strncmp (s
, "[^", 2)) {
710 /* a * or + at the beginning or end of the line must be interpreted literally */
711 if ((unsigned long) p
== (unsigned long) r
|| strlen (s
) == 1)
717 if ((unsigned long) p
== (unsigned long) r
|| strlen (s
) == 1)
733 #define whiteness(x) ((x) == '\t' || (x) == '\n' || (x) == ' ')
735 static void get_args (char *l
, char **args
, int *argc
)
741 for (p
= l
+ 1; *p
&& whiteness (*p
); p
++);
744 for (l
= p
+ 1; *l
&& !whiteness (*l
); l
++);
746 *args
= strdup_convert (p
);
753 static void free_args (char **args
)
762 #define check_a {if(!*a){result=line;break;}}
763 #define check_not_a {if(*a){result=line;break;}}
767 int try_alloc_color_pair (char *fg
, char *bg
);
769 int this_try_alloc_color_pair (char *fg
, char *bg
)
771 char f
[80], b
[80], *p
;
786 return try_alloc_color_pair (fg
, bg
);
789 int this_allocate_color (char *fg
)
793 return allocate_color (0);
794 p
= strchr (fg
, '/');
796 return allocate_color (fg
);
797 return allocate_color (p
+ 1);
801 /* returns line number on error */
802 static int edit_read_syntax_rules (WEdit
* edit
, FILE * f
)
805 char whole_right
[256];
806 char whole_left
[256];
807 char *args
[1024], *l
= 0;
809 struct context_rule
**r
, *c
;
810 int num_words
= -1, num_contexts
= -1;
811 int argc
, result
= 0;
816 strcpy (whole_left
, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890");
817 strcpy (whole_right
, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890");
819 r
= edit
->rules
= syntax_malloc (256 * sizeof (struct context_rule
*));
824 if (!read_one_line (&l
, f
))
826 get_args (l
, args
, &argc
);
830 } else if (!strcmp (args
[0], "wholechars")) {
832 if (!strcmp (*a
, "left")) {
834 strcpy (whole_left
, *a
);
835 } else if (!strcmp (*a
, "right")) {
837 strcpy (whole_right
, *a
);
839 strcpy (whole_left
, *a
);
840 strcpy (whole_right
, *a
);
844 } else if (!strcmp (args
[0], "context")) {
846 if (num_contexts
== -1) {
847 if (strcmp (*a
, "default")) { /* first context is the default */
852 c
= r
[0] = syntax_malloc (sizeof (struct context_rule
));
853 c
->left
= strdup (" ");
854 c
->right
= strdup (" ");
857 c
= r
[num_contexts
] = syntax_malloc (sizeof (struct context_rule
));
858 if (!strcmp (*a
, "exclusive")) {
860 c
->between_delimiters
= 1;
863 if (!strcmp (*a
, "whole")) {
865 c
->whole_word_chars_left
= strdup (whole_left
);
866 c
->whole_word_chars_right
= strdup (whole_right
);
867 } else if (!strcmp (*a
, "wholeleft")) {
869 c
->whole_word_chars_left
= strdup (whole_left
);
870 } else if (!strcmp (*a
, "wholeright")) {
872 c
->whole_word_chars_right
= strdup (whole_right
);
875 if (!strcmp (*a
, "linestart")) {
877 c
->line_start_left
= 1;
880 c
->left
= strdup (*a
++);
882 if (!strcmp (*a
, "linestart")) {
884 c
->line_start_right
= 1;
887 c
->right
= strdup (*a
++);
888 c
->last_left
= c
->left
[strlen (c
->left
) - 1];
889 c
->last_right
= c
->right
[strlen (c
->right
) - 1];
890 c
->first_left
= *c
->left
;
891 c
->first_right
= *c
->right
;
892 c
->single_char
= (strlen (c
->right
) == 1);
894 c
->keyword
= syntax_malloc (1024 * sizeof (struct key_word
*));
896 c
->keyword
[0] = syntax_malloc (sizeof (struct key_word
));
904 c
->keyword
[0]->fg
= this_try_alloc_color_pair (fg
, bg
);
906 c
->keyword
[0]->fg
= this_allocate_color (fg
);
907 c
->keyword
[0]->bg
= this_allocate_color (bg
);
909 c
->keyword
[0]->keyword
= strdup (" ");
912 } else if (!strcmp (args
[0], "keyword")) {
917 k
= r
[num_contexts
- 1]->keyword
[num_words
] = syntax_malloc (sizeof (struct key_word
));
918 if (!strcmp (*a
, "whole")) {
920 k
->whole_word_chars_left
= strdup (whole_left
);
921 k
->whole_word_chars_right
= strdup (whole_right
);
922 } else if (!strcmp (*a
, "wholeleft")) {
924 k
->whole_word_chars_left
= strdup (whole_left
);
925 } else if (!strcmp (*a
, "wholeright")) {
927 k
->whole_word_chars_right
= strdup (whole_right
);
930 if (!strcmp (*a
, "linestart")) {
935 if (!strcmp (*a
, "whole")) {
939 k
->keyword
= strdup (*a
++);
940 k
->last
= k
->keyword
[strlen (k
->keyword
) - 1];
941 k
->first
= *k
->keyword
;
949 k
->fg
= this_try_alloc_color_pair (fg
, bg
);
951 k
->fg
= this_allocate_color (fg
);
952 k
->bg
= this_allocate_color (bg
);
956 } else if (!strncmp (args
[0], "#", 1)) {
957 /* do nothing for comment */
958 } else if (!strcmp (args
[0], "file")) {
960 } else { /* anything else is an error */
973 if (num_contexts
== -1) {
977 for (i
= 1; edit
->rules
[i
]; i
++) {
978 for (j
= i
+ 1; edit
->rules
[j
]; j
++) {
979 if (strstr (edit
->rules
[j
]->right
, edit
->rules
[i
]->right
) && strcmp (edit
->rules
[i
]->right
, "\n")) {
981 if (!edit
->rules
[i
]->conflicts
)
982 edit
->rules
[i
]->conflicts
= syntax_malloc (sizeof (unsigned char) * 260);
983 s
= edit
->rules
[i
]->conflicts
;
984 s
[strlen ((char *) s
)] = (unsigned char) j
;
990 char first_chars
[1024], *p
;
991 char last_chars
[1024], *q
;
992 for (i
= 0; edit
->rules
[i
]; i
++) {
998 for (j
= 1; c
->keyword
[j
]; j
++) {
999 *p
++ = c
->keyword
[j
]->first
;
1000 *q
++ = c
->keyword
[j
]->last
;
1004 c
->keyword_first_chars
= strdup (first_chars
);
1005 c
->keyword_last_chars
= strdup (last_chars
);
1012 void (*syntax_change_callback
) (CWidget
*) = 0;
1014 void edit_set_syntax_change_callback (void (*callback
) (CWidget
*))
1016 syntax_change_callback
= callback
;
1019 void edit_free_syntax_rules (WEdit
* edit
)
1026 syntax_free (edit
->syntax_type
);
1027 if (syntax_change_callback
)
1029 (*syntax_change_callback
) (&edit
->widget
);
1031 (*syntax_change_callback
) (edit
->widget
);
1033 for (i
= 0; edit
->rules
[i
]; i
++) {
1034 if (edit
->rules
[i
]->keyword
) {
1035 for (j
= 0; edit
->rules
[i
]->keyword
[j
]; j
++) {
1036 syntax_free (edit
->rules
[i
]->keyword
[j
]->keyword
);
1037 syntax_free (edit
->rules
[i
]->keyword
[j
]->whole_word_chars_left
);
1038 syntax_free (edit
->rules
[i
]->keyword
[j
]->whole_word_chars_right
);
1039 syntax_free (edit
->rules
[i
]->keyword
[j
]);
1042 syntax_free (edit
->rules
[i
]->conflicts
);
1043 syntax_free (edit
->rules
[i
]->left
);
1044 syntax_free (edit
->rules
[i
]->right
);
1045 syntax_free (edit
->rules
[i
]->whole_word_chars_left
);
1046 syntax_free (edit
->rules
[i
]->whole_word_chars_right
);
1047 syntax_free (edit
->rules
[i
]->keyword
);
1048 syntax_free (edit
->rules
[i
]->keyword_first_chars
);
1049 syntax_free (edit
->rules
[i
]->keyword_last_chars
);
1050 syntax_free (edit
->rules
[i
]);
1052 syntax_free (edit
->rules
);
1055 #define CURRENT_SYNTAX_RULES_VERSION "22"
1058 "# syntax rules version " CURRENT_SYNTAX_RULES_VERSION
"\n"
1059 "# Allowable colors for mc are\n"
1060 "# (after the slash is a Cooledit color, 0-26 or any of the X colors in rgb.txt)\n"
1078 "###############################################################################\n"
1079 "file ..\\*\\\\.tex$ LaTeX\\s2.09\\sDocument\n"
1081 "wholechars left \\\\\n"
1082 "wholechars right abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n"
1085 " keyword whole \\\\tiny yellow/24\n"
1086 " keyword whole \\\\scriptsize yellow/24\n"
1087 " keyword whole \\\\footnotesize yellow/24\n"
1088 " keyword whole \\\\small yellow/24\n"
1089 " keyword whole \\\\normalsize yellow/24\n"
1090 " keyword whole \\\\large yellow/24\n"
1091 " keyword whole \\\\Large yellow/24\n"
1092 " keyword whole \\\\LARGE yellow/24\n"
1093 " keyword whole \\\\huge yellow/24\n"
1094 " keyword whole \\\\Huge yellow/24\n"
1096 "# accents and symbols\n"
1097 " keyword whole \\\\`{\\[aeiouAEIOU\\]} yellow/24\n"
1098 " keyword whole \\\\'{\\[aeiouAEIOU\\]} yellow/24\n"
1099 " keyword whole \\\\^{\\[aeiouAEIOU\\]} yellow/24\n"
1100 " keyword whole \\\\\"{\\[aeiouAEIOU\\]} yellow/24\n"
1101 " keyword whole \\\\~{\\[aeiouAEIOU\\]} yellow/24\n"
1102 " keyword whole \\\\={\\[aeiouAEIOU\\]} yellow/24\n"
1103 " keyword whole \\\\.{\\[aeiouAEIOU\\]} yellow/24\n"
1104 " keyword whole \\\\u{\\[aeiouAEIOU\\]} yellow/24\n"
1105 " keyword whole \\\\v{\\[aeiouAEIOU\\]} yellow/24\n"
1106 " keyword whole \\\\H{\\[aeiouAEIOU\\]} yellow/24\n"
1107 " keyword whole \\\\t{\\[aeiouAEIOU\\]} yellow/24\n"
1108 " keyword whole \\\\c{\\[aeiouAEIOU\\]} yellow/24\n"
1109 " keyword whole \\\\d{\\[aeiouAEIOU\\]} yellow/24\n"
1110 " keyword whole \\\\b{\\[aeiouAEIOU\\]} yellow/24\n"
1112 " keyword whole \\\\dag yellow/24\n"
1113 " keyword whole \\\\ddag yellow/24\n"
1114 " keyword whole \\\\S yellow/24\n"
1115 " keyword whole \\\\P yellow/24\n"
1116 " keyword whole \\\\copyright yellow/24\n"
1117 " keyword whole \\\\pounds yellow/24\n"
1119 "# sectioning and table of contents\n"
1120 " keyword whole \\\\part[*]{*} brightred/19\n"
1121 " keyword whole \\\\part{*} brightred/19\n"
1122 " keyword whole \\\\part\\*{*} brightred/19\n"
1123 " keyword whole \\\\chapter[*]{*} brightred/19\n"
1124 " keyword whole \\\\chapter{*} brightred/19\n"
1125 " keyword whole \\\\chapter\\*{*} brightred/19\n"
1126 " keyword whole \\\\section[*]{*} brightred/19\n"
1127 " keyword whole \\\\section{*} brightred/19\n"
1128 " keyword whole \\\\section\\*{*} brightred/19\n"
1129 " keyword whole \\\\subsection[*]{*} brightred/19\n"
1130 " keyword whole \\\\subsection{*} brightred/19\n"
1131 " keyword whole \\\\subsection\\*{*} brightred/19\n"
1132 " keyword whole \\\\subsubsection[*]{*} brightred/19\n"
1133 " keyword whole \\\\subsubsection{*} brightred/19\n"
1134 " keyword whole \\\\subsubsection\\*{*} brightred/19\n"
1135 " keyword whole \\\\paragraph[*]{*} brightred/19\n"
1136 " keyword whole \\\\paragraph{*} brightred/19\n"
1137 " keyword whole \\\\paragraph\\*{*} brightred/19\n"
1138 " keyword whole \\\\subparagraph[*]{*} brightred/19\n"
1139 " keyword whole \\\\subparagraph{*} brightred/19\n"
1140 " keyword whole \\\\subparagraph\\*{*} brightred/19\n"
1142 " keyword whole \\\\appendix brightred/19\n"
1143 " keyword whole \\\\tableofcontents brightred/19\n"
1146 " keyword whole \\\\item[*] yellow/24\n"
1147 " keyword whole \\\\item yellow/24\n"
1148 " keyword whole \\\\\\\\ yellow/24\n"
1149 " keyword \\\\\\s yellow/24 black/0\n"
1150 " keyword %% yellow/24\n"
1152 "# docuement and page styles \n"
1153 " keyword whole \\\\documentstyle[*]{*} yellow/20\n"
1154 " keyword whole \\\\documentstyle{*} yellow/20\n"
1155 " keyword whole \\\\pagestyle{*} yellow/20\n"
1157 "# cross references\n"
1158 " keyword whole \\\\label{*} yellow/24\n"
1159 " keyword whole \\\\ref{*} yellow/24\n"
1161 "# bibliography and citations\n"
1162 " keyword whole \\\\bibliography{*} yellow/24\n"
1163 " keyword whole \\\\bibitem[*]{*} yellow/24\n"
1164 " keyword whole \\\\bibitem{*} yellow/24\n"
1165 " keyword whole \\\\cite[*]{*} yellow/24\n"
1166 " keyword whole \\\\cite{*} yellow/24\n"
1168 "# splitting the input\n"
1169 " keyword whole \\\\input{*} yellow/20\n"
1170 " keyword whole \\\\include{*} yellow/20\n"
1171 " keyword whole \\\\includeonly{*} yellow/20\n"
1174 " keyword whole \\\\linebreak[\\[01234\\]] yellow/24\n"
1175 " keyword whole \\\\nolinebreak[\\[01234\\]] yellow/24\n"
1176 " keyword whole \\\\linebreak yellow/24\n"
1177 " keyword whole \\\\nolinebreak yellow/24\n"
1178 " keyword whole \\\\[+] yellow/24\n"
1179 " keyword whole \\\\- yellow/24\n"
1180 " keyword whole \\\\sloppy yellow/24\n"
1183 " keyword whole \\\\pagebreak[\\[01234\\]] yellow/24\n"
1184 " keyword whole \\\\nopagebreak[\\[01234\\]] yellow/24\n"
1185 " keyword whole \\\\pagebreak yellow/24\n"
1186 " keyword whole \\\\nopagebreak yellow/24\n"
1187 " keyword whole \\\\samepage yellow/24\n"
1188 " keyword whole \\\\newpage yellow/24\n"
1189 " keyword whole \\\\clearpage yellow/24\n"
1192 " keyword \\\\newcommand{*}[*] cyan/5\n"
1193 " keyword \\\\newcommand{*} cyan/5\n"
1194 " keyword \\\\newenvironment{*}[*]{*} cyan/5\n"
1195 " keyword \\\\newenvironment{*}{*} cyan/5\n"
1199 "# begins and ends\n"
1200 " keyword \\\\begin{document} brightred/14\n"
1201 " keyword \\\\begin{equation} brightred/14\n"
1202 " keyword \\\\begin{eqnarray} brightred/14\n"
1203 " keyword \\\\begin{quote} brightred/14\n"
1204 " keyword \\\\begin{quotation} brightred/14\n"
1205 " keyword \\\\begin{center} brightred/14\n"
1206 " keyword \\\\begin{verse} brightred/14\n"
1207 " keyword \\\\begin{verbatim} brightred/14\n"
1208 " keyword \\\\begin{itemize} brightred/14\n"
1209 " keyword \\\\begin{enumerate} brightred/14\n"
1210 " keyword \\\\begin{description} brightred/14\n"
1211 " keyword \\\\begin{array} brightred/14\n"
1212 " keyword \\\\begin{tabular} brightred/14\n"
1213 " keyword \\\\begin{thebibliography}{*} brightred/14\n"
1214 " keyword \\\\begin{sloppypar} brightred/14\n"
1216 " keyword \\\\end{document} brightred/14\n"
1217 " keyword \\\\end{equation} brightred/14\n"
1218 " keyword \\\\end{eqnarray} brightred/14\n"
1219 " keyword \\\\end{quote} brightred/14\n"
1220 " keyword \\\\end{quotation} brightred/14\n"
1221 " keyword \\\\end{center} brightred/14\n"
1222 " keyword \\\\end{verse} brightred/14\n"
1223 " keyword \\\\end{verbatim} brightred/14\n"
1224 " keyword \\\\end{itemize} brightred/14\n"
1225 " keyword \\\\end{enumerate} brightred/14\n"
1226 " keyword \\\\end{description} brightred/14\n"
1227 " keyword \\\\end{array} brightred/14\n"
1228 " keyword \\\\end{tabular} brightred/14\n"
1229 " keyword \\\\end{thebibliography}{*} brightred/14\n"
1230 " keyword \\\\end{sloppypar} brightred/14\n"
1232 " keyword \\\\begin{*} brightcyan/16\n"
1233 " keyword \\\\end{*} brightcyan/16\n"
1235 " keyword \\\\theorem{*}{*} yellow/24\n"
1237 "# if all else fails\n"
1238 " keyword whole \\\\+[*]{*}{*}{*} brightcyan/17\n"
1239 " keyword whole \\\\+[*]{*}{*} brightcyan/17\n"
1240 " keyword whole \\\\+{*}{*}{*}{*} brightcyan/17\n"
1241 " keyword whole \\\\+{*}{*}{*} brightcyan/17\n"
1242 " keyword whole \\\\+{*}{*} brightcyan/17\n"
1243 " keyword whole \\\\+{*} brightcyan/17\n"
1244 " keyword \\\\\\[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\\]\\n brightcyan/17\n"
1245 " keyword \\\\\\[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\\]\\s brightcyan/17\n"
1246 " keyword \\\\\\[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\\]\\t brightcyan/17\n"
1248 "context \\\\pagenumbering{ } yellow/20\n"
1249 " keyword arabic brightcyan/17\n"
1250 " keyword roman brightcyan/17\n"
1251 " keyword alph brightcyan/17\n"
1252 " keyword Roman brightcyan/17\n"
1253 " keyword Alph brightcyan/17\n"
1255 "context % \\n brown/22\n"
1257 "# mathematical formulas\n"
1258 "context $ $ brightgreen/6\n"
1259 "context exclusive \\\\begin{equation} \\\\end{equation} brightgreen/6\n"
1260 "context exclusive \\\\begin{eqnarray} \\\\end{eqnarray} brightgreen/6\n"
1263 "###############################################################################\n"
1264 "file ..\\*\\\\.([chC]|CC|cxx|cc|cpp|CPP|CXX)$ C/C\\+\\+\\sProgram\n"
1266 " keyword whole auto yellow/24\n"
1267 " keyword whole break yellow/24\n"
1268 " keyword whole case yellow/24\n"
1269 " keyword whole char yellow/24\n"
1270 " keyword whole const yellow/24\n"
1271 " keyword whole continue yellow/24\n"
1272 " keyword whole default yellow/24\n"
1273 " keyword whole do yellow/24\n"
1274 " keyword whole double yellow/24\n"
1275 " keyword whole else yellow/24\n"
1276 " keyword whole enum yellow/24\n"
1277 " keyword whole extern yellow/24\n"
1278 " keyword whole float yellow/24\n"
1279 " keyword whole for yellow/24\n"
1280 " keyword whole goto yellow/24\n"
1281 " keyword whole if yellow/24\n"
1282 " keyword whole int yellow/24\n"
1283 " keyword whole long yellow/24\n"
1284 " keyword whole register yellow/24\n"
1285 " keyword whole return yellow/24\n"
1286 " keyword whole short yellow/24\n"
1287 " keyword whole signed yellow/24\n"
1288 " keyword whole sizeof yellow/24\n"
1289 " keyword whole static yellow/24\n"
1290 " keyword whole struct yellow/24\n"
1291 " keyword whole switch yellow/24\n"
1292 " keyword whole typedef yellow/24\n"
1293 " keyword whole union yellow/24\n"
1294 " keyword whole unsigned yellow/24\n"
1295 " keyword whole void yellow/24\n"
1296 " keyword whole volatile yellow/24\n"
1297 " keyword whole while yellow/24\n"
1298 " keyword whole asm yellow/24\n"
1299 " keyword whole catch yellow/24\n"
1300 " keyword whole class yellow/24\n"
1301 " keyword whole friend yellow/24\n"
1302 " keyword whole delete yellow/24\n"
1303 " keyword whole inline yellow/24\n"
1304 " keyword whole new yellow/24\n"
1305 " keyword whole operator yellow/24\n"
1306 " keyword whole private yellow/24\n"
1307 " keyword whole protected yellow/24\n"
1308 " keyword whole public yellow/24\n"
1309 " keyword whole this yellow/24\n"
1310 " keyword whole throw yellow/24\n"
1311 " keyword whole template yellow/24\n"
1312 " keyword whole try yellow/24\n"
1313 " keyword whole virtual yellow/24\n"
1314 " keyword whole bool yellow/24\n"
1315 " keyword whole const_cast yellow/24\n"
1316 " keyword whole dynamic_cast yellow/24\n"
1317 " keyword whole explicit yellow/24\n"
1318 " keyword whole false yellow/24\n"
1319 " keyword whole mutable yellow/24\n"
1320 " keyword whole namespace yellow/24\n"
1321 " keyword whole reinterpret_cast yellow/24\n"
1322 " keyword whole static_cast yellow/24\n"
1323 " keyword whole true yellow/24\n"
1324 " keyword whole typeid yellow/24\n"
1325 " keyword whole typename yellow/24\n"
1326 " keyword whole using yellow/24\n"
1327 " keyword whole wchar_t yellow/24\n"
1328 " keyword whole ... yellow/24\n"
1330 " keyword /\\* brown/22\n"
1331 " keyword \\*/ brown/22\n"
1333 " keyword '\\s' brightgreen/16\n"
1334 " keyword '+' brightgreen/16\n"
1335 " keyword > yellow/24\n"
1336 " keyword < yellow/24\n"
1337 " keyword \\+ yellow/24\n"
1338 " keyword - yellow/24\n"
1339 " keyword \\* yellow/24\n"
1340 " keyword / yellow/24\n"
1341 " keyword % yellow/24\n"
1342 " keyword = yellow/24\n"
1343 " keyword != yellow/24\n"
1344 " keyword == yellow/24\n"
1345 " keyword { brightcyan/14\n"
1346 " keyword } brightcyan/14\n"
1347 " keyword ( brightcyan/15\n"
1348 " keyword ) brightcyan/15\n"
1349 " keyword [ brightcyan/14\n"
1350 " keyword ] brightcyan/14\n"
1351 " keyword , brightcyan/14\n"
1352 " keyword : brightcyan/14\n"
1353 " keyword ; brightmagenta/19\n"
1354 "context exclusive /\\* \\*/ brown/22\n"
1355 "context linestart # \\n brightred/18\n"
1356 " keyword \\\\\\n yellow/24\n"
1357 " keyword /\\**\\*/ brown/22\n"
1358 " keyword \"+\" red/19\n"
1359 " keyword <+> red/19\n"
1360 "context \" \" green/6\n"
1361 " keyword \\\\\" brightgreen/16\n"
1362 " keyword %% brightgreen/16\n"
1363 " keyword %\\[#0\\s-\\+,\\]\\[0123456789\\]\\[.\\]\\[0123456789\\]\\[L\\]e brightgreen/16\n"
1364 " keyword %\\[#0\\s-\\+,\\]\\[0123456789\\]\\[.\\]\\[0123456789\\]\\[L\\]E brightgreen/16\n"
1365 " keyword %\\[#0\\s-\\+,\\]\\[0123456789\\]\\[.\\]\\[0123456789\\]\\[L\\]f brightgreen/16\n"
1366 " keyword %\\[#0\\s-\\+,\\]\\[0123456789\\]\\[.\\]\\[0123456789\\]\\[L\\]g brightgreen/16\n"
1367 " keyword %\\[#0\\s-\\+,\\]\\[0123456789\\]\\[.\\]\\[0123456789\\]\\[L\\]G brightgreen/16\n"
1368 " keyword %\\[0\\s-\\+,\\]\\[0123456789\\]\\[.\\]\\[0123456789\\]\\[hl\\]d brightgreen/16\n"
1369 " keyword %\\[0\\s-\\+,\\]\\[0123456789\\]\\[.\\]\\[0123456789\\]\\[hl\\]i brightgreen/16\n"
1370 " keyword %\\[#0\\s-\\+,\\]\\[0123456789\\]\\[.\\]\\[0123456789\\]\\[hl\\]o brightgreen/16\n"
1371 " keyword %\\[0\\s-\\+,\\]\\[0123456789\\]\\[.\\]\\[0123456789\\]\\[hl\\]u brightgreen/16\n"
1372 " keyword %\\[#0\\s-\\+,\\]\\[0123456789\\]\\[.\\]\\[0123456789\\]\\[hl\\]x brightgreen/16\n"
1373 " keyword %\\[#0\\s-\\+,\\]\\[0123456789\\]\\[.\\]\\[0123456789\\]\\[hl\\]X brightgreen/16\n"
1374 " keyword %\\[hl\\]n brightgreen/16\n"
1375 " keyword %\\[.\\]\\[0123456789\\]s brightgreen/16\n"
1376 " keyword %[*] brightgreen/16\n"
1377 " keyword %c brightgreen/16\n"
1378 " keyword \\\\\\\\ brightgreen/16\n"
1380 "###############################################################################\n"
1381 "file .\\*ChangeLog$ GNU\\sDistribution\\sChangeLog\\sFile\n"
1384 " keyword \\s+() brightmagenta/23\n"
1385 " keyword \\t+() brightmagenta/23\n"
1387 "context linestart \\t\\* : brightcyan/17\n"
1388 "context linestart \\s\\s\\s\\s\\s\\s\\s\\s\\* : brightcyan/17\n"
1390 "context linestart 19+-+\\s \\n yellow/24\n"
1391 " keyword <+@+> brightred/19\n"
1392 "context linestart 20+-+\\s \\n yellow/24\n"
1393 " keyword <+@+> brightred/19\n"
1394 "context linestart Mon\\s+\\s+\\s+\\s \\n yellow/24\n"
1395 " keyword <+@+> brightred/19\n"
1396 "context linestart Tue\\s+\\s+\\s+\\s \\n yellow/24\n"
1397 " keyword <+@+> brightred/19\n"
1398 "context linestart Wed\\s+\\s+\\s+\\s \\n yellow/24\n"
1399 " keyword <+@+> brightred/19\n"
1400 "context linestart Thu\\s+\\s+\\s+\\s \\n yellow/24\n"
1401 " keyword <+@+> brightred/19\n"
1402 "context linestart Fri\\s+\\s+\\s+\\s \\n yellow/24\n"
1403 " keyword <+@+> brightred/19\n"
1404 "context linestart Sat\\s+\\s+\\s+\\s \\n yellow/24\n"
1405 " keyword <+@+> brightred/19\n"
1406 "context linestart Sun\\s+\\s+\\s+\\s \\n yellow/24\n"
1407 " keyword <+@+> brightred/19\n"
1410 "###############################################################################\n"
1411 "file .\\*Makefile[\\\\\\.a-z]\\*$ Makefile\n"
1414 " keyword $(*) yellow/24\n"
1415 " keyword ${*} brightgreen/16\n"
1416 " keyword whole linestart include magenta\n"
1417 " keyword whole linestart endif magenta\n"
1418 " keyword whole linestart ifeq magenta\n"
1419 " keyword whole linestart ifneq magenta\n"
1420 " keyword whole linestart else magenta\n"
1421 " keyword linestart \\t lightgray/13 red\n"
1422 " keyword whole .PHONY white/25\n"
1423 " keyword whole .NOEXPORT white/25\n"
1424 " keyword = white/25\n"
1425 " keyword : yellow/24\n"
1426 " keyword \\\\\\n yellow/24\n"
1427 "# this handles strange cases like @something@@somethingelse@ properly\n"
1428 " keyword whole @+@ brightmagenta/23 black/0\n"
1429 " keyword @+@ brightmagenta/23 black/0\n"
1431 "context linestart # \\n brown/22\n"
1432 " keyword whole @+@ brightmagenta/23 black/0\n"
1433 " keyword @+@ brightmagenta/23 black/0\n"
1435 "context exclusive = \\n brightcyan/17\n"
1436 " keyword \\\\\\n yellow/24\n"
1437 " keyword $(*) yellow/24\n"
1438 " keyword ${*} brightgreen/16\n"
1439 " keyword linestart \\t lightgray/13 red\n"
1440 " keyword whole @+@ brightmagenta/23 black/0\n"
1441 " keyword @+@ brightmagenta/23 black/0\n"
1443 "context exclusive linestart \\t \\n\n"
1444 " keyword \\\\\\n yellow/24\n"
1445 " keyword $(*) yellow/24\n"
1446 " keyword ${*} brightgreen/16\n"
1447 " keyword linestart \\t lightgray/13 red\n"
1448 " keyword whole @+@ brightmagenta/23 black/0\n"
1449 " keyword @+@ brightmagenta/23 black/0\n"
1451 "###############################################################################\n"
1453 "file .\\*syntax$ Syntax\\sHighlighting\\sdefinitions\n"
1456 " keyword whole keyw\\ord yellow/24\n"
1457 " keyword whole whole\\[\\t\\s\\]l\\inestart brightcyan/17\n"
1458 " keyword whole whole\\[\\t\\s\\]l\\inestart brightcyan/17\n"
1459 " keyword whole wh\\oleleft\\[\\t\\s\\]l\\inestart brightcyan/17\n"
1460 " keyword whole wh\\oleright\\[\\t\\s\\]l\\inestart brightcyan/17\n"
1461 " keyword whole l\\inestart\\[\\t\\s\\]wh\\ole\n"
1462 " keyword whole l\\inestart\\[\\t\\s\\]wh\\ole\n"
1463 " keyword whole l\\inestart\\[\\t\\s\\]wh\\oleleft\n"
1464 " keyword whole l\\inestart\\[\\t\\s\\]wh\\oleright\n"
1465 " keyword wholeleft whole\\s brightcyan/17\n"
1466 " keyword wholeleft whole\\t brightcyan/17\n"
1467 " keyword whole wh\\oleleft brightcyan/17\n"
1468 " keyword whole wh\\oleright brightcyan/17\n"
1469 " keyword whole lin\\[e\\]start brightcyan/17\n"
1470 " keyword whole c\\ontext\\[\\t\\s\\]exclusive brightred/18\n"
1471 " keyword whole c\\ontext\\[\\t\\s\\]default brightred/18\n"
1472 " keyword whole c\\ontext brightred/18\n"
1473 " keyword whole wh\\olechars\\[\\t\\s\\]left brightcyan/17\n"
1474 " keyword whole wh\\olechars\\[\\t\\s\\]right brightcyan/17\n"
1475 " keyword whole wh\\olechars brightcyan/17\n"
1476 " keyword whole f\\ile brightgreen/6\n"
1478 " keyword whole 0 lightgray/0 blue/26\n"
1479 " keyword whole 1 lightgray/1 blue/26\n"
1480 " keyword whole 2 lightgray/2 blue/26\n"
1481 " keyword whole 3 lightgray/3 blue/26\n"
1482 " keyword whole 4 lightgray/4 blue/26\n"
1483 " keyword whole 5 lightgray/5 blue/26\n"
1484 " keyword whole 6 lightgray/6\n"
1485 " keyword whole 7 lightgray/7\n"
1486 " keyword whole 8 lightgray/8\n"
1487 " keyword whole 9 lightgray/9\n"
1488 " keyword whole 10 lightgray/10\n"
1489 " keyword whole 11 lightgray/11\n"
1490 " keyword whole 12 lightgray/12\n"
1491 " keyword whole 13 lightgray/13\n"
1492 " keyword whole 14 lightgray/14\n"
1493 " keyword whole 15 lightgray/15\n"
1494 " keyword whole 16 lightgray/16\n"
1495 " keyword whole 17 lightgray/17\n"
1496 " keyword whole 18 lightgray/18\n"
1497 " keyword whole 19 lightgray/19\n"
1498 " keyword whole 20 lightgray/20\n"
1499 " keyword whole 21 lightgray/21\n"
1500 " keyword whole 22 lightgray/22\n"
1501 " keyword whole 23 lightgray/23\n"
1502 " keyword whole 24 lightgray/24\n"
1503 " keyword whole 25 lightgray/25\n"
1504 " keyword whole 26 lightgray/26\n"
1506 " keyword wholeleft black\\/ black/0\n"
1507 " keyword wholeleft red\\/ red/DarkRed\n"
1508 " keyword wholeleft green\\/ green/green3\n"
1509 " keyword wholeleft brown\\/ brown/saddlebrown\n"
1510 " keyword wholeleft blue\\/ blue/blue3\n"
1511 " keyword wholeleft magenta\\/ magenta/magenta3\n"
1512 " keyword wholeleft cyan\\/ cyan/cyan3\n"
1513 " keyword wholeleft lightgray\\/ lightgray/lightgray\n"
1514 " keyword wholeleft gray\\/ gray/gray\n"
1515 " keyword wholeleft brightred\\/ brightred/red\n"
1516 " keyword wholeleft brightgreen\\/ brightgreen/green1\n"
1517 " keyword wholeleft yellow\\/ yellow/yellow\n"
1518 " keyword wholeleft brightblue\\/ brightblue/blue1\n"
1519 " keyword wholeleft brightmagenta\\/ brightmagenta/magenta\n"
1520 " keyword wholeleft brightcyan\\/ brightcyan/cyan1\n"
1521 " keyword wholeleft white\\/ white/26\n"
1523 "context linestart # \\n brown/22\n"
1525 "file \\.\\* Help\\ssupport\\sother\\sfile\\stypes\n"
1527 "file \\.\\* by\\scoding\\srules\\sin\\s~/.cedit/syntax.\n"
1529 "file \\.\\* See\\sman/syntax\\sin\\sthe\\ssource\\sdistribution\n"
1531 "file \\.\\* and\\sconsult\\sthe\\sman\\spage.\n"
1532 "context default\n";
1536 FILE *upgrade_syntax_file (char *syntax_file
)
1540 f
= fopen (syntax_file
, "r");
1542 f
= fopen (syntax_file
, "w");
1545 fprintf (f
, "%s", syntax_text
);
1547 return fopen (syntax_file
, "r");
1549 memset (line
, 0, 79);
1550 fread (line
, 80, 1, f
);
1551 if (!strstr (line
, "syntax rules version")) {
1552 goto rename_rule_file
;
1555 p
= strstr (line
, "version") + strlen ("version") + 1;
1556 if (atoi (p
) < atoi (CURRENT_SYNTAX_RULES_VERSION
)) {
1559 strcpy (s
, syntax_file
);
1562 rename (syntax_file
, s
);
1563 unlink (syntax_file
); /* might rename() fail ? */
1565 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. ");
1567 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. ");
1569 return upgrade_syntax_file (syntax_file
);
1575 return 0; /* not reached */
1578 /* returns -1 on file error, line number on error in file syntax */
1579 static int edit_read_syntax_file (WEdit
* edit
, char **names
, char *syntax_file
, char *editor_file
, char *type
)
1583 regmatch_t pmatch
[1];
1584 char *args
[1024], *l
;
1590 f
= upgrade_syntax_file (syntax_file
);
1597 if (!read_one_line (&l
, f
))
1599 get_args (l
, args
, &argc
);
1601 } else if (!strcmp (args
[0], "file")) {
1602 if (!args
[1] || !args
[2]) {
1606 if (regcomp (&r
, args
[1], REG_EXTENDED
)) {
1611 names
[count
++] = strdup (args
[2]);
1614 if (!strcmp (type
, args
[2]))
1616 } else if (editor_file
&& edit
) {
1617 if (!regexec (&r
, editor_file
, 1, pmatch
, 0)) {
1620 line_error
= edit_read_syntax_rules (edit
, f
);
1622 result
= line
+ line_error
;
1624 syntax_free (edit
->syntax_type
);
1625 edit
->syntax_type
= strdup (args
[2]);
1626 if (syntax_change_callback
)
1628 (*syntax_change_callback
) (&edit
->widget
);
1630 (*syntax_change_callback
) (edit
->widget
);
1632 /* if there are no rules then turn off syntax highlighting for speed */
1633 if (!edit
->rules
[1])
1634 if (!edit
->rules
[0]->keyword
[1])
1635 edit_free_syntax_rules (edit
);
1652 /* loads rules into edit struct. one of edit or names must be zero. if
1653 edit is zero, a list of types will be stored into name. type may be zero
1654 in which case the type will be selected according to the filename. */
1655 void edit_load_syntax (WEdit
* edit
, char **names
, char *type
)
1660 edit_free_syntax_rules (edit
);
1663 if (!SLtt_Use_Ansi_Colors
)
1668 if (!edit
->filename
)
1670 if (!*edit
->filename
&& !type
)
1673 f
= catstrs (home_dir
, SYNTAX_FILE
, 0);
1674 r
= edit_read_syntax_file (edit
, names
, f
, edit
? edit
->filename
: 0, type
);
1676 edit_free_syntax_rules (edit
);
1677 edit_error_dialog (_ (" Load syntax file "), _ (" File access error "));
1682 edit_free_syntax_rules (edit
);
1683 sprintf (s
, _ (" Syntax error in file %s on line %d "), f
, r
);
1684 edit_error_dialog (_ (" Load syntax file "), s
);
1691 int option_syntax_highlighting
= 0;
1693 void edit_load_syntax (WEdit
* edit
, char **names
, char *type
)
1698 void edit_free_syntax_rules (WEdit
* edit
)
1703 void edit_get_syntax_color (WEdit
* edit
, long byte_index
, int *fg
, int *bg
)
1708 #endif /* !defined(MIDNIGHT) || defined(HAVE_SYNTAXH) */