1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleskandars Gluchovas
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
23 #if defined( wxUSE_TEMPLATE_STL )
29 #include "sourcepainter.h"
31 const int MAX_KEYWORD_LEN
= 16;
35 char keyWord
[MAX_KEYWORD_LEN
];
39 // source fragment ranks :
45 // multil-language keywords map
47 static KeywordT __gKeyWords
[] =
119 ////////////////////////////////////////////////////
153 ////////////////////////////////////////////////////
155 { "dynamic_cast", 1 },
158 //////// some hacks for VB /////////
167 /////// data types ///////
248 { "throw", 2 }, // C++
249 { "throws", 1 }, // Java
267 //////////// meta-information //////////////
298 { "implementation", 2 },
299 { "Implementation", 2 },
300 { "IMPLEMENTATION", 2 },
357 { "[ag_slammer]",2 },
358 { "Aleksandras", 2 },
375 inline bool operator()( char* x
, char* y
) const
376 { return ( strcmp( x
,y
) < 0 );
380 #if defined( wxUSE_TEMPLATE_STL )
382 typedef map
< char*, char*, less_c_str
> KeywordMapT
;
386 typedef char* CharPtrT
;
387 typedef WXSTL_MAP( CharPtrT
, CharPtrT
,less_c_str
) KeywordMapT
;
391 static KeywordMapT __gMultiLangMap
;
392 static int __gMapReady
= 0;
394 void check_keyword_map( int keywordMapNr
)
400 // "make sure" the address of the first member of non-polimorphic class
401 // coinsides with the address of the instance
406 if ( (char*)& dummy != &dummy.keyWord[0] )
410 int size
= sizeof(__gKeyWords
) / sizeof( KeywordT
);
412 for( int i
= 0; i
!= size
; ++i
)
414 __gMultiLangMap
.insert(
415 KeywordMapT::value_type( (char*)&__gKeyWords
[i
],
416 (char*)&__gKeyWords
[i
]
422 int get_rank( char* start
, char* end
)
424 // FIXME:: what if end is no longer leagal adress?
427 *end
= '\0'; // put temporary terminator
429 KeywordMapT::iterator i
;
431 if ( (i
= __gMultiLangMap
.find( start
) ) != __gMultiLangMap
.end() )
433 KeywordT
* pKey
= (KeywordT
*)(*i
).second
;
446 static inline void store_range( SPBlockListT
& results
, int rank
, int range_len
)
448 if ( !range_len
) return;
450 results
.push_back ( ( rank
<< 16 ) | ( range_len
) );
454 #define STORE_RANGE store_range( results, cur_rank, cur_range_len );\
455 cur_rank = cur_range_len = 0;
457 #define NEXT_CHAR cur_range_len++; \
461 static inline int is_alpha( char ch
)
463 return ( (( ch
>= '_' ) && ( ch
<= 'z' )) ||
464 (( ch
>= 'A' ) && ( ch
<= 'Z' ))
469 // Ziema atEjo netikEtai
471 static void heighlight_syntax( char* str
, int strLen
,
472 SPBlockListT
& results
, bool& isComment
)
474 bool isMultiline
= 0;
476 char* end
= str
+ strLen
;
478 int cur_rank
= ( isComment
== 1 ) ? RANK_GREEN
: RANK_BLACK
;
479 int cur_range_len
= 0;
483 int has_next
= ( cur
+1 != end
);
488 if ( has_next
&& *(cur
+1) == '/' )
490 // turn off multiline comment mode
510 cur_rank = RANK_GREEN;
511 cur_range_len = end - cur;
522 if ( *(cur
+1) == '/' )
527 while ( eol
< end
&& *eol
!= 10 )
530 cur_rank
= RANK_GREEN
;
531 cur_range_len
= eol
- cur
;
538 if ( *(cur
+1) == '*' )
541 cur_rank
= RANK_GREEN
;
553 if ( ( is_alpha( *cur
) || *(cur
) == '#' )
557 if ( is_alpha( *(cur
+1) ) )
562 while ( cur
!= end
&& is_alpha(*cur
) ) ++cur
;
566 if ( (wordRank
= get_rank( start
, cur
)) > 0 )
570 store_range( results
, wordRank
, int(cur
-start
) );
571 cur_rank
= cur_range_len
= 0;
575 cur_range_len
+= ( cur
-start
);
585 if ( cur_range_len
> 0 ) STORE_RANGE
;
588 /***** Implementation for class SourcePainter ******/
590 SourcePainter::SourcePainter( bool assembleResultString
)
591 : mCollectResultsOn( assembleResultString
),
592 mIsInComment( FALSE
),
593 mCommentIsMultiline( FALSE
)
595 check_keyword_map(0);
598 void SourcePainter::ProcessSource( char* src
, int srcLen
)
600 // TBD:: multilne state...
602 heighlight_syntax( src
, srcLen
, mBlocks
, mIsInComment
);
604 if ( mCollectResultsOn
)
606 mResultStr
+= string( src
, srcLen
);
609 void SourcePainter::SetState( bool isInComment
,
610 bool commentIsMultiline
)
612 mIsInComment
= isInComment
;
613 mCommentIsMultiline
= commentIsMultiline
;
616 void SourcePainter::Init(bool assembleResultString
)
619 mCommentIsMultiline
= 0;
620 mCollectResultsOn
= assembleResultString
;
624 mBlocks
.erase( mBlocks
.begin(), mBlocks
.end() );
627 static int rank_tags_map
[] =
635 void SourcePainter::GetResultString(string
& result
, MarkupTagsT tags
)
637 // this method works, only if results of processing
639 // ASSERT( mCollectResultsOn );
644 for( size_t i
= 0; i
!= mBlocks
.size(); ++i
)
646 int desc
= mBlocks
[i
];
648 unsigned len
= desc
& 0xFFFF;
649 int rank
= (desc
>> 16) & 0xFFFF;
651 result
+= tags
[ rank_tags_map
[rank
] ].start
;
653 for( unsigned n
= 0; n
!= len
; ++n
)
655 result
+= mResultStr
[(unsigned int)(pos
+n
)];
659 result
+= tags
[ rank_tags_map
[rank
] ].end
;
663 SPBlockListT
& SourcePainter::GetBlocks()
668 bool SourcePainter::IsKeyword( char* word
, int wordLen
)
670 check_keyword_map(0);
672 int rank
= get_rank( word
, word
+ wordLen
);
674 return ( rank
== RANK_BLUE
|| rank
== RANK_RED
);