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 )
32 #include "sourcepainter.h"
34 const int MAX_KEYWORD_LEN
= 16;
38 char keyWord
[MAX_KEYWORD_LEN
];
42 // source fragment ranks :
48 // multil-language keywords map
50 static KeywordT __gKeyWords
[] =
122 ////////////////////////////////////////////////////
156 ////////////////////////////////////////////////////
158 { "dynamic_cast", 1 },
161 //////// some hacks for VB /////////
170 /////// data types ///////
251 { "throw", 2 }, // C++
252 { "throws", 1 }, // Java
270 //////////// meta-information //////////////
301 { "implementation", 2 },
302 { "Implementation", 2 },
303 { "IMPLEMENTATION", 2 },
360 { "[ag_slammer]",2 },
361 { "Aleksandras", 2 },
378 inline bool operator()( char* x
, char* y
) const
379 { return ( strcmp( x
,y
) < 0 );
383 #if defined( wxUSE_TEMPLATE_STL )
385 typedef map
< char*, char*, less_c_str
> KeywordMapT
;
389 typedef char* CharPtrT
;
390 typedef WXSTL_MAP( CharPtrT
, CharPtrT
,less_c_str
) KeywordMapT
;
394 static KeywordMapT __gMultiLangMap
;
395 static int __gMapReady
= 0;
397 void check_keyword_map( int keywordMapNr
)
403 // "make sure" the address of the first member of non-polimorphic class
404 // coinsides with the address of the instance
408 if ( (char*)& dummy
!= &dummy
.keyWord
[0] )
411 int size
= sizeof(__gKeyWords
) / sizeof( KeywordT
);
413 for( int i
= 0; i
!= size
; ++i
)
415 __gMultiLangMap
.insert(
416 KeywordMapT::value_type( (char*)&__gKeyWords
[i
],
417 (char*)&__gKeyWords
[i
]
423 int get_rank( char* start
, char* end
)
425 // FIXME:: what if end is no longer leagal adress?
428 *end
= '\0'; // put temporary terminator
430 KeywordMapT::iterator i
;
432 if ( (i
= __gMultiLangMap
.find( start
) ) != __gMultiLangMap
.end() )
434 KeywordT
* pKey
= (KeywordT
*)(*i
).second
;
447 static inline void store_range( SPBlockListT
& results
, int rank
, int range_len
)
449 if ( !range_len
) return;
451 results
.push_back ( ( rank
<< 16 ) | ( range_len
) );
455 #define STORE_RANGE store_range( results, cur_rank, cur_range_len );\
456 cur_rank = cur_range_len = 0;
458 #define NEXT_CHAR cur_range_len++; \
462 static inline int is_alpha( char ch
)
464 return ( (( ch
>= '_' ) && ( ch
<= 'z' )) ||
465 (( ch
>= 'A' ) && ( ch
<= 'Z' ))
470 // Ziema atEjo netikEtai
472 static void heighlight_syntax( char* str
, int strLen
,
473 SPBlockListT
& results
, bool& isComment
)
475 bool isMultiline
= 0;
477 char* end
= str
+ strLen
;
479 int cur_rank
= ( isComment
== 1 ) ? RANK_GREEN
: RANK_BLACK
;
480 int cur_range_len
= 0;
484 int has_next
= ( cur
+1 != end
);
489 if ( has_next
&& *(cur
+1) == '/' )
491 // turn off multiline comment mode
511 cur_rank = RANK_GREEN;
512 cur_range_len = end - cur;
523 if ( *(cur
+1) == '/' )
528 while ( eol
< end
&& *eol
!= 10 )
531 cur_rank
= RANK_GREEN
;
532 cur_range_len
= eol
- cur
;
539 if ( *(cur
+1) == '*' )
542 cur_rank
= RANK_GREEN
;
554 if ( ( is_alpha( *cur
) || *(cur
) == '#' )
558 if ( is_alpha( *(cur
+1) ) )
563 while ( cur
!= end
&& is_alpha(*cur
) ) ++cur
;
567 if ( (wordRank
= get_rank( start
, cur
)) > 0 )
571 store_range( results
, wordRank
, int(cur
-start
) );
572 cur_rank
= cur_range_len
= 0;
576 cur_range_len
+= ( cur
-start
);
586 if ( cur_range_len
> 0 ) STORE_RANGE
;
589 /***** Implementation for class SourcePainter ******/
591 SourcePainter::SourcePainter( bool assembleResultString
)
592 : mCollectResultsOn( assembleResultString
),
593 mIsInComment( FALSE
),
594 mCommentIsMultiline( FALSE
)
596 check_keyword_map(0);
599 void SourcePainter::ProcessSource( char* src
, int srcLen
)
601 // TBD:: multilne state...
603 heighlight_syntax( src
, srcLen
, mBlocks
, mIsInComment
);
605 if ( mCollectResultsOn
)
607 mResultStr
+= string( src
, srcLen
);
610 void SourcePainter::SetState( bool isInComment
,
611 bool commentIsMultiline
)
613 mIsInComment
= isInComment
;
614 mCommentIsMultiline
= commentIsMultiline
;
617 void SourcePainter::Init(bool assembleResultString
)
620 mCommentIsMultiline
= 0;
621 mCollectResultsOn
= assembleResultString
;
625 mBlocks
.erase( mBlocks
.begin(), mBlocks
.end() );
628 static int rank_tags_map
[] =
636 void SourcePainter::GetResultString(string
& result
, MarkupTagsT tags
)
638 // this method works, only if results of processing
640 ASSERT( mCollectResultsOn
);
645 for( size_t i
= 0; i
!= mBlocks
.size(); ++i
)
647 int desc
= mBlocks
[i
];
649 int len
= desc
& 0xFFFF;
650 int rank
= (desc
>> 16) & 0xFFFF;
652 result
+= tags
[ rank_tags_map
[rank
] ].start
;
654 for( int n
= 0; n
!= len
; ++n
)
656 result
+= mResultStr
[pos
+n
];
660 result
+= tags
[ rank_tags_map
[rank
] ].end
;
664 SPBlockListT
& SourcePainter::GetBlocks()
669 bool SourcePainter::IsKeyword( char* word
, int wordLen
)
671 check_keyword_map(0);
673 int rank
= get_rank( word
, word
+ wordLen
);
675 return ( rank
== RANK_BLUE
|| rank
== RANK_RED
);