]> git.saurik.com Git - wxWidgets.git/blame - utils/HelpGen/src/sourcepainter.cpp
obsolete CW versions
[wxWidgets.git] / utils / HelpGen / src / sourcepainter.cpp
CommitLineData
cecfc5e7
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: No names yet.
3// Purpose: Contrib. demo
4// Author: Aleksandras Gluchovas
5// Modified by:
6// Created: 22/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Aleskandars Gluchovas
8ad74db3 9// Licence: wxWindows licence
cecfc5e7
VZ
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx/wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16#pragma hdrstop
17#endif
18
19#ifndef WX_PRECOMP
20#include "wx/wx.h"
21#endif
22
23#if defined( wxUSE_TEMPLATE_STL )
ad053960 24# include <map>
cecfc5e7 25#else
ad053960 26# include "wxstlac.h"
cecfc5e7
VZ
27#endif
28
29#include "sourcepainter.h"
30
31const int MAX_KEYWORD_LEN = 16;
32
33struct KeywordT
34{
8ad74db3
WS
35 char keyWord[MAX_KEYWORD_LEN];
36 int rank;
cecfc5e7
VZ
37};
38
39// source fragment ranks :
40
41// 0 - nomral text
42// 1 - basic types
43// 2 - reserved words
44
45// multil-language keywords map
46
47static KeywordT __gKeyWords[] =
48{
8ad74db3
WS
49 { "for", 1 },
50 { "FOR", 1 },
51 { "For", 1 },
52
53 { "next", 1 },
54 { "Next", 1 },
55 { "NEXT", 1 },
cecfc5e7 56
8ad74db3
WS
57 { "if", 1 },
58 { "If", 1 },
59 { "IF", 1 },
cecfc5e7 60
8ad74db3
WS
61 { "then", 1 },
62 { "Then", 1 },
63 { "THEN", 1 },
cecfc5e7 64
8ad74db3
WS
65 { "else", 1 },
66 { "Else", 1 },
67 { "ELSE", 1 },
68
69 { "do", 1 },
70 { "Do", 1 },
71 { "DO", 1 },
cecfc5e7
VZ
72
73
8ad74db3
WS
74 { "break", 1 },
75 { "Break", 1 },
76 { "BREAK", 1 },
cecfc5e7 77
8ad74db3 78 { "continue", 1 },
cecfc5e7 79
8ad74db3
WS
80 { "goto", 1 },
81 { "Goto", 1 },
82 { "GOTO", 1 },
cecfc5e7 83
8ad74db3
WS
84 { "switch", 1 },
85 { "default", 1 },
86 { "case", 1 },
cecfc5e7 87
8ad74db3
WS
88 { "repeat", 1 },
89 { "Repeat", 1 },
90 { "REPEAT", 1 },
cecfc5e7 91
8ad74db3
WS
92 { "until", 1 },
93 { "Until", 1 },
94 { "UNTIL", 1 },
cecfc5e7 95
8ad74db3
WS
96 { "return", 1 },
97 { "Return", 1 },
98 { "RETURN", 1 },
cecfc5e7 99
8ad74db3
WS
100 { "unit", 1 },
101 { "Unit", 1 },
102 { "UNIT", 1 },
cecfc5e7 103
8ad74db3
WS
104 { "procedure", 1 },
105 { "Procedure", 1 },
106 { "PROCEDURE", 1 },
cecfc5e7 107
8ad74db3
WS
108 { "function", 1 },
109 { "Function", 1 },
110 { "FUNCTION", 1 },
cecfc5e7 111
8ad74db3
WS
112 { "begin", 1 },
113 { "Begin", 1 },
114 { "BEGIN", 1 },
cecfc5e7 115
8ad74db3
WS
116 { "End", 1 },
117 { "END", 1 },
cecfc5e7 118
8ad74db3 119 ////////////////////////////////////////////////////
cecfc5e7 120
8ad74db3
WS
121 { "enum", 1 },
122 { "static", 1 },
123 { "const", 1 },
124 { "mutable", 1 },
125 { "volatile", 1 },
126 { "__asm", 1 },
127 { "asm", 1 },
cecfc5e7 128
8ad74db3
WS
129 { "typeid", 1 },
130 { "sizeof", 1 },
131 { "typeof", 1 },
cecfc5e7
VZ
132
133
8ad74db3 134 { "native", 1 },
cecfc5e7 135
8ad74db3
WS
136 { "#include", 1 },
137 { "#define", 1 },
138 { "#def", 1 },
139 { "#undef", 1 },
cecfc5e7 140 { "#ifdef", 1 },
8ad74db3
WS
141 { "#ifndef", 1 },
142 { "#if", 1 },
143 { "#endif", 1 },
144 { "#elif", 1 },
145 { "#else", 1 },
146 { "#pragma", 1 },
147 { "#line", 1 },
148
149 { "package", 1 },
150 { "import", 1 },
151 { "export", 1 },
152
153 ////////////////////////////////////////////////////
154
155 { "dynamic_cast", 1 },
156 { "const_cast", 1 },
157
158 //////// some hacks for VB /////////
159
160 { "sub", 1 },
161 { "Sub", 1 },
162 { "SUB", 1 },
163 { "as", 1 },
164 { "As", 1 },
165 { "AS", 1 },
166
167 /////// data types ///////
168
169 { "int" , 1 },
170 { "integer", 1 },
171 { "Integer", 1 },
172 { "INTEGER", 1 },
173
174 { "real", 1 },
175 { "Real", 1 },
176 { "REAL", 1 },
177
178 { "float", 1 },
179 { "Float", 1 },
180 { "FLOAT", 1 },
181
182 { "char", 1 },
183 { "Char", 1 },
184 { "CHAR", 1 },
185
186 { "register", 1 },
187
188 { "string", 1 },
189 { "String", 1 },
190 { "STRING", 1 },
cecfc5e7 191
8ad74db3
WS
192 { "array", 1 },
193 { "Array", 1 },
194 { "ARRAY", 1 },
cecfc5e7 195
8ad74db3
WS
196 { "packed", 1 },
197 { "Packed", 1 },
198 { "PACKED", 1 },
cecfc5e7 199
8ad74db3
WS
200 { "property", 1 },
201 { "Property", 1 },
202 { "PROPERTY", 1 },
cecfc5e7 203
8ad74db3 204 { "unsigned", 1 },
cecfc5e7 205
8ad74db3
WS
206 { "long", 1 },
207 { "double", 1 },
208 { "short", 1 },
209 { "bool", 1 },
cecfc5e7 210
8ad74db3
WS
211 { "longint", 1 },
212 { "Longint", 1 },
213 { "LONGINT", 1 },
cecfc5e7 214
8ad74db3
WS
215 { "extended", 1 },
216 { "Extended", 1 },
217 { "EXTENTED", 1 },
cecfc5e7 218
8ad74db3
WS
219 { "pointer", 1 },
220 { "Pointer", 1 },
221 { "POINTER", 1 },
cecfc5e7 222
8ad74db3
WS
223 { "and", 1 },
224 { "And", 1 },
225 { "AND", 1 },
226 { "or", 1 },
227 { "Or", 1 },
228 { "OR", 1 },
229 { "xor", 1 },
230 { "Xor", 1 },
231 { "XOR", 1 },
232
233 { "void", 1 },
234 { "__stdcall", 1 },
235 { "__declspec", 1 },
236 { "extern", 1 },
237 { "stdcall", 1 },
238 { "dllimport", 1 },
239 { "dllexport", 1 },
240 { "__cdecl", 1 },
241 { "cdecl", 1 },
242 { "template", 1 },
243 { "typedef", 1 },
244 { "naked", 1 },
245
246 { "try", 1 },
247 { "catch", 1 },
248 { "throw", 2 }, // C++
249 { "throws", 1 }, // Java
250
251
252 { "finalize", 1 },
253
254 // "STL-suport"
255
256 { "size_t", 1 },
257 { "NPOS", 1 },
258 { "vector", 1 },
259 { "list", 1 },
260 { "map", 1 },
261 { "multimap", 1 },
262
263 { "external", 1 },
264 { "External", 1 },
265 { "EXTERNAL", 1 },
266
267 //////////// meta-information //////////////
268
269 { "virtual", 2 },
270 { "Virtual", 2 },
271
272 { "override", 2 },
273 { "Override", 2 },
274
275 { "class", 2 },
276 { "Class", 2 },
277 { "CLASS", 2 },
278
279 { "struct", 2 },
280 { "union", 2 },
281
282 { "record", 2 },
283 { "Record", 2 },
284 { "RECORD", 2 },
285
286 { "form", 1 },
287 { "Form", 1 },
288 { "FORM", 1 },
289
290 { "namespace", 2 },
291
292 { "interface" , 2 },
293 { "abstract", 2 },
294
295 { "Interface" , 2 },
296 { "INTERFACE" , 2 },
297
298 { "implementation", 2 },
299 { "Implementation", 2 },
300 { "IMPLEMENTATION", 2 },
301
302 { "label", 2 },
303 { "Label", 2 },
304 { "LABEL", 2 },
305
306 { "implements", 2 },
307
308 { "public", 2 },
309 { "private", 2 },
310 { "protected", 2 },
311
312 { "this", 2 },
313 { "This", 2 },
314 { "THIS", 2 },
315
316 { "new", 2 },
317 { "New", 2 },
318 { "NEW", 2 },
319
320 { "delete", 2 },
321 { "inline", 2 },
322
323 { "operator", 2 },
324
325 { "Inherited", 2 },
326 { "Inherited", 2 },
327
328 { "final", 2 },
329 { "implements", 2 },
330 { "super", 2 },
331
332 // even more...
333 { "java", 2 },
334 { "Java", 2 },
335 { "JAVA", 2 },
336 { "delphi", 2 },
337 { "Delphi", 2 },
338 { "SmallTalk", 2 },
339 { "Smalltalk", 2 },
340 { "smalltalk", 2 },
341 { "assembler", 2 },
342 { "Assembler", 2 },
343 { "Basic", 2 },
344 { "BASIC", 2 },
345 { "basic", 2 },
346 { "CORBA", 2 },
347 { "COBOL", 2 },
348 { "ADA", 2 },
349 { "LISP", 2 },
350
351 // just for fun...
352 { "life", 2 },
353 { "sucks", 2 },
354 { "rules", 2 },
355 { "Quake", 2 },
356 { "QuakeWorld", 2 },
357 { "[ag_slammer]",2 },
358 { "Aleksandras", 2 },
359 { "Gluchovas" , 2 },
360 { "Alex", 2 },
361 { "alex", 2 },
362 { "aleks", 2 },
363 { "aleksas", 3 },
364 { "AlexSoft", 2 },
365 { "Alexsoft", 2 },
366 { "SpringSky", 2 },
367 { "SK_Team", 2 },
368 { "soften", 2 },
369 { "UB40", 2 },
370 { "U96", 2 }
cecfc5e7
VZ
371};
372
8ad74db3 373struct less_c_str
cecfc5e7 374{
8ad74db3
WS
375 inline bool operator()( char* x, char* y) const
376 { return ( strcmp( x,y ) < 0 );
377 }
cecfc5e7
VZ
378};
379
380#if defined( wxUSE_TEMPLATE_STL )
381
8ad74db3 382 typedef map< char*, char*, less_c_str > KeywordMapT;
cecfc5e7
VZ
383
384#else
385
8ad74db3
WS
386 typedef char* CharPtrT;
387 typedef WXSTL_MAP( CharPtrT, CharPtrT ,less_c_str) KeywordMapT;
cecfc5e7
VZ
388
389#endif
390
391static KeywordMapT __gMultiLangMap;
392static int __gMapReady = 0;
393
8ad74db3 394void check_keyword_map( int WXUNUSED(keywordMapNr) )
cecfc5e7 395{
8ad74db3
WS
396 if ( !__gMapReady )
397 {
398 __gMapReady = 1;
cecfc5e7 399
8ad74db3
WS
400 // "make sure" the address of the first member of non-polimorphic class
401 // coinsides with the address of the instance
cecfc5e7 402
a7adaeda 403/*
8ad74db3 404 KeywordT dummy;
cecfc5e7 405
8ad74db3
WS
406 if ( (char*)& dummy != &dummy.keyWord[0] )
407 throw;
a5a0dd06 408*/
cecfc5e7 409
8ad74db3 410 int size = sizeof(__gKeyWords) / sizeof( KeywordT );
cecfc5e7 411
8ad74db3 412 for( int i = 0; i != size; ++i )
cecfc5e7 413
8ad74db3
WS
414 __gMultiLangMap.insert(
415 KeywordMapT::value_type( (char*)&__gKeyWords[i],
416 (char*)&__gKeyWords[i]
417 )
418 );
419 }
cecfc5e7
VZ
420}
421
422int get_rank( char* start, char* end )
423{
8ad74db3 424 // FIXME:: what if end is no longer leagal adress?
cecfc5e7 425
8ad74db3
WS
426 char tmp = *end;
427 *end = '\0'; // put temporary terminator
cecfc5e7 428
8ad74db3 429 KeywordMapT::iterator i;
cecfc5e7 430
8ad74db3
WS
431 if ( (i = __gMultiLangMap.find( start ) ) != __gMultiLangMap.end() )
432 {
433 KeywordT* pKey = (KeywordT*)(*i).second;
cecfc5e7 434
8ad74db3 435 *end = tmp;
cecfc5e7 436
8ad74db3
WS
437 return pKey->rank;
438 }
439 else
440 {
441 *end = tmp;
442 return 0;
443 }
cecfc5e7
VZ
444}
445
446static inline void store_range( SPBlockListT& results, int rank, int range_len )
447{
8ad74db3 448 if ( !range_len ) return;
cecfc5e7 449
8ad74db3 450 results.push_back ( ( rank << 16 ) | ( range_len ) );
cecfc5e7
VZ
451}
452
453
8ad74db3
WS
454#define STORE_RANGE store_range( results, cur_rank, cur_range_len ); \
455 cur_rank = cur_range_len = 0; \
456 wxUnusedVar( cur_rank );
cecfc5e7
VZ
457
458#define NEXT_CHAR cur_range_len++; \
8ad74db3
WS
459 ++cur; \
460 continue;
cecfc5e7
VZ
461
462static inline int is_alpha( char ch )
463{
8ad74db3
WS
464 return ( (( ch >= '_' ) && ( ch <= 'z' )) ||
465 (( ch >= 'A' ) && ( ch <= 'Z' ))
466 );
cecfc5e7
VZ
467}
468
8ad74db3 469 // _ . .
cecfc5e7
VZ
470 // Ziema atEjo netikEtai
471
8ad74db3
WS
472static void heighlight_syntax( char* str, int strLen,
473 SPBlockListT& results, bool& isComment )
cecfc5e7 474{
8ad74db3
WS
475 bool isMultiline = false;
476 char* cur = str;
477 char* end = str + strLen;
478
479 int cur_rank = ( isComment == 1 ) ? RANK_GREEN : RANK_BLACK;
480 int cur_range_len = 0;
481
482 while ( cur != end )
483 {
484 int has_next = ( cur+1 != end );
485
486 if ( isComment )
487 {
488 if ( *cur == '*' )
489 if ( has_next && *(cur+1) == '/' )
490 {
491 // turn off multiline comment mode
492 cur += 2;
493 cur_range_len += 2;
494 isComment = 0;
495 isMultiline = 0;
496 STORE_RANGE;
497
498 continue;
499 }
500
501 ++cur_range_len;
502 ++cur;
503 continue;
504 }
505
506 /*
507 if ( *cur == 10 )
508 if ( isComment )
509 if ( isMultiline )
510 {
511 cur_rank = RANK_GREEN;
512 cur_range_len = end - cur;
513 STORE_RANGE;
514 isComment = 0;
515 isMultiline = 0;
516 continue;
517 }*/
518
519 if ( *cur == '/' )
520 {
521 if ( has_next )
522 {
523 if ( *(cur+1) == '/' )
524 {
525 STORE_RANGE;
526
527 char* eol = cur;
528 while ( eol < end && *eol != 10 )
529 ++eol;
530
531 cur_rank = RANK_GREEN;
532 cur_range_len = eol - cur;
533 cur = eol;
534 STORE_RANGE;
535
536 continue;
537 }
538
539 if ( *(cur+1) == '*' )
540 {
541 STORE_RANGE;
542 cur_rank = RANK_GREEN;
543 cur_range_len = 2;
544 isComment = 1;
545 cur += 2;
546 isMultiline = 1;
547 continue;
548 }
549 }
550
551 NEXT_CHAR;
552 }
553
554 if ( ( is_alpha( *cur ) || *(cur) == '#' )
555 && has_next
556 )
557 {
558 if ( is_alpha( *(cur+1) ) )
559 {
560 char* start = cur;
561 cur += 2;
562
563 while ( cur != end && is_alpha(*cur) ) ++cur;
564
565 int wordRank;
566
567 if ( (wordRank = get_rank( start, cur )) > 0 )
568 {
569 STORE_RANGE;
570
571 store_range( results, wordRank, int(cur-start) );
572 cur_rank = cur_range_len = 0;
573 continue;
574 }
575
576 cur_range_len += ( cur-start );
577 continue;
578 }
579 else
580 NEXT_CHAR;
581 }
582
583 NEXT_CHAR;
584 }
585
586 if ( cur_range_len > 0 ) STORE_RANGE;
587
588 wxUnusedVar(isMultiline);
cecfc5e7
VZ
589}
590
591/***** Implementation for class SourcePainter ******/
592
593SourcePainter::SourcePainter( bool assembleResultString )
8ad74db3
WS
594 : mCollectResultsOn( assembleResultString ),
595 mIsInComment( false ),
596 mCommentIsMultiline( false )
cecfc5e7 597{
8ad74db3 598 check_keyword_map(0);
cecfc5e7
VZ
599}
600
601void SourcePainter::ProcessSource( char* src, int srcLen )
602{
8ad74db3 603 // TBD:: multilne state...
cecfc5e7 604
8ad74db3 605 heighlight_syntax( src, srcLen, mBlocks, mIsInComment );
cecfc5e7 606
8ad74db3
WS
607 if ( mCollectResultsOn )
608
609 mResultStr += string( src, srcLen );
cecfc5e7
VZ
610}
611
612void SourcePainter::SetState( bool isInComment,
8ad74db3 613 bool commentIsMultiline )
cecfc5e7 614{
8ad74db3
WS
615 mIsInComment = isInComment;
616 mCommentIsMultiline = commentIsMultiline;
cecfc5e7
VZ
617}
618
619void SourcePainter::Init(bool assembleResultString)
620{
8ad74db3
WS
621 mIsInComment = 0;
622 mCommentIsMultiline = 0;
623 mCollectResultsOn = assembleResultString;
cecfc5e7 624
8ad74db3 625 mResultStr = "";
cecfc5e7 626
8ad74db3 627 mBlocks.erase( mBlocks.begin(), mBlocks.end() );
cecfc5e7
VZ
628}
629
8ad74db3
WS
630static int rank_tags_map[] =
631{
632 TAG_BLACK_FONT,
633 TAG_BLUE_FONT,
634 TAG_RED_FONT,
635 TAG_GREEN_FONT
cecfc5e7
VZ
636};
637
638void SourcePainter::GetResultString(string& result, MarkupTagsT tags)
639{
8ad74db3
WS
640 // this method works, only if results of processing
641 // are collected
642 // ASSERT( mCollectResultsOn );
643 result = "";
cecfc5e7 644
8ad74db3 645 unsigned pos = 0;
cecfc5e7 646
8ad74db3
WS
647 for( size_t i = 0; i != mBlocks.size(); ++i )
648 {
649 int desc = mBlocks[i];
cecfc5e7 650
8ad74db3
WS
651 unsigned len = desc & 0xFFFF;
652 int rank = (desc >> 16) & 0xFFFF;
cecfc5e7 653
8ad74db3 654 result += tags[ rank_tags_map[rank] ].start;
cecfc5e7 655
8ad74db3
WS
656 for( unsigned n = 0; n != len; ++n )
657
658 result += mResultStr[(unsigned int)(pos+n)];
cecfc5e7 659
8ad74db3 660 pos += len;
cecfc5e7 661
8ad74db3
WS
662 result += tags[ rank_tags_map[rank] ].end;
663 }
cecfc5e7
VZ
664}
665
666SPBlockListT& SourcePainter::GetBlocks()
667{
8ad74db3 668 return mBlocks;
cecfc5e7
VZ
669}
670
671bool SourcePainter::IsKeyword( char* word, int wordLen )
672{
8ad74db3 673 check_keyword_map(0);
cecfc5e7 674
8ad74db3 675 int rank = get_rank( word, word + wordLen );
cecfc5e7 676
8ad74db3 677 return ( rank == RANK_BLUE || rank == RANK_RED );
cecfc5e7 678}