1{------------------------------------------------------------------------------- 2The contents of this file are subject to the Mozilla Public License 3Version 1.1 (the "License"); you may not use this file except in compliance 4with the License. You may obtain a copy of the License at 5http://www.mozilla.org/MPL/ 6 7Software distributed under the License is distributed on an "AS IS" basis, 8WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for 9the specific language governing rights and limitations under the License. 10 11The Original Code is: SynHighlighterCpp.pas, released 2000-04-10. 12The Original Code is based on the dcjCppSyn.pas file from the 13mwEdit component suite by Martin Waldenburg and other developers, the Initial 14Author of this file is Michael Trier. 15All Rights Reserved. 16 17Contributors to the SynEdit and mwEdit projects are listed in the 18Contributors.txt file. 19 20Alternatively, the contents of this file may be used under the terms of the 21GNU General Public License Version 2 or later (the "GPL"), in which case 22the provisions of the GPL are applicable instead of those above. 23If you wish to allow use of your version of this file only under the terms 24of the GPL and not to allow others to use your version of this file 25under the MPL, indicate your decision by deleting the provisions above and 26replace them with the notice and other provisions required by the GPL. 27If you do not delete the provisions above, a recipient may use your version 28of this file under either the MPL or the GPL. 29 30$Id$ 31 32You may retrieve the latest version of this file at the SynEdit home page, 33located at http://SynEdit.SourceForge.net 34 35Known Issues: 36 - strings on multiple lines are not supported 37-------------------------------------------------------------------------------} 38{ 39@abstract(Provides a C++ syntax highlighter for SynEdit) 40@author(Michael Trier) 41@created(1998) 42@lastmod(2000-05-05) 43The SynHighlighterCpp unit provides SynEdit with a C++ syntax highlighter. 44Thanks to Martin Waldenburg. 45} 46unit SynHighlighterCpp; 47 48{$I synedit.inc} 49 50interface 51 52uses 53 SysUtils, 54 LCLIntf, 55 Classes, Registry, Controls, Graphics, 56 SynEditTypes, SynEditHighlighter, SynEditStrConst; 57 58type 59 TtkTokenKind = (tkAsm, tkComment, tkDirective, tkIdentifier, tkKey, tkNull, 60 tkNumber, tkSpace, tkString, tkSymbol, tkUnknown); 61 62 TxtkTokenKind = ( 63 xtkAdd, xtkAddAssign, xtkAnd, xtkAndAssign, xtkArrow, xtkAssign, 64 xtkBitComplement, xtkBraceClose, xtkBraceOpen, xtkColon, xtkComma, 65 xtkDecrement, xtkDivide, xtkDivideAssign, xtkEllipse, xtkGreaterThan, 66 xtkGreaterThanEqual, xtkIncOr, xtkIncOrAssign, xtkIncrement, xtkLessThan, 67 xtkLessThanEqual, xtkLogAnd, xtkLogComplement, xtkLogEqual, xtkLogOr, 68 xtkMod, xtkModAssign, xtkMultiplyAssign, xtkNotEqual, xtkPoint, xtkQuestion, 69 xtkRoundClose, xtkRoundOpen, xtkScopeResolution, xtkSemiColon, xtkShiftLeft, 70 xtkShiftLeftAssign, xtkShiftRight, xtkShiftRightAssign, xtkSquareClose, 71 xtkSquareOpen, xtkStar, xtkSubtract, xtkSubtractAssign, xtkXor, 72 xtkXorAssign); 73 74 TRangeState = (rsUnknown, rsAnsiC, rsAnsiCAsm, rsAnsiCAsmBlock, rsAsm, 75 rsAsmBlock, rsDirective, rsDirectiveComment, {rsString34, rsString39,} 76 rsAsmBlockString, rsAsmString, rsDirectiveString, rsString 77 ); 78 79const 80 // map the range into a stringtype range (comments are never mapped into string) 81 // keep the range, if it already is a string-range 82 SynCppRangeToStringRange: Array [TRangeState] of TRangeState 83 = (rsString, rsString, rsString, rsString, rsAsmString, 84 rsAsmBlockString, rsDirectiveString, rsString, 85 rsAsmBlockString, rsAsmString, rsDirectiveString, rsString 86 ); 87 // map the string-range back into the correct range 88 // non string ranges are kept as they were 89 SynCppStringRangeToRange: Array [TRangeState] of TRangeState 90 = (rsUnknown, rsAnsiC, rsAnsiCAsm, rsAnsiCAsmBlock, rsAsm, 91 rsAsmBlock, rsDirective, rsDirectiveComment, 92 rsAsmBlock, rsAsm, rsDirective, rsUnknown 93 ); 94 95type 96 97 TProcTableProc = procedure of object; 98 99 PIdentFuncTableFunc = ^TIdentFuncTableFunc; 100 TIdentFuncTableFunc = function: TtkTokenKind of object; 101 102 TSynCppSyn = class(TSynCustomHighlighter) 103 private 104 fAsmStart: Boolean; 105 fRange: TRangeState; 106 fLine: PChar; 107 fProcTable: array[#0..#255] of TProcTableProc; 108 Run: LongInt; 109 fStringLen: Integer; 110 fToIdent: PChar; 111 fTokenPos: Integer; 112 FTokenID: TtkTokenKind; 113 FExtTokenID: TxtkTokenKind; 114 fLineNumber: Integer; 115 fIdentFuncTable: array[0..206] of TIdentFuncTableFunc; 116 fAsmAttri: TSynHighlighterAttributes; 117 fCommentAttri: TSynHighlighterAttributes; 118 fDirecAttri: TSynHighlighterAttributes; 119 fIdentifierAttri: TSynHighlighterAttributes; 120 fInvalidAttri: TSynHighlighterAttributes; 121 fKeyAttri: TSynHighlighterAttributes; 122 fNumberAttri: TSynHighlighterAttributes; 123 fSpaceAttri: TSynHighlighterAttributes; 124 fStringAttri: TSynHighlighterAttributes; 125 fSymbolAttri: TSynHighlighterAttributes; 126 function KeyHash(ToHash: PChar): Integer; 127 function KeyComp(const aKey: String): Boolean; 128 function Func17: TtkTokenKind; 129 function Func21: TtkTokenKind; 130 function Func32: TtkTokenKind; 131 function Func34: TtkTokenKind; 132 function Func36: TtkTokenKind; 133 function Func40: TtkTokenKind; 134 function Func42: TtkTokenKind; 135 function Func45: TtkTokenKind; 136 function Func46: TtkTokenKind; 137 function Func48: TtkTokenKind; 138 function Func52: TtkTokenKind; 139 function Func54: TtkTokenKind; 140 function Func57: TtkTokenKind; 141 function Func58: TtkTokenKind; 142 function Func59: TtkTokenKind; 143 function Func60: TtkTokenKind; 144 function Func61: TtkTokenKind; 145 function Func62: TtkTokenKind; 146 function Func64: TtkTokenKind; 147 function Func65: TtkTokenKind; 148 function Func66: TtkTokenKind; 149 function Func67: TtkTokenKind; 150 function Func68: TtkTokenKind; 151 function Func69: TtkTokenKind; 152 function Func71: TtkTokenKind; 153 function Func74: TtkTokenKind; 154 function Func75: TtkTokenKind; 155 function Func76: TtkTokenKind; 156 function Func78: TtkTokenKind; 157 function Func79: TtkTokenKind; 158 function Func81: TtkTokenKind; 159 function Func82: TtkTokenKind; 160 function Func85: TtkTokenKind; 161 function Func86: TtkTokenKind; 162 function Func88: TtkTokenKind; 163 function Func89: TtkTokenKind; 164 function Func92: TtkTokenKind; 165 function Func97: TtkTokenKind; 166 function Func98: TtkTokenKind; 167 function Func100: TtkTokenKind; 168 function Func101: TtkTokenKind; 169 function Func102: TtkTokenKind; 170 function Func104: TtkTokenKind; 171 function Func105: TtkTokenKind; 172 function Func106: TtkTokenKind; 173 function Func107: TtkTokenKind; 174 function Func109: TtkTokenKind; 175 function Func110: TtkTokenKind; 176 function Func115: TtkTokenKind; 177 function Func116: TtkTokenKind; 178 function Func121: TtkTokenKind; 179 function Func123: TtkTokenKind; 180 function Func125: TtkTokenKind; 181 function Func141: TtkTokenKind; 182 function Func206: TtkTokenKind; 183 procedure AnsiCProc; 184 procedure AndSymbolProc; 185 procedure AsciiCharProc; 186 procedure AtSymbolProc; 187 procedure BraceCloseProc; 188 procedure BraceOpenProc; 189 procedure CRProc; 190 procedure ColonProc; 191 procedure CommaProc; 192 procedure DirectiveProc; 193 procedure EqualProc; 194 procedure GreaterProc; 195 procedure IdentProc; 196 procedure LFProc; 197 procedure LowerProc; 198 procedure MinusProc; 199 procedure ModSymbolProc; 200 procedure NotSymbolProc; 201 procedure NullProc; 202 procedure NumberProc; 203 procedure OrSymbolProc; 204 procedure PlusProc; 205 procedure PointProc; 206 procedure QuestionProc; 207 procedure RoundCloseProc; 208 procedure RoundOpenProc; 209 procedure SemiColonProc; 210 procedure SlashProc; 211 procedure SpaceProc; 212 procedure SquareCloseProc; 213 procedure SquareOpenProc; 214 procedure StarProc; 215 procedure StringProc; 216 procedure TildeProc; 217 procedure XOrSymbolProc; 218 procedure UnknownProc; 219 function AltFunc: TtkTokenKind; 220 procedure InitIdent; 221 function IdentKind(MayBe: PChar): TtkTokenKind; 222 procedure MakeMethodTables; 223 protected 224 function GetIdentChars: TSynIdentChars; override; 225 function GetExtTokenID: TxtkTokenKind; 226 public 227 class function GetCapabilities: TSynHighlighterCapabilities; override; 228 class function GetLanguageName: string; override; 229 public 230 constructor Create(AOwner: TComponent); override; 231 function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes; 232 override; 233 function GetEol: Boolean; override; 234 function GetRange: Pointer; override; 235 function GetTokenID: TtkTokenKind; 236 procedure SetLine(const NewValue: String; LineNumber:Integer); override; 237 function GetToken: String; override; 238 procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer); override; 239 function GetTokenAttribute: TSynHighlighterAttributes; override; 240 function GetTokenKind: integer; override; 241 function GetTokenPos: Integer; override; 242 procedure Next; override; 243 procedure SetRange(Value: Pointer); override; 244 procedure ResetRange; override; 245 function UseUserSettings(settingIndex: integer): boolean; override; 246 procedure EnumUserSettings(settings: TStrings); override; 247 property ExtTokenID: TxtkTokenKind read GetExtTokenID; 248 published 249 property AsmAttri: TSynHighlighterAttributes read fAsmAttri write fAsmAttri; 250 property CommentAttri: TSynHighlighterAttributes read fCommentAttri 251 write fCommentAttri; 252 property DirecAttri: TSynHighlighterAttributes read fDirecAttri 253 write fDirecAttri; 254 property IdentifierAttri: TSynHighlighterAttributes read fIdentifierAttri 255 write fIdentifierAttri; 256 property InvalidAttri: TSynHighlighterAttributes read fInvalidAttri 257 write fInvalidAttri; 258 property KeyAttri: TSynHighlighterAttributes read fKeyAttri write fKeyAttri; 259 property NumberAttri: TSynHighlighterAttributes read fNumberAttri 260 write fNumberAttri; 261 property SpaceAttri: TSynHighlighterAttributes read fSpaceAttri 262 write fSpaceAttri; 263 property StringAttri: TSynHighlighterAttributes read fStringAttri 264 write fStringAttri; 265 property SymbolAttri: TSynHighlighterAttributes read fSymbolAttri 266 write fSymbolAttri; 267 end; 268 269implementation 270 271var 272 Identifiers: array[#0..#255] of ByteBool; 273 mHashTable: array[#0..#255] of Integer; 274 275procedure MakeIdentTable; 276var 277 I: Char; 278begin 279 for I := #0 to #255 do 280 begin 281 Case I of 282 '_', '0'..'9', 'a'..'z', 'A'..'Z': Identifiers[I] := True; 283 else Identifiers[I] := False; 284 end; 285 Case I in['a'..'z', 'A'..'Z'] of { Bug fix: mHashTable['_'] was uninitialised. [Kit] } 286 True: 287 begin 288 if (I > #64) and (I < #91) then mHashTable[I] := Ord(I) - 64 else 289 mHashTable[I] := Ord(I) - 95; 290 end; 291 else mHashTable[I] := 0; 292 end; 293 end; 294end; 295 296procedure TSynCppSyn.InitIdent; 297var 298 I: Integer; 299 pF: PIdentFuncTableFunc; 300begin 301 pF := PIdentFuncTableFunc(@fIdentFuncTable); 302 for I := Low(fIdentFuncTable) to High(fIdentFuncTable) do begin 303 pF^ := @AltFunc; 304 Inc(pF); 305 end; 306 fIdentFuncTable[17] := @Func17; 307 fIdentFuncTable[21] := @Func21; 308 fIdentFuncTable[32] := @Func32; 309 fIdentFuncTable[34] := @Func34; 310 fIdentFuncTable[36] := @Func36; 311 fIdentFuncTable[40] := @Func40; 312 fIdentFuncTable[42] := @Func42; 313 fIdentFuncTable[45] := @Func45; 314 fIdentFuncTable[46] := @Func46; 315 fIdentFuncTable[48] := @Func48; 316 fIdentFuncTable[52] := @Func52; 317 fIdentFuncTable[54] := @Func54; 318 fIdentFuncTable[57] := @Func57; 319 fIdentFuncTable[58] := @Func58; 320 fIdentFuncTable[59] := @Func59; 321 fIdentFuncTable[60] := @Func60; 322 fIdentFuncTable[61] := @Func61; 323 fIdentFuncTable[62] := @Func62; 324 fIdentFuncTable[64] := @Func64; 325 fIdentFuncTable[65] := @Func65; 326 fIdentFuncTable[66] := @Func66; 327 fIdentFuncTable[67] := @Func67; 328 fIdentFuncTable[68] := @Func68; 329 fIdentFuncTable[69] := @Func69; 330 fIdentFuncTable[71] := @Func71; 331 fIdentFuncTable[74] := @Func74; 332 fIdentFuncTable[75] := @Func75; 333 fIdentFuncTable[76] := @Func76; 334 fIdentFuncTable[78] := @Func78; 335 fIdentFuncTable[79] := @Func79; 336 fIdentFuncTable[81] := @Func81; 337 fIdentFuncTable[82] := @Func82; 338 fIdentFuncTable[85] := @Func85; 339 fIdentFuncTable[86] := @Func86; 340 fIdentFuncTable[88] := @Func88; 341 fIdentFuncTable[89] := @Func89; 342 fIdentFuncTable[92] := @Func92; 343 fIdentFuncTable[97] := @Func97; 344 fIdentFuncTable[98] := @Func98; 345 fIdentFuncTable[100] := @Func100; 346 fIdentFuncTable[101] := @Func101; 347 fIdentFuncTable[102] := @Func102; 348 fIdentFuncTable[104] := @Func104; 349 fIdentFuncTable[105] := @Func105; 350 fIdentFuncTable[106] := @Func106; 351 fIdentFuncTable[107] := @Func107; 352 fIdentFuncTable[109] := @Func109; 353 fIdentFuncTable[110] := @Func110; 354 fIdentFuncTable[115] := @Func115; 355 fIdentFuncTable[116] := @Func116; 356 fIdentFuncTable[121] := @Func121; 357 fIdentFuncTable[123] := @Func123; 358 fIdentFuncTable[125] := @Func125; 359 fIdentFuncTable[141] := @Func141; 360 fIdentFuncTable[206] := @Func206; 361end; 362 363function TSynCppSyn.KeyHash(ToHash: PChar): Integer; 364begin 365 Result := 0; 366 while ToHash^ in ['_', '0'..'9', 'a'..'z', 'A'..'Z'] do 367 begin 368 inc(Result, mHashTable[ToHash^]); 369 inc(ToHash); 370 end; 371 fStringLen := ToHash - fToIdent; 372end; { KeyHash } 373 374function TSynCppSyn.KeyComp(const aKey: String): Boolean; 375var 376 I: Integer; 377 Temp: PChar; 378begin 379 Temp := fToIdent; 380 if Length(aKey) = fStringLen then 381 begin 382 Result := True; 383 for i := 1 to fStringLen do 384 begin 385 if Temp^ <> aKey[i] then 386 begin 387 Result := False; 388 break; 389 end; 390 inc(Temp); 391 end; 392 end else Result := False; 393end; { KeyComp } 394 395function TSynCppSyn.Func17: TtkTokenKind; 396begin 397 if KeyComp('if') then Result := tkKey else Result := tkIdentifier; 398end; 399 400function TSynCppSyn.Func21: TtkTokenKind; 401begin 402 if KeyComp('do') then Result := tkKey else Result := tkIdentifier; 403end; 404 405function TSynCppSyn.Func32: TtkTokenKind; 406begin 407 if KeyComp('cdecl') then Result := tkKey else 408 if KeyComp('case') then Result := tkKey else 409 if KeyComp('_cdecl') then Result := tkKey else 410 if KeyComp('__cdecl') then Result := tkKey else Result := tkIdentifier; 411end; 412 413function TSynCppSyn.Func34: TtkTokenKind; 414begin 415 if KeyComp('char') then Result := tkKey else Result := tkIdentifier; 416end; 417 418function TSynCppSyn.Func36: TtkTokenKind; 419begin 420 if KeyComp('asm') or KeyComp('_asm') or KeyComp('__asm') then 421 begin 422 Result := tkKey; 423 fRange := rsAsm; 424 fAsmStart := True; 425 end else 426 Result := tkIdentifier; 427end; 428 429function TSynCppSyn.Func40: TtkTokenKind; 430begin 431 if KeyComp('catch') then Result := tkKey else Result := tkIdentifier; 432end; 433 434function TSynCppSyn.Func42: TtkTokenKind; 435begin 436 if KeyComp('for') then Result := tkKey else 437 if KeyComp('break') then Result := tkKey else Result := tkIdentifier; 438end; 439 440function TSynCppSyn.Func45: TtkTokenKind; 441begin 442 if KeyComp('else') then Result := tkKey else 443 if KeyComp('new') then Result := tkKey else Result := tkIdentifier; 444end; 445 446function TSynCppSyn.Func46: TtkTokenKind; 447begin 448 if KeyComp('__int8') then Result := tkKey else 449 if KeyComp('__int16') then Result := tkKey else 450 if KeyComp('int') then Result := tkKey else 451 if KeyComp('__int32') then Result := tkKey else 452 if KeyComp('__int64') then Result := tkKey else Result := tkIdentifier; 453end; 454 455function TSynCppSyn.Func48: TtkTokenKind; 456begin 457 if KeyComp('false') then Result := tkKey else 458 if KeyComp('bool') then Result := tkKey else Result := tkIdentifier; 459end; 460 461function TSynCppSyn.Func52: TtkTokenKind; 462begin 463 if KeyComp('long') then Result := tkKey else Result := tkIdentifier; 464end; 465 466function TSynCppSyn.Func54: TtkTokenKind; 467begin 468 if KeyComp('void') then Result := tkKey else Result := tkIdentifier; 469end; 470 471function TSynCppSyn.Func57: TtkTokenKind; 472begin 473 if KeyComp('enum') then Result := tkKey else 474 if KeyComp('delete') then Result := tkKey else Result := tkIdentifier; 475end; 476 477function TSynCppSyn.Func58: TtkTokenKind; 478begin 479 if KeyComp('_pascal') then Result := tkKey else 480 if KeyComp('__pascal') then Result := tkKey else 481 if KeyComp('pascal') then Result := tkKey else Result := tkIdentifier; 482end; 483 484function TSynCppSyn.Func59: TtkTokenKind; 485begin 486 if KeyComp('class') then Result := tkKey else 487 if KeyComp('float') then Result := tkKey else Result := tkIdentifier; 488end; 489 490function TSynCppSyn.Func60: TtkTokenKind; 491begin 492 if KeyComp('this') then Result := tkKey else Result := tkIdentifier; 493end; 494 495function TSynCppSyn.Func61: TtkTokenKind; 496begin 497 if KeyComp('goto') then Result := tkKey else 498 if KeyComp('auto') then Result := tkKey else Result := tkIdentifier; 499end; 500 501function TSynCppSyn.Func62: TtkTokenKind; 502begin 503 if KeyComp('__thread') then Result := tkKey else 504 if KeyComp('while') then Result := tkKey else 505 if KeyComp('friend') then Result := tkKey else Result := tkIdentifier; 506end; 507 508function TSynCppSyn.Func64: TtkTokenKind; 509begin 510 if KeyComp('signed') then Result := tkKey else Result := tkIdentifier; 511end; 512 513function TSynCppSyn.Func65: TtkTokenKind; 514begin 515 if KeyComp('double') then Result := tkKey else Result := tkIdentifier; 516end; 517 518function TSynCppSyn.Func66: TtkTokenKind; 519begin 520 if KeyComp('__try') then Result := tkKey else 521 if KeyComp('try') then Result := tkKey else Result := tkIdentifier; 522end; 523 524function TSynCppSyn.Func67: TtkTokenKind; 525begin 526 if KeyComp('__dispid') then Result := tkKey else Result := tkIdentifier; 527end; 528 529function TSynCppSyn.Func68: TtkTokenKind; 530begin 531 if KeyComp('true') then Result := tkKey else Result := tkIdentifier; 532end; 533 534function TSynCppSyn.Func69: TtkTokenKind; 535begin 536 if KeyComp('public') then Result := tkKey else 537 if KeyComp('inline') then Result := tkKey else Result := tkIdentifier; 538end; 539 540function TSynCppSyn.Func71: TtkTokenKind; 541begin 542 if KeyComp('__rtti') then Result := tkKey else Result := tkIdentifier; 543end; 544 545function TSynCppSyn.Func74: TtkTokenKind; 546begin 547 if KeyComp('__classid') then Result := tkKey else Result := tkIdentifier; 548end; 549 550function TSynCppSyn.Func75: TtkTokenKind; 551begin 552 if KeyComp('__declspec') then Result := tkKey else 553 if KeyComp('using') then Result := tkKey else Result := tkIdentifier; 554end; 555 556function TSynCppSyn.Func76: TtkTokenKind; 557begin 558 if KeyComp('const') then Result := tkKey else 559 if KeyComp('default') then Result := tkKey else Result := tkIdentifier; 560end; 561 562function TSynCppSyn.Func78: TtkTokenKind; 563begin 564 if KeyComp('_stdcall') then Result := tkKey else 565 if KeyComp('union') then Result := tkKey else 566 if KeyComp('__stdcall') then Result := tkKey else 567 if KeyComp('static') then Result := tkKey else Result := tkIdentifier; 568end; 569 570function TSynCppSyn.Func79: TtkTokenKind; 571begin 572 if KeyComp('__except') then Result := tkKey else 573 if KeyComp('wchar_t') then Result := tkKey else Result := tkIdentifier; 574end; 575 576function TSynCppSyn.Func81: TtkTokenKind; 577begin 578 if KeyComp('mutable') then Result := tkKey else Result := tkIdentifier; 579end; 580 581function TSynCppSyn.Func82: TtkTokenKind; 582begin 583 if KeyComp('_fastcall') then Result := tkKey else 584 if KeyComp('__fastcall') then Result := tkKey else Result := tkIdentifier; 585end; 586 587function TSynCppSyn.Func85: TtkTokenKind; 588begin 589 if KeyComp('short') then Result := tkKey else 590 if KeyComp('typeid') then Result := tkKey else Result := tkIdentifier; 591end; 592 593function TSynCppSyn.Func86: TtkTokenKind; 594begin 595 if KeyComp('sizeof') then Result := tkKey else 596 if KeyComp('__finally') then Result := tkKey else 597 if KeyComp('namespace') then Result := tkKey else Result := tkIdentifier; 598end; 599 600function TSynCppSyn.Func88: TtkTokenKind; 601begin 602 if KeyComp('switch') then Result := tkKey else 603 if KeyComp('typedef') then Result := tkKey else Result := tkIdentifier; 604end; 605 606function TSynCppSyn.Func89: TtkTokenKind; 607begin 608 if KeyComp('throw') then Result := tkKey else Result := tkIdentifier; 609end; 610 611function TSynCppSyn.Func92: TtkTokenKind; 612begin 613 if KeyComp('extern') then Result := tkKey else Result := tkIdentifier; 614end; 615 616function TSynCppSyn.Func97: TtkTokenKind; 617begin 618 if KeyComp('__import') then Result := tkKey else 619 if KeyComp('_import') then Result := tkKey else Result := tkIdentifier; 620end; 621 622function TSynCppSyn.Func98: TtkTokenKind; 623begin 624 if KeyComp('private') then Result := tkKey else Result := tkIdentifier; 625end; 626 627function TSynCppSyn.Func100: TtkTokenKind; 628begin 629 if KeyComp('template') then Result := tkKey else 630 if KeyComp('__closure') then Result := tkKey else Result := tkIdentifier; 631end; 632 633function TSynCppSyn.Func101: TtkTokenKind; 634begin 635 if KeyComp('unsigned') then Result := tkKey else Result := tkIdentifier; 636end; 637 638function TSynCppSyn.Func102: TtkTokenKind; 639begin 640 if KeyComp('return') then Result := tkKey else Result := tkIdentifier; 641end; 642 643function TSynCppSyn.Func104: TtkTokenKind; 644begin 645 if KeyComp('volatile') then Result := tkKey else 646 if KeyComp('_export') then Result := tkKey else 647 if KeyComp('__export') then Result := tkKey else Result := tkIdentifier; 648end; 649 650function TSynCppSyn.Func105: TtkTokenKind; 651begin 652 if KeyComp('__published') then Result := tkKey else Result := tkIdentifier; 653end; 654 655function TSynCppSyn.Func106: TtkTokenKind; 656begin 657 if KeyComp('explicit') then Result := tkKey else Result := tkIdentifier; 658end; 659 660function TSynCppSyn.Func107: TtkTokenKind; 661begin 662 if KeyComp('typename') then Result := tkKey else 663 if KeyComp('struct') then Result := tkKey else Result := tkIdentifier; 664end; 665 666function TSynCppSyn.Func109: TtkTokenKind; 667begin 668 if KeyComp('register') then Result := tkKey else 669 if KeyComp('continue') then Result := tkKey else 670 if KeyComp('__automated') then Result := tkKey else Result := tkIdentifier; 671end; 672 673function TSynCppSyn.Func110: TtkTokenKind; 674begin 675 if KeyComp('virtual') then Result := tkKey else Result := tkIdentifier; 676end; 677 678function TSynCppSyn.Func115: TtkTokenKind; 679begin 680 if KeyComp('protected') then Result := tkKey else Result := tkIdentifier; 681end; 682 683function TSynCppSyn.Func116: TtkTokenKind; 684begin 685 if KeyComp('operator') then Result := tkKey else Result := tkIdentifier; 686end; 687 688function TSynCppSyn.Func121: TtkTokenKind; 689begin 690 if KeyComp('_vectorcall') then Result := tkKey else 691 if KeyComp('__vectorcall') then Result := tkKey else 692 Result := tkIdentifier; 693end; 694 695function TSynCppSyn.Func123: TtkTokenKind; 696begin 697 if KeyComp('dynamic_cast') then Result := tkKey else 698 if KeyComp('const_cast') then Result := tkKey else Result := tkIdentifier; 699end; 700 701function TSynCppSyn.Func125: TtkTokenKind; 702begin 703 if KeyComp('static_cast') then Result := tkKey else Result := tkIdentifier; 704end; 705 706function TSynCppSyn.Func141: TtkTokenKind; 707begin 708 if KeyComp('__property') then Result := tkKey else Result := tkIdentifier; 709end; 710 711function TSynCppSyn.Func206: TtkTokenKind; 712begin 713 if KeyComp('reinterpret_cast') then Result := tkKey else Result := tkIdentifier; 714end; 715 716function TSynCppSyn.AltFunc: TtkTokenKind; 717begin 718 Result := tkIdentifier; 719end; 720 721function TSynCppSyn.IdentKind(MayBe: PChar): TtkTokenKind; 722var 723 HashKey: Integer; 724begin 725 fToIdent := MayBe; 726 HashKey := KeyHash(MayBe); 727 if HashKey < 207 then 728 Result := fIdentFuncTable[HashKey]() 729 else 730 Result := tkIdentifier; 731end; 732 733procedure TSynCppSyn.MakeMethodTables; 734var 735 I: Char; 736begin 737 for I := #0 to #255 do 738 case I of 739 '&': fProcTable[I] := @AndSymbolProc; 740 #39: fProcTable[I] := @AsciiCharProc; 741 '@': fProcTable[I] := @AtSymbolProc; 742 '}': fProcTable[I] := @BraceCloseProc; 743 '{': fProcTable[I] := @BraceOpenProc; 744 #13: fProcTable[I] := @CRProc; 745 ':': fProcTable[I] := @ColonProc; 746 ',': fProcTable[I] := @CommaProc; 747 '#': fProcTable[I] := @DirectiveProc; 748 '=': fProcTable[I] := @EqualProc; 749 '>': fProcTable[I] := @GreaterProc; 750 '?': fProcTable[I] := @QuestionProc; 751 'A'..'Z', 'a'..'z', '_': fProcTable[I] := @IdentProc; 752 #10: fProcTable[I] := @LFProc; 753 '<': fProcTable[I] := @LowerProc; 754 '-': fProcTable[I] := @MinusProc; 755 '%': fProcTable[I] := @ModSymbolProc; 756 '!': fProcTable[I] := @NotSymbolProc; 757 #0: fProcTable[I] := @NullProc; 758 '0'..'9': fProcTable[I] := @NumberProc; 759 '|': fProcTable[I] := @OrSymbolProc; 760 '+': fProcTable[I] := @PlusProc; 761 '.': fProcTable[I] := @PointProc; 762 ')': fProcTable[I] := @RoundCloseProc; 763 '(': fProcTable[I] := @RoundOpenProc; 764 ';': fProcTable[I] := @SemiColonProc; 765 '/': fProcTable[I] := @SlashProc; 766 #1..#9, #11, #12, #14..#32: fProcTable[I] := @SpaceProc; 767 ']': fProcTable[I] := @SquareCloseProc; 768 '[': fProcTable[I] := @SquareOpenProc; 769 '*': fProcTable[I] := @StarProc; 770 #34: fProcTable[I] := @StringProc; 771 '~': fProcTable[I] := @TildeProc; 772 '^': fProcTable[I] := @XOrSymbolProc; 773 else fProcTable[I] := @UnknownProc; 774 end; 775end; 776 777constructor TSynCppSyn.Create(AOwner: TComponent); 778begin 779 inherited Create(AOwner); 780 fAsmAttri := TSynHighlighterAttributes.Create(@SYNS_AttrAssembler, SYNS_XML_AttrAssembler); 781 AddAttribute(fAsmAttri); 782 fCommentAttri := TSynHighlighterAttributes.Create(@SYNS_AttrComment, SYNS_XML_AttrComment); 783 fCommentAttri.Style:= [fsItalic]; 784 AddAttribute(fCommentAttri); 785 fIdentifierAttri := TSynHighlighterAttributes.Create(@SYNS_AttrIdentifier, SYNS_XML_AttrIdentifier); 786 AddAttribute(fIdentifierAttri); 787 fInvalidAttri := TSynHighlighterAttributes.Create(@SYNS_AttrIllegalChar, SYNS_XML_AttrIllegalChar); 788 AddAttribute(fInvalidAttri); 789 fKeyAttri := TSynHighlighterAttributes.Create(@SYNS_AttrReservedWord, SYNS_XML_AttrReservedWord); 790 fKeyAttri.Style:= [fsBold]; 791 AddAttribute(fKeyAttri); 792 fNumberAttri := TSynHighlighterAttributes.Create(@SYNS_AttrNumber, SYNS_XML_AttrNumber); 793 AddAttribute(fNumberAttri); 794 fSpaceAttri := TSynHighlighterAttributes.Create(@SYNS_AttrSpace, SYNS_XML_AttrSpace); 795 fSpaceAttri.Foreground := clWindow; 796 AddAttribute(fSpaceAttri); 797 fStringAttri := TSynHighlighterAttributes.Create(@SYNS_AttrString, SYNS_XML_AttrString); 798 AddAttribute(fStringAttri); 799 fSymbolAttri := TSynHighlighterAttributes.Create(@SYNS_AttrSymbol, SYNS_XML_AttrSymbol); 800 AddAttribute(fSymbolAttri); 801 fDirecAttri := TSynHighlighterAttributes.Create(@SYNS_AttrPreprocessor, SYNS_XML_AttrPreprocessor); 802 AddAttribute(fDirecAttri); 803 SetAttributesOnChange(@DefHighlightChange); 804 InitIdent; 805 MakeMethodTables; 806 fRange := rsUnknown; 807 fAsmStart := False; 808 fDefaultFilter := SYNS_FilterCPP; 809end; { Create } 810 811procedure TSynCppSyn.SetLine(const NewValue: String; LineNumber:Integer); 812begin 813 inherited; 814 fLine := PChar(NewValue); 815 Run := 0; 816 fLineNumber := LineNumber; 817 Next; 818end; { SetLine } 819 820procedure TSynCppSyn.AnsiCProc; 821begin 822 fTokenID := tkComment; 823 case FLine[Run] of 824 #0: 825 begin 826 NullProc; 827 exit; 828 end; 829 #10: 830 begin 831 LFProc; 832 exit; 833 end; 834 #13: 835 begin 836 CRProc; 837 exit; 838 end; 839 end; 840 841 while FLine[Run] <> #0 do 842 case FLine[Run] of 843 '*': 844 if fLine[Run + 1] = '/' then 845 begin 846 inc(Run, 2); 847 if fRange = rsAnsiCAsm then 848 fRange := rsAsm 849 else if fRange = rsAnsiCAsmBlock then 850 fRange := rsAsmBlock 851 else if fRange = rsDirectiveComment then 852 fRange := rsDirective 853 else 854 fRange := rsUnKnown; 855 break; 856 end else 857 inc(Run); 858 #10: break; 859 #13: break; 860 else inc(Run); 861 end; 862end; 863 864procedure TSynCppSyn.AndSymbolProc; 865begin 866 fTokenID := tkSymbol; 867 case FLine[Run + 1] of 868 '=': {and assign} 869 begin 870 inc(Run, 2); 871 FExtTokenID := xtkAndAssign; 872 end; 873 '&': {logical and} 874 begin 875 inc(Run, 2); 876 FExtTokenID := xtkLogAnd; 877 end; 878 else {and} 879 begin 880 inc(Run); 881 FExtTokenID := xtkAnd; 882 end; 883 end; 884end; 885 886procedure TSynCppSyn.AsciiCharProc; 887begin 888 fTokenID := tkString; 889 repeat 890 if fLine[Run] = '\' then begin 891 if fLine[Run + 1] in [#39, '\'] then //ek 2000-04-26 892 inc(Run); 893 end; 894 inc(Run); 895 until fLine[Run] in [#0, #10, #13, #39]; 896 if fLine[Run] = #39 then 897 inc(Run); 898end; 899 900procedure TSynCppSyn.AtSymbolProc; 901begin 902 fTokenID := tkUnknown; 903 inc(Run); 904end; 905 906procedure TSynCppSyn.BraceCloseProc; 907begin 908 inc(Run); 909 fTokenId := tkSymbol; 910 FExtTokenID := xtkBraceClose; 911 if fRange = rsAsmBlock then fRange := rsUnknown; 912end; 913 914procedure TSynCppSyn.BraceOpenProc; 915begin 916 inc(Run); 917 fTokenId := tkSymbol; 918 FExtTokenID := xtkBraceOpen; 919 if fRange = rsAsm then 920 begin 921 fRange := rsAsmBlock; 922 fAsmStart := True; 923 end; 924end; 925 926procedure TSynCppSyn.CRProc; 927begin 928 fTokenID := tkSpace; 929 Inc(Run); 930 if fLine[Run + 1] = #10 then Inc(Run); 931end; 932 933procedure TSynCppSyn.ColonProc; 934begin 935 fTokenID := tkSymbol; 936 Case FLine[Run + 1] of 937 ':': {scope resolution operator} 938 begin 939 inc(Run, 2); 940 FExtTokenID := xtkScopeResolution; 941 end; 942 else {colon} 943 begin 944 inc(Run); 945 FExtTokenID := xtkColon; 946 end; 947 end; 948end; 949 950procedure TSynCppSyn.CommaProc; 951begin 952 inc(Run); 953 fTokenID := tkSymbol; 954 FExtTokenID := xtkComma; 955end; 956 957procedure TSynCppSyn.DirectiveProc; 958begin 959 if fLine[Run] in [#0, #10, #13] then begin 960 if (Run <= 0) or (fLine[Run - 1] <> '\') then 961 fRange := rsUnknown; 962 fProcTable[fLine[Run]]; 963 end else begin 964 fTokenID := tkDirective; 965 while TRUE do 966 case fLine[Run] of 967 '/': // comment? 968 begin 969 if fLine[Run + 1] = '/' then begin // is end of directive as well 970 fRange := rsUnknown; //ek 2000-04-25 971 break; 972 end else if fLine[Run + 1] = '*' then begin // might be embedded only 973 fRange := rsDirectiveComment; 974 break; 975 end else 976 Inc(Run); 977 end; 978 '\': // directive continued on next line? 979 begin 980 Inc(Run); 981 if fLine[Run] in [#0, #10, #13] then begin 982 fRange := rsDirective; 983 break; 984 end; 985 end; 986 #0, #10, #13: 987 begin 988 fRange := rsUnknown; 989 break; 990 end; 991 else Inc(Run); 992 end; 993 end; 994end; 995 996procedure TSynCppSyn.EqualProc; 997begin 998 fTokenID := tkSymbol; 999 case FLine[Run + 1] of 1000 '=': {logical equal} 1001 begin 1002 inc(Run, 2); 1003 FExtTokenID := xtkLogEqual; 1004 end; 1005 else {assign} 1006 begin 1007 inc(Run); 1008 FExtTokenID := xtkAssign; 1009 end; 1010 end; 1011end; 1012 1013procedure TSynCppSyn.GreaterProc; 1014begin 1015 fTokenID := tkSymbol; 1016 Case FLine[Run + 1] of 1017 '=': {greater than or equal to} 1018 begin 1019 inc(Run, 2); 1020 FExtTokenID := xtkGreaterThanEqual; 1021 end; 1022 '>': 1023 begin 1024 if FLine[Run + 2] = '=' then {shift right assign} 1025 begin 1026 inc(Run, 3); 1027 FExtTokenID := xtkShiftRightAssign; 1028 end 1029 else {shift right} 1030 begin 1031 inc(Run, 2); 1032 FExtTokenID := xtkShiftRight; 1033 end; 1034 end; 1035 else {greater than} 1036 begin 1037 inc(Run); 1038 FExtTokenID := xtkGreaterThan; 1039 end; 1040 end; 1041end; 1042 1043procedure TSynCppSyn.QuestionProc; 1044begin 1045 fTokenID := tkSymbol; {conditional} 1046 FExtTokenID := xtkQuestion; 1047 inc(Run); 1048end; 1049 1050procedure TSynCppSyn.IdentProc; 1051begin 1052 fTokenID := IdentKind((fLine + Run)); 1053 inc(Run, fStringLen); 1054 while Identifiers[fLine[Run]] do inc(Run); 1055end; 1056 1057procedure TSynCppSyn.LFProc; 1058begin 1059 fTokenID := tkSpace; 1060 inc(Run); 1061end; 1062 1063procedure TSynCppSyn.LowerProc; 1064begin 1065 fTokenID := tkSymbol; 1066 case FLine[Run + 1] of 1067 '=': {less than or equal to} 1068 begin 1069 inc(Run, 2); 1070 FExtTokenID := xtkLessThanEqual; 1071 end; 1072 '<': 1073 begin 1074 if FLine[Run + 2] = '=' then {shift left assign} 1075 begin 1076 inc(Run, 3); 1077 FExtTokenID := xtkShiftLeftAssign; 1078 end 1079 else {shift left} 1080 begin 1081 inc(Run, 2); 1082 FExtTokenID := xtkShiftLeft; 1083 end; 1084 end; 1085 else {less than} 1086 begin 1087 inc(Run); 1088 FExtTokenID := xtkLessThan; 1089 end; 1090 end; 1091end; 1092 1093procedure TSynCppSyn.MinusProc; 1094begin 1095 fTokenID := tkSymbol; 1096 case FLine[Run + 1] of 1097 '=': {subtract assign} 1098 begin 1099 inc(Run, 2); 1100 FExtTokenID := xtkSubtractAssign; 1101 end; 1102 '-': {decrement} 1103 begin 1104 inc(Run, 2); 1105 FExtTokenID := xtkDecrement; 1106 end; 1107 '>': {arrow} 1108 begin 1109 inc(Run, 2); 1110 FExtTokenID := xtkArrow; 1111 end; 1112 else {subtract} 1113 begin 1114 inc(Run); 1115 FExtTokenID := xtkSubtract; 1116 end; 1117 end; 1118end; 1119 1120procedure TSynCppSyn.ModSymbolProc; 1121begin 1122 fTokenID := tkSymbol; 1123 case FLine[Run + 1] of 1124 '=': {mod assign} 1125 begin 1126 inc(Run, 2); 1127 FExtTokenID := xtkModAssign; 1128 end; 1129 else {mod} 1130 begin 1131 inc(Run); 1132 FExtTokenID := xtkMod; 1133 end; 1134 end; 1135end; 1136 1137procedure TSynCppSyn.NotSymbolProc; 1138begin 1139 fTokenID := tkSymbol; 1140 case FLine[Run + 1] of 1141 '=': {not equal} 1142 begin 1143 inc(Run, 2); 1144 FExtTokenID := xtkNotEqual; 1145 end; 1146 else {not} 1147 begin 1148 inc(Run); 1149 FExtTokenID := xtkLogComplement; 1150 end; 1151 end; 1152end; 1153 1154procedure TSynCppSyn.NullProc; 1155begin 1156 fTokenID := tkNull; 1157end; 1158 1159procedure TSynCppSyn.NumberProc; 1160begin 1161 fTokenID := tkNumber; 1162 1163 if (FLine[Run] = '0') and (FLine[Run+1] in ['x', 'X'])then 1164 begin 1165 inc(Run, 2); 1166 while FLine[Run] in ['0'..'9', 'A'..'F', 'a'..'f'] do inc(Run); 1167 if FLine[Run] in ['u', 'U', 'l', 'L'] then inc(Run); 1168 exit; 1169 end; 1170 1171 inc(Run); 1172 while FLine[Run] in ['0'..'9'] do inc(Run); 1173 if (FLine[Run]='.') and not(fLine[Run+1]='.') then begin 1174 inc(Run); 1175 while FLine[Run] in ['0'..'9'] do inc(Run); 1176 end; 1177 if (FLine[Run]='e') or (fLine[Run]='E') then begin 1178 inc(Run); 1179 if (FLine[Run]='+') or (fLine[Run]='-') then inc(Run); 1180 while FLine[Run] in ['0'..'9'] do inc(Run); 1181 end; 1182 if FLine[Run] in ['u', 'U', 'l', 'L'] then inc(Run); 1183end; 1184 1185procedure TSynCppSyn.OrSymbolProc; 1186begin 1187 fTokenID := tkSymbol; 1188 case FLine[Run + 1] of 1189 '=': {or assign} 1190 begin 1191 inc(Run, 2); 1192 FExtTokenID := xtkIncOrAssign; 1193 end; 1194 '|': {logical or} 1195 begin 1196 inc(Run, 2); 1197 FExtTokenID := xtkLogOr; 1198 end; 1199 else {or} 1200 begin 1201 inc(Run); 1202 FExtTokenID := xtkIncOr; 1203 end; 1204 end; 1205end; 1206 1207procedure TSynCppSyn.PlusProc; 1208begin 1209 fTokenID := tkSymbol; 1210 case FLine[Run + 1] of 1211 '=': {add assign} 1212 begin 1213 inc(Run, 2); 1214 FExtTokenID := xtkAddAssign; 1215 end; 1216 '+': {increment} 1217 begin 1218 inc(Run, 2); 1219 FExtTokenID := xtkIncrement; 1220 end; 1221 else {add} 1222 begin 1223 inc(Run); 1224 FExtTokenID := xtkAdd; 1225 end; 1226 end; 1227end; 1228 1229procedure TSynCppSyn.PointProc; 1230begin 1231 fTokenID := tkSymbol; 1232 if (FLine[Run + 1] = '.') and (FLine[Run + 2] = '.') then 1233 begin {ellipse} 1234 inc(Run, 3); 1235 FExtTokenID := xtkEllipse; 1236 end 1237 else {point} 1238 begin 1239 inc(Run); 1240 FExtTokenID := xtkPoint; 1241 end; 1242end; 1243 1244procedure TSynCppSyn.RoundCloseProc; 1245begin 1246 inc(Run); 1247 fTokenID := tkSymbol; 1248 FExtTokenID := xtkRoundClose; 1249end; 1250 1251procedure TSynCppSyn.RoundOpenProc; 1252begin 1253 inc(Run); 1254 FTokenID := tkSymbol; 1255 FExtTokenID := xtkRoundOpen; 1256end; 1257 1258procedure TSynCppSyn.SemiColonProc; 1259begin 1260 inc(Run); 1261 fTokenID := tkSymbol; 1262 FExtTokenID := xtkSemiColon; 1263 if fRange = rsAsm then fRange := rsUnknown; 1264end; 1265 1266procedure TSynCppSyn.SlashProc; 1267begin 1268 case FLine[Run + 1] of 1269 '/': {c++ style comments} 1270 begin 1271 fTokenID := tkComment; 1272 inc(Run, 2); 1273 while not (fLine[Run] in [#0, #10, #13]) do Inc(Run); 1274 end; 1275 '*': {c style comments} 1276 begin 1277 fTokenID := tkComment; 1278 if fRange = rsAsm then 1279 fRange := rsAnsiCAsm 1280 else if fRange = rsAsmBlock then 1281 fRange := rsAnsiCAsmBlock 1282 else if fRange <> rsDirectiveComment then 1283 fRange := rsAnsiC; 1284 inc(Run, 2); 1285 while fLine[Run] <> #0 do 1286 case fLine[Run] of 1287 '*': 1288 if fLine[Run + 1] = '/' then 1289 begin 1290 inc(Run, 2); 1291 if fRange = rsDirectiveComment then 1292 fRange := rsDirective 1293 else if fRange = rsAnsiCAsm then 1294 fRange := rsAsm 1295 else 1296 begin 1297 if fRange = rsAnsiCAsmBlock then 1298 fRange := rsAsmBlock 1299 else 1300 fRange := rsUnKnown; 1301 end; 1302 break; 1303 end else inc(Run); 1304 #10, #13: 1305 begin 1306 if fRange = rsDirectiveComment then 1307 fRange := rsAnsiC; 1308 break; 1309 end; 1310 else inc(Run); 1311 end; 1312 end; 1313 '=': {divide assign} 1314 begin 1315 inc(Run, 2); 1316 fTokenID := tkSymbol; 1317 FExtTokenID := xtkDivideAssign; 1318 end; 1319 else {divide} 1320 begin 1321 inc(Run); 1322 fTokenID := tkSymbol; 1323 FExtTokenID := xtkDivide; 1324 end; 1325 end; 1326end; 1327 1328procedure TSynCppSyn.SpaceProc; 1329begin 1330 inc(Run); 1331 fTokenID := tkSpace; 1332 while FLine[Run] in [#1..#9, #11, #12, #14..#32] do inc(Run); 1333end; 1334 1335procedure TSynCppSyn.SquareCloseProc; 1336begin 1337 inc(Run); 1338 fTokenID := tkSymbol; 1339 FExtTokenID := xtkSquareClose; 1340end; 1341 1342procedure TSynCppSyn.SquareOpenProc; 1343begin 1344 inc(Run); 1345 fTokenID := tkSymbol; 1346 FExtTokenID := xtkSquareOpen; 1347end; 1348 1349procedure TSynCppSyn.StarProc; 1350begin 1351 fTokenID := tkSymbol; 1352 case FLine[Run + 1] of 1353 '=': {multiply assign} 1354 begin 1355 inc(Run, 2); 1356 FExtTokenID := xtkMultiplyAssign; 1357 end; 1358 else {star} 1359 begin 1360 inc(Run); 1361 FExtTokenID := xtkStar; 1362 end; 1363 end; 1364end; 1365 1366procedure TSynCppSyn.StringProc; 1367begin 1368 case FLine[Run] of 1369 #0: 1370 begin 1371 NullProc; 1372 exit; 1373 end; 1374 #10: 1375 begin 1376 LFProc; 1377 exit; 1378 end; 1379 #13: 1380 begin 1381 CRProc; 1382 exit; 1383 end; 1384 end; 1385 fTokenID := tkString; 1386 if not((fRange in [rsAsmBlockString,rsAsmString,rsDirectiveString,rsString]) 1387 and (Run = 0) and (FLine[Run] = #34 )) 1388 then 1389 repeat 1390 if fLine[Run] = '\' then begin 1391 if fLine[Run + 1] in [#34, '\'] then //ek 2000-04-26 1392 Inc(Run); 1393 end; 1394 inc(Run); 1395 until fLine[Run] in [#0, #10, #13, #34]; 1396 if FLine[Run] = #34 then begin 1397 inc(Run); 1398 fRange := SynCppStringRangeToRange[fRange]; 1399 end else begin 1400 // string continues in next line 1401 fRange := SynCppRangeToStringRange[fRange]; 1402 end; 1403end; 1404 1405procedure TSynCppSyn.TildeProc; 1406begin 1407 inc(Run); {bitwise complement} 1408 fTokenId := tkSymbol; 1409 FExtTokenID := xtkBitComplement; 1410end; 1411 1412procedure TSynCppSyn.XOrSymbolProc; 1413begin 1414 fTokenID := tkSymbol; 1415 Case FLine[Run + 1] of 1416 '=': {xor assign} 1417 begin 1418 inc(Run, 2); 1419 FExtTokenID := xtkXorAssign; 1420 end; 1421 else {xor} 1422 begin 1423 inc(Run); 1424 FExtTokenID := xtkXor; 1425 end; 1426 end; 1427end; 1428 1429procedure TSynCppSyn.UnknownProc; 1430begin 1431 inc(Run); 1432 while (fLine[Run] in [#128..#191]) OR // continued utf8 subcode 1433 ((fLine[Run]<>#0) and (fProcTable[fLine[Run]] = @UnknownProc)) do inc(Run); 1434 fTokenID := tkUnknown; 1435end; 1436 1437procedure TSynCppSyn.Next; 1438begin 1439 fAsmStart := False; 1440 fTokenPos := Run; 1441 case fRange of 1442 rsAnsiC, rsAnsiCAsm, rsAnsiCAsmBlock, rsDirectiveComment: 1443 AnsiCProc; 1444 rsAsmBlockString,rsAsmString,rsDirectiveString,rsString: 1445 StringProc; 1446 rsDirective: 1447 DirectiveProc; 1448 else 1449 begin 1450 fRange := rsUnknown; 1451 fProcTable[fLine[Run]]; 1452 end; 1453 end; 1454end; 1455 1456function TSynCppSyn.GetDefaultAttribute(Index: integer): TSynHighlighterAttributes; 1457begin 1458 case Index of 1459 SYN_ATTR_COMMENT: Result := fCommentAttri; 1460 SYN_ATTR_IDENTIFIER: Result := fIdentifierAttri; 1461 SYN_ATTR_KEYWORD: Result := fKeyAttri; 1462 SYN_ATTR_STRING: Result := fStringAttri; 1463 SYN_ATTR_WHITESPACE: Result := fSpaceAttri; 1464 SYN_ATTR_NUMBER: Result := fNumberAttri; 1465 SYN_ATTR_DIRECTIVE: Result := fDirecAttri; 1466 SYN_ATTR_ASM: Result := fAsmAttri; 1467 else Result := nil; 1468 end; 1469end; 1470 1471function TSynCppSyn.GetEol: Boolean; 1472begin 1473 Result := fTokenID = tkNull; 1474end; 1475 1476function TSynCppSyn.GetRange: Pointer; 1477begin 1478 Result := Pointer(PtrInt(fRange)); 1479end; 1480 1481function TSynCppSyn.GetToken: String; 1482var 1483 Len: LongInt; 1484begin 1485 Result := ''; 1486 Len := Run - fTokenPos; 1487 SetString(Result, (FLine + fTokenPos), Len); 1488end; 1489 1490procedure TSynCppSyn.GetTokenEx(out TokenStart: PChar; 1491 out TokenLength: integer); 1492begin 1493 TokenLength:=Run-fTokenPos; 1494 TokenStart:=FLine + fTokenPos; 1495end; 1496 1497function TSynCppSyn.GetTokenID: TtkTokenKind; 1498begin 1499 Result := fTokenId; 1500 if ((fRange = rsAsm) or (fRange = rsAsmBlock)) and not fAsmStart 1501 and not (fTokenId in [tkComment, tkSpace, tkNull]) 1502 then 1503 Result := tkAsm; 1504end; 1505 1506function TSynCppSyn.GetExtTokenID: TxtkTokenKind; 1507begin 1508 Result := FExtTokenID; 1509end; 1510 1511function TSynCppSyn.GetTokenAttribute: TSynHighlighterAttributes; 1512begin 1513 case fTokenID of 1514 tkAsm: Result := fAsmAttri; 1515 tkComment: Result := fCommentAttri; 1516 tkDirective: Result := fDirecAttri; 1517 tkIdentifier: Result := fIdentifierAttri; 1518 tkKey: Result := fKeyAttri; 1519 tkNumber: Result := fNumberAttri; 1520 tkSpace: Result := fSpaceAttri; 1521 tkString: Result := fStringAttri; 1522 tkSymbol: Result := fSymbolAttri; 1523 tkUnknown: Result := fInvalidAttri; 1524 else Result := nil; 1525 end; 1526end; 1527 1528function TSynCppSyn.GetTokenKind: integer; 1529begin 1530 Result := Ord(GetTokenID); 1531end; 1532 1533function TSynCppSyn.GetTokenPos: Integer; 1534begin 1535 Result := fTokenPos; 1536end; 1537 1538procedure TSynCppSyn.ReSetRange; 1539begin 1540 fRange:= rsUnknown; 1541end; 1542 1543procedure TSynCppSyn.SetRange(Value: Pointer); 1544begin 1545 fRange := TRangeState(PtrUInt(Value)); 1546end; 1547 1548procedure TSynCppSyn.EnumUserSettings(settings: TStrings); 1549begin 1550 { returns the user settings that exist in the registry } 1551 with TRegistry.Create do 1552 begin 1553 try 1554 RootKey := HKEY_LOCAL_MACHINE; 1555 {$IFNDEF SYN_LAZARUS} 1556 if OpenKeyReadOnly('\SOFTWARE\Borland\C++Builder') then 1557 begin 1558 try 1559 GetKeyNames(settings); 1560 finally 1561 CloseKey; 1562 end; 1563 end; 1564 {$ENDIF} 1565 finally 1566 Free; 1567 end; 1568 end; 1569end; 1570 1571function TSynCppSyn.UseUserSettings(settingIndex: integer): boolean; 1572// Possible parameter values: 1573// index into TStrings returned by EnumUserSettings 1574// Possible return values: 1575// true : settings were read and used 1576// false: problem reading settings or invalid version specified - old settings 1577// were preserved 1578 1579 function ReadCPPBSettings(settingIndex: integer): boolean; 1580 1581 function ReadCPPBSetting(settingTag: string; attri: TSynHighlighterAttributes; key: string): boolean; 1582 1583 function ReadCPPB1(settingTag: string; attri: TSynHighlighterAttributes; name: string): boolean; 1584 var 1585 i: integer; 1586 begin 1587 for i := 1 to Length(name) do 1588 if name[i] = ' ' then name[i] := '_'; 1589 Result := attri.LoadFromBorlandRegistry(HKEY_CURRENT_USER, 1590 '\SOFTWARE\Borland\C++Builder\'+settingTag+'\Highlight',name,true); 1591 end; { ReadCPPB1 } 1592 1593 function ReadCPPB3OrMore(settingTag: string; attri: TSynHighlighterAttributes; key: string): boolean; 1594 begin 1595 Result := attri.LoadFromBorlandRegistry(HKEY_CURRENT_USER, 1596 '\Software\Borland\C++Builder\'+settingTag+'\Editor\Highlight', 1597 key,false); 1598 end; { ReadCPPB3OrMore } 1599 1600 begin { ReadCPPBSetting } 1601 try 1602 if (settingTag[1] = '1') 1603 then Result := ReadCPPB1(settingTag,attri,key) 1604 else Result := ReadCPPB3OrMore(settingTag,attri,key); 1605 except Result := false; end; 1606 end; { ReadCPPBSetting } 1607 1608 var 1609 tmpStringAttri : TSynHighlighterAttributes; 1610 tmpNumberAttri : TSynHighlighterAttributes; 1611 tmpKeyAttri : TSynHighlighterAttributes; 1612 tmpSymbolAttri : TSynHighlighterAttributes; 1613 tmpAsmAttri : TSynHighlighterAttributes; 1614 tmpCommentAttri : TSynHighlighterAttributes; 1615 tmpIdentifierAttri: TSynHighlighterAttributes; 1616 tmpInvalidAttri : TSynHighlighterAttributes; 1617 tmpSpaceAttri : TSynHighlighterAttributes; 1618 tmpDirecAttri : TSynHighlighterAttributes; 1619 s : TStringList; 1620 1621 begin { ReadCPPBSettings } 1622 s := TStringList.Create; 1623 try 1624 EnumUserSettings(s); 1625 if settingIndex >= s.Count then Result := false 1626 else begin 1627 tmpStringAttri := TSynHighlighterAttributes.Create(nil); 1628 tmpNumberAttri := TSynHighlighterAttributes.Create(nil); 1629 tmpKeyAttri := TSynHighlighterAttributes.Create(nil); 1630 tmpSymbolAttri := TSynHighlighterAttributes.Create(nil); 1631 tmpAsmAttri := TSynHighlighterAttributes.Create(nil); 1632 tmpCommentAttri := TSynHighlighterAttributes.Create(nil); 1633 tmpIdentifierAttri:= TSynHighlighterAttributes.Create(nil); 1634 tmpInvalidAttri := TSynHighlighterAttributes.Create(nil); 1635 tmpSpaceAttri := TSynHighlighterAttributes.Create(nil); 1636 tmpDirecAttri := TSynHighlighterAttributes.Create(nil); 1637 tmpStringAttri .Assign(fStringAttri); 1638 tmpNumberAttri .Assign(fNumberAttri); 1639 tmpKeyAttri .Assign(fKeyAttri); 1640 tmpSymbolAttri .Assign(fSymbolAttri); 1641 tmpAsmAttri .Assign(fAsmAttri); 1642 tmpCommentAttri .Assign(fCommentAttri); 1643 tmpIdentifierAttri.Assign(fIdentifierAttri); 1644 tmpInvalidAttri .Assign(fInvalidAttri); 1645 tmpSpaceAttri .Assign(fSpaceAttri); 1646 tmpDirecAttri .Assign(fDirecAttri); 1647 if s[settingIndex][1] = '1' 1648 then Result := ReadCPPBSetting(s[settingIndex],fAsmAttri,'Plain text') 1649 else Result := ReadCPPBSetting(s[settingIndex],fAsmAttri,'Assembler'); 1650 Result := Result and 1651 ReadCPPBSetting(s[settingIndex],fCommentAttri,'Comment') and 1652 ReadCPPBSetting(s[settingIndex],fIdentifierAttri,'Identifier') and 1653 ReadCPPBSetting(s[settingIndex],fInvalidAttri,'Illegal Char') and 1654 ReadCPPBSetting(s[settingIndex],fKeyAttri,'Reserved word') and 1655 ReadCPPBSetting(s[settingIndex],fNumberAttri,'Integer') and 1656 ReadCPPBSetting(s[settingIndex],fSpaceAttri,'Whitespace') and 1657 ReadCPPBSetting(s[settingIndex],fStringAttri,'String') and 1658 ReadCPPBSetting(s[settingIndex],fSymbolAttri,'Symbol') and 1659 ReadCPPBSetting(s[settingIndex],fDirecAttri,'Preprocessor'); 1660 if not Result then begin 1661 fStringAttri .Assign(tmpStringAttri); 1662 fNumberAttri .Assign(tmpNumberAttri); 1663 fKeyAttri .Assign(tmpKeyAttri); 1664 fSymbolAttri .Assign(tmpSymbolAttri); 1665 fAsmAttri .Assign(tmpAsmAttri); 1666 fCommentAttri .Assign(tmpCommentAttri); 1667 fIdentifierAttri.Assign(tmpIdentifierAttri); 1668 fInvalidAttri.Assign(tmpInvalidAttri); 1669 fSpaceAttri .Assign(tmpSpaceAttri); 1670 fDirecAttri .Assign(tmpDirecAttri); 1671 end; 1672 tmpStringAttri .Free; 1673 tmpNumberAttri .Free; 1674 tmpKeyAttri .Free; 1675 tmpSymbolAttri .Free; 1676 tmpAsmAttri .Free; 1677 tmpCommentAttri .Free; 1678 tmpIdentifierAttri.Free; 1679 tmpInvalidAttri .Free; 1680 tmpSpaceAttri .Free; 1681 tmpDirecAttri .Free; 1682 end; 1683 finally s.Free; end; 1684 end; { ReadCPPBSettings } 1685 1686begin 1687 Result := ReadCPPBSettings(settingIndex); 1688end; { TSynCppSyn.UseUserSettings } 1689 1690function TSynCppSyn.GetIdentChars: TSynIdentChars; 1691begin 1692 Result := ['_', '0'..'9', 'a'..'z', 'A'..'Z']; 1693end; 1694 1695class function TSynCppSyn.GetLanguageName: string; 1696begin 1697 Result := SYNS_LangCPP; 1698end; 1699 1700class function TSynCppSyn.GetCapabilities: TSynHighlighterCapabilities; 1701begin 1702 Result := inherited GetCapabilities + [hcUserSettings]; 1703end; 1704 1705initialization 1706 MakeIdentTable; 1707 RegisterPlaceableHighlighter(TSynCppSyn); 1708 1709end. 1710 1711