lots'o' wxpython modules files
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3345 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
696
utils/wxPython/modules/lseditor/sourcepainter.cpp
Normal file
696
utils/wxPython/modules/lseditor/sourcepainter.cpp
Normal file
@@ -0,0 +1,696 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: No names yet.
|
||||
// Purpose: Contrib. demo
|
||||
// Author: Aleksandras Gluchovas
|
||||
// Modified by:
|
||||
// Created: 22/09/98
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) Aleksandars Gluchovas
|
||||
// Licence: GNU General Public License
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if defined( wxUSE_TEMPLATE_STL )
|
||||
|
||||
#include <map>
|
||||
using namespace std;
|
||||
#else
|
||||
|
||||
#include <wxstlac.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include "sourcepainter.h"
|
||||
|
||||
const int MAX_KEYWORD_LEN = 16;
|
||||
|
||||
struct KeywordT
|
||||
{
|
||||
char keyWord[MAX_KEYWORD_LEN];
|
||||
int rank;
|
||||
};
|
||||
|
||||
// source fragment ranks :
|
||||
|
||||
// 0 - nomral text
|
||||
// 1 - basic types
|
||||
// 2 - reserved words
|
||||
|
||||
// multil-language keywords map
|
||||
|
||||
static KeywordT __gKeyWords[] =
|
||||
{
|
||||
{ "for", 1 },
|
||||
{ "FOR", 1 },
|
||||
{ "For", 1 },
|
||||
|
||||
{ "next", 1 },
|
||||
{ "Next", 1 },
|
||||
{ "NEXT", 1 },
|
||||
|
||||
{ "if", 1 },
|
||||
{ "If", 1 },
|
||||
{ "IF", 1 },
|
||||
|
||||
{ "then", 1 },
|
||||
{ "Then", 1 },
|
||||
{ "THEN", 1 },
|
||||
|
||||
{ "else", 1 },
|
||||
{ "Else", 1 },
|
||||
{ "ELSE", 1 },
|
||||
|
||||
{ "do", 1 },
|
||||
{ "Do", 1 },
|
||||
{ "DO", 1 },
|
||||
|
||||
|
||||
{ "break", 1 },
|
||||
{ "Break", 1 },
|
||||
{ "BREAK", 1 },
|
||||
|
||||
{ "continue", 1 },
|
||||
|
||||
{ "goto", 1 },
|
||||
{ "Goto", 1 },
|
||||
{ "GOTO", 1 },
|
||||
|
||||
{ "switch", 1 },
|
||||
{ "default", 1 },
|
||||
{ "case", 1 },
|
||||
|
||||
{ "repeat", 1 },
|
||||
{ "Repeat", 1 },
|
||||
{ "REPEAT", 1 },
|
||||
|
||||
{ "until", 1 },
|
||||
{ "Until", 1 },
|
||||
{ "UNTIL", 1 },
|
||||
|
||||
{ "return", 1 },
|
||||
{ "Return", 1 },
|
||||
{ "RETURN", 1 },
|
||||
|
||||
{ "unit", 1 },
|
||||
{ "Unit", 1 },
|
||||
{ "UNIT", 1 },
|
||||
|
||||
{ "procedure", 1 },
|
||||
{ "Procedure", 1 },
|
||||
{ "PROCEDURE", 1 },
|
||||
|
||||
{ "function", 1 },
|
||||
{ "Function", 1 },
|
||||
{ "FUNCTION", 1 },
|
||||
|
||||
{ "begin", 1 },
|
||||
{ "Begin", 1 },
|
||||
{ "BEGIN", 1 },
|
||||
|
||||
{ "End", 1 },
|
||||
{ "END", 1 },
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
{ "enum", 1 },
|
||||
{ "static", 1 },
|
||||
{ "const", 1 },
|
||||
{ "mutable", 1 },
|
||||
{ "volatile", 1 },
|
||||
{ "__asm", 1 },
|
||||
{ "asm", 1 },
|
||||
|
||||
{ "typeid", 1 },
|
||||
{ "sizeof", 1 },
|
||||
{ "typeof", 1 },
|
||||
|
||||
|
||||
{ "native", 1 },
|
||||
|
||||
{ "#include", 1 },
|
||||
{ "#define", 1 },
|
||||
{ "#def", 1 },
|
||||
{ "#undef", 1 },
|
||||
{ "#ifdef", 1 },
|
||||
{ "#ifndef", 1 },
|
||||
{ "#if", 1 },
|
||||
{ "#endif", 1 },
|
||||
{ "#elif", 1 },
|
||||
{ "#else", 1 },
|
||||
{ "#pragma", 1 },
|
||||
{ "#line", 1 },
|
||||
|
||||
{ "package", 1 },
|
||||
{ "import", 1 },
|
||||
{ "export", 1 },
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
{ "dynamic_cast", 1 },
|
||||
{ "const_cast", 1 },
|
||||
|
||||
//////// some hacks for VB /////////
|
||||
|
||||
{ "sub", 1 },
|
||||
{ "Sub", 1 },
|
||||
{ "SUB", 1 },
|
||||
{ "as", 1 },
|
||||
{ "As", 1 },
|
||||
{ "AS", 1 },
|
||||
|
||||
/////// data types ///////
|
||||
|
||||
{ "int" , 1 },
|
||||
{ "integer", 1 },
|
||||
{ "Integer", 1 },
|
||||
{ "INTEGER", 1 },
|
||||
|
||||
{ "real", 1 },
|
||||
{ "Real", 1 },
|
||||
{ "REAL", 1 },
|
||||
|
||||
{ "float", 1 },
|
||||
{ "Float", 1 },
|
||||
{ "FLOAT", 1 },
|
||||
|
||||
{ "char", 1 },
|
||||
{ "Char", 1 },
|
||||
{ "CHAR", 1 },
|
||||
|
||||
{ "register", 1 },
|
||||
|
||||
{ "string", 1 },
|
||||
{ "String", 1 },
|
||||
{ "STRING", 1 },
|
||||
|
||||
{ "array", 1 },
|
||||
{ "Array", 1 },
|
||||
{ "ARRAY", 1 },
|
||||
|
||||
{ "packed", 1 },
|
||||
{ "Packed", 1 },
|
||||
{ "PACKED", 1 },
|
||||
|
||||
{ "property", 1 },
|
||||
{ "Property", 1 },
|
||||
{ "PROPERTY", 1 },
|
||||
|
||||
{ "unsigned", 1 },
|
||||
|
||||
{ "long", 1 },
|
||||
{ "double", 1 },
|
||||
{ "short", 1 },
|
||||
{ "bool", 1 },
|
||||
|
||||
{ "longint", 1 },
|
||||
{ "Longint", 1 },
|
||||
{ "LONGINT", 1 },
|
||||
|
||||
{ "extended", 1 },
|
||||
{ "Extended", 1 },
|
||||
{ "EXTENTED", 1 },
|
||||
|
||||
{ "pointer", 1 },
|
||||
{ "Pointer", 1 },
|
||||
{ "POINTER", 1 },
|
||||
|
||||
{ "and", 1 },
|
||||
{ "And", 1 },
|
||||
{ "AND", 1 },
|
||||
{ "or", 1 },
|
||||
{ "Or", 1 },
|
||||
{ "OR", 1 },
|
||||
{ "xor", 1 },
|
||||
{ "Xor", 1 },
|
||||
{ "XOR", 1 },
|
||||
|
||||
{ "void", 1 },
|
||||
{ "__stdcall", 1 },
|
||||
{ "__declspec", 1 },
|
||||
{ "extern", 1 },
|
||||
{ "stdcall", 1 },
|
||||
{ "dllimport", 1 },
|
||||
{ "dllexport", 1 },
|
||||
{ "__cdecl", 1 },
|
||||
{ "cdecl", 1 },
|
||||
{ "template", 1 },
|
||||
{ "typedef", 1 },
|
||||
{ "naked", 1 },
|
||||
|
||||
{ "try", 1 },
|
||||
{ "catch", 1 },
|
||||
{ "throw", 2 }, // C++
|
||||
{ "throws", 1 }, // Java
|
||||
|
||||
|
||||
{ "finalize", 1 },
|
||||
|
||||
// "STL-suport"
|
||||
|
||||
{ "size_t", 1 },
|
||||
{ "NPOS", 1 },
|
||||
{ "vector", 1 },
|
||||
{ "list", 1 },
|
||||
{ "map", 1 },
|
||||
{ "multimap", 1 },
|
||||
|
||||
{ "external", 1 },
|
||||
{ "External", 1 },
|
||||
{ "EXTERNAL", 1 },
|
||||
|
||||
//////////// meta-information //////////////
|
||||
|
||||
{ "virtual", 2 },
|
||||
{ "Virtual", 2 },
|
||||
|
||||
{ "override", 2 },
|
||||
{ "Override", 2 },
|
||||
|
||||
{ "class", 2 },
|
||||
{ "Class", 2 },
|
||||
{ "CLASS", 2 },
|
||||
|
||||
{ "struct", 2 },
|
||||
{ "union", 2 },
|
||||
|
||||
{ "record", 2 },
|
||||
{ "Record", 2 },
|
||||
{ "RECORD", 2 },
|
||||
|
||||
{ "form", 1 },
|
||||
{ "Form", 1 },
|
||||
{ "FORM", 1 },
|
||||
|
||||
{ "namespace", 2 },
|
||||
|
||||
{ "interface" , 2 },
|
||||
{ "abstract", 2 },
|
||||
|
||||
{ "Interface" , 2 },
|
||||
{ "INTERFACE" , 2 },
|
||||
|
||||
{ "implementation", 2 },
|
||||
{ "Implementation", 2 },
|
||||
{ "IMPLEMENTATION", 2 },
|
||||
|
||||
{ "label", 2 },
|
||||
{ "Label", 2 },
|
||||
{ "LABEL", 2 },
|
||||
|
||||
{ "implements", 2 },
|
||||
{ "extends", 2 },
|
||||
|
||||
{ "public", 2 },
|
||||
{ "private", 2 },
|
||||
{ "protected", 2 },
|
||||
|
||||
{ "this", 1 },
|
||||
{ "This", 1 },
|
||||
{ "THIS", 1 },
|
||||
|
||||
{ "new", 1 },
|
||||
{ "New", 1 },
|
||||
{ "NEW", 1 },
|
||||
|
||||
{ "delete", 2 },
|
||||
{ "inline", 2 },
|
||||
|
||||
{ "operator", 1 },
|
||||
|
||||
{ "Inherited", 2 },
|
||||
{ "Inherited", 2 },
|
||||
|
||||
{ "final", 2 },
|
||||
{ "implements", 2 },
|
||||
{ "super", 2 },
|
||||
|
||||
// even more...
|
||||
{ "java", 2 },
|
||||
{ "Java", 2 },
|
||||
{ "JAVA", 2 },
|
||||
{ "delphi", 2 },
|
||||
{ "Delphi", 2 },
|
||||
{ "SmallTalk", 2 },
|
||||
{ "Smalltalk", 2 },
|
||||
{ "smalltalk", 2 },
|
||||
{ "assembler", 2 },
|
||||
{ "Assembler", 2 },
|
||||
{ "Basic", 2 },
|
||||
{ "BASIC", 2 },
|
||||
{ "basic", 2 },
|
||||
{ "CORBA", 2 },
|
||||
{ "COBOL", 2 },
|
||||
{ "ADA", 2 },
|
||||
{ "LISP", 2 },
|
||||
|
||||
// just for fun...
|
||||
{ "life", 2 },
|
||||
{ "sucks", 2 },
|
||||
{ "rules", 2 },
|
||||
{ "Quake", 2 },
|
||||
{ "QuakeWorld", 2 },
|
||||
{ "[ag_slammer]",2 },
|
||||
{ "Aleksandras", 2 },
|
||||
{ "Gluchovas" , 2 },
|
||||
{ "Alex", 2 },
|
||||
{ "alex", 2 },
|
||||
{ "aleks", 2 },
|
||||
{ "aleksas", 3 },
|
||||
{ "AlexSoft", 2 },
|
||||
{ "Alexsoft", 2 },
|
||||
{ "SpringSky", 2 },
|
||||
{ "SK_Team", 2 },
|
||||
{ "soften", 2 },
|
||||
{ "UB40", 2 },
|
||||
{ "U96", 2 }
|
||||
};
|
||||
|
||||
struct less_c_str
|
||||
{
|
||||
inline bool operator()( char* x, char* y) const
|
||||
{ return ( strcmp( x,y ) < 0 );
|
||||
}
|
||||
};
|
||||
|
||||
#if defined( wxUSE_TEMPLATE_STL )
|
||||
|
||||
typedef map< char*, char*, less_c_str > KeywordMapT;
|
||||
|
||||
#else
|
||||
|
||||
typedef char* CharPtrT;
|
||||
typedef WXSTL_MAP( CharPtrT, CharPtrT ,less_c_str) KeywordMapT;
|
||||
|
||||
#endif
|
||||
|
||||
static KeywordMapT __gMultiLangMap;
|
||||
static int __gMapReady = 0;
|
||||
|
||||
void check_keyword_map( int keywordMapNr )
|
||||
{
|
||||
if ( !__gMapReady )
|
||||
{
|
||||
__gMapReady = 1;
|
||||
|
||||
// "make sure" the address of the first member of non-polimorphic class
|
||||
// coinsides with the address of the instance
|
||||
|
||||
KeywordT dummy;
|
||||
|
||||
if ( (char*)& dummy != &dummy.keyWord[0] )
|
||||
throw;
|
||||
|
||||
int size = sizeof(__gKeyWords) / sizeof( KeywordT );
|
||||
|
||||
for( int i = 0; i != size; ++i )
|
||||
|
||||
__gMultiLangMap.insert(
|
||||
KeywordMapT::value_type( (char*)&__gKeyWords[i],
|
||||
(char*)&__gKeyWords[i]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
int get_rank( char* start, char* end )
|
||||
{
|
||||
// FIXME:: what if end is no longer leagal adress?
|
||||
|
||||
char tmp = *end;
|
||||
*end = '\0'; // put temporary terminator
|
||||
|
||||
KeywordMapT::iterator i;
|
||||
|
||||
if ( (i = __gMultiLangMap.find( start ) ) != __gMultiLangMap.end() )
|
||||
{
|
||||
KeywordT* pKey = (KeywordT*)(*i).second;
|
||||
|
||||
*end = tmp;
|
||||
|
||||
return pKey->rank;
|
||||
}
|
||||
else
|
||||
{
|
||||
*end = tmp;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void store_range( IntListT& results, int rank, int range_len )
|
||||
{
|
||||
if ( !range_len ) return;
|
||||
|
||||
results.push_back ( ( rank << 16 ) | ( range_len ) );
|
||||
}
|
||||
|
||||
|
||||
#define STORE_RANGE store_range( results, cur_rank, cur_range_len );\
|
||||
cur_rank = cur_range_len = 0;
|
||||
|
||||
#define NEXT_CHAR cur_range_len++; \
|
||||
++cur; \
|
||||
continue;
|
||||
|
||||
static inline int is_alpha( char ch )
|
||||
{
|
||||
return ( (( ch >= '_' ) && ( ch <= 'z' )) ||
|
||||
(( ch >= 'A' ) && ( ch <= 'Z' ))
|
||||
);
|
||||
}
|
||||
|
||||
// _ . .
|
||||
// Ziema atEjo netikEtai
|
||||
|
||||
static void heighlight_syntax( char* str, int strLen,
|
||||
IntListT& results, bool& isComment )
|
||||
{
|
||||
bool isMultiline = 0;
|
||||
char* cur = str;
|
||||
char* end = str + strLen;
|
||||
|
||||
int cur_rank = ( isComment == 1 ) ? RANK_GREEN : RANK_BLACK;
|
||||
int cur_range_len = 0;
|
||||
|
||||
while ( cur != end )
|
||||
{
|
||||
int has_next = ( cur+1 != end );
|
||||
|
||||
if ( isComment )
|
||||
{
|
||||
if ( *cur == '*' )
|
||||
if ( has_next && *(cur+1) == '/' )
|
||||
{
|
||||
// turn off multiline comment mode
|
||||
cur += 2;
|
||||
cur_range_len += 2;
|
||||
isComment = 0;
|
||||
isMultiline = 0;
|
||||
STORE_RANGE;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
++cur_range_len;
|
||||
++cur;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
if ( *cur == 10 )
|
||||
if ( isComment )
|
||||
if ( isMultiline )
|
||||
{
|
||||
cur_rank = RANK_GREEN;
|
||||
cur_range_len = end - cur;
|
||||
STORE_RANGE;
|
||||
isComment = 0;
|
||||
isMultiline = 0;
|
||||
continue;
|
||||
}*/
|
||||
|
||||
if ( *cur == '/' )
|
||||
{
|
||||
if ( has_next )
|
||||
{
|
||||
if ( *(cur+1) == '/' )
|
||||
{
|
||||
STORE_RANGE;
|
||||
|
||||
char* eol = cur;
|
||||
while ( eol < end && *eol != 10 )
|
||||
++eol;
|
||||
|
||||
cur_rank = RANK_GREEN;
|
||||
cur_range_len = eol - cur;
|
||||
cur = eol;
|
||||
STORE_RANGE;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( *(cur+1) == '*' )
|
||||
{
|
||||
STORE_RANGE;
|
||||
cur_rank = RANK_GREEN;
|
||||
cur_range_len = 2;
|
||||
isComment = 1;
|
||||
cur += 2;
|
||||
isMultiline = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
NEXT_CHAR;
|
||||
}
|
||||
|
||||
if ( ( is_alpha( *cur ) || *(cur) == '#' )
|
||||
&& has_next
|
||||
)
|
||||
{
|
||||
if ( is_alpha( *(cur+1) ) )
|
||||
{
|
||||
char* start = cur;
|
||||
cur += 2;
|
||||
|
||||
while ( cur != end && is_alpha(*cur) ) ++cur;
|
||||
|
||||
int wordRank;
|
||||
|
||||
if ( (wordRank = get_rank( start, cur )) > 0 )
|
||||
{
|
||||
STORE_RANGE;
|
||||
|
||||
store_range( results, wordRank, int(cur-start) );
|
||||
cur_rank = cur_range_len = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
cur_range_len += ( cur-start );
|
||||
continue;
|
||||
}
|
||||
else
|
||||
NEXT_CHAR;
|
||||
}
|
||||
|
||||
NEXT_CHAR;
|
||||
}
|
||||
|
||||
if ( cur_range_len > 0 ) STORE_RANGE;
|
||||
}
|
||||
|
||||
/***** Implementation for class SourcePainter ******/
|
||||
|
||||
SourcePainter::SourcePainter( bool assembleResultString )
|
||||
: mCollectResultsOn( assembleResultString ),
|
||||
mIsInComment( FALSE ),
|
||||
mCommentIsMultiline( FALSE )
|
||||
{
|
||||
check_keyword_map(0);
|
||||
}
|
||||
|
||||
void SourcePainter::ProcessSource( char* src, int srcLen )
|
||||
{
|
||||
// TBD:: multilne state...
|
||||
|
||||
heighlight_syntax( src, srcLen, mBlocks, mIsInComment );
|
||||
|
||||
if ( mCollectResultsOn )
|
||||
|
||||
mResultStr += string( src, srcLen );
|
||||
}
|
||||
|
||||
void SourcePainter::SetState( bool isInComment,
|
||||
bool commentIsMultiline )
|
||||
{
|
||||
mIsInComment = isInComment;
|
||||
mCommentIsMultiline = commentIsMultiline;
|
||||
}
|
||||
|
||||
void SourcePainter::Init(bool assembleResultString)
|
||||
{
|
||||
mIsInComment = 0;
|
||||
mCommentIsMultiline = 0;
|
||||
mCollectResultsOn = assembleResultString;
|
||||
|
||||
mResultStr = "";
|
||||
|
||||
mBlocks.erase( mBlocks.begin(), mBlocks.end() );
|
||||
}
|
||||
|
||||
static int rank_tags_map[] =
|
||||
{
|
||||
TAG_BLACK_FONT,
|
||||
TAG_BLUE_FONT,
|
||||
TAG_RED_FONT,
|
||||
TAG_GREEN_FONT
|
||||
};
|
||||
|
||||
void SourcePainter::GetResultString(string& result, MarkupTagsT tags)
|
||||
{
|
||||
// this method works, only if results of processing
|
||||
// are collected
|
||||
ASSERT( mCollectResultsOn );
|
||||
result = "";
|
||||
|
||||
int pos = 0;
|
||||
|
||||
for( size_t i = 0; i != mBlocks.size(); ++i )
|
||||
{
|
||||
int desc = mBlocks[i];
|
||||
|
||||
int len = desc & 0xFFFF;
|
||||
int rank = (desc >> 16) & 0xFFFF;
|
||||
|
||||
result += tags[ rank_tags_map[rank] ].start;
|
||||
|
||||
for( int n = 0; n != len; ++n )
|
||||
|
||||
result += mResultStr[pos+n];
|
||||
|
||||
pos += len;
|
||||
|
||||
result += tags[ rank_tags_map[rank] ].end;
|
||||
}
|
||||
}
|
||||
|
||||
IntListT& SourcePainter::GetBlocks()
|
||||
{
|
||||
return mBlocks;
|
||||
}
|
||||
|
||||
bool SourcePainter::IsKeyword( char* word, int wordLen )
|
||||
{
|
||||
check_keyword_map(0);
|
||||
|
||||
int rank = get_rank( word, word + wordLen );
|
||||
|
||||
return ( rank == RANK_BLUE || rank == RANK_RED );
|
||||
}
|
Reference in New Issue
Block a user