/[beaver]/beaver/src/editor.c
ViewVC logotype

Diff of /beaver/src/editor.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.9 by mikix, Fri Mar 28 08:04:24 2003 UTC revision 1.10 by mikix, Sun Mar 30 01:20:22 2003 UTC
# Line 63  further syhi optimizations : name tags, Line 63  further syhi optimizations : name tags,
63  #include "interface.h"  #include "interface.h"
64  #include "undoredo.h"  #include "undoredo.h"
65  #include "conf.h"  #include "conf.h"
66    #include "oldsyhi.h"
67    
68  extern t_settings Settings;  extern t_settings Settings;
69    
# Line 533  extern void            refresh_editor(GtkWidget *E Line 534  extern void            refresh_editor(GtkWidget *E
534  }  }
535    
536    
   
 /* preconditions:  iter points to possible start of interesting word    
 postconditions: end is set to the end of the word in the buffer if it was found.  
 if word found, returns TRUE, else FALSE*/  
 inline gboolean starts_string (gchar *text, gint i, gchar *word, gint *end)  
 {  
         gunichar ch;  
         gunichar k;  
         gint j = 0;  
           
         ch = text[i];  
         k = word[j];  
         while (ch && k)  
         {  
                 if (ch != k)  
                 {  
                         return FALSE;  
                 }  
                   
                 i++;  
                 ch = text[i];  
                 j++;  
                 k = word[j];  
         }  
           
         if (!ch && k)  
         {  
                 return FALSE;  
         }  
           
         if (end)  
                 *end = i;  
         return TRUE;  
 }  
   
   
   
 /* returns color index of match, or -1 if none */  
 inline gint is_matching_keyword (gint Lg, const gchar *str)  
 {  
         gint rv = -1;  
         gpointer val;  
           
         val = g_hash_table_lookup (Prefs.L[Lg].Hash, str);  
           
         if (val)  
                 return GPOINTER_TO_INT (val) - 1;  
         else  
                 return -1;  
           
         return rv;  
 }  
   
   
 inline void refresh_markers (GtkTextBuffer *Buffer)  
 {  
         gint CurrentPage;  
         gint Lg;  
         GList *markers, *tmp;  
         GtkTextIter start, end;  
           
         START_FCN  
           
         CurrentPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(MainNotebook));  
         Lg = FPROPS(CurrentPage, WidgetInfo.Lg);  
         markers = FPROPS(CurrentPage, WidgetInfo.markers);  
           
         /* get rid of old tags */  
         gtk_text_buffer_get_bounds (FPROPS(CurrentPage, Buffer), &start, &end);  
         gtk_text_buffer_remove_tag (FPROPS(CurrentPage, Buffer),  
                 FPROPS(CurrentPage, WidgetInfo.string0_tag), &start, &end);  
         gtk_text_buffer_remove_tag (FPROPS(CurrentPage, Buffer),  
                 FPROPS(CurrentPage, WidgetInfo.string1_tag), &start, &end);  
         gtk_text_buffer_remove_tag (FPROPS(CurrentPage, Buffer),  
                 FPROPS(CurrentPage, WidgetInfo.comment_tag), &start, &end);  
         gtk_text_buffer_remove_tag (FPROPS(CurrentPage, Buffer),  
                 FPROPS(CurrentPage, WidgetInfo.comment_alt_tag), &start, &end);  
           
         /* go through list of markers, applying tags */  
         tmp = markers;  
         while (tmp)  
         {  
                 t_marker *m;  
                 gunichar ch;  
                 gboolean found = FALSE;  
                   
                 m = (t_marker *) tmp->data;  
                   
                 gtk_text_buffer_get_iter_at_mark (Buffer, &start, m->mark);  
                   
                 switch (m->type)  
                 {  
                 case TypeString0:  
                         /* find next string0 */  
                         tmp = tmp->next;  
                         while (tmp)  
                         {  
                                 t_marker *m2;  
                                   
                                 m2 = (t_marker *) tmp->data;  
                                   
                                 if (m2->type == TypeString0)  
                                 {  
                                         found = TRUE;  
                                         gtk_text_buffer_get_iter_at_mark (Buffer, &end, m2->mark);  
                                         gtk_text_iter_forward_cursor_position (&end);  
                                         break;  
                                 }  
                                   
                                 tmp = tmp->next;  
                         }  
                           
                         if (!found)  
                         {  
                                 gtk_text_buffer_get_end_iter (Buffer, &end);  
                         }  
                           
                         gtk_text_buffer_apply_tag (Buffer, FPROPS(CurrentPage, WidgetInfo.string0_tag),  
                                 &start, &end);  
                         break;  
                   
                 case TypeString1:  
                         /* find next string1 */  
                         tmp = tmp->next;  
                         while (tmp)  
                         {  
                                 t_marker *m2;  
                                   
                                 m2 = (t_marker *) tmp->data;  
                                   
                                 if (m2->type == TypeString1)  
                                 {  
                                         found = TRUE;  
                                         gtk_text_buffer_get_iter_at_mark (Buffer, &end, m2->mark);  
                                         gtk_text_iter_forward_cursor_position (&end);  
                                         break;  
                                 }  
                                   
                                 tmp = tmp->next;  
                         }  
                           
                         if (!found)  
                         {  
                                 gtk_text_buffer_get_end_iter (Buffer, &end);  
                         }  
                           
                         gtk_text_buffer_apply_tag (Buffer, FPROPS(CurrentPage, WidgetInfo.string1_tag),  
                                 &start, &end);  
                         break;  
                           
                 case TypeBlockCommentOn:  
                         /* find next BlockCommentOff */  
                         tmp = tmp->next;  
                         while (tmp)  
                         {  
                                 t_marker *m2;  
                                   
                                 m2 = (t_marker *) tmp->data;  
                                   
                                 if (m2->type == TypeBlockCommentOff)  
                                 {  
                                         found = TRUE;  
                                         gtk_text_buffer_get_iter_at_mark (Buffer, &end, m2->mark);  
                                         gtk_text_iter_forward_chars (&end, strlen (Prefs.L[Lg].BlockCommentOff));  
                                         break;  
                                 }  
                                   
                                 tmp = tmp->next;  
                         }  
                           
                         if (!found)  
                         {  
                                 gtk_text_buffer_get_end_iter (Buffer, &end);  
                         }  
                           
                         gtk_text_buffer_apply_tag (Buffer, FPROPS(CurrentPage, WidgetInfo.comment_tag),  
                                 &start, &end);  
                         break;  
                           
                 case TypeBlockCommentOnAlt:  
                         /* find next BlockCommentOffAlt*/  
                         tmp = tmp->next;  
                         while (tmp)  
                         {  
                                 t_marker *m2;  
                                   
                                 m2 = (t_marker *) tmp->data;  
                                   
                                 if (m2->type == TypeBlockCommentOffAlt)  
                                 {  
                                         found = TRUE;  
                                         gtk_text_buffer_get_iter_at_mark (Buffer, &end, m2->mark);  
                                         gtk_text_iter_forward_chars (&end, strlen (Prefs.L[Lg].BlockCommentOffAlt));  
                                         break;  
                                 }  
                                   
                                 tmp = tmp->next;  
                         }  
                           
                         if (!found)  
                         {  
                                 gtk_text_buffer_get_end_iter (Buffer, &end);  
                         }  
                           
                         gtk_text_buffer_apply_tag (Buffer, FPROPS(CurrentPage, WidgetInfo.comment_alt_tag),  
                                 &start, &end);  
                         break;  
                   
                 case TypeLineComment:  
                         /* find next end of line */  
                         end = start;  
                         do  
                         {  
                                 gtk_text_iter_forward_cursor_position (&end);  
                                 ch = gtk_text_iter_get_char (&end);  
                         }  
                         while (ch && (ch != '\n' && ch != '\r'));  
                           
                         gtk_text_iter_forward_cursor_position (&end);  
                           
                         tmp = tmp->next;  
                         while (tmp)  
                         {  
                                 t_marker *m2;  
                                 GtkTextIter iter;  
                                   
                                 m2 = (t_marker *) tmp->data;  
                                   
                                 gtk_text_buffer_get_iter_at_mark (Buffer, &iter, m2->mark);  
                                   
                                 if (gtk_text_iter_compare (&iter, &end) >= 0)  
                                 {  
                                         // back up  
                                         tmp = tmp->prev;  
                                         break;  
                                 }  
                                   
                                 tmp = tmp->next;  
                         }  
                           
                         gtk_text_buffer_apply_tag (Buffer, FPROPS(CurrentPage, WidgetInfo.comment_tag),  
                                 &start, &end);  
                         break;  
                           
                 case TypeLineCommentAlt:  
                         /* find next end of line */  
                         end = start;  
                         do  
                         {  
                                 gtk_text_iter_forward_cursor_position (&end);  
                                 ch = gtk_text_iter_get_char (&end);  
                         }  
                         while (ch && (ch != '\n' && ch != '\r'));  
                           
                         gtk_text_iter_forward_cursor_position (&end);  
                           
                         tmp = tmp->next;  
                         while (tmp)  
                         {  
                                 t_marker *m2;  
                                 GtkTextIter iter;  
                                   
                                 m2 = (t_marker *) tmp->data;  
                                   
                                 gtk_text_buffer_get_iter_at_mark (Buffer, &iter, m2->mark);  
                                   
                                 if (gtk_text_iter_compare (&iter, &end) >= 0)  
                                 {  
                                         // back up  
                                         tmp = tmp->prev;  
                                         break;  
                                 }  
                                   
                                 tmp = tmp->next;  
                         }  
                           
                         gtk_text_buffer_apply_tag (Buffer, FPROPS(CurrentPage, WidgetInfo.comment_alt_tag),  
                                 &start, &end);  
                         break;  
                 }  
                   
                 if (tmp)  
                         tmp = tmp->next;  
         }  
           
         END_FCN  
 }  
   
 void search_for_keyword_correctly (gint page, GtkTextBuffer *Buffer, gchar *text, gint *i, gint offset, gint Lg)  
 {  
         /* search for a keyword */  
         gint tmp;  
         gint next, prev, edge, possible = -1;  
         gboolean last_was_delimiter;  
         int color = -1;  
           
         START_FCN  
           
         next = *i;  
         tmp = text[*i];  
           
         /* get to first useless char */  
         while (tmp && (Prefs.L[Lg].KeywordStatus[(int) tmp] & 1))  
         {  
                 next++;  
                 tmp = text[next];  
         }  
           
         edge = prev = next;  
         prev++;  
           
         last_was_delimiter = FALSE;  
         do  
         {  
                 if ((last_was_delimiter || Prefs.L[Lg].IsADelimiter[tmp]) &&  
                      Prefs.L[Lg].KeywordStatus[tmp] & 4) /* ends a keyword */  
                 {  
                         gchar *stuff;  
                           
                         /* let's get text including this char */  
                         stuff = g_strndup (&text[*i], prev - *i);  
                         color = is_matching_keyword (Lg, stuff);  
                         g_free (stuff);  
                           
                         if (color >= 0)  
                         {  
                                 edge = prev;  
                                 /* we found our match */  
                                 break;  
                         }  
                 }  
                   
                 if (Prefs.L[Lg].IsADelimiter[tmp])  
                 {  
                         if (next != *i &&  
                             ((Prefs.L[Lg].KeywordStatus[tmp] & 2) ||  
                             (Prefs.L[Lg].KeywordStatus[tmp] & 8)))  
                         {  
                                 /* this starts some keywords, so we should come back to it  
                                    if we can't find a match */  
                                 possible = next;  
                         }  
                           
                         last_was_delimiter = TRUE;  
                 }  
                 else  
                 {  
                         last_was_delimiter = FALSE;  
                 }  
                   
                 prev = next;  
                 next--;  
                 tmp = text[next];  
         }  
         while (*i <= next);  
           
         if (color != -1)  
         {  
                 GtkTextIter start, end;  
                   
                 /* apply tag */  
                 gtk_text_buffer_get_iter_at_offset (Buffer, &start, offset + *i);  
                 gtk_text_buffer_get_iter_at_offset (Buffer, &end, offset + edge);  
                 gtk_text_buffer_apply_tag (Buffer,  
                         FPROPS (page, WidgetInfo.keyword_tags[color]), &start, &end);  
         }  
         else  
         {  
                 if (possible >= 0)  
                 {  
                         edge = possible;  
                 }  
         }  
           
         *i = edge;  
           
         END_FCN  
 }  
   
   
 inline void search_for_keyword_fastly (gint page, GtkTextBuffer *Buffer, gchar *text, gint *i, gint offset, gint Lg)  
 {  
         /* search for a keyword */  
         gint tmp, next;  
         gboolean possibly_a_keyword = TRUE;  
         int color = -1;  
         gchar *key;  
           
         START_FCN  
           
         next = *i;  
         tmp = text[next];  
           
         if (Prefs.L[Lg].IsADelimiter[tmp])  
         {  
                 if (Prefs.L[Lg].KeywordStatus[tmp] & 2)  
                 {  
                         /* check if this delimiter is itself a keyword.  This is a work-around  
                          for coloring operators */  
                         next++;  
                 }  
                 else  
                 {  
                         *i += 1;  
                         return;  
                 }  
         }  
         else  
         {  
                 /* get to first useless char  or delimiter */  
                 while (tmp && !Prefs.L[Lg].IsADelimiter[tmp])  
                 {  
                         if (!Prefs.L[Lg].KeywordStatus[tmp] & 1)  
                         {  
                                 /* if we hit something that isn't in a keyword before we hit a delimiter,  
                                  note it and stop */  
                                 possibly_a_keyword = FALSE;  
                         }  
                           
                         next++;  
                         tmp = text[next];  
                 }  
         }  
           
         if (possibly_a_keyword)  
         {  
                 key = g_strndup (&text[*i], next - *i);  
                 color = is_matching_keyword (Lg, key);  
                 g_free (key);  
                   
                 if (color != -1)  
                 {  
                         GtkTextIter start, end;  
                           
                         /* apply tag */  
                         gtk_text_buffer_get_iter_at_offset (Buffer, &start, offset + *i);  
                         gtk_text_buffer_get_iter_at_offset (Buffer, &end, offset + next);  
                         gtk_text_buffer_apply_tag (Buffer,  
                                 FPROPS (page, WidgetInfo.keyword_tags[color]), &start, &end);  
                 }  
         }  
           
         *i = next;  
           
         END_FCN  
 }  
   
 void search_for_keyword (gint page, GtkTextBuffer *Buffer, gchar *text, gint *i, gint offset, gint Lg)  
 {  
         /* the difference between searching fast or correct is that the fast search assumes no delimiters  
          appear in keywords.  Correct checks for this and also prefers the longest applicable match.  
   
         HTML is the only big language right now that uses this, so we only do correct thing for HTML.  
         */  
           
         if (Prefs.L[Lg].IsHTML)  
         {  
                 search_for_keyword_correctly (page, Buffer, text, i, offset, Lg);  
         }  
         else  
         {  
                 search_for_keyword_fastly (page, Buffer, text, i, offset, Lg);  
         }  
 }  
   
 void markup_syhi_range (GtkTextBuffer *Buffer, GtkTextIter start, GtkTextIter end)  
 {  
         int CurrentPage;  
         gint Lg, position, i, j;  
         GList *markers, *tmp, *prev;  
         gchar *text;  
         GtkTextIter textiter;  
         gboolean prev_set;  
         gboolean last_was_escape;  
         gboolean restart = FALSE;  
         gboolean markers_changed = FALSE;  
         GTimer *timer = g_timer_new ();  
           
         START_FCN  
           
         CurrentPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(MainNotebook));  
         Lg = FPROPS(CurrentPage, WidgetInfo.Lg);  
         markers = FPROPS(CurrentPage, WidgetInfo.markers);  
           
         text = gtk_text_iter_get_text (&start, &end);  
         i = 0;  
           
 #ifdef DEBUG_SYHI  
         g_print(__FILE__": %s(): Language of file modified: /L%i \"%s\"\n", __func__,  
                 Lg + 1, Prefs.L[Lg].Description);  
         {  
                 gchar *s;  
                 s = gtk_text_iter_get_text (&start, &end);  
                 g_print(__FILE__": Examining string \"%s\"\n", s);  
                 g_free (s);  
         }  
 #endif  
           
         /* find place right before where we are in marker list,  
             and delete all the markers between start and end*/  
         tmp = markers;  
         prev = NULL;  
         prev_set = FALSE;  
         position = 0;  
         while (tmp)  
         {  
                 gtk_text_buffer_get_iter_at_mark (Buffer, &textiter, ((t_marker *) tmp->data)->mark);  
                   
                 if (!prev && gtk_text_iter_compare (&textiter, &start) >= 0)  
                 {  
                         /* save previous marker */  
                         prev = tmp->prev;  
                         prev_set = TRUE;  
                 }  
                   
                 if (prev_set && gtk_text_iter_compare (&textiter, &end) <= 0)  
                 {  
                         GList *deleted;  
                         gtk_text_buffer_delete_mark (Buffer, ((t_marker *) tmp->data)->mark);  
                         deleted = tmp;  
                         tmp = tmp->next;  
                         markers = g_list_remove_link (markers, deleted);  
                         g_free (deleted->data);  
                         g_list_free_1 (deleted);  
                           
                         markers_changed = TRUE;  
                 }  
                 else if (!prev_set)  
                 {  
                         tmp = tmp->next;  
                         position ++;  
                 }  
                 else  
                         break;  
         }  
           
         if (prev)  
                 position = g_list_position (markers, prev) + 1;  
         else if (!markers)  
                 position = 0;  
           
         gtk_text_buffer_remove_tag (Buffer, FPROPS(CurrentPage, WidgetInfo.number_tag), &start, &end);  
         for (j = 0; j < MAX_COL; j++)  
         {  
                 gtk_text_buffer_remove_tag (Buffer,  
                         FPROPS(CurrentPage, WidgetInfo.keyword_tags[j]), &start, &end);  
         }  
           
         last_was_escape = FALSE;  
         g_timer_start (timer);  
         while (text[i] && !restart)  
         {  
                 gint ch;  
                 gint word_end;  
                 t_marker *m;  
                 gboolean scan = FALSE;  
                   
                 ch = text[i];  
                 if (Prefs.L[Lg].EscapeChar == ch)  
                 {  
                         i++;  
                           
                         if (!last_was_escape)  
                         {  
                                 last_was_escape = TRUE;  
                                 continue;  
                         }  
                 }  
                 else if (Prefs.L[Lg].KeywordStatus[ch] & 8)  
                 {  
                         if (Prefs.L[Lg].HaveString && Prefs.L[Lg].StringChar0 != '\0' &&  
                             Prefs.L[Lg].StringChar0 == ch)  
                         {  
                                 if (last_was_escape)  
                                 {  
                                         i++;  
                                 }  
                                 else  
                                 {  
                                         GtkTextIter iter = start;  
                                           
                                         m = g_malloc (sizeof (t_marker));  
                                           
                                         gtk_text_iter_forward_chars (&iter, i);  
                                         m->mark = gtk_text_buffer_create_mark (Buffer, NULL, &iter, FALSE);  
                                         m->type = TypeString0;  
                                         markers = g_list_insert (markers, m, position++);  
                                         markers_changed = TRUE;  
                                           
                                         i++;  
                                 }  
                         }  
                         else if (Prefs.L[Lg].HaveString && Prefs.L[Lg].StringChar1 != '\0' &&  
                              Prefs.L[Lg].StringChar1 == ch)  
                         {  
                                 if (last_was_escape)  
                                 {  
                                         i++;  
                                 }  
                                 else  
                                 {  
                                         GtkTextIter iter = start;  
                                           
                                         m = g_malloc (sizeof (t_marker));  
                                           
                                         gtk_text_iter_forward_chars (&iter, i);  
                                         m->mark = gtk_text_buffer_create_mark (Buffer, NULL, &iter, FALSE);  
                                         m->type = TypeString1;  
                                         markers = g_list_insert (markers, m, position++);  
                                         markers_changed = TRUE;  
                                           
                                         i++;  
                                 }  
                         }  
                         else if (Prefs.L[Lg].LineComment != NULL &&  
                                 starts_string (text, i, Prefs.L[Lg].LineComment, &word_end))  
                         {  
                                 GtkTextIter iter = start;  
                                   
                                 m = g_malloc (sizeof (t_marker));  
                                   
                                 gtk_text_iter_forward_chars (&iter, i);  
                                 m->mark = gtk_text_buffer_create_mark (Buffer, NULL, &iter, FALSE);  
                                 m->type = TypeLineComment;  
                                 markers = g_list_insert (markers, m, position++);  
                                 markers_changed = TRUE;  
                                   
                                 i = word_end;  
                         }  
                         else if (Prefs.L[Lg].LineCommentAlt != NULL &&  
                                 starts_string (text, i, Prefs.L[Lg].LineCommentAlt, &word_end))  
                         {  
                                 GtkTextIter iter = start;  
                                   
                                 m = g_malloc (sizeof (t_marker));  
                                   
                                 gtk_text_iter_forward_chars (&iter, i);  
                                 m->mark = gtk_text_buffer_create_mark (Buffer, NULL, &iter, FALSE);  
                                 m->type = TypeLineCommentAlt;  
                                 markers = g_list_insert (markers, m, position++);  
                                 markers_changed = TRUE;  
                                   
                                 i = word_end;  
                         }  
                         else if (Prefs.L[Lg].BlockCommentOn != NULL &&  
                                 starts_string (text, i, Prefs.L[Lg].BlockCommentOn, &word_end))  
                         {  
                                 GtkTextIter iter = start;  
                                   
                                 m = g_malloc (sizeof (t_marker));  
                                   
                                 gtk_text_iter_forward_chars (&iter, i);  
                                 m->mark = gtk_text_buffer_create_mark (Buffer, NULL, &iter, FALSE);  
                                 m->type = TypeBlockCommentOn;  
                                 markers = g_list_insert (markers, m, position++);  
                                 markers_changed = TRUE;  
                                   
                                 i = word_end;  
                         }  
                         else if (Prefs.L[Lg].BlockCommentOnAlt != NULL &&  
                                 starts_string (text, i, Prefs.L[Lg].BlockCommentOnAlt, &word_end))  
                         {  
                                 GtkTextIter iter = start;  
                                   
                                 m = g_malloc (sizeof (t_marker));  
                                   
                                 gtk_text_iter_forward_chars (&iter, i);  
                                 m->mark = gtk_text_buffer_create_mark (Buffer, NULL, &iter, FALSE);  
                                 m->type = TypeBlockCommentOnAlt;  
                                 markers = g_list_insert (markers, m, position++);  
                                 markers_changed = TRUE;  
                                   
                                 i = word_end;  
                         }  
                         else if (Prefs.L[Lg].BlockCommentOff != NULL &&  
                                 starts_string (text, i, Prefs.L[Lg].BlockCommentOff, &word_end))  
                         {  
                                 GtkTextIter iter = start;  
                                   
                                 m = g_malloc (sizeof (t_marker));  
                                   
                                 gtk_text_iter_forward_chars (&iter, i);  
                                 m->mark = gtk_text_buffer_create_mark (Buffer, NULL, &iter, FALSE);  
                                 m->type = TypeBlockCommentOff;  
                                 markers = g_list_insert (markers, m, position++);  
                                 markers_changed = TRUE;  
                                   
                                 i = word_end;  
                         }  
                         else if (Prefs.L[Lg].BlockCommentOffAlt != NULL &&  
                                 starts_string (text, i, Prefs.L[Lg].BlockCommentOffAlt, &word_end))  
                         {  
                                 GtkTextIter iter = start;  
                                   
                                 m = g_malloc (sizeof (t_marker));  
                                   
                                 gtk_text_iter_forward_chars (&iter, i);  
                                 m->mark = gtk_text_buffer_create_mark (Buffer, NULL, &iter, FALSE);  
                                 m->type = TypeBlockCommentOffAlt;  
                                 markers = g_list_insert (markers, m, position++);  
                                 markers_changed = TRUE;  
                                   
                                 i = word_end;  
                         }  
                         else  
                         {  
                                 scan = TRUE;  
                         }  
                 }  
                 else  
                 {  
                         scan = TRUE;  
                 }  
                   
                 last_was_escape = FALSE;  
                   
                 if (!scan)  
                         continue;  
                   
                 if (g_ascii_isdigit (ch))  
                 {  
                         GtkTextIter iter = start, iter2 = start;  
                           
                         gtk_text_iter_forward_chars (&iter, i);  
                           
                         /* go forward to next delimiter */  
                         do  
                         {  
                                 i++;  
                                 ch = text[i];  
                         }  
                         while (ch && (ch > 255 || !Prefs.L[Lg].IsADelimiter[ch]));  
                           
                         /* apply tag */  
                         gtk_text_iter_forward_chars (&iter2, i);  
                         gtk_text_buffer_apply_tag (Buffer,  
                                 FPROPS (CurrentPage, WidgetInfo.number_tag), &iter, &iter2);                              
                 }  
                 else if (!(Prefs.L[Lg].KeywordStatus[ch] & 0x2))  
                 {  
                         /* this character does *not* start a keyword.  */  
                           
                         if (Prefs.L[Lg].IsADelimiter[ch])  
                         {  
                                 i++;  
                         }  
                         else  
                         {  
                                 /* go forward to next delimiter */  
                                 do  
                                 {  
                                         i++;  
                                         ch = text[i];  
                                 }  
                                 while (ch && (ch > 255 || !Prefs.L[Lg].IsADelimiter[ch]));  
                         }  
                 }  
                 else  
                 {  
                         search_for_keyword (CurrentPage, Buffer, text, &i, gtk_text_iter_get_offset (&start), Lg);  
                 }  
                   
                 /* this block is needed because if syhi is taking a long time, we want to update the gui --  
                    to make it feel like it is running at reasonable speed */  
 #if 1  
                 if (g_timer_elapsed (timer, NULL) >= 0.5) /* if half a second has elapsed, */  
                 {  
                         GtkTextMark *start_mark, *end_mark;  
                           
                         FPROPS(CurrentPage, WidgetInfo.markers) = markers;  
                         if (markers_changed)  
                         {  
                                 refresh_markers (Buffer);  
                         }  
                           
                         FPROPS(CurrentPage, WidgetInfo.syhi_ran) = FALSE;  
                         start_mark = gtk_text_buffer_create_mark (Buffer, NULL,  
                                 &start, TRUE);  
                         end_mark = gtk_text_buffer_create_mark (Buffer, NULL,  
                                 &end, TRUE);  
                           
                         gtk_main_iteration_do (FALSE);  
                           
                         /* if an insertion happened while we were 'sleeping,' restart syhi */  
                         if (FPROPS (CurrentPage, WidgetInfo.syhi_ran))  
                         {  
                                 gtk_text_buffer_get_iter_at_mark (Buffer, &start, start_mark);  
                                 gtk_text_buffer_get_iter_at_mark (Buffer, &end, end_mark);  
                                   
                                 expand_syhi_iters (Buffer, &start, &end, Lg);  
                                   
                                 restart = TRUE;  
                         }  
                           
                         gtk_text_buffer_delete_mark (Buffer, start_mark);  
                         gtk_text_buffer_delete_mark (Buffer, end_mark);  
                           
                         g_timer_start (timer);  
                 }  
 #endif  
         }  
           
         g_free (text);  
         g_timer_destroy (timer);  
           
         FPROPS (CurrentPage, WidgetInfo.syhi_ran) = TRUE;  
         FPROPS(CurrentPage, WidgetInfo.markers) = markers;  
           
         if (restart)  
         {  
                 markup_syhi_range (Buffer, start, end);  
         }  
         else  
         {  
                 if (markers_changed)  
                 {  
                         refresh_markers (Buffer);  
                 }  
                   
                 /* redraw the current page, because we may have changed some colors around */  
                 gtk_widget_queue_draw (FPROPS(CurrentPage, Text));  
         }  
           
         END_FCN  
 }  
   
   
 void expand_syhi_iters (GtkTextBuffer *Buffer, GtkTextIter *start, GtkTextIter *end, gint Lg)  
 {  
         gunichar tmp;  
         gboolean inside_buffer;  
           
         START_FCN  
           
         /* go backwards  */  
         do  
         {  
                 inside_buffer = gtk_text_iter_backward_cursor_position (start);  
                 tmp = gtk_text_iter_get_char (start);  
         }  
         while (inside_buffer &&  
                (tmp <= 255 && ((Prefs.L[Lg].KeywordStatus[tmp] & 8) ||  
                                 (Prefs.L[Lg].KeywordStatus[tmp] & 1))));  
           
         if (inside_buffer)  
                 gtk_text_iter_forward_cursor_position (start);  
           
         while (gtk_text_iter_get_char (start) &&  
                !g_unichar_isprint (gtk_text_iter_get_char (start)))  
         {  
                 gtk_text_iter_forward_cursor_position (start);  
         }  
           
         /* go forwards  */  
         inside_buffer = tmp = gtk_text_iter_get_char (end);  
         while (inside_buffer &&  
                (tmp <= 255 && ((Prefs.L[Lg].KeywordStatus[tmp] & 8) ||  
                                (Prefs.L[Lg].KeywordStatus[tmp] & 1))))  
         {  
                 inside_buffer = gtk_text_iter_forward_cursor_position (end);  
                 tmp = gtk_text_iter_get_char (end);  
         }  
           
         END_FCN  
 }  
   
   
 void refresh_syhi_on_insert (GtkTextBuffer *Buffer, GtkTextIter *end_in, gchar *text,  
         gint size, gpointer data)  
 {  
         GtkTextIter start, end;  
         gint CurrentPage, Lg;  
           
         START_FCN  
           
         CurrentPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(MainNotebook));  
         Lg = FPROPS(CurrentPage, WidgetInfo.Lg);  
           
         if (Lg == -1)  
                 return;  
           
         /* first we must move iters out to interesting edges */  
         end = start = *end_in;  
         gtk_text_iter_backward_chars (&start, size);  
         expand_syhi_iters (Buffer, &start, &end, Lg);  
           
         markup_syhi_range (Buffer, start, end);  
           
         END_FCN  
 }  
   
   
 void refresh_syhi_on_delete (GtkTextBuffer *Buffer, GtkTextIter *start_in,  
         GtkTextIter *end_in, gpointer data)  
 {  
         GtkTextIter start, end;  
         gint CurrentPage, Lg;  
           
         START_FCN  
           
         CurrentPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(MainNotebook));  
         Lg = FPROPS(CurrentPage, WidgetInfo.Lg);  
           
         if (Lg == -1)  
                 return;  
           
         start = *start_in;  
         end = *end_in;  
         expand_syhi_iters (Buffer, &start, &end, Lg);  
           
         markup_syhi_range (Buffer, start, end);  
           
         END_FCN  
 }  
   
   
 void refresh_syhi_all (GtkTextView *View)  
 {  
         GtkTextIter start, end;  
         GtkTextBuffer *Buffer;  
         gint Lg, CurrentPage;  
           
         START_FCN  
           
         CurrentPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(MainNotebook));  
         Lg = FPROPS(CurrentPage, WidgetInfo.Lg);  
           
         Buffer = gtk_text_view_get_buffer (View);  
         gtk_text_buffer_get_start_iter (Buffer, &start);  
         gtk_text_buffer_get_end_iter (Buffer, &end);  
         expand_syhi_iters (Buffer, &start, &end, Lg);   // this catches some cases, so we still need to call it  
         markup_syhi_range (Buffer, start, end);  
           
         END_FCN  
 }  
   
537  void auto_indent_on_insert (GtkTextBuffer *Buffer, GtkTextIter *iter, gchar *text,  void auto_indent_on_insert (GtkTextBuffer *Buffer, GtkTextIter *iter, gchar *text,
538          gint size, gpointer data)          gint size, gpointer data)
539  {  {
# Line 1621  void auto_unindent_on_insert (GtkTextBuf Line 686  void auto_unindent_on_insert (GtkTextBuf
686          END_FCN          END_FCN
687  }  }
688    
   
 /*  
 ** This func returns the language number of the current Editor  
 **  
 ** Parameters :  
 **  void  
 **  
 ** Return Values :  
 **  -1                  Unknown language (extension not recognized)  
 ** 0..MAX_LANG - 1      Language number  
 **  
 ** NOTE_WARNING: UEdit language numbers belongs to [1..MAX_LANG]  
 */  
 gint                    guess_lang(void)  
 {  
   gchar                 *ext_orig;  
   gint                  ext_len;  
   gchar                 *ext_up;  
   gint                  i;  
   gint                  CurrentPage;  
   
 #ifdef DEBUG_FCN  
   g_print(__FILE__": %s(): Begin\n", __func__);  
 #endif  
   CurrentPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(MainNotebook));  
   ext_orig = FPROPS(CurrentPage, Type);  
 #ifdef DEBUG_EXT_REC  
   g_print(__FILE__": %s(): Getting length of ext_orig...\n", __func__);  
 #endif  
   ext_len = strlen(ext_orig);  
   /* This macro FPROPS is awful :) */  
 #ifdef DEBUG_EXT_REC  
   g_print(__FILE__": %s(): Original extension = \"%s\", len = %i\n", __func__,  
           ext_orig, ext_len);  
 #endif  
   ext_up = malloc(ext_len + 3); /* 1 space before, 1 after, and '\0' */  
   strcpy(ext_up + 1, ext_orig);  
   ext_up[0] = ' ';  
   ext_up[ext_len + 1] = ' ';  
   ext_up[ext_len + 2] = '\0';  
   for (i = 1; i < ext_len + 1; i++)  
     ext_up[i] = toupper(ext_up[i]);  
   /* Now, ext_up contains the extension in upper case */  
 #ifdef DEBUG_EXT_REC  
   g_print(__FILE__": %s(): ' ' + EXTENSION + ' ': \"%s\"\n", __func__, ext_up);  
 #endif  
   for (i = 0; i < MAX_LANG; i++)  
     {  
 #ifdef DEBUG_EXT_REC  
       g_print(__FILE__": %s(): Ext of language /L%i = \"%s\"\n", __func__,  
               i + 1, Prefs.L[i].Extensions);  
 #endif  
       if (Prefs.L[i].IsDefined && strstr(Prefs.L[i].Extensions, ext_up))  
         {  
           free(ext_up);  
 #ifdef DEBUG_FCN  
           g_print(__FILE__": %s(): End\n", __func__);  
 #endif  
           return i;  
         }  
     }  
   free(ext_up);  
 #ifdef DEBUG_FCN  
   g_print(__FILE__": %s(): End\n", __func__);  
 #endif  
   return -1;  
 }  
   
   
 /*  
 ** This fcn is used to read the UltraEdit wordfile to init different  
 ** fields of the global variable Prefs  
 **  
 ** Parameters :  
 **  wf_name             UEdit wordfile name  
 **  
 ** Return Values :  
 **  0                   All is right  
 **  -1                  Can not open wordfile  
 **  -2                  Parse error in a language section  
 */  
 extern gint             read_uedit_wordfile(const gchar *wf_name)  
 {  
   FILE                  *fp;  
   gint                  filesize;  
   gchar                 *buffer;  
   gint                  i;  
   gint                  j;  
   
 #ifdef DEBUG_FCN  
   g_print(__FILE__": %s(): Begin\n", __func__);  
 #endif  
   /* Initialisation of all variables */  
   /* TODO: Free all these variables by creating a new fcn called when  
      exiting Beaver */  
   for (i = 0; i < MAX_LANG; i++)  
     {  
       for (j = 0; j < MAX_COL; j++)  
         {  
           Prefs.L[i].C[j].Keywords = NULL;  
           Prefs.L[i].C[j].Description[0] = '\0';  
         }  
       Prefs.L[i].IsDefined = FALSE;  
       Prefs.L[i].LargestKeyword = 0;  
       Prefs.L[i].Description[0] = '\0';  
       Prefs.L[i].Extensions = NULL;  
       Prefs.L[i].LineComment = NULL;  
       Prefs.L[i].LineCommentAlt = NULL;  
       Prefs.L[i].BlockCommentOn = NULL;  
       Prefs.L[i].BlockCommentOff = NULL;  
       Prefs.L[i].BlockCommentOnAlt = NULL;  
       Prefs.L[i].BlockCommentOffAlt = NULL;  
       Prefs.L[i].IsCaseSensitive = TRUE;  
       Prefs.L[i].HaveString = TRUE;  
       Prefs.L[i].StringChar0 = '\"';  
       Prefs.L[i].StringChar1 = '\0';  
       Prefs.L[i].EscapeChar = '\0';  
       Prefs.L[i].Delimiters = NULL;  
       Prefs.L[i].IndentString = NULL;  
       Prefs.L[i].UnindentString = NULL;  
       Prefs.L[i].MarkerChars = NULL;  
       Prefs.L[i].FunctionString = NULL;  
       Prefs.L[i].IsHTML = FALSE;  
     }  
 #ifdef DEBUG_WORDFILE  
   g_print(__FILE__": %s(): Opening \"%s\"...\n", __func__, wf_name);  
 #endif  
   if (!(fp = fopen(wf_name, "rt")))  
     {  
       gchar *wf_not_found;  
         
       wf_not_found = g_strdup_printf(_("WARNING: Cannot find wordfile \"%s\"."), wf_name);  
       print_msg (wf_not_found);  
       g_free (wf_not_found);  
       return -1;  
     }  
   filesize = 0;  
   while (getc(fp) != EOF)  
     filesize++;  
   if (filesize > 0)  
     {  
       buffer = g_malloc(filesize + 2);  
       fseek(fp, 0, SEEK_SET);  
       for (i = 0; i < filesize; i++)  
         buffer[i] = getc(fp);  
       buffer[filesize] = '\n';  
       buffer[filesize + 1] = '\0';  
     }  
   else  
     buffer = NULL;  
   fclose(fp);  
 #ifdef DEBUG_WORDFILE  
   g_print(__FILE__": %s(): Wordfile size = %i\n", __func__, filesize);  
 #endif  
   /* Here: main work */  
   i = 0;  
   while (i + 1 <= filesize)  
     {  
       if (!strncmp(buffer + i, "/L", 2))  
         {  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): Calling "  
                   "parse_language_section()\n", __func__);  
 #endif  
           if (parse_language_section(buffer, filesize, &i))  
             {  
               g_print(__FILE__": %s(): End, parse error in a "  
                       "language section of \"%s\"\n", __func__, wf_name);  
               g_free(buffer);  
               return -2;  
             }  
         }  
       else  
         i++;  
     }  
   g_free(buffer);  
   for (i = 0; i < MAX_LANG; i++)  
     {  
       if (!Prefs.L[i].IsDefined)  
         sprintf(Prefs.L[i].Description, "Language %i", i + 1);  
       Prefs.L[i].Description[MAXLEN_LANG_DESCRIPTION] = 0;  
       for (j = 0; j < MAX_COL; j++)  
         {  
           if (!Prefs.L[i].C[j].Keywords)  
             sprintf(Prefs.L[i].C[j].Description, "Keywords Group %i", j + 1);  
           Prefs.L[i].C[j].Description[MAXLEN_COL_DESCRIPTION] = 0;  
         }  
     }  
 #ifdef DEBUG_FCN  
   g_print(__FILE__": %s(): End\n", __func__);  
 #endif  
   return 0;  
 }  
   
 /*  
 ** Parse a language section in a UEdit wordfile  
 **  
 ** Parameters:  
 **  buffer              Is a null-terminated string, representing the /Lx  
 **                      section in a wordfile  
 **  size                Size of the buffer  
 **  start               buffer + *start points on "/Lx..."  
 **  
 ** Return values:  
 **  0                   All is right  
 **  -1                  Parse error in a color section  
 */  
 gint                    parse_language_section(gchar *buffer,  
                                                gint size,  
                                                gint *start)  
 {  
   gint                  Lg;  
   gint                  i;  
   gint                  j;  
   gchar                 c;  
   
 #ifdef DEBUG_FCN  
   g_print(__FILE__": %s(): Begin\n", __func__);  
 #endif  
   i = *start;  
   i = i + 2;  
   /* buffer[i] is the 1st digit of language number */  
   j = i;  
   while (isdigit(buffer[j]))  
     j++;  
   /* buffer[j] is the first char after the last digit of language number */  
   c = buffer[j];  
   buffer[j] = 0;  
   Lg = atoi(buffer + i) - 1;  
   buffer[j] = c;  
   if (Lg + 1 > MAX_LANG)  
     {  
       g_print(__FILE__": %s(): Warning, /L%i section detected in wordfile "  
               "but only %i are allowed\n", __func__, Lg + 1, MAX_LANG);  
       return -1;  
     }  
 #ifdef DEBUG_WORDFILE  
   g_print(__FILE__": %s(): /L%i section detected\n", __func__, Lg + 1);  
 #endif  
   Prefs.L[Lg].IsDefined = TRUE;  
   i = j;  
   if (buffer[i] == '\"')  
     {  
       /* There is a description of the language */  
       j = ++i;  
       while (buffer[j] != '\"')  
         j++;  
       /* buffer[i] is the 1st char of description and buffer[j] the 2nd '\"' */  
       if ((j - i) > MAXLEN_LANG_DESCRIPTION)  
         {  
           g_print(__FILE__": %s(): Warning, description of "  
                   "language %i is longer than %i\n", __func__, Lg + 1,  
                   MAXLEN_LANG_DESCRIPTION);  
           return -1;  
         }  
       strncpy(Prefs.L[Lg].Description, buffer + i, j - i);  
       Prefs.L[Lg].Description[j - i] = '\0';  
       i = ++j;  
     }  
 #ifdef DEBUG_WORDFILE  
   g_print(__FILE__": %s(): Description of language %i = "  
           "\"%s\"\n", __func__, Lg + 1, Prefs.L[Lg].Description);  
 #endif  
   memset (Prefs.L[Lg].KeywordStatus, 0, 256);  
   /* Here, buffer[i (= j)] is next non-identified char */  
   /* The while loop below reads the line /Lx of a wordfile */  
   while (buffer[i] != '\n')  
     {  
       /* LineComment */  
       if (!strncmp(buffer + i, "Line Comment = ", 15))  
         {  
           Prefs.L[Lg].LineComment = g_malloc(MAXLEN_LINE_COMMENT + 1);  
           i += 15;  
           j = -1;  
           while ((++j < MAXLEN_LINE_COMMENT) && (buffer[i + j] != ' '))  
           {  
             Prefs.L[Lg].KeywordStatus[(int) buffer[i + j]] |= 8;  
             Prefs.L[Lg].LineComment[j] = buffer[i + j];  
           }  
           if ((j == MAXLEN_LINE_COMMENT) && (buffer[i + j] != ' '))  
             {  
               g_print(__FILE__": %s(): Warning, Line Comment of "  
                       "language /L%i is longer than %i\n", __func__,  
                       Lg + 1, MAXLEN_LINE_COMMENT);  
               return -1;  
             }  
           Prefs.L[Lg].LineComment[j] = '\0';  
           i += j;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): Line Comment = \"%s\"\n", __func__,  
                   Prefs.L[Lg].LineComment);  
 #endif  
         }  
       /* LineCommentAlt */  
       else if (!strncmp(buffer + i, "Line Comment Alt = ", 19))  
         {  
           Prefs.L[Lg].LineCommentAlt = g_malloc(MAXLEN_LINE_COMMENT + 1);  
           i += 19;  
           j = -1;  
           while ((++j < MAXLEN_LINE_COMMENT) && (buffer[i + j] != ' '))  
           {  
             Prefs.L[Lg].KeywordStatus[(int) buffer[i + j]] |= 8;  
             Prefs.L[Lg].LineCommentAlt[j] = buffer[i + j];  
           }  
           if ((j == MAXLEN_LINE_COMMENT) && (buffer[i + j] != ' '))  
             {  
               g_print(__FILE__": %s(): Warning, Line Comment Alt of "  
                       "language /L%i is longer than %i\n", __func__,  
                       Lg + 1, MAXLEN_LINE_COMMENT);  
               return -1;  
             }  
           Prefs.L[Lg].LineCommentAlt[j] = '\0';  
           i += j;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): Line Comment Alt = \"%s\"\n", __func__,  
                   Prefs.L[Lg].LineCommentAlt);  
 #endif  
         }  
       /* LineComment Num */  
       else if (!strncmp(buffer + i, "Line Comment Num = ", 19))  
         {  
           gint          line_cmt_len;  
   
           Prefs.L[Lg].LineComment = g_malloc(MAXLEN_LINE_COMMENT + 1);  
           line_cmt_len = buffer[i += 19] - '0';  
           if (line_cmt_len > MAXLEN_LINE_COMMENT)  
             {  
               g_print(__FILE__": %s(): Warning, Line Comment Num of "  
                       "language /L%i is longer than %i\n", __func__,  
                       Lg + 1, MAXLEN_LINE_COMMENT);  
               return -1;  
             }  
           i++;  
           /* Here buffer[i] is the 1st char of LineComment */  
           for (j = 0; j < line_cmt_len; j++)  
           {  
             Prefs.L[Lg].KeywordStatus[(int) buffer[i + j]] |= 8;  
             Prefs.L[Lg].LineComment[j] = buffer[i + j];  
           }  
           Prefs.L[Lg].LineComment[j] = '\0';  
           i += line_cmt_len;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): Line Comment Num = \"%s\"\n", __func__,  
                   Prefs.L[Lg].LineComment);  
 #endif  
         }  
       /* BlockCommentOn */  
       else if (!strncmp(buffer + i, "Block Comment On = ", 19))  
         {  
           Prefs.L[Lg].BlockCommentOn = g_malloc(MAXLEN_BLOCK_COMMENT + 1);  
           i += 19;  
           j = -1;  
           while ((++j < MAXLEN_BLOCK_COMMENT) && (buffer[i + j] != ' '))  
           {  
             Prefs.L[Lg].KeywordStatus[(int) buffer[i + j]] |= 8;  
             Prefs.L[Lg].BlockCommentOn[j] = buffer[i + j];  
           }  
           if ((j == MAXLEN_BLOCK_COMMENT) && (buffer[i + j] != ' '))  
             {  
               g_print(__FILE__": %s(): Warning, Block Comment On of "  
                       "language /L%i is longer than %i\n", __func__,  
                       Lg + 1, MAXLEN_BLOCK_COMMENT);  
               return -1;  
             }  
           Prefs.L[Lg].BlockCommentOn[j] = '\0';  
           i += j;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): Block Comment On = \"%s\"\n", __func__,  
                   Prefs.L[Lg].BlockCommentOn);  
 #endif  
         }  
       /* BlockCommentOff */  
       else if (!strncmp(buffer + i, "Block Comment Off = ", 20))  
         {  
           Prefs.L[Lg].BlockCommentOff = g_malloc(MAXLEN_BLOCK_COMMENT + 1);  
           i += 20;  
           j = -1;  
           while ((++j < MAXLEN_BLOCK_COMMENT) && (buffer[i + j] != ' '))  
           {  
             Prefs.L[Lg].KeywordStatus[(int) buffer[i + j]] |= 8;  
             Prefs.L[Lg].BlockCommentOff[j] = buffer[i + j];  
           }  
           if ((j == MAXLEN_BLOCK_COMMENT) && (buffer[i + j] != ' '))  
             {  
               g_print(__FILE__": %s(): Warning, Block Comment Off of "  
                       "language /L%i is longer than %i\n", __func__,  
                       Lg + 1, MAXLEN_BLOCK_COMMENT);  
               return -1;  
             }  
           Prefs.L[Lg].BlockCommentOff[j] = '\0';  
           i += j;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): Block Comment Off = \"%s\"\n", __func__,  
                   Prefs.L[Lg].BlockCommentOff);  
 #endif  
         }  
       /* BlockCommentOnAlt */  
       else if (!strncmp(buffer + i, "Block Comment On Alt = ", 23))  
         {  
           Prefs.L[Lg].BlockCommentOnAlt = g_malloc(MAXLEN_BLOCK_COMMENT + 1);  
           i += 23;  
           j = -1;  
           while ((++j < MAXLEN_BLOCK_COMMENT) && (buffer[i + j] != ' '))  
           {  
             Prefs.L[Lg].KeywordStatus[(int) buffer[i + j]] |= 8;  
             Prefs.L[Lg].BlockCommentOnAlt[j] = buffer[i + j];  
           }  
           if ((j == MAXLEN_BLOCK_COMMENT) && (buffer[i + j] != ' '))  
             {  
               g_print(__FILE__": %s(): Warning, Block Comment On Alt "  
                       "of language /L%i is longer than %i\n", __func__,  
                       Lg + 1, MAXLEN_BLOCK_COMMENT);  
               return -1;  
             }  
           Prefs.L[Lg].BlockCommentOnAlt[j] = '\0';  
           i += j;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): Block Comment On Alt = \"%s\"\n", __func__,  
                   Prefs.L[Lg].BlockCommentOnAlt);  
 #endif  
         }  
       /* BlockCommentOffAlt */  
       else if (!strncmp(buffer + i, "Block Comment Off Alt = ", 24))  
         {  
           Prefs.L[Lg].BlockCommentOffAlt = g_malloc(MAXLEN_BLOCK_COMMENT + 1);  
           i += 24;  
           j = -1;  
           while ((++j < MAXLEN_BLOCK_COMMENT) && (buffer[i + j] != ' '))  
           {  
             Prefs.L[Lg].KeywordStatus[(int) buffer[i + j]] |= 8;  
             Prefs.L[Lg].BlockCommentOffAlt[j] = buffer[i + j];  
           }  
           if ((j == MAXLEN_BLOCK_COMMENT) && (buffer[i + j] != ' '))  
             {  
               g_print(__FILE__": %s(): Warning, Block Comment Off Alt "  
                       "of language /L%i is longer than %i\n", __func__,  
                       Lg + 1, MAXLEN_BLOCK_COMMENT);  
               return -1;  
             }  
           Prefs.L[Lg].BlockCommentOffAlt[j] = '\0';  
           i += j;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): Block Comment Off Alt = \"%s\"\n", __func__,  
                   Prefs.L[Lg].BlockCommentOffAlt);  
 #endif  
         }  
       /* StringChars */  
       else if (!strncmp(buffer + i, "String Chars = ", 15))  
         {  
           i += 15;  
           if (buffer[i] != ' ')  
           {  
             Prefs.L[Lg].KeywordStatus[(int) buffer[i]] |= 8;  
             Prefs.L[Lg].StringChar0 = buffer[i];  
           }  
           i++;  
           if (buffer[i] != ' ')  
           {  
             Prefs.L[Lg].KeywordStatus[(int) buffer[i]] |= 8;  
             Prefs.L[Lg].StringChar1 = buffer[i];  
           }  
           i++;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): String Chars = \'%c\' & \'%c\'\n", __func__,  
                   Prefs.L[Lg].StringChar0, Prefs.L[Lg].StringChar1);  
 #endif  
         }  
       /* EscapeChar */  
       else if (!strncmp(buffer + i, "Escape Char = ", 14))  
         {  
           i += 14;  
           if (buffer[i] != ' ')  
           {  
             Prefs.L[Lg].KeywordStatus[(int) buffer[i]] |= 8;  
             Prefs.L[Lg].EscapeChar = buffer[i];  
           }  
           i++;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): Escape Char = \'%c\'\n", __func__,  
                   Prefs.L[Lg].EscapeChar);  
 #endif  
         }  
       /* FileExtensions */  
       /* NOTE_WARNING: This sections is supposed to end the line /Lx */  
       else if (!strncmp(buffer + i, "File Extensions = ", 18))  
         {  
           i += 18;  
           j = 0;  
           while (buffer[i + j] != '\n')  
             j++;  
           Prefs.L[Lg].Extensions = g_malloc(1 + j + 1 + 1);  
           Prefs.L[Lg].Extensions[0] = ' ';  
           for (j = 0; buffer[i + j] != '\n'; j++)  
               Prefs.L[Lg].Extensions[1 + j] = buffer[i + j];  
           Prefs.L[Lg].Extensions[j] = ' ';  
           Prefs.L[Lg].Extensions[j + 1] = '\0';  
           i += j;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): File Extensions = \"%s\"\n", __func__,  
                   Prefs.L[Lg].Extensions);  
 #endif  
         }  
       /* Nocase */  
       else if (!strncmp(buffer + i, "Nocase ", 7))  
         {  
           i += 7;  
           Prefs.L[Lg].IsCaseSensitive = FALSE;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): Nocase\n", __func__);  
 #endif  
         }  
       /* Noquote */  
       else if (!strncmp(buffer + i, "Noquote ", 8))  
         {  
           i += 8;  
           Prefs.L[Lg].HaveString = FALSE;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): Noquote\n", __func__);  
 #endif  
         }  
       /* HTML */  
       else if (!strncmp(buffer + i, "HTML_LANG ", 10))  
         {  
           i += 10;  
           Prefs.L[Lg].IsHTML = TRUE;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): HTML_LANG\n", __func__);  
 #endif  
         }  
       /* FORTRAN_LANG */  
       /* NOTE_TODO: Implement it: 'C', 'c' or '*' in the 1st column is a  
          line comment */  
       else if (!strncmp(buffer + i, "FORTRAN_LANG ", 13))  
         {  
           i += 13;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): FORTRAN_LANG\n", __func__);  
 #endif  
         }  
       /* LATEX_LANG */  
       /* NOTE_REMARK: LATEX_LANG is ignored, Beaver does not need it ! */  
       else if (!strncmp(buffer + i, "LATEX_LANG ", 11))  
         {  
           i += 11;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): LATEX_LANG\n", __func__);  
 #endif  
         }  
       else if ((buffer[i] == ' ') || (buffer[i] == '\t'))  
         i++;  
       /* Nothing */  
       else  
         {  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): Unreconized string in /Lx line, "  
                   "beginning = \"%c%c%c%c...\"\n", __func__,  
                   buffer[i], buffer[i + 1], buffer[i + 2], buffer[i + 3]);  
 #endif  
           i++;  
         }  
     } /* while (buffer[i] != '\n') */  
   i++;  
   while ((i + 1 < size) && strncmp(buffer + i, "/C", 2))  
     {  
       if (!strncmp(buffer + i, "/Delimiters = ", 14))  
         {  
           /* Delimiters */  
           j = (i += 14);  
           while (buffer[j] != '\n')  
             j++;  
           j++;  
           /* NOTE_WARNING: Yes, the '\n' needs to be into the Delimiters */  
           Prefs.L[Lg].Delimiters = g_malloc(j - i + 1);  
           strncpy(Prefs.L[Lg].Delimiters, buffer + i, j - i);  
           Prefs.L[Lg].Delimiters[j - i] = '\0';  
           i = j;  
           for (j = 0; j < 256; j++)  
             Prefs.L[Lg].IsADelimiter[j] =  
               strchr(Prefs.L[Lg].Delimiters, j) ? 1 : 0;  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): Delimiters = \"%s\"\n", __func__,  
                   Prefs.L[Lg].Delimiters);  
 #endif  
         }  
       else if (!strncmp(buffer + i, "/Indent Strings =", 17))  
         {  
           /* Indent Strings */  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): Indent String = ", __func__);  
 #endif  
           i += 17;  
           while ((buffer[i] != '\n') && (buffer[i] != '\"'))  
             i++;  
           if (buffer[i] == '\"')  
             {  
               j = ++i;  
               while ((buffer[j] != '\n') && (buffer[j] != '\"'))  
                 j++;  
               /* Here, if buffer[j] == '\n', it is considered as a '\"' */  
               Prefs.L[Lg].IndentString = g_malloc(j - i + 1);  
               strncpy(Prefs.L[Lg].IndentString, buffer + i, j - i);  
               Prefs.L[Lg].IndentString[j - i] = '\0';  
               i = j;  
               /* NOTE_TODO : Support multiple indent string... */  
               while (buffer[i] != '\n')  
                 i++;  
               i++;  
 #ifdef DEBUG_WORDFILE  
               g_print("\"%s\"\n", Prefs.L[Lg].IndentString);  
 #endif  
             }  
           else  
             i++;  
         }  
       else if (!strncmp(buffer + i, "/Unindent Strings =", 19))  
         {  
           /* Unindent Strings */  
           i += 19;  
           while ((buffer[i] != '\n') && (buffer[i] != '\"'))  
             i++;  
           if (buffer[i] == '\"')  
             {  
               j = ++i;  
               while ((buffer[j] != '\n') && (buffer[j] != '\"'))  
                 j++;  
               /* Here, if buffer[j] == '\n', it is considered as a '\"' */  
               Prefs.L[Lg].UnindentString = g_malloc(j - i + 1);  
               strncpy(Prefs.L[Lg].UnindentString, buffer + i, j - i);  
               Prefs.L[Lg].UnindentString[j - i] = '\0';  
               i = j;  
               /* NOTE_TODO : Support multiple unindent string... */  
               while (buffer[i] != '\n')  
                 i++;  
               i++;  
 #ifdef DEBUG_WORDFILE  
               g_print(__FILE__": %s(): Unindent String = \"%s\"\n", __func__,  
                       Prefs.L[Lg].UnindentString);  
 #endif  
             }  
           else  
             i++;  
         }  
       else if (!strncmp(buffer + i, "/Marker Characters =", 20))  
         {  
           /* Marker Characters */  
 #ifdef DEBUG_WORDFILE  
               g_print(__FILE__": %s(): Marker Chars = ", __func__);  
 #endif  
           i += 20;  
           while ((buffer[i] != '\n') && (buffer[i] != '\"'))  
             i++;  
           if (buffer[i] == '\"')  
             {  
               j = ++i;  
               while ((buffer[j] != '\n') && (buffer[j] != '\"'))  
                 j++;  
               /* Here, if buffer[j] == '\n', it is considered as a '\"' */  
               Prefs.L[Lg].MarkerChars = g_malloc(j - i + 1);  
               strncpy(Prefs.L[Lg].MarkerChars, buffer + i, j - i);  
               Prefs.L[Lg].MarkerChars[j - i] = '\0';  
               i = j;  
               /* NOTE_TODO : Support marker chars... */  
               while (buffer[i] != '\n')  
                 i++;  
               i++;  
 #ifdef DEBUG_WORDFILE  
               g_print("\"%s\"\n", Prefs.L[Lg].MarkerChars);  
 #endif  
             }  
           else  
             i++;  
         }  
       else if (!strncmp(buffer + i, "/Function String =", 18))  
         {  
           /* Function String */  
 #ifdef DEBUG_WORDFILE  
               g_print(__FILE__": %s(): Function String = ", __func__);  
 #endif  
           i += 18;  
           while ((buffer[i] != '\n') && (buffer[i] != '\"'))  
             i++;  
           if (buffer[i] == '\"')  
             {  
               j = ++i;  
               while ((buffer[j] != '\n') && (buffer[j] != '\"'))  
                 j++;  
               /* Here, if buffer[j] == '\n', it is considered as a '\"' */  
               Prefs.L[Lg].FunctionString = g_malloc(j - i + 1);  
               strncpy(Prefs.L[Lg].FunctionString, buffer + i, j - i);  
               Prefs.L[Lg].FunctionString[j - i] = '\0';  
               i = j;  
               /* NOTE_TODO : Support function string */  
               while (buffer[i] != '\n')  
                 i++;  
               i++;  
 #ifdef DEBUG_WORDFILE  
               g_print("\"%s\"\n", Prefs.L[Lg].FunctionString);  
 #endif  
             }  
           else  
             i++;  
         }  
       else if ((buffer[i] == ' ') || (buffer[i] == '\t'))  
         i++;  
       else  
         {  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): Unregonized string between /Lx "  
                   "and /Cy: \"%c%c%c%c...\"\n", __func__,  
                   buffer[i], buffer[i + 1], buffer[i + 2], buffer[i + 3]);  
 #endif  
           i++;  
         }  
     } /* while (strncmp(buffer + i, "/C", 2)) */  
   while ((i + 1 <= size) && strncmp(buffer + i, "/L", 2))  
     {  
       if (!strncmp(buffer + i, "/C", 2))  
         {  
           if (parse_color_section(buffer, size, &i, Lg))  
             {  
               g_print(__FILE__": %s(): End, parse error in a color "  
                       "section of /L%i\n", __func__, Lg + 1);  
               return -1;  
             }  
         }  
       else  
         i++;  
     }  
   *start = i;  
   /*  
   ** Now that all Prefs.L[Lg].C[_var_].Keywords are initialized, we can  
   ** fill in the keywords hash tables  
   */  
 #ifdef DEBUG_HASHTABLE  
   g_print(__FILE__": %s(): Creating hash table for Lg %i\n", __func__, Lg);  
 #endif  
   if (Prefs.L[Lg].IsCaseSensitive)  
       Prefs.L[Lg].Hash = g_hash_table_new(g_str_hash, g_str_equal);  
   else  
       Prefs.L[Lg].Hash = g_hash_table_new(my_g_strcase_hash,  
                                           my_g_strcase_equal);  
   for (i = 0; i < MAX_COL; i++)  
       if (Prefs.L[Lg].C[i].Keywords)  
         {  
 #ifdef DEBUG_HASHTABLE  
           g_print(__FILE__": %s(): Inserting keywords group %i\n", __func__, i);  
 #endif  
           j = 1;  
           while (Prefs.L[Lg].C[i].Keywords[j])  
             {  
               int       len = 0;  
   
               while (Prefs.L[Lg].C[i].Keywords[j + len] != ' ')  
                   len++;  
               /*  
               ** Now, Keywords[j] is the 1st char of a word and len is its  
               ** length. We will insert it in the hash table. The value  
               ** associated to it will be the color plus 1 (i + 1).  
               */  
               Prefs.L[Lg].C[i].Keywords[j + len] = '\0';  
                 
               Prefs.L[Lg].LargestKeyword = MAX (Prefs.L[Lg].LargestKeyword, len);  
                 
 #ifdef DEBUG_HASHTABLE  
               g_print(__FILE__": %s(): Inserting keyword %s\n", __func__,  
                       Prefs.L[Lg].C[i].Keywords + j);  
 #endif  
               g_hash_table_insert(Prefs.L[Lg].Hash,  
                       g_strdup(Prefs.L[Lg].C[i].Keywords + j),  
                       GINT_TO_POINTER(i + 1));  
               Prefs.L[Lg].C[i].Keywords[j + len] = ' ';  
               j += len + 1;  
             }  
         }  
 #ifdef DEBUG_HASHTABLE  
   g_print(__FILE__": %s(): Hash table created for Lg %i\n", __func__, Lg);  
 #endif  
 #ifdef DEBUG_FCN  
   g_print(__FILE__": %s(): End\n", __func__);  
 #endif  
   return 0;  
 }  
   
 /*  
 ** Equivalent to the standard g_str_equal() function, but this one  
 ** is case-independant  
 */  
 gint            my_g_strcase_equal (gconstpointer v, gconstpointer v2)  
 {  
   return strcasecmp ((const gchar*)v, (const gchar*)v2) == 0;  
 }  
   
 /*  
 ** Equivalent to the standard g_str_hash() function, but this one  
 ** is case-independant  
 */  
 guint           my_g_strcase_hash (gconstpointer key)  
 {  
   const char *p = key;  
   guint h = *p;  
     
   if (h)  
     {  
       if (h >= 'A' && h <= 'Z')  
           h |= 0x20;  
       for (p += 1; *p != '\0'; p++)  
           h = (h << 5) - h + ((*p >= 'A' && *p <= 'Z') ? (*p | 0x20) : (*p));  
     }  
   return h;  
 }  
   
   
 /*  
 ** Parse of color section in a UEdit wordfile  
 **  
 ** Parameters:  
 **  buffer              Is a null-terminated string, representing the /Cx  
 **                      section in a wordfile  
 **  size                Size of the buffer  
 **  start               buffer + *start points on "/Cx..."  
 **  
 ** Return values:  
 **  0                   No errors  
 **  -1                  Parse error in a line  
 */  
 gint                    parse_color_section(gchar *buffer,  
                                             gint size,  
                                             gint *start,  
                                             gint Lg)  
 {  
   gint                  col;  
   gint                  i;  
   gint                  j;  
   gchar                 c;  
   
 #ifdef DEBUG_FCN  
   g_print(__FILE__": %s(): Begin\n", __func__);  
 #endif  
   i = *start;  
   i = i + 2;  
   /* buffer[i] is the 1st digit of color number */  
   j = i;  
   while (isdigit(buffer[j]))  
     j++;  
   /* buffer[j] is the first char after the last digit of language number */  
   c = buffer[j];  
   buffer[j] = 0;  
   col = atoi(buffer + i) - 1;  
   buffer[j] = c;  
   if (col + 1 > MAX_COL)  
     {  
       g_print(__FILE__": %s(): Warning, color %i section detected "  
               "but only %i are allowed\n", __func__, col + 1, MAX_COL);  
       return -1;  
     }  
 #ifdef DEBUG_WORDFILE  
   g_print(__FILE__": %s(): Color %i section detected\n", __func__, col + 1);  
 #endif  
   i = j;  
   if (buffer[i] == '\"' || buffer[i] == ' ')  
     {  
       /* There is a description of the color */  
       j = ++i;  
       while (buffer[j] != '\"' && buffer[j] != '\n')  
         j++;  
       /* buffer[i] is the 1st char of description and buffer[j] the 2nd '\"' */  
       if ((j - i) > MAXLEN_COL_DESCRIPTION)  
         {  
           g_print(__FILE__": %s(): Warning, description of color %i "  
                   "of language %i is longer than %i\n", __func__, col + 1,  
                   Lg + 1, MAXLEN_COL_DESCRIPTION);  
           return -1;  
         }  
       strncpy(Prefs.L[Lg].C[col].Description, buffer + i, j - i);  
       Prefs.L[Lg].C[col].Description[j - i] = '\0';  
       i = j;  
     }  
 #ifdef DEBUG_WORDFILE  
   g_print(__FILE__": %s(): Description of color %i = "  
           "\"%s\"\n", __func__, col + 1, Prefs.L[Lg].C[col].Description);  
 #endif  
   while (buffer[i] != '\n')  
     i++;  
   j = ++i;  
   /* Here, buffer[i] is the first char of keywords area */  
   while ((i + 1 <= size) &&  
          strncmp(buffer + i, "/C", 2) &&  
          strncmp(buffer + i, "/L", 2))  
     {  
       if ((buffer[i] == '/') && (buffer[i + 1] != '/'))  
         {  
           /* NOTE_TODO: Take into account this case (execute the 'command') */  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): In /L%i /C%i, command ignored\n", __func__,  
                   Lg + 1, col + 1);  
 #endif  
           while (buffer[i] != '\n')  
             i++;  
           i++;  
         }  
       else  if (!strncmp(buffer + i, "**", 2))  
         {  
           /* NOTE_TODO: Take into account this case (colorize all words  
              beginning with following prefixes) */  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): In /L%i, '**' ignored\n", __func__,  
                   Lg + 1);  
 #endif  
           while (buffer[i] != '\n')  
             i++;  
           i++;  
         }  
       else  
         {  
           if ((buffer[i] == '/') && (buffer[i + 1] == '/'))  
             {  
 #ifdef DEBUG_WORDFILE  
               g_print(__FILE__": %s(): In /L%i, '//' detected\n", __func__,  
                       Lg + 1);  
 #endif  
               i += 2;  
             }  
           if (parse_line_of_keywords(buffer, size, &i, Lg, col))  
             {  
               g_print(__FILE__": %s(): End, parse error in a line of "  
                       "keywords of /L%i /C%i\n", __func__, Lg + 1, col + 1);  
               return -1;  
             }  
         }  
     }  
   *start = i;  
 #ifdef DEBUG_FCN  
   g_print(__FILE__": %s(): End\n", __func__);  
 #endif  
   return 0;  
 }  
   
 /*  
 ** Parse 1 line of keywords in a UEdit wordfile  
 **  
 ** Parameters:  
 **  buffer              Is a null-terminated string, representing the /Cx  
 **                      section in a wordfile  
 **  size                Size of the buffer  
 **  start               buffer + *start points on "/Cx..."  
 **  
 ** Return values:  
 **  0                   No errors  
 **  -1                  Error while parsing line  
 */  
 gint                    parse_line_of_keywords(gchar *buffer,  
                                                gint size,  
                                                gint *start,  
                                                gint Lg,  
                                                gint col)  
 {  
   gint                  i, j, k;  
   gchar                 c;  
   gint                  strlen_k;  
   gint                  strlen_b;  
   
 #ifdef DEBUG_FCN  
   g_print(__FILE__": %s(): Begin\n", __func__);  
 #endif  
   (void)size;  
   i = *start;  
   while ((buffer[i] != '\r') && (buffer[i] != '\n'))  
     {  
       if ((buffer[i] == ' ') || (buffer[i] == '\t'))  
           i++;  
       else  
         {  
           /* buffer[i] is the first char of the keyword */  
           j = i;  
           while ((buffer[j] != ' ') && (buffer[j] != '\t') &&  
                  (buffer[j] != '\r') && (buffer[j] != '\n'))  
             j++;  
           /* buffer[j] is the first char after the last one of the keyword */  
           c = buffer[j];  
           buffer[j] = '\0';  
 #ifdef DEBUG_WORDFILE  
           g_print(__FILE__": %s(): In /L%i /C%i, keyword \"%s\" "  
                   "detected\n", __func__, Lg + 1, col + 1, buffer + i);  
 #endif  
           if (Prefs.L[Lg].C[col].Keywords == NULL)  
             {  
 #ifdef DEBUG_WORDFILE  
               g_print(__FILE__": %s(): Ah ! Keywords == NULL\n", __func__);  
 #endif  
               if (!(Prefs.L[Lg].C[col].Keywords = g_malloc(2)))  
                 {  
                   g_print(__FILE__": %s(): End, g_malloc() failed\n", __func__);  
                   return -1;  
                 }  
               Prefs.L[Lg].C[col].Keywords[0] = ' ';  
               Prefs.L[Lg].C[col].Keywords[1] = '\0';  
             }  
           strlen_k = strlen(Prefs.L[Lg].C[col].Keywords);  
           strlen_b = strlen(buffer + i);  
           Prefs.L[Lg].C[col].Keywords =  
             g_realloc(Prefs.L[Lg].C[col].Keywords, strlen_k + strlen_b + 2);  
           if (Prefs.L[Lg].C[col].Keywords == NULL)  
             {  
               g_print(__FILE__": %s(): End, g_realloc() failed\n", __func__);  
               return -1;  
             }  
           strcat(Prefs.L[Lg].C[col].Keywords, buffer + i);  
           strcat(Prefs.L[Lg].C[col].Keywords, " ");  
             
           if (Prefs.L[Lg].IsCaseSensitive)  
           {  
                 Prefs.L[Lg].KeywordStatus[(int) *(buffer + i)] |= 0x2;  
 /*              if (j - i > 1)  
                 {  
                         Prefs.L[Lg].KeywordStatus[(int) *(buffer + i + 1)] |= 0x16;  
                 }*/  
                 for (k = i; k < j; k++)  
                 {  
                         Prefs.L[Lg].KeywordStatus[(int) *(buffer + k)] |= 0x1;  
                 }  
                 Prefs.L[Lg].KeywordStatus[(int) *(buffer + j - 1)] |= 0x4;  
           }  
           else  
           {  
                 Prefs.L[Lg].KeywordStatus[(int) g_ascii_toupper (*(buffer + i))] |= 0x2;  
                 Prefs.L[Lg].KeywordStatus[(int) g_ascii_tolower (*(buffer + i))] |= 0x2;  
 /*              if (j - i > 1)  
                 {  
                         Prefs.L[Lg].KeywordStatus[(int) g_ascii_toupper (*(buffer + i + 1))] |= 0x16;  
                         Prefs.L[Lg].KeywordStatus[(int) g_ascii_tolower (*(buffer + i + 1))] |= 0x16;  
                 }*/  
                 for (k = i; k < j; k++)  
                 {  
                         Prefs.L[Lg].KeywordStatus[(int) g_ascii_toupper (*(buffer + k))] |= 0x1;  
                         Prefs.L[Lg].KeywordStatus[(int) g_ascii_tolower (*(buffer + k))] |= 0x1;  
                 }  
                 Prefs.L[Lg].KeywordStatus[(int) g_ascii_toupper (*(buffer + j - 1))] |= 0x4;  
                 Prefs.L[Lg].KeywordStatus[(int) g_ascii_tolower (*(buffer + j - 1))] |= 0x4;  
           }  
             
           buffer[j] = c;  
           i = j;  
         } /* !((buffer[i] == ' ') || (buffer[i] == '\t')) */  
     }  
   if (buffer[i] == '\r')  
     i++;  
   *start = i + 1;  
 #ifdef DEBUG_FCN  
   g_print(__FILE__": %s(): End\n", __func__);  
 #endif  
   
   return 0;  
 }  
   

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26