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 WXUNUSED(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; \
456 wxUnusedVar( cur_rank );
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
= false;
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
;
588 wxUnusedVar(isMultiline
);
591 /***** Implementation for class SourcePainter ******/
593 SourcePainter::SourcePainter( bool assembleResultString
)
594 : mCollectResultsOn( assembleResultString
),
595 mIsInComment( false ),
596 mCommentIsMultiline( false )
598 check_keyword_map(0);
601 void SourcePainter::ProcessSource( char* src
, int srcLen
)
603 // TBD:: multilne state...
605 heighlight_syntax( src
, srcLen
, mBlocks
, mIsInComment
);
607 if ( mCollectResultsOn
)
609 mResultStr
+= wxString( src
, srcLen
);
612 void SourcePainter::SetState( bool isInComment
,
613 bool commentIsMultiline
)
615 mIsInComment
= isInComment
;
616 mCommentIsMultiline
= commentIsMultiline
;
619 void SourcePainter::Init(bool assembleResultString
)
622 mCommentIsMultiline
= 0;
623 mCollectResultsOn
= assembleResultString
;
625 mResultStr
= wxEmptyString
;
627 mBlocks
.erase( mBlocks
.begin(), mBlocks
.end() );
630 static int rank_tags_map
[] =
638 void SourcePainter::GetResultString(wxString
& result
, MarkupTagsT tags
)
640 // this method works, only if results of processing
642 // ASSERT( mCollectResultsOn );
643 result
= wxEmptyString
;
647 for( size_t i
= 0; i
!= mBlocks
.size(); ++i
)
649 int desc
= mBlocks
[i
];
651 unsigned len
= desc
& 0xFFFF;
652 int rank
= (desc
>> 16) & 0xFFFF;
654 result
+= tags
[ rank_tags_map
[rank
] ].start
;
656 for( unsigned n
= 0; n
!= len
; ++n
)
658 result
+= mResultStr
[(unsigned int)(pos
+n
)];
663 result
+= tags
[ rank_tags_map
[rank
] ].end
;
667 SPBlockListT
& SourcePainter::GetBlocks()
672 bool SourcePainter::IsKeyword( char* word
, int wordLen
)
674 check_keyword_map(0);
676 int rank
= get_rank( word
, word
+ wordLen
);
678 return ( rank
== RANK_BLUE
|| rank
== RANK_RED
);