KDevelop API Documentation

cpp_colorizer.cpp

Go to the documentation of this file.
00001 /* $Id: cpp_colorizer.cpp,v 1.16 2003/02/25 10:46:31 antlarr Exp $
00002  *
00003  *  This file is part of Klint
00004  *  Copyright (C) 2001 Roberto Raggi (roberto@kdevelop.org)
00005  *
00006  *  This program is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU General Public
00008  *  License as published by the Free Software Foundation; either
00009  *  version 2 of the License, or (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *  General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; see the file COPYING.  If not, write to
00018  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019  *  Boston, MA 02111-1307, USA.
00020  *
00021  */
00022 
00023 
00024 #include "cpp_colorizer.h"
00025 #include "qeditor_part.h"
00026 #include "paragdata.h"
00027 
00028 #include <qfont.h>
00029 #include <private/qrichtext_p.h>
00030 
00031 #include <qdom.h>
00032 #include <qfile.h>
00033 
00034 #include <kapplication.h>
00035 #include <kdebug.h>
00036 #include <kconfig.h>
00037 #include <kstandarddirs.h>
00038 
00039 
00040 static const char *cpp_keywords[] = {
00041     "break", "case", "continue", "default", "do", "else", "enum", "extern",
00042     "for", "goto", "if", "return", "sizeof", "struct",
00043     "switch", "typedef", "union", "while",
00044     "auto", "char", "uchar", "const", "double", "float", "int", "uint", "long", "register",
00045     "short", "signed", "static", "unsigned", "void", "volatile",
00046     "asm", "catch", "class", "const_cast", "const", "delete", "dynamic_cast",
00047     "explicit", "export", "false", "friend", "inline", "namespace", "new",
00048     "operator", "private", "protected", "public", "reinterpret_cast",
00049     "static_cast", "template", "this", "throw", "true", "try", "typeid",
00050     "typename", "using", "virtual",
00051     "and_eq", "and", "bitand", "bitor", "compl", "not_eq", "not", "or_eq", "or",
00052     "xor_eq", "xor",
00053     "slots", "signals",
00054     "bool", "wchar_t", "mutable",
00055     0
00056 };
00057 
00058 class CppPreprocHLItem: public HLItem{
00059 public:
00060     CppPreprocHLItem( int state, int context )
00061         : HLItem( state, context ) {}
00062 
00063     int checkHL( const QChar* buffer, int pos, int length, int*, int* ){
00064     //kdDebug(9032) << "CppPreprocHLItem::checkHLItem" << endl;
00065     int start_pos = pos;
00066     
00067     while( (pos<length) && buffer[pos].isSpace() )
00068         ++pos;
00069     
00070     if( (pos < length) && buffer[pos] == '#' )
00071         return pos + 1;
00072 
00073     return start_pos;
00074     }
00075 };
00076 
00077 class CppPreprocLineHLItem: public HLItem{
00078 public:
00079     CppPreprocLineHLItem( int state, int context )
00080         : HLItem( state, context ) {}
00081 
00082     int checkHL( const QChar* buffer, int pos, int length, int*, int* ){
00083     //kdDebug(9032) << "CppPreprocLineHLItem::checkHLItem" << endl;
00084     int end_pos = length - 1;
00085     
00086     while( (end_pos>=0) && buffer[end_pos].isSpace() )
00087         --end_pos;
00088     
00089     if( (end_pos >= 0) && buffer[end_pos] == '\\' )
00090         return length;
00091     
00092     return pos;
00093     }
00094 };
00095 
00096 using namespace std;
00097 
00098 CppColorizer::CppColorizer( QEditor* editor )
00099     : QSourceColorizer( editor )
00100 {
00101     loadDynamicKeywords();
00102     
00103     // default context
00104     HLItemCollection* context0 = new HLItemCollection( 0 );
00105     context0->appendChild( new CppPreprocHLItem( PreProcessor, 4 ) );
00106     context0->appendChild( new WhiteSpacesHLItem( Normal, 0 ) );
00107     context0->appendChild( new StringHLItem( "'", String, 1 ) );
00108     context0->appendChild( new StringHLItem( "\"", String, 2 ) );
00109     context0->appendChild( new StringHLItem( "/*", Comment, 3 ) );
00110     context0->appendChild( new StartsWithHLItem( "//", Comment, 0 ) );  
00111     context0->appendChild( new HexHLItem( Constant, 0 ) );
00112     context0->appendChild( new NumberHLItem( Constant, 0 ) );
00113     context0->appendChild( new KeywordsHLItem( m_dynamicKeywords, BuiltInClass, Normal, 0, false ) );
00114     context0->appendChild( new KeywordsHLItem( cpp_keywords, Keyword, Normal, 0 ) );
00115 
00116     HLItemCollection* context1 = new HLItemCollection( String );
00117     context1->appendChild( new StringHLItem( "\\\\", String, 1 ) );
00118     context1->appendChild( new StringHLItem( "\\'", String, 1 ) );
00119     context1->appendChild( new StringHLItem( "'", String, 0 ) );
00120 
00121     HLItemCollection* context2 = new HLItemCollection( String );
00122     context2->appendChild( new StringHLItem( "\\\\", String, 2 ) );
00123     context2->appendChild( new StringHLItem( "\\\"", String, 2 ) );
00124     context2->appendChild( new StringHLItem( "\"", String, 0 ) );
00125 
00126     HLItemCollection* context3 = new HLItemCollection( Comment );
00127     context3->appendChild( new StringHLItem( "*/", Comment, 0 ) );
00128 
00129     HLItemCollection* context4 = new HLItemCollection( PreProcessor );
00130     context4->appendChild( new CppPreprocLineHLItem( PreProcessor, 4 ) );
00131     context4->appendChild( new StartsWithHLItem( "", PreProcessor, 0 ) );
00132 
00133 
00134     m_items.append( context0 );
00135     m_items.append( context1 );
00136     m_items.append( context2 );
00137     m_items.append( context3 );
00138     m_items.append( context4 );
00139 }
00140 
00141 CppColorizer::~CppColorizer()
00142 {
00143 }
00144 
00145 void CppColorizer::loadDynamicKeywords()
00146 {
00147     QString strFileNameTag( "name" );
00148     QString strClassNameTag( "name" );
00149     
00150     m_dynamicKeywords.clear();
00151     
00152     QString hlFileDir = KGlobal::dirs()->findResourceDir( "data", "qeditorpart/highlight/highlighting.xml" );
00153     
00154     hlFileDir += "qeditorpart/highlight/";
00155     
00156     //kdDebug(9032) << "Highlighting Dir: " << hlFileDir << endl;
00157     
00158     if( hlFileDir.isNull() )
00159     return;
00160     
00161     QDomDocument hlFile( "hlfile" ), curDoc ( "classlist" );
00162     QFile hlRawFile( hlFileDir + "highlighting.xml" );
00163     int keywordIndex = 0;
00164     if( !hlRawFile.open( IO_ReadOnly ) )
00165     return;
00166     if( !hlFile.setContent( &hlRawFile ) ) {
00167     hlRawFile.close();
00168     return;
00169     }
00170     hlRawFile.close();
00171     
00172     QDomElement e = hlFile.documentElement();
00173     QDomNode n = e.firstChild();
00174     while( !n.isNull() ) {
00175     e = n.toElement();
00176     if( !e.isNull() ) {
00177         
00178         // kdDebug(9032) << "Loading classes-file: " << (hlFileDir + e.attribute( strFileNameTag )) << endl;
00179         
00180         QFile clsRawFile( hlFileDir + e.attribute( strFileNameTag ) );
00181         if( clsRawFile.open( IO_ReadOnly ) && curDoc.setContent( &clsRawFile ) ) {
00182         
00183         QDomElement e = curDoc.documentElement();
00184         QDomNode n = e.firstChild();
00185         while( !n.isNull() ) {
00186             e = n.toElement();
00187             if( !e.isNull()) {
00188             // kdDebug(9032) << "Adding dynamic keyword: '" << e.attribute( strClassNameTag ) << "'" << endl;
00189             m_dynamicKeywords.insert( e.attribute( strClassNameTag ), keywordIndex++ );
00190             }
00191             n = n.nextSibling();
00192         }
00193         
00194         }
00195         clsRawFile.close();
00196     }
00197     n = n.nextSibling();
00198     }
00199 }
00200 
00201 int CppColorizer::computeLevel( QTextParagraph* parag, int startLevel )
00202 {
00203     int level = startLevel;
00204 
00205     ParagData* data = (ParagData*) parag->extraData();
00206     if( !data ){
00207         return startLevel;
00208     }
00209 
00210     data->setBlockStart( false );
00211 
00212     QValueList<Symbol> symbols = data->symbolList();
00213     QValueList<Symbol>::Iterator it = symbols.begin();
00214     while( it != symbols.end() ){
00215         Symbol sym = *it++;
00216         if( sym.ch() == '{' ){
00217             ++level;
00218         } else if( sym.ch() == '}' ){
00219             --level;
00220         }
00221     }
00222 
00223     if( level > startLevel ){
00224         data->setBlockStart( true );
00225     }
00226 
00227     return level;
00228 }
00229 
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:23 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003