home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / AP / JED / JED097-1.TAR / jed / src / syntax.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-12  |  13.5 KB  |  603 lines

  1. /*
  2.  *  Copyright (c) 1994 John E. Davis  (davis@amy.tch.harvard.edu)
  3.  *  All Rights Reserved.
  4.  */
  5. #include <stdio.h>
  6. #include "buffer.h"
  7. #include "screen.h"
  8.  
  9. static unsigned char Symbol_Colors[128] = 
  10. {
  11.    JNORMAL_COLOR,    /* 0 */
  12.    JNORMAL_COLOR,    /* 1 */
  13.    JNORMAL_COLOR,    /* 2 */
  14.    JNORMAL_COLOR,    /* 3 */
  15.    JNORMAL_COLOR,    /* 4 */
  16.    JNORMAL_COLOR,    /* 5 */
  17.    JNORMAL_COLOR,    /* 6 */
  18.    JNORMAL_COLOR,    /* 7 */
  19.    JNORMAL_COLOR,    /* 8 */
  20.    JNORMAL_COLOR,    /* 9 */
  21.    JNORMAL_COLOR,    /* 10 */
  22.    JNORMAL_COLOR,    /* 11 */
  23.    JNORMAL_COLOR,    /* 12 */
  24.    JNORMAL_COLOR,    /* 13 */
  25.    JNORMAL_COLOR,    /* 14 */
  26.    JNORMAL_COLOR,    /* 15 */
  27.    JNORMAL_COLOR,    /* 16 */
  28.    JNORMAL_COLOR,    /* 17 */
  29.    JNORMAL_COLOR,    /* 18 */
  30.    JNORMAL_COLOR,    /* 19 */
  31.    JNORMAL_COLOR,    /* 20 */
  32.    JNORMAL_COLOR,    /* 21 */
  33.    JNORMAL_COLOR,    /* 22 */
  34.    JNORMAL_COLOR,    /* 23 */
  35.    JNORMAL_COLOR,    /* 24 */
  36.    JNORMAL_COLOR,    /* 25 */
  37.    JNORMAL_COLOR,    /* 26 */
  38.    JNORMAL_COLOR,    /* 27 */
  39.    JNORMAL_COLOR,    /* 28 */
  40.    JNORMAL_COLOR,    /* 29 */
  41.    JNORMAL_COLOR,    /* 30 */
  42.    JNORMAL_COLOR,    /* 31 */
  43.    JNORMAL_COLOR,    /* 32 */
  44.    JOP_COLOR,    /* ! */
  45.    JSTR_COLOR,    /* " */
  46.    JOP_COLOR,    /* # */
  47.    JKEY_COLOR,    /* $ */
  48.    JOP_COLOR,    /* % */
  49.    JOP_COLOR,    /* & */
  50.    JSTR_COLOR,    /* ' */
  51.    JDELIM_COLOR,    /* ( */
  52.    JDELIM_COLOR,    /* ) */
  53.    JOP_COLOR,    /* * */
  54.    JOP_COLOR,    /* + */
  55.    JDELIM_COLOR,    /* , */
  56.    JOP_COLOR,    /* - */
  57.    JDELIM_COLOR,    /* . */
  58.    JOP_COLOR,    /* / */
  59.    JNUM_COLOR,    /* 0 */
  60.    JNUM_COLOR,    /* 1 */
  61.    JNUM_COLOR,    /* 2 */
  62.    JNUM_COLOR,    /* 3 */
  63.    JNUM_COLOR,    /* 4 */
  64.    JNUM_COLOR,    /* 5 */
  65.    JNUM_COLOR,    /* 6 */
  66.    JNUM_COLOR,    /* 7 */
  67.    JNUM_COLOR,    /* 8 */
  68.    JNUM_COLOR,    /* 9 */
  69.    JOP_COLOR,    /* : */
  70.    JDELIM_COLOR,    /* ; */
  71.    JOP_COLOR,    /* < */
  72.    JOP_COLOR,    /* = */
  73.    JOP_COLOR,    /* > */
  74.    JOP_COLOR,    /* ? */
  75.    JKEY_COLOR,    /* @ */
  76.    JKEY_COLOR,    /* A */
  77.    JKEY_COLOR,    /* B */
  78.    JKEY_COLOR,    /* C */
  79.    JKEY_COLOR,    /* D */
  80.    JKEY_COLOR,    /* E */
  81.    JKEY_COLOR,    /* F */
  82.    JKEY_COLOR,    /* G */
  83.    JKEY_COLOR,    /* H */
  84.    JKEY_COLOR,    /* I */
  85.    JKEY_COLOR,    /* J */
  86.    JKEY_COLOR,    /* K */
  87.    JKEY_COLOR,    /* L */
  88.    JKEY_COLOR,    /* M */
  89.    JKEY_COLOR,    /* N */
  90.    JKEY_COLOR,    /* O */
  91.    JKEY_COLOR,    /* P */
  92.    JKEY_COLOR,    /* Q */
  93.    JKEY_COLOR,    /* R */
  94.    JKEY_COLOR,    /* S */
  95.    JKEY_COLOR,    /* T */
  96.    JKEY_COLOR,    /* U */
  97.    JKEY_COLOR,    /* V */
  98.    JKEY_COLOR,    /* W */
  99.    JKEY_COLOR,    /* X */
  100.    JKEY_COLOR,    /* Y */
  101.    JKEY_COLOR,    /* Z */
  102.    JDELIM_COLOR,    /* [ */
  103.    JDELIM_COLOR,    /* \ */
  104.    JDELIM_COLOR,    /* ] */
  105.    JOP_COLOR,    /* ^ */
  106.    JKEY_COLOR,    /* _ */
  107.    JKEY_COLOR,    /* ` */
  108.    JKEY_COLOR,    /* a */
  109.    JKEY_COLOR,    /* b */
  110.    JKEY_COLOR,    /* c */
  111.    JKEY_COLOR,    /* d */
  112.    JKEY_COLOR,    /* e */
  113.    JKEY_COLOR,    /* f */
  114.    JKEY_COLOR,    /* g */
  115.    JKEY_COLOR,    /* h */
  116.    JKEY_COLOR,    /* i */
  117.    JKEY_COLOR,    /* j */
  118.    JKEY_COLOR,    /* k */
  119.    JKEY_COLOR,    /* l */
  120.    JKEY_COLOR,    /* m */
  121.    JKEY_COLOR,    /* n */
  122.    JKEY_COLOR,    /* o */
  123.    JKEY_COLOR,    /* p */
  124.    JKEY_COLOR,    /* q */
  125.    JKEY_COLOR,    /* r */
  126.    JKEY_COLOR,    /* s */
  127.    JKEY_COLOR,    /* t */
  128.    JKEY_COLOR,    /* u */
  129.    JKEY_COLOR,    /* v */
  130.    JKEY_COLOR,    /* w */
  131.    JKEY_COLOR,    /* x */
  132.    JKEY_COLOR,    /* y */
  133.    JKEY_COLOR,    /* z */
  134.    JDELIM_COLOR,    /* { */
  135.    JOP_COLOR,    /* | */
  136.    JDELIM_COLOR,    /* } */
  137.    JOP_COLOR,    /* ~ */
  138.    JNORMAL_COLOR,
  139. };
  140.  
  141. /* These are the C++ keywords:
  142.  * asm auto
  143.  * break
  144.  * case catch char class const continue
  145.  * default delete do double
  146.  * else enum extern
  147.  * float for friend
  148.  * goto
  149.  * if inline int
  150.  * long
  151.  * new
  152.  * operator
  153.  * private protected public
  154.  * register return
  155.  * short signed sizeof static struct switch
  156.  * template this throw try typedef
  157.  * union unsigned
  158.  * virtual void volatile
  159.  * while
  160.  */
  161.  
  162. static char *C_Keywords[] = /* length 2 to 9 */
  163. {
  164.    "doif",                   /* di */
  165.    "asmforintnewtry",               /* afint */
  166.    "autocasecharelseenumgotolongthisvoid",    /* acceegltv */
  167.    "breakcatchclassconstfloatshortthrowunionwhile",   /* bcccfstuw */
  168.    "deletedoubleexternfriendinlinepublicreturnsignedsizeofstaticstructswitch",
  169.                           /* ddefiprsssss */
  170.    "defaultprivatetypedefvirtual",     /* dptv */
  171.    "continueoperatorregistertemplateunsignedvolatile",   /* cortuv */
  172.    "protected",                   /* p */
  173. };
  174.  
  175. /* Fortran 77 keywords + include, record, structure, while:
  176.  * backspace block
  177.  * call character common complex continue
  178.  * data dimension do double
  179.  * else end enddo endfile endif entry equivalence exit external
  180.  * format function
  181.  * goto 
  182.  * if implicit include inquire integer intrinsic
  183.  * logical
  184.  * parameter pause precision program
  185.  * real return rewind
  186.  * save stop subroutine
  187.  * then
  188.  * while
  189.  */
  190.  
  191. static char *Fortran_Keywords[] = /* length 2 to 11 */
  192. {
  193.    "dogoifto",                   /* 2: di */
  194.    "end",                   /* 3: e */
  195.    "calldataelseexitgotoopenreadrealsavestopthen",  /* 4: cdeegorrsst */
  196.    "blockcloseenddoendifentrypauseprintwhilewrite", /* 5: bceeeppww */
  197.    "commondoubleformatrecordreturnrewind",          /* 6: cdfrrr */
  198.    "complexendfileincludeinquireintegerlogicalprogram", /* 7: ceiiilp */
  199.    "continueexternalfunctionimplicit", /* 8: cefi */
  200.    "backspacecharacterdimensionintrinsicparameterprecisionstructure", /* 9: bcdipps */
  201.    "subroutine",               /* 10: s */
  202.    "equivalence"               /* 11: e */
  203. };
  204.  
  205. static int Max_Keyword_Len;           /* max length of a keyword */
  206. static char **Keywords = NULL;           /* array of keywords */
  207. static int The_Highlight_Mode;
  208. static int Keyword_Not_Case_Sensitive;
  209.  
  210. void init_syntax_highlight (void)
  211. {
  212.    unsigned int flags = CBuf->modes;
  213.    
  214.    Keyword_Not_Case_Sensitive = 0;
  215.    Mode_Has_Syntax_Highlight = 1;
  216.    if (flags & C_MODE)
  217.      {
  218.     Max_Keyword_Len = 9;
  219.     Keywords = C_Keywords;
  220.     The_Highlight_Mode = C_MODE;
  221.      }
  222.    else if (flags & TEX_MODE)
  223.      {
  224.     The_Highlight_Mode = TEX_MODE;
  225.      }
  226.    else if (flags & F_MODE)
  227.      {
  228.     Max_Keyword_Len = 11;
  229.     Keywords = Fortran_Keywords;
  230.     Keyword_Not_Case_Sensitive = 0x20;   /* This value is exploited */
  231.     The_Highlight_Mode = F_MODE;
  232.      } 
  233.    else    Mode_Has_Syntax_Highlight = 0;
  234. }
  235.  
  236.  
  237. static unsigned short *highlight_token(register unsigned short *p, unsigned short *pmax)
  238. {
  239.    register char *t;
  240.    register unsigned short *q;
  241.    unsigned char ch = (unsigned char) *p;
  242.    int color, skip = 0, n;
  243.    
  244.    q = p;
  245.    while (q < pmax)
  246.      {
  247.     ch = (unsigned char) *q & 0x7F;
  248.     color = Symbol_Colors[ch];
  249.     if (color == JNUM_COLOR) skip = 1;
  250.     else if (color != JKEY_COLOR) break;
  251.     q++;
  252.      }
  253.  
  254.    if (skip) return q;
  255.    n = (int) (q - p);
  256.    if ((n < 2) || (n > Max_Keyword_Len)) return q;
  257.    
  258.    t = Keywords[n - 2];
  259.    while (*t)
  260.      {
  261.     p = q - n;
  262.     if (Keyword_Not_Case_Sensitive == 0)
  263.       {
  264.          while ((p < q) && (*t == (char) *p))
  265.            {
  266.           p++; t++;
  267.            }
  268.       }
  269.     else  while ((p < q) && (*t == ((char) *p | 0x20)))
  270.       {
  271.          p++; t++;
  272.       }
  273.     
  274.     if (p == q)
  275.       {
  276.          p = q - n;
  277.          while (p < q) *p++ |= JKEY_COLOR << 8;
  278.          return q;
  279.       }
  280.     
  281.     /* alphabetical */
  282.     if (*t > ((char) *p | Keyword_Not_Case_Sensitive))
  283.       break;
  284.     
  285.     t += (int) (q - p);
  286.      }
  287.    return q;
  288. }
  289.  
  290.     
  291.  
  292. unsigned short *highlight_string (unsigned short *p, unsigned short *pmax)
  293. {
  294.    unsigned char ch;
  295.    unsigned char q = (unsigned char) *p;
  296.  
  297.    *p++ |= JSTR_COLOR << 8;
  298.    while (p < pmax)
  299.      {
  300.     ch = (unsigned char) *p;
  301.     *p++ |= JSTR_COLOR << 8;
  302.     if (ch == q) break;
  303.     if ((ch == '\\') && (p < pmax))
  304.       {
  305.          *p++ |= JSTR_COLOR << 8;
  306.       }
  307.      }
  308.    return p;
  309. }
  310.  
  311. unsigned short *highlight_number (unsigned short *p, unsigned short *pmax)
  312. {
  313.    unsigned short *p1;
  314.    unsigned char ch, ch1;
  315.    unsigned char color;
  316.    int expon = 0, dec = 0;
  317.    
  318.    ch = (unsigned char) *p;
  319.    if (ch == '-')
  320.      {
  321.     p1 = p + 1;
  322.     if ((p1 < p) && (JNUM_COLOR == Symbol_Colors[(unsigned char) *p1]))
  323.       {
  324.          *p |= JNUM_COLOR << 8;
  325.          *p1 |= JNUM_COLOR << 8;
  326.          p += 2;
  327.       }
  328.     else 
  329.       {
  330.          *p |= JOP_COLOR;
  331.          return p + 1;
  332.       }
  333.      }
  334.    
  335.    while (p < pmax)
  336.      {
  337.     ch = (unsigned char) *p;
  338.     color = Symbol_Colors[ch & 0x7F];
  339.     
  340.     if (color != JNUM_COLOR)
  341.       {
  342.          if (expon > 0) break;
  343.          if (ch == '.')
  344.            {
  345.           if (dec || (expon < 0)) break;
  346.           dec = 1;
  347.            }
  348.          else 
  349.            {
  350.           ch1 = ch | 0x20;
  351.           if (The_Highlight_Mode == F_MODE)
  352.             {
  353.                expon = 1;
  354.                if ((ch1 != 'e') && (ch1 != 'd')) break;   /* exponent */
  355.                if (p + 1 < pmax)
  356.              {
  357.                 ch1 = *(p + 1);
  358.                 if ((ch1 == '-') || (JNUM_COLOR == Symbol_Colors[ch1 & 0x7F]))
  359.                 *p++ |= JNUM_COLOR << 8;
  360.                 else break; 
  361.              }
  362.             }
  363.           else if (ch1 != 'x')
  364.             {
  365.                if (expon == 0)
  366.              {
  367.                 if (ch1 != 'e') break;
  368.                 if ((p + 1 < pmax) && (*(p + 1) == '-'))
  369.                   *p++ |= JNUM_COLOR << 8;
  370.                 expon = 1;
  371.              }
  372.                /* Note that expon == -1 here */
  373.                else if (color != JKEY_COLOR) break;
  374.             }
  375.           else if (expon == -1) break;
  376.           else expon = -1;
  377.            }
  378.       }
  379.     
  380.     *p++ |= JNUM_COLOR << 8;
  381.      }
  382.          
  383.    return p;
  384. }
  385.       
  386. unsigned short *C_highlight_comment (unsigned short *p, unsigned short *pmax)
  387. {
  388.    char ch;
  389.    while (p < pmax)
  390.      {
  391.     ch = (char) *p;
  392.     *p++ |= JCOM_COLOR << 8;
  393.     if ((ch == '*') && (p < pmax) && (*p == '/'))
  394.       {
  395.          *p++ |= JCOM_COLOR << 8;
  396.          break;
  397.       }
  398.      }
  399.    return p;
  400. }
  401.  
  402. static unsigned short *highlight_preprocess (unsigned short *p, unsigned short *pmax)
  403. {
  404.    while (p < pmax)
  405.      {
  406.     *p++ |= JPREPROC_COLOR << 8;
  407.      }
  408.    return p;
  409. }
  410.  
  411. void syntax_highlight (register unsigned short *p, register unsigned short *pmax)
  412. {
  413.    register unsigned char ch = 0;
  414.    unsigned short *pmin;
  415.    register unsigned int color;
  416.  
  417.    /* If we are looking at fortran, then lets assume that the user is not
  418.     * editing beyond 80 columns so that if something other than a digit
  419.     * is present, we have a comment.
  420.     */
  421.    if (CBuf->modes & F_MODE)
  422.      {
  423.     ch = (unsigned char) *p;
  424.     if (((ch > '9') || (ch < '0')) && (ch > ' '))
  425.       {
  426.          while (p < pmax) *p++ |= JCOM_COLOR << 8;
  427.          return;
  428.       }
  429.      }
  430.  
  431.    /* Skip the whitespace and if we find a '*' with a followed by whitespace,
  432.     * highlight it as a comment-- like these lines
  433.     */
  434.    
  435.    while (p < pmax)
  436.      {
  437.     ch = (unsigned char) *p;
  438.     if (ch > ' ') break;
  439.     p++;
  440.      }
  441.    
  442.    if (p == pmax) return;
  443.    
  444.    pmin = p;
  445.  
  446.    if (The_Highlight_Mode == TEX_MODE)
  447.      {
  448.     while (p < pmax)
  449.       {
  450.          unsigned char ch1;
  451.          unsigned short *p1;
  452.          
  453.          ch = (unsigned char) *p;
  454.          ch1 = ch | 0x20;
  455.          
  456.          if (((ch1 >= 'a') && (ch1 <= 'z'))
  457.          || (ch == ' '))
  458.            p++;
  459.          else if (ch == '\\')
  460.            {
  461.           *p++ |= JKEY_COLOR << 8;
  462.           p1 = p;
  463.           while (p < pmax)
  464.             {
  465.                ch = *p;
  466.                ch1 = ch | 0x20;
  467.                
  468.                if ((ch1 >= 'a') && (ch1 <= 'z'))
  469.                     *p++ |= JKEY_COLOR << 8;
  470.                else if (p == p1)
  471.              {
  472.                 if ((ch == '(') || (ch == '[') || (ch == ')') || (ch == ']'))
  473.                   {
  474.                  *(p - 1) = (unsigned short) '\\' | (JNUM_COLOR << 8);
  475.                  *p++ |= JNUM_COLOR << 8;
  476.                   }
  477.                 else
  478.                   *p++ |= JKEY_COLOR << 8;
  479.                 break;
  480.              }
  481.                else break;
  482.             }
  483.            }
  484.          else if (ch == '%')
  485.            {
  486.           while (p < pmax) *p++ |= JCOM_COLOR << 8;
  487.           return;
  488.            }
  489.          else if (ch == '$')
  490.            {
  491.           *p++ = (unsigned short) '$' | (JNUM_COLOR << 8);
  492.           if (p == pmax) break;
  493.           ch1 = (unsigned char) *p;
  494.           if (ch1 == '$')
  495.             {
  496.                *p++ = (unsigned short) '$' | (JNUM_COLOR << 8);
  497.             }
  498.           
  499.           while ((p < pmax) && ((ch = (unsigned char) *p) != '$'))
  500.             {
  501.                if (ch == '%')
  502.              {
  503.                 while (p < pmax) *p++ |= JCOM_COLOR << 8;
  504.                 return;
  505.              }
  506.                
  507.                *p++ = (unsigned short) ch | (JNUM_COLOR << 8);
  508.                if ((ch == '\\') && (p < pmax))
  509.              {
  510.                 *p++ |= (JNUM_COLOR << 8);
  511.              }
  512.             }
  513.           if (p < pmax) *p++ = (unsigned short) '$' | (JNUM_COLOR << 8);
  514.           if ((ch1 == '$') && (p < pmax))
  515.             {
  516.                if (*p == ch1)
  517.                     *p++ = (unsigned short) '$' | (JNUM_COLOR << 8);
  518.                else while (p < pmax) *p++ |= (JNUM_COLOR << 8);
  519.             }
  520.            }
  521.          else if ((ch == '{') || (ch == '}') || (ch == '&')) *p++ |= JKEY_COLOR << 8;
  522.          else p++;
  523.       }
  524.     return;
  525.      }
  526.    
  527.    
  528.    if (ch <= '*')
  529.      {
  530.     if (ch == '#') 
  531.       {
  532.          highlight_preprocess (p, pmax);
  533.          return;
  534.       }
  535.     else if (((ch == '*') && (CBuf->modes & C_MODE))
  536.          || ((ch == '%') && (CBuf->modes == SL_MODE)))
  537.       {
  538.          p++;
  539.          while ((p < pmax) && ((unsigned char) *p == ch)) p++;
  540.          if ((p == pmax) || (*p <= ' ')) 
  541.            p = C_highlight_comment (pmin, pmax);
  542.          else p = pmin;
  543.       }
  544.      }
  545.     
  546.          
  547.    while (p < pmax)
  548.      {
  549.     ch = (unsigned char) *p;
  550.     if ((ch > 32) && (ch < 127))
  551.       {         
  552.          color = (unsigned int) Symbol_Colors[ch];
  553.          if (color == JKEY_COLOR) p = highlight_token (p, pmax);
  554.          else if (color == JSTR_COLOR) p = highlight_string(p, pmax);
  555.          else if (color == JNUM_COLOR) p = highlight_number (p, pmax);
  556.          else if (color == JDELIM_COLOR) *p++ |= color << 8; 
  557.          else if ((ch == '/') && (p + 1 < pmax))
  558.            {
  559.           ch = *(p + 1);
  560.           if (ch == '/')
  561.             {
  562.                if (The_Highlight_Mode == C_MODE)
  563.              {
  564.                 while (p < pmax)
  565.                   {
  566.                  *p++ |= JCOM_COLOR << 8;
  567.                   }
  568.                 return;
  569.              }
  570.                else *p++ |= JOP_COLOR << 8;
  571.             }
  572.           else if (ch == '*') 
  573.             {
  574.                *p++ |= JCOM_COLOR << 8; *p++ |= JCOM_COLOR << 8;
  575.                p = C_highlight_comment (p, pmax);
  576.             }
  577.           else *p++ |= JOP_COLOR << 8;
  578.            }
  579.          else if ((ch == '*') && (p + 1 < pmax) && (*(p + 1) == '/'))
  580.            {
  581.           /* missed the comment.  This means it was started on a 
  582.            * previous line and the person did not follow the 
  583.            * rules like this comment does.
  584.            */
  585.           
  586.           p += 2;
  587.           while (pmin < p) 
  588.             {
  589.                *pmin &= 0xFF;
  590.                *pmin |= JCOM_COLOR << 8;
  591.                pmin++;
  592.             }
  593.            }
  594.          else if ((ch == '%') && (CBuf->modes & SL_MODE))
  595.            p = C_highlight_comment (p, pmax);
  596.          else *p++ |= color << 8; 
  597.       }
  598.     else p++;
  599.      }
  600. }
  601.            
  602.     
  603.