| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 | {    "SHEdit" - Text editor with syntax highlighting    Copyright (C) 1999-2000 by Sebastian Guenther ([email protected])    See the file COPYING.FPC, included in this distribution,    for details about the copyright.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.}// Syntax highlighting class for Pascal sources// !!! Slightly modified version for fpDoc !!!{$MODE objfpc}{$H+}{$IFDEF Debug}{$ASSERTIONS On}{$ENDIF}unit sh_pas;interfaceconst  LF_SH_Valid      = $01;  LF_SH_Multiline1 = $02;  LF_SH_Multiline2 = $04;  LF_SH_Multiline3 = $08;  LF_SH_Multiline4 = $10;  LF_SH_Multiline5 = $20;  LF_SH_Multiline6 = $40;  LF_SH_Multiline7 = $80;  LF_Escape = #10;  shDefault = 1;  shInvalid = 2;  shSymbol = 3;  shKeyword = 4;  shComment = 5;  shDirective = 6;  shNumbers = 7;  shCharacters = 8;  shStrings = 9;  shAssembler = 10;procedure DoPascalHighlighting(var flags: Byte; source, dest: PChar);implementationuses Strings;const  LF_SH_Comment1 = LF_SH_Multiline1;    { Normal braced Comments}  LF_SH_Comment2 = LF_SH_Multiline2;    { (* *) Comments}  LF_SH_Asm      = LF_SH_Multiline3;  MaxKeywordLength = 15;  MaxKeyword = 60;  KeywordTable: array[0..MaxKeyword] of PChar =    ('AND', 'ARRAY', 'ASM', 'ASSEMBLER',     'BEGIN', 'BREAK',     'CASE', 'CONST', 'CONSTRUCTOR', 'CLASS',     'DEFAULT', 'DESTRUCTOR', 'DIV', 'DO', 'DOWNTO',     'ELSE', 'END', 'EXCEPT', 'EXIT',     'FINALIZATION', 'FINALLY', 'FOR', 'FUNCTION',     'GOTO',     'IF', 'IMPLEMENTATION', 'IN', 'INHERITED', 'INITIALIZATION', 'INTERFACE',     'NIL', 'NOT',     'OBJECT', 'OF', 'ON', 'OR', 'OVERRIDE',     'PACKED', 'PRIVATE', 'PROCEDURE', 'PROGRAM', 'PROPERTY', 'PROTECTED',       'PUBLIC', 'PUBLISHED',     'RAISE', 'RECORD', 'REPEAT', 'RESOURCESTRING',     'SET',     'THEN', 'TRY', 'TYPE',     'UNIT', 'UNTIL', 'USES',     'VAR', 'VIRTUAL',     'WHILE', 'WITH',     'XOR');  KeywordAsmIndex = 2;procedure DoPascalHighlighting(var flags: Byte; source, dest: PChar);var  dp: Integer;          // Destination position - current offset in dest  LastSHPos: Integer;   // Position of last highlighting character, or 0  procedure AddSH(sh: Byte);  begin    ASSERT(sh > 0);    if (LastSHPos > 0) and (dp = LastSHPos + 1) then Dec(dp, 2);    dest[dp] := LF_Escape; Inc(dp);    LastSHPos := dp;    dest[dp] := Chr(sh); Inc(dp);  end;  procedure PutChar;  begin    dest[dp] := source[0]; Inc(dp); Inc(source);  end;  procedure ProcessComment1;  begin    while source[0] <> #0 do begin      if source[0] = '}' then begin        PutChar;        flags := flags and not LF_SH_Comment1;        AddSH(shDefault);        break;      end;      PutChar;    end;  end;  procedure ProcessComment2;  begin    while source[0] <> #0 do begin      if (source[0] = '*') and (source[1] = ')') then begin        PutChar; PutChar;        flags := flags and not LF_SH_Comment2;        AddSH(shDefault);        break;      end;      PutChar;    end;  end;  { Checks if we are at the beginning of a comment (or directive) and processes    all types of comments and directives, or returns False }  function CheckForComment: Boolean;  begin    Result := True;    if source[0] = '{' then begin      if source[1] = '$' then        AddSH(shDirective)      else        AddSH(shComment);      PutChar;      flags := flags or LF_SH_Comment1;      ProcessComment1;    end else if (source[0] = '(') and (source[1] = '*') then begin      AddSH(shComment);      PutChar; PutChar;      flags := flags or LF_SH_Comment2;      ProcessComment2;    end else if (source[0] = '/') and (source[1] = '/') then begin      AddSH(shComment);      repeat PutChar until source[0] = #0;      AddSH(shDefault);    end else      Result := False;  end;  procedure ProcessAsm;  var    LastChar: Char;  begin    LastChar := ' ';    while source[0] <> #0 do begin      if (LastChar in [' ', #9, #10, #13]) and        (UpCase(source[0]) = 'E') and (UpCase(source[1]) = 'N') and        (UpCase(source[2]) = 'D') then begin        AddSH(shKeyword);        PutChar; PutChar; PutChar;        flags := flags and not LF_SH_Asm;        AddSH(shDefault);        break;      end else        if CheckForComment then LastChar := ' '        else begin          LastChar := source[0];          PutChar;        end;    end;  end;  procedure ProcessSymbol;  begin    AddSH(shSymbol);    if (source[0] = ':') and (source[1] = '=') then      PutChar;    PutChar;    AddSH(shDefault);  end;  function CheckForKeyword: Boolean;  var    keyword, ukeyword: array[0..MaxKeywordLength] of Char;    i, j: Integer;  begin    i := 0;    while (source[i] <> #0) and (i < MaxKeywordLength) and      (source[i] in ['0'..'9', 'A'..'Z', 'a'..'z']) do begin      keyword[i] := source[i];      ukeyword[i] := UpCase(source[i]);      Inc(i);    end;    keyword[i] := #0; ukeyword[i] := #0;    Result := False;    if i < MaxKeywordLength then      for j := 0 to MaxKeyword do        if StrIComp(KeywordTable[j], ukeyword) = 0 then begin          Result := True; break;        end;    if not Result then exit;    Inc(source, i);    AddSH(shKeyword);    StrCopy(dest + dp, keyword);    Inc(dp, i);    if j <> KeywordAsmIndex then      AddSH(shDefault)    else begin      AddSH(shAssembler);      flags := flags or LF_SH_Asm;      ProcessAsm;    end;  end;var  StringLength: Integer;begin  dp := 0;  LastSHPos := 0;  if (flags and LF_SH_Comment1) <> 0 then begin    AddSH(shComment);    ProcessComment1;  end;  if (flags and LF_SH_Comment2) <> 0 then begin    AddSH(shComment);    ProcessComment2;  end;  if (flags and LF_SH_Asm) <> 0 then begin    AddSH(shAssembler);    ProcessAsm;  end;  while source[0] <> #0 do begin    if CheckForComment then continue;    case source[0] of      ',', ';', ':', '.', '(', ')', '[', ']', '<', '>', '=',      '*', '/', '+', '-', '^', '&', '@': ProcessSymbol;      '#': begin          AddSH(shCharacters);          PutChar;          if source[0] = '$' then PutChar;          while (source[0] >= '0') and (source[0] <= '9') do PutChar;          AddSH(shDefault);        end;      '$': begin          AddSH(shNumbers);          PutChar;          while source[0] in ['0'..'9', 'A'..'F', 'a'..'f'] do PutChar;          AddSH(shDefault);        end;      '0'..'9': begin          AddSH(shNumbers);          PutChar;          while (source[0] >= '0') and (source[0] <= '9') do PutChar;          AddSH(shDefault);        end;      '''': begin          AddSH(shStrings);          PutChar;          StringLength := 0;          while source[0] <> #0  do begin            if source[0] = '''' then              if source[1] = '''' then PutChar              else begin                PutChar; break;              end;            Inc(StringLength);            PutChar;          end;          if StringLength = 1 then            dest[LastSHPos] := Chr(shCharacters);          if (source[0] = #0) and (dest[dp - 1] <> '''') then            dest[LastSHPos] := Chr(shInvalid);          AddSH(shDefault);        end;      '_', 'A'..'Z', 'a'..'z': begin          if not CheckForKeyword then            repeat              PutChar            until not (source[0] in ['0'..'9', '_', 'A'..'Z', 'a'..'z']);        end;      ' ': PutChar;      else begin        AddSH(shInvalid);        PutChar;  // = found an invalid char!        AddSH(shDefault);      end;    end;  end;  dest[dp] := #0;end;end.
 |