"Fossies" - the Fresh Open Source Software Archive

Member "jed-0.99-19/src/syntax.c" (14 Dec 2009, 12312 Bytes) of package /linux/misc/jed-0.99-19.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "syntax.c" see the Fossies "Dox" file reference documentation.

    1 /* -*- mode: C; mode: fold; -*- */
    2 /* Copyright (c) 1992, 1998, 2000, 2002, 2003, 2004, 2005, 2006 John E. Davis
    3  * This file is part of JED editor library source.
    4  *
    5  * You may distribute this file under the terms the GNU General Public
    6  * License.  See the file COPYING for more information.
    7  */
    8 #include "config.h"
    9 #include "jed-feat.h"
   10 
   11 #include <stdio.h>
   12 #include <string.h>
   13 #include "buffer.h"
   14 #include "screen.h"
   15 #include "colors.h"
   16 #include "file.h"
   17 #include "misc.h"
   18 #include "ledit.h"
   19 #include "indent.h"
   20 
   21 static unsigned short *Char_Syntax;
   22 static char **Keywords = NULL;         /* array of keywords */
   23 static int Keyword_Not_Case_Sensitive;
   24 
   25 static unsigned char *write_using_color (unsigned char *p,
   26                      unsigned char *pmax,
   27                      int color)
   28 {
   29    if ((color == 0) && (Jed_Highlight_WS & HIGHLIGHT_WS_TAB))
   30      {
   31     unsigned char *p1 = p;
   32     while (p1 < pmax)
   33       {
   34          if (*p1 != '\t')
   35            {
   36           p1++;
   37           continue;
   38            }
   39          
   40          if (p1 != p)
   41            {
   42           SLsmg_set_color (0);
   43           SLsmg_write_nchars ((char *)p, (unsigned int)(p1-p));
   44           p = p1;
   45            }
   46          while ((p1 < pmax) && (*p1 == '\t'))
   47            p1++;
   48          SLsmg_set_color (JTAB_COLOR);
   49          SLsmg_write_nchars ((char *)p, (unsigned int)(p1-p));
   50          p = p1;
   51       }
   52      }
   53    /* drop */
   54    SLsmg_set_color (color);
   55 #if SLANG_VERSION < 20000
   56    SLsmg_write_nchars ((char *)p, (unsigned int) (pmax - p));
   57 #else
   58    SLsmg_write_chars (p, pmax);
   59 #endif
   60    SLsmg_set_color (0);
   61    return pmax;
   62 }
   63 
   64 #if JED_HAS_COLOR_COLUMNS
   65 # if SLANG_VERSION < 20000
   66 static void color_columns (int row, register unsigned char *p, register unsigned char *pmax)
   67 {
   68    unsigned char *c, *cmax, *pmin;
   69    int color;
   70 
   71    c = CBuf->column_colors;
   72    if (c != NULL) cmax = c + CBuf->num_column_colors;
   73    else cmax = c;
   74 
   75    pmin = p;
   76    color = 0;
   77    while (p < pmax)
   78      {
   79     if (c < cmax)
   80       {
   81          if (color != (int) *c)
   82            {
   83           if (pmin != p)
   84             pmin = write_using_color (pmin, p, color);
   85           color = *c;
   86            }
   87          c++;
   88       }
   89     p++;
   90      }
   91 
   92    if (pmin != p)
   93      (void) write_using_color (pmin, p, color);
   94 }
   95 # else
   96 static void color_columns (int row, register unsigned char *p, register unsigned char *pmax)
   97 {
   98    unsigned char *c;
   99    int color;
  100    int x0, x1, nx;
  101 
  102    if (p != pmax)
  103      (void) write_using_color (p, pmax, 0);
  104    
  105    if (NULL == (c = CBuf->column_colors))
  106      return;
  107    
  108    nx = CBuf->num_column_colors;
  109    color = 0;
  110    x1 = x0 = 0;
  111    while (x1 < nx)
  112      {
  113     if (color != (int)c[x1])
  114       {
  115          if (x0 != x1)
  116            {
  117           if (color != 0)
  118             SLsmg_set_color_in_region (color, row, x0, 1, x1 - x0);
  119            }
  120          color = (int) c[x1];
  121          x0 = x1;
  122       }
  123     x1++;
  124      }
  125    if ((x1 != x0) && (color != 0))
  126      SLsmg_set_color_in_region (color, row, x0, 1, x1 - x0);
  127 }
  128 # endif                    /* SLANG_VERSION < 20000 */
  129 #endif                     /* JED_HAS_COLOR_COLUMNS */
  130 
  131 static int try_keyword (register unsigned char *q, int n, register char *t, unsigned char color) /*{{{*/
  132 {
  133    unsigned char *p;
  134 
  135    while (*t)
  136      {
  137     p = q - n;
  138     if (Keyword_Not_Case_Sensitive == 0)
  139       {
  140          while ((p < q) && (*t == (char) *p))
  141            {
  142           p++; t++;
  143            }
  144       }
  145     else while ((p < q) && (*t == (char) LOWER_CASE (*p)))
  146       {
  147          p++; t++;
  148       }
  149 
  150     if (p == q)
  151       {
  152          p = q - n;
  153          write_using_color (p, q, color);
  154          return 0;
  155       }
  156 
  157     /* alphabetical */
  158     if (*t > ((char) *p | Keyword_Not_Case_Sensitive))
  159       break;
  160 
  161     t += (int) (q - p);
  162      }
  163    return -1;
  164 }
  165 
  166 /*}}}*/
  167 
  168 static unsigned char *highlight_word (unsigned char *p, unsigned char *pmax) /*{{{*/
  169 {
  170    char **kwds;
  171    register unsigned char *q;
  172    int n;
  173    int i;
  174    int color;
  175 
  176    q = p;
  177    while ((q < pmax) && (Char_Syntax[*q] & WORD_SYNTAX)) q++;
  178 
  179    n = (int) (q - p);
  180 
  181    kwds = Keywords;
  182    if ((kwds != NULL) && (n <= MAX_KEYWORD_LEN))
  183      {
  184     for (i = 0; i < MAX_KEYWORD_TABLES; i++)
  185       {
  186          char *t;
  187          t = kwds[n - 1];
  188          if (t != NULL)
  189            {
  190           color = (JKEY_COLOR + i);
  191           if (0 == try_keyword (q, n, t, color))
  192             return q;
  193            }
  194          kwds += MAX_KEYWORD_LEN;
  195       }
  196      }
  197    return write_using_color (p, q, 0);
  198 }
  199 
  200 /*}}}*/
  201 
  202 static unsigned char *highlight_string (unsigned char *p, unsigned char *pmax, /*{{{*/
  203                     unsigned char quote, unsigned char str_char,
  204                     int ofs)
  205 {
  206    unsigned char ch;
  207    unsigned char *p1;
  208 
  209    p1 = p + ofs;
  210    while (p1 < pmax)
  211      {
  212     ch = (unsigned char) *p1++;
  213     if (ch == str_char) break;
  214     if ((ch == quote) && (p1 < pmax))
  215       p1++;
  216      }
  217    return write_using_color (p, p1, JSTR_COLOR);
  218 }
  219 
  220 /*}}}*/
  221 
  222 static unsigned char *highlight_number (unsigned char *p, unsigned char *pmax) /*{{{*/
  223 {
  224    unsigned char *p1;
  225    unsigned char ch;
  226 
  227    ch = (unsigned char) *p;
  228 
  229    p1 = p + 1;
  230    if (ch == '-')
  231      {
  232     if ((p1 < pmax) && (Char_Syntax[*p1] & NUMBER_SYNTAX))
  233       p1++;
  234     else
  235       return write_using_color (p, p1, JOP_COLOR);
  236      }
  237 
  238    while ((p1 < pmax) && (Char_Syntax[*p1] & NUMBER_SYNTAX))
  239      {
  240     if ((*p1 == '-') || (*p1 == '+'))
  241       {
  242          ch = *(p1 - 1);
  243          if ((ch != 'e') && (ch != 'E'))
  244            break;
  245       }
  246     p1++;
  247      }
  248 
  249    return write_using_color (p, p1, JNUM_COLOR);
  250 }
  251 
  252 /*}}}*/
  253 
  254 static unsigned char *highlight_comment (unsigned char *p,
  255                      unsigned char *p1,
  256                      unsigned char *pmax, /*{{{*/
  257                      Syntax_Table_Type *st)
  258 {
  259    unsigned char stop_char;
  260    char *s;
  261    unsigned int len;
  262 
  263    if (NULL == (s = st->comment_stop)) s = "";
  264 
  265    stop_char = *s;
  266    len = st->comment_stop_len;
  267 
  268    while (p1 < pmax)
  269      {
  270     if (*p1 == stop_char)
  271       {
  272          if ((p1 + len < pmax)
  273          && (0 == strncmp ((char *)p1, s, len)))
  274            {
  275           p1 += len;
  276           break;
  277            }
  278       }
  279     p1++;
  280      }
  281 
  282    return write_using_color (p, p1, JCOM_COLOR);
  283 }
  284 
  285 /*}}}*/
  286 
  287 #if JED_HAS_DFA_SYNTAX
  288 # include "dfasyntx.c"
  289 #endif
  290 
  291 static unsigned char *write_whitespace (unsigned char *p, unsigned char *pmax, int trailing_color)
  292 {
  293    unsigned char *p1;
  294 
  295    p1 = p;
  296    while ((p1 < pmax) && ((*p1 == ' ') || (*p1 == '\t')))
  297      p1++;
  298    if (p1 == p)
  299      return p;
  300 
  301    if ((p1 == pmax) && (Jed_Highlight_WS & HIGHLIGHT_WS_TRAILING))
  302      return write_using_color (p, pmax, trailing_color);
  303 
  304    return write_using_color (p, p1, 0);
  305 }
  306 
  307 void write_syntax_highlight (int row, Line *l, unsigned int len)
  308 {
  309    Syntax_Table_Type *st = CBuf->syntax_table;
  310    unsigned char ch;
  311    unsigned int flags;
  312    unsigned char *p1;
  313    unsigned short syntax;
  314    register unsigned char *p;
  315    register unsigned char *pmax;
  316    int context;
  317 
  318    p = l->data;
  319    pmax = p + len;
  320 
  321 #if JED_HAS_COLOR_COLUMNS
  322    if (CBuf->coloring_style)
  323      {
  324     color_columns (row, p, pmax);
  325     return;
  326      }
  327 #endif
  328 
  329    if (st == NULL) return;
  330 
  331 #if JED_HAS_DFA_SYNTAX
  332    if (st->use_dfa_syntax
  333        && (st->hilite != NULL)
  334        && (st->hilite->dfa != NULL))
  335      {
  336     dfa_syntax_highlight (p, pmax, st);
  337     return;
  338      }
  339 #endif
  340 
  341    flags = st->flags;
  342 
  343 #if JED_HAS_LINE_ATTRIBUTES
  344    context = l->flags & JED_LINE_SYNTAX_BITS;
  345 #else
  346    context = 0;
  347 #endif
  348 
  349    if (context & JED_LINE_IN_COMMENT)
  350      {
  351     /* I do not like the whitespace that preceeds the
  352      * '*' on the current line to be highlighted.  So...
  353      */
  354     if (flags & C_COMMENT_TYPE)
  355       {
  356          p1 = p;
  357          while ((p1 < pmax) && ((*p1 == ' ') || (*p1 == '\t')))
  358            p1++;
  359 
  360          if ((p1 < pmax) && (*p1 == '*'))
  361            p = write_using_color (p, p1, 0);
  362       }
  363 
  364     p = highlight_comment (p, p, pmax, st);
  365      }
  366    else if (context & JED_LINE_IN_STRING0)
  367      {
  368     p = highlight_string (p, pmax, st->quote_char, st->string_chars[0], 0);
  369      }
  370    else if (context & JED_LINE_IN_STRING1)
  371      {
  372     p = highlight_string (p, pmax, st->quote_char, st->string_chars[1], 0);
  373      }
  374    else if (context & JED_LINE_IN_HTML)
  375      {
  376     p1 = p;
  377     ch = st->sgml_stop_char;
  378     while ((p1 < pmax) && (*p1++ != ch))
  379       ;
  380     p = write_using_color (p, p1, JHTML_KEY_COLOR);
  381      }
  382    else if ((flags & FORTRAN_TYPE)
  383         && st->fortran_comment_chars[*p])
  384      {
  385     (void) write_using_color (p, pmax, JCOM_COLOR);
  386     return;
  387      }
  388    else
  389      {
  390     /* Handle the preprocessor */
  391     if (flags & PREPROCESS_IGNORE_WHITESPACE)
  392       {
  393          p = write_whitespace (p, pmax, JTWS_COLOR);
  394          if (p == pmax)
  395            return;
  396       }
  397     if (*p == st->preprocess)
  398       {
  399          if (flags & PREPROCESS_COLOR_WHOLE_LINE)
  400            {
  401           (void) write_using_color (p, pmax, JPREPROC_COLOR);
  402           return;
  403            }
  404          p1 = p + 1;
  405          /* FIXME!!! I need to add a whitespace syntax */
  406          while ((p1 < pmax) && ((*p1 == ' ') || (*p1 == '\t')))
  407            p1++;
  408          while ((p1 < pmax) && (Char_Syntax[*p1] != 0))
  409            p1++;
  410 
  411          p = write_using_color (p, p1, JPREPROC_COLOR);
  412       }
  413      }
  414 
  415    /* Now the preliminary stuff is done so do the hard part */
  416    while (p < pmax)
  417      {
  418     syntax = Char_Syntax[*p];
  419 
  420     /* Do comment syntax before word syntax since the comment start
  421      * may be a word.
  422      */
  423     if (syntax & COMMENT_SYNTAX)
  424       {
  425          p1 = p + 1;
  426          ch = *p;
  427 
  428          if ((st->comment_start != NULL)
  429          && (ch == st->comment_start[0])
  430          && (p + st->comment_start_len <= pmax)
  431          && (0 == strncmp ((char *)p, st->comment_start, st->comment_start_len)))
  432            {
  433           p = highlight_comment (p, p + st->comment_start_len, pmax, st);
  434           continue;
  435            }
  436 
  437          if (_jed_is_eol_comment_start (st, l, p, pmax, NULL))
  438            {
  439           (void) write_using_color (p, pmax, JCOM_COLOR);
  440           return;
  441            }
  442       }
  443 
  444     if (syntax & WORD_SYNTAX)
  445       {
  446          if ((*p > '9') || (0 == (syntax & NUMBER_SYNTAX)))
  447            {
  448           p = highlight_word (p, pmax);
  449           continue;
  450            }
  451       }
  452 
  453     if (syntax == 0)
  454       {
  455          p1 = p;
  456          while ((p1 < pmax) && (Char_Syntax[*p1] == 0))
  457            p1++;
  458          if ((p1 != pmax)
  459          || ((Jed_Highlight_WS & HIGHLIGHT_WS_TRAILING) == 0))
  460            {
  461           p = write_using_color (p, p1, 0);
  462           continue;
  463            }
  464          while (p1 > p)
  465            {
  466           p1--;
  467           if ((*p1 != ' ') && (*p1 != '\t'))
  468             {
  469                p1++;
  470                break;
  471             }
  472            }
  473          p = write_using_color (p, p1, 0);
  474          if (p1 != pmax)
  475            (void) write_using_color (p1, pmax, JTWS_COLOR);
  476          return;
  477       }
  478 
  479     if (syntax & DELIM_SYNTAX)
  480       {
  481          p = write_using_color (p, p + 1, JDELIM_COLOR);
  482          continue;
  483       }
  484 
  485     if (syntax & STRING_SYNTAX)
  486       {
  487          p = highlight_string (p, pmax, st->quote_char, *p, 1);
  488          continue;
  489       }
  490 
  491     if (syntax & OP_SYNTAX)
  492       {
  493          p = write_using_color (p, p + 1, JOP_COLOR);
  494          continue;
  495       }
  496 
  497     if (syntax & NUMBER_SYNTAX)
  498       {
  499          p = highlight_number (p, pmax);
  500          continue;
  501       }
  502 
  503     if (syntax & HTML_START_SYNTAX)
  504       {
  505          p1 = p;
  506          while (p1 < pmax)
  507            {
  508           if (Char_Syntax[*p1] & HTML_END_SYNTAX)
  509             {
  510                p1++;
  511                break;
  512             }
  513           p1++;
  514            }
  515          p = write_using_color (p, p1, JHTML_KEY_COLOR);
  516          continue;
  517       }
  518 
  519     if (syntax & HTML_END_SYNTAX)  /* missed start from previous line */
  520       {
  521          /* FIXME!!! Start from beginning */
  522          p = write_using_color (p, p + 1, JHTML_KEY_COLOR);
  523          continue;
  524       }
  525 
  526     if ((syntax & OPEN_DELIM_SYNTAX) || (syntax & CLOSE_DELIM_SYNTAX))
  527       {
  528          p = write_using_color (p, p + 1, JDELIM_COLOR);
  529          continue;
  530       }
  531 
  532     if ((syntax & QUOTE_SYNTAX) && (flags & TEX_LIKE_KEYWORDS))
  533       {
  534          p1 = p + 1;
  535          if (p1 < pmax)
  536            {
  537           if (Char_Syntax[*p1] & WORD_SYNTAX)
  538             {
  539                do
  540              {
  541                 p1++;
  542              }
  543                while ((p1 < pmax) && (Char_Syntax[*p1] & WORD_SYNTAX));
  544             }
  545           else p1++;
  546            }
  547          p = write_using_color (p, p1, JKEY_COLOR);
  548          continue;
  549       }
  550 
  551     if (syntax & QUOTE_SYNTAX)
  552       {
  553          p1 = jed_multibyte_chars_forward (p, pmax, 2, NULL, 1);
  554          /* p1 = p + 2; */
  555          if (p1 < pmax)
  556            {
  557           p = write_using_color (p, p1, 0);
  558           continue;
  559            }
  560       }
  561 
  562     /* Undefined. */
  563     p = write_using_color (p, p + 1, 0);
  564      }
  565 }
  566 
  567 /*}}}*/
  568 
  569 void init_syntax_highlight (void) /*{{{*/
  570 {
  571     Syntax_Table_Type *st = CBuf->syntax_table;
  572 
  573     Mode_Has_Syntax_Highlight = 1;
  574     if (CBuf->coloring_style) return;
  575 
  576    if ((st == NULL) || (st == Default_Syntax_Table))
  577      {
  578         Mode_Has_Syntax_Highlight = 0;
  579         return;
  580     }
  581 
  582 #if JED_HAS_DFA_SYNTAX
  583    if (st->use_dfa_syntax
  584        && ((NULL != st->hilite) && (NULL != st->hilite->dfa)))
  585      return;
  586 #endif
  587 
  588    Char_Syntax = st->char_syntax;
  589 
  590    if (st->flags & SYNTAX_NOT_CASE_SENSITIVE)
  591      Keyword_Not_Case_Sensitive = 0x20;
  592    else
  593      Keyword_Not_Case_Sensitive = 0;
  594 
  595    Keywords = (char **) st->keywords;
  596 }
  597 
  598 /*}}}*/
  599