00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include "katehighlight.h"
00024
#include "katehighlight.moc"
00025
00026
#include "katetextline.h"
00027
#include "katedocument.h"
00028
#include "katesyntaxdocument.h"
00029
#include "katerenderer.h"
00030
#include "katefactory.h"
00031
#include "kateschema.h"
00032
#include "kateconfig.h"
00033
00034
#include <kconfig.h>
00035
#include <kglobal.h>
00036
#include <kinstance.h>
00037
#include <kmimetype.h>
00038
#include <klocale.h>
00039
#include <kregexp.h>
00040
#include <kpopupmenu.h>
00041
#include <kglobalsettings.h>
00042
#include <kdebug.h>
00043
#include <kstandarddirs.h>
00044
#include <kmessagebox.h>
00045
#include <kstaticdeleter.h>
00046
#include <kapplication.h>
00047
00048
#include <qstringlist.h>
00049
#include <qtextstream.h>
00050
00051
00052
00053
#define KATE_HL_HOWMANY 1024
00054
00055
00056
00057
class HlItem
00058 {
00059
public:
00060 HlItem(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00061
virtual ~HlItem();
00062
00063
public:
00064
virtual bool alwaysStartEnable()
const {
return true; };
00065
virtual bool hasCustomStartEnable()
const {
return false; };
00066
virtual bool startEnable(
const QChar&);
00067
00068
00069
00070
00071
00072
virtual int checkHgl(
const QString& text,
int offset,
int len) = 0;
00073
00074
virtual bool lineContinue(){
return false;}
00075
00076
QPtrList<HlItem> *subItems;
00077
int attr;
00078
int ctx;
00079
signed char region;
00080
signed char region2;
00081 };
00082
00083
class HlContext
00084 {
00085
public:
00086 HlContext (
int attribute,
int lineEndContext,
int _lineBeginContext,
00087
bool _fallthrough,
int _fallthroughContext);
00088
00089
QPtrList<HlItem> items;
00090
int attr;
00091
int ctx;
00092
int lineBeginContext;
00098
bool fallthrough;
00099
int ftctx;
00100 };
00101
00102
class EmbeddedHlInfo
00103 {
00104
public:
00105 EmbeddedHlInfo() {loaded=
false;context0=-1;}
00106 EmbeddedHlInfo(
bool l,
int ctx0) {loaded=l;context0=ctx0;}
00107
00108
public:
00109
bool loaded;
00110
int context0;
00111 };
00112
00113
class IncludeRule
00114 {
00115
public:
00116 IncludeRule(
int ctx_, uint pos_,
const QString &incCtxN_) {ctx=ctx_;pos=pos_;incCtxN=incCtxN_;incCtx=-1;}
00117 IncludeRule(
int ctx_, uint pos_) {ctx=ctx_;pos=pos_;incCtx=-1;incCtxN=
"";}
00118
00119
public:
00120 uint pos;
00121
int ctx;
00122
int incCtx;
00123
QString incCtxN;
00124 };
00125
00126
class HlCharDetect :
public HlItem
00127 {
00128
public:
00129 HlCharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar);
00130
virtual int checkHgl(
const QString& text,
int offset,
int len);
00131
00132
private:
00133
QChar sChar;
00134 };
00135
00136
class Hl2CharDetect :
public HlItem
00137 {
00138
public:
00139 Hl2CharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar ch1,
QChar ch2);
00140 Hl2CharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QChar *ch);
00141
00142
virtual int checkHgl(
const QString& text,
int offset,
int len);
00143
00144
private:
00145
QChar sChar1;
00146
QChar sChar2;
00147 };
00148
00149
class HlStringDetect :
public HlItem
00150 {
00151
public:
00152 HlStringDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QString &,
bool inSensitive=
false);
00153
00154
virtual ~HlStringDetect();
00155
virtual int checkHgl(
const QString& text,
int offset,
int len);
00156
00157
private:
00158
const QString str;
00159
bool _inSensitive;
00160 };
00161
00162
class HlRangeDetect :
public HlItem
00163 {
00164
public:
00165 HlRangeDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar ch1,
QChar ch2);
00166
00167
virtual int checkHgl(
const QString& text,
int offset,
int len);
00168
00169
private:
00170
QChar sChar1;
00171
QChar sChar2;
00172 };
00173
00174
class HlKeyword :
public HlItem
00175 {
00176
public:
00177 HlKeyword(
int attribute,
int context,
signed char regionId,
signed char regionId2,
bool casesensitive,
const QString& delims);
00178
virtual ~HlKeyword();
00179
00180
virtual void addWord(
const QString &);
00181
virtual void addList(
const QStringList &);
00182
virtual int checkHgl(
const QString& text,
int offset,
int len);
00183
virtual bool startEnable(
const QChar& c);
00184
virtual bool alwaysStartEnable() const;
00185 virtual
bool hasCustomStartEnable() const;
00186
00187 private:
00188
QDict<
bool> dict;
00189
bool _caseSensitive;
00190 const
QString& deliminators;
00191 };
00192
00193 class HlInt : public HlItem
00194 {
00195
public:
00196 HlInt(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00197
00198
virtual int checkHgl(
const QString& text,
int offset,
int len);
00199
virtual bool alwaysStartEnable() const;
00200 };
00201
00202 class HlFloat : public HlItem
00203 {
00204
public:
00205 HlFloat(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00206
00207
virtual int checkHgl(
const QString& text,
int offset,
int len);
00208
virtual bool alwaysStartEnable() const;
00209 };
00210
00211 class HlCOct : public HlItem
00212 {
00213
public:
00214 HlCOct(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00215
00216
virtual int checkHgl(
const QString& text,
int offset,
int len);
00217
virtual bool alwaysStartEnable() const;
00218 };
00219
00220 class HlCHex : public HlItem
00221 {
00222
public:
00223 HlCHex(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00224
00225
virtual int checkHgl(
const QString& text,
int offset,
int len);
00226
virtual bool alwaysStartEnable() const;
00227 };
00228
00229 class HlCFloat : public HlFloat
00230 {
00231
public:
00232 HlCFloat(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00233
00234
virtual int checkHgl(
const QString& text,
int offset,
int len);
00235
int checkIntHgl(
const QString& text,
int offset,
int len);
00236
virtual bool alwaysStartEnable() const;
00237 };
00238
00239 class HlLineContinue : public HlItem
00240 {
00241
public:
00242 HlLineContinue(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00243
00244
virtual bool endEnable(
QChar c) {
return c ==
'\0';}
00245
virtual int checkHgl(
const QString& text,
int offset,
int len);
00246
virtual bool lineContinue(){
return true;}
00247 };
00248
00249
class HlCStringChar :
public HlItem
00250 {
00251
public:
00252 HlCStringChar(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00253
00254
virtual int checkHgl(
const QString& text,
int offset,
int len);
00255 };
00256
00257
class HlCChar :
public HlItem
00258 {
00259
public:
00260 HlCChar(
int attribute,
int context,
signed char regionId,
signed char regionId2);
00261
00262
virtual int checkHgl(
const QString& text,
int offset,
int len);
00263 };
00264
00265
class HlAnyChar :
public HlItem
00266 {
00267
public:
00268 HlAnyChar(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QString& charList);
00269
00270
virtual int checkHgl(
const QString& text,
int offset,
int len);
00271
00272
private:
00273
const QString _charList;
00274 };
00275
00276
class HlRegExpr :
public HlItem
00277 {
00278
public:
00279 HlRegExpr(
int attribute,
int context,
signed char regionId,
signed char regionId2 ,
QString expr,
bool insensitive,
bool minimal);
00280 ~HlRegExpr(){
delete Expr;};
00281
00282
virtual int checkHgl(
const QString& text,
int offset,
int len);
00283
00284
private:
00285
QRegExp *Expr;
00286
bool handlesLinestart;
00287 };
00288
00289
00290
00291
00292 HlManager *HlManager::s_self = 0;
00293
00294
enum Item_styles { dsNormal,dsKeyword,dsDataType,dsDecVal,dsBaseN,dsFloat,dsChar,dsString,dsComment,dsOthers};
00295
00296
static const bool trueBool =
true;
00297
static const QString stdDeliminator =
QString (
" \t.():!+,-<=>%&*/;?[]^{|}~\\");
00298
00299
00300
00301
static int getDefStyleNum(QString name)
00302 {
00303
if (
name==
"dsNormal")
return dsNormal;
00304
else if (
name==
"dsKeyword")
return dsKeyword;
00305
else if (
name==
"dsDataType")
return dsDataType;
00306
else if (
name==
"dsDecVal")
return dsDecVal;
00307
else if (
name==
"dsBaseN")
return dsBaseN;
00308
else if (
name==
"dsFloat")
return dsFloat;
00309
else if (
name==
"dsChar")
return dsChar;
00310
else if (
name==
"dsString")
return dsString;
00311
else if (
name==
"dsComment")
return dsComment;
00312
else if (
name==
"dsOthers")
return dsOthers;
00313
00314
return dsNormal;
00315 }
00316
00317
00318
00319 HlItem::HlItem(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00320 : attr(attribute), ctx(context),region(regionId),region2(regionId2) {subItems=0;
00321 }
00322
00323 HlItem::~HlItem()
00324 {
00325
00326
if (subItems!=0)
00327 {
00328 subItems->setAutoDelete(
true);
00329 subItems->clear();
00330
delete subItems;
00331 }
00332 }
00333
00334
bool HlItem::startEnable(
const QChar& c)
00335 {
00336
00337
00338 Q_ASSERT(
false);
00339
return stdDeliminator.
find(c) != -1;
00340 }
00341
00342
00343
00344 HlCharDetect::HlCharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar c)
00345 : HlItem(attribute,context,regionId,regionId2), sChar(c)
00346 {
00347 }
00348
00349
int HlCharDetect::checkHgl(
const QString& text,
int offset,
int len)
00350 {
00351
if (len && text[offset] == sChar)
00352
return offset + 1;
00353
00354
return 0;
00355 }
00356
00357
00358
00359 Hl2CharDetect::Hl2CharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar ch1,
QChar ch2)
00360 : HlItem(attribute,context,regionId,regionId2)
00361 {
00362 sChar1 = ch1;
00363 sChar2 = ch2;
00364 }
00365
00366
int Hl2CharDetect::checkHgl(
const QString& text,
int offset,
int len)
00367 {
00368
if (len < 2)
00369
return offset;
00370
00371
if (text[offset++] == sChar1 && text[offset++] == sChar2)
00372
return offset;
00373
00374
return 0;
00375 }
00376
00377
00378
00379 HlStringDetect::HlStringDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QString &s,
bool inSensitive)
00380 : HlItem(attribute, context,regionId,regionId2), str(inSensitive ? s.upper():s), _inSensitive(inSensitive) {
00381 }
00382
00383 HlStringDetect::~HlStringDetect() {
00384 }
00385
00386
int HlStringDetect::checkHgl(
const QString& text,
int offset,
int len)
00387 {
00388
if (len < (
int)str.length())
00389
return 0;
00390
00391
if (
QConstString(text.
unicode() + offset, str.length()).string().find(str, 0, !_inSensitive) == 0)
00392
return offset + str.length();
00393
00394
return 0;
00395 }
00396
00397
00398
00399
00400 HlRangeDetect::HlRangeDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
QChar ch1,
QChar ch2)
00401 : HlItem(attribute,context,regionId,regionId2) {
00402 sChar1 = ch1;
00403 sChar2 = ch2;
00404 }
00405
00406
int HlRangeDetect::checkHgl(
const QString& text,
int offset,
int len)
00407 {
00408
if ((len > 0) && (text[offset] == sChar1))
00409 {
00410
do
00411 {
00412 offset++;
00413 len--;
00414
if (len < 1)
return 0;
00415 }
00416
while (text[offset] != sChar2);
00417
00418
return offset + 1;
00419 }
00420
return 0;
00421 }
00422
00423
00424
00425 HlKeyword::HlKeyword (
int attribute,
int context,
signed char regionId,
signed char regionId2,
bool casesensitive,
const QString& delims)
00426 : HlItem(attribute,context,regionId,regionId2)
00427 , dict (113, casesensitive)
00428 , _caseSensitive(casesensitive)
00429 , deliminators(delims)
00430 {
00431 }
00432
00433 HlKeyword::~HlKeyword() {
00434 }
00435
00436
bool HlKeyword::alwaysStartEnable()
const
00437
{
00438
return false;
00439 }
00440
00441
bool HlKeyword::hasCustomStartEnable()
const
00442
{
00443
return true;
00444 }
00445
00446
bool HlKeyword::startEnable(
const QChar& c)
00447 {
00448
return deliminators.
find(c) != -1;
00449 }
00450
00451
00452
00453
void HlKeyword::addWord(
const QString &word)
00454 {
00455 dict.insert(word,&trueBool);
00456 }
00457
00458
void HlKeyword::addList(
const QStringList& list)
00459 {
00460
for(uint i=0;i<list.count();i++) dict.insert(list[i], &trueBool);
00461 }
00462
00463
int HlKeyword::checkHgl(
const QString& text,
int offset,
int len)
00464 {
00465
if (len == 0 || dict.isEmpty())
return 0;
00466
00467
int offset2 = offset;
00468
00469
while (len > 0 && deliminators.
find(text[offset2]) == -1 )
00470 {
00471 offset2++;
00472 len--;
00473 }
00474
00475
if (offset2 == offset)
return 0;
00476
00477
if ( dict.find(text.
mid(offset, offset2 - offset)) )
return offset2;
00478
00479
return 0;
00480 }
00481
00482
00483
00484 HlInt::HlInt(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00485 : HlItem(attribute,context,regionId,regionId2)
00486 {
00487 }
00488
00489
bool HlInt::alwaysStartEnable()
const
00490
{
00491
return false;
00492 }
00493
00494
int HlInt::checkHgl(
const QString& text,
int offset,
int len)
00495 {
00496
int offset2 = offset;
00497
00498
while ((len > 0) && text[offset2].isDigit())
00499 {
00500 offset2++;
00501 len--;
00502 }
00503
00504
if (offset2 > offset)
00505 {
00506
if (subItems)
00507 {
00508
for (HlItem *it = subItems->first(); it; it = subItems->next())
00509 {
00510
if ( (offset = it->checkHgl(text, offset2, len)) )
00511
return offset;
00512 }
00513 }
00514
00515
return offset2;
00516 }
00517
00518
return 0;
00519 }
00520
00521
00522
00523 HlFloat::HlFloat(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00524 : HlItem(attribute,context, regionId,regionId2) {
00525 }
00526
00527
bool HlFloat::alwaysStartEnable()
const
00528
{
00529
return false;
00530 }
00531
00532
int HlFloat::checkHgl(
const QString& text,
int offset,
int len)
00533 {
00534
bool b =
false;
00535
bool p =
false;
00536
00537
while ((len > 0) && text[offset].isDigit())
00538 {
00539 offset++;
00540 len--;
00541 b =
true;
00542 }
00543
00544
if ((len > 0) && (p = (text[offset] ==
'.')))
00545 {
00546 offset++;
00547 len--;
00548
00549
while ((len > 0) && text[offset].isDigit())
00550 {
00551 offset++;
00552 len--;
00553 b =
true;
00554 }
00555 }
00556
00557
if (!b)
00558
return 0;
00559
00560
if ((len > 0) && ((text[offset] & 0xdf) ==
'E'))
00561 {
00562 offset++;
00563 len--;
00564 }
00565
else
00566 {
00567
if (!p)
00568
return 0;
00569
else
00570 {
00571
if (subItems)
00572 {
00573
for (HlItem *it = subItems->first(); it; it = subItems->next())
00574 {
00575
int offset2 = it->checkHgl(text, offset, len);
00576
00577
if (offset2)
00578
return offset2;
00579 }
00580 }
00581
00582
return offset;
00583 }
00584 }
00585
00586
if ((len > 0) && (text[offset] ==
'-' || text[offset] ==
'+'))
00587 {
00588 offset++;
00589 len--;
00590 }
00591
00592 b =
false;
00593
00594
while ((len > 0) && text[offset].isDigit())
00595 {
00596 offset++;
00597 len--;
00598 b =
true;
00599 }
00600
00601
if (b)
00602 {
00603
if (subItems)
00604 {
00605
for (HlItem *it = subItems->first(); it; it = subItems->next())
00606 {
00607
int offset2 = it->checkHgl(text, offset, len);
00608
00609
if (offset2)
00610
return offset2;
00611 }
00612 }
00613
00614
return offset;
00615 }
00616
00617
return 0;
00618 }
00619
00620
00621
00622 HlCOct::HlCOct(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00623 : HlItem(attribute,context,regionId,regionId2) {
00624 }
00625
00626
bool HlCOct::alwaysStartEnable()
const
00627
{
00628
return false;
00629 }
00630
00631
int HlCOct::checkHgl(
const QString& text,
int offset,
int len)
00632 {
00633
if ((len > 0) && text[offset] ==
'0')
00634 {
00635 offset++;
00636 len--;
00637
00638
int offset2 = offset;
00639
00640
while ((len > 0) && (text[offset2] >=
'0' && text[offset2] <=
'7'))
00641 {
00642 offset2++;
00643 len--;
00644 }
00645
00646
if (offset2 > offset)
00647 {
00648
if ((len > 0) && ((text[offset2] & 0xdf) ==
'L' || (text[offset] & 0xdf) ==
'U' ))
00649 offset2++;
00650
00651
return offset2;
00652 }
00653 }
00654
00655
return 0;
00656 }
00657
00658
00659
00660 HlCHex::HlCHex(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00661 : HlItem(attribute,context,regionId,regionId2) {
00662 }
00663
00664
bool HlCHex::alwaysStartEnable()
const
00665
{
00666
return false;
00667 }
00668
00669
int HlCHex::checkHgl(
const QString& text,
int offset,
int len)
00670 {
00671
if ((len > 1) && (text[offset++] ==
'0') && ((text[offset++] & 0xdf) ==
'X' ))
00672 {
00673 len -= 2;
00674
00675
int offset2 = offset;
00676
00677
while ((len > 0) && (text[offset2].isDigit() || ((text[offset2] & 0xdf) >=
'A' && (text[offset2] & 0xdf) <=
'F')))
00678 {
00679 offset2++;
00680 len--;
00681 }
00682
00683
if (offset2 > offset)
00684 {
00685
if ((len > 0) && ((text[offset2] & 0xdf) ==
'L' || (text[offset2] & 0xdf) ==
'U' ))
00686 offset2++;
00687
00688
return offset2;
00689 }
00690 }
00691
00692
return 0;
00693 }
00694
00695
00696
00697 HlCFloat::HlCFloat(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00698 : HlFloat(attribute,context,regionId,regionId2) {
00699 }
00700
00701
bool HlCFloat::alwaysStartEnable()
const
00702
{
00703
return false;
00704 }
00705
00706
int HlCFloat::checkIntHgl(
const QString& text,
int offset,
int len)
00707 {
00708
int offset2 = offset;
00709
00710
while ((len > 0) && text[offset].isDigit()) {
00711 offset2++;
00712 len--;
00713 }
00714
00715
if (offset2 > offset)
00716
return offset2;
00717
00718
return 0;
00719 }
00720
00721
int HlCFloat::checkHgl(
const QString& text,
int offset,
int len)
00722 {
00723
int offset2 = HlFloat::checkHgl(text, offset, len);
00724
00725
if (offset2)
00726 {
00727
if ((text[offset2] & 0xdf) ==
'F' )
00728 offset2++;
00729
00730
return offset2;
00731 }
00732
else
00733 {
00734 offset2 = checkIntHgl(text, offset, len);
00735
00736
if (offset2 && ((text[offset2] & 0xdf) ==
'F' ))
00737
return ++offset2;
00738
else
00739
return 0;
00740 }
00741 }
00742
00743
00744
00745 HlAnyChar::HlAnyChar(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QString& charList)
00746 : HlItem(attribute, context,regionId,regionId2)
00747 , _charList(charList)
00748 {
00749 }
00750
00751
int HlAnyChar::checkHgl(
const QString& text,
int offset,
int len)
00752 {
00753
if ((len > 0) && _charList.find(text[offset]) != -1)
00754
return ++offset;
00755
00756
return 0;
00757 }
00758
00759
00760
00761 HlRegExpr::HlRegExpr(
int attribute,
int context,
signed char regionId,
signed char regionId2, QString regexp,
bool insensitive,
bool minimal )
00762 : HlItem(attribute, context, regionId,regionId2)
00763 {
00764 handlesLinestart=regexp.
startsWith(
"^");
00765
if(!handlesLinestart) regexp.
prepend(
"^");
00766 Expr=
new QRegExp(regexp, !insensitive);
00767 Expr->setMinimal(minimal);
00768 }
00769
00770
int HlRegExpr::checkHgl(
const QString& text,
int offset,
int )
00771 {
00772
if (offset && handlesLinestart)
00773
return 0;
00774
00775
int offset2 = Expr->search( text, offset, QRegExp::CaretAtOffset );
00776
00777
if (offset2 == -1)
return 0;
00778
00779
return (offset + Expr->matchedLength());
00780 }
00781
00782
00783
00784 HlLineContinue::HlLineContinue(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00785 : HlItem(attribute,context,regionId,regionId2) {
00786 }
00787
00788
int HlLineContinue::checkHgl(
const QString& text,
int offset,
int len)
00789 {
00790
if ((len == 1) && (text[offset] ==
'\\'))
00791
return ++offset;
00792
00793
return 0;
00794 }
00795
00796
00797
00798 HlCStringChar::HlCStringChar(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00799 : HlItem(attribute,context,regionId,regionId2) {
00800 }
00801
00802
00803
static int checkEscapedChar(
const QString& text,
int offset,
int& len)
00804 {
00805
int i;
00806
if (text[offset] ==
'\\' && len > 1)
00807 {
00808 offset++;
00809 len--;
00810
00811
switch(text[offset])
00812 {
00813
case 'a':
00814
case 'b':
00815
case 'e':
00816
case 'f':
00817
00818
case 'n':
00819
case 'r':
00820
case 't':
00821
case 'v':
00822
case '\'':
00823
case '\"':
00824
case '?' :
00825
case '\\':
00826 offset++;
00827 len--;
00828
break;
00829
00830
case 'x':
00831 offset++;
00832 len--;
00833
00834
00835
00836
00837
for (i = 0; (len > 0) && (i < 2) && (text[offset] >=
'0' && text[offset] <=
'9' || (text[offset] & 0xdf) >=
'A' && (text[offset] & 0xdf) <=
'F'); i++)
00838 {
00839 offset++;
00840 len--;
00841 }
00842
00843
if (i == 0)
00844
return 0;
00845
00846
break;
00847
00848
case '0':
case '1':
case '2':
case '3' :
00849
case '4':
case '5':
case '6':
case '7' :
00850
for (i = 0; (len > 0) && (i < 3) && (text[offset] >=
'0'&& text[offset] <=
'7'); i++)
00851 {
00852 offset++;
00853 len--;
00854 }
00855
break;
00856
00857
default:
00858
return 0;
00859 }
00860
00861
return offset;
00862 }
00863
00864
return 0;
00865 }
00866
00867
int HlCStringChar::checkHgl(
const QString& text,
int offset,
int len)
00868 {
00869
return checkEscapedChar(text, offset, len);
00870 }
00871
00872
00873
00874 HlCChar::HlCChar(
int attribute,
int context,
signed char regionId,
signed char regionId2)
00875 : HlItem(attribute,context,regionId,regionId2) {
00876 }
00877
00878
int HlCChar::checkHgl(
const QString& text,
int offset,
int len)
00879 {
00880
if ((len > 1) && (text[offset] ==
'\'') && (text[offset+1] !=
'\''))
00881 {
00882
int oldl;
00883 oldl = len;
00884
00885 len--;
00886
00887
int offset2 = checkEscapedChar(text, offset + 1, len);
00888
00889
if (!offset2)
00890 {
00891
if (oldl > 2)
00892 {
00893 offset2 = offset + 2;
00894 len = oldl - 2;
00895 }
00896
else
00897 {
00898
return 0;
00899 }
00900 }
00901
00902
if ((len > 0) && (text[offset2] ==
'\''))
00903
return ++offset2;
00904 }
00905
00906
return 0;
00907 }
00908
00909
00910 ItemData::ItemData(
const QString name,
int defStyleNum)
00911 :
name(
name), defStyleNum(defStyleNum) {
00912 }
00913
00914 HlData::HlData(
const QString &wildcards,
const QString &mimetypes,
const QString &identifier,
int priority)
00915 : wildcards(wildcards), mimetypes(mimetypes), identifier(identifier), priority(priority)
00916 {
00917 }
00918
00919 HlContext::HlContext (
int attribute,
int lineEndContext,
int _lineBeginContext,
bool _fallthrough,
int _fallthroughContext)
00920 {
00921 attr = attribute;
00922 ctx = lineEndContext;
00923 lineBeginContext = _lineBeginContext;
00924 fallthrough = _fallthrough;
00925 ftctx = _fallthroughContext;
00926 }
00927
00928 Hl2CharDetect::Hl2CharDetect(
int attribute,
int context,
signed char regionId,
signed char regionId2,
const QChar *s)
00929 : HlItem(attribute,context,regionId,regionId2) {
00930 sChar1 = s[0];
00931 sChar2 = s[1];
00932 }
00933
00934
00935 Highlight::Highlight(
const syntaxModeListItem *def) : refCount(0)
00936 {
00937 m_attributeArrays.setAutoDelete (
true);
00938
00939 errorsAndWarnings =
"";
00940 building=
false;
00941 noHl =
false;
00942 m_foldingIndentationSensitive =
false;
00943 folding=
false;
00944 internalIDList.setAutoDelete(
true);
00945
00946
if (def == 0)
00947 {
00948 noHl =
true;
00949 iName =
I18N_NOOP(
"None");
00950 iSection =
"";
00951 m_priority = 0;
00952 }
00953
else
00954 {
00955 iName = def->
name;
00956 iSection = def->
section;
00957 iWildcards = def->
extension;
00958 iMimetypes = def->
mimetype;
00959 identifier = def->
identifier;
00960 iVersion=def->
version;
00961 m_priority=def->
priority.
toInt();
00962 }
00963
00964 deliminator = stdDeliminator;
00965 }
00966
00967 Highlight::~Highlight()
00968 {
00969 contextList.setAutoDelete(
true );
00970 }
00971
00972
void Highlight::generateContextStack(
int *ctxNum,
int ctx,
QMemArray<short>* ctxs,
int *prevLine,
bool lineContinue)
00973 {
00974
00975
00976
if (lineContinue)
00977 {
00978
if ( !ctxs->
isEmpty() )
00979 {
00980 (*ctxNum)=(*ctxs)[ctxs->size()-1];
00981 (*prevLine)--;
00982 }
00983
else
00984 {
00985
00986 (*ctxNum)=0;
00987 }
00988
00989
return;
00990 }
00991
00992
if (ctx >= 0)
00993 {
00994 (*ctxNum) = ctx;
00995
00996 ctxs->
resize (ctxs->
size()+1);
00997 (*ctxs)[ctxs->
size()-1]=(*ctxNum);
00998 }
00999
else
01000 {
01001
if (ctx < -1)
01002 {
01003
while (ctx < -1)
01004 {
01005
if ( ctxs->
isEmpty() )
01006 (*ctxNum)=0;
01007
else
01008 {
01009 ctxs->
truncate (ctxs->
size()-1);
01010
01011 (*ctxNum) = ( (ctxs->
isEmpty() ) ? 0 : (*ctxs)[ctxs->
size()-1]);
01012 }
01013
01014 ctx++;
01015 }
01016
01017 ctx = 0;
01018
01019
if ((*prevLine) >= (
int)(ctxs->
size()-1))
01020 {
01021 *prevLine=ctxs->
size()-1;
01022
01023
if ( ctxs->
isEmpty() )
01024
return;
01025
01026
if (contextNum((*ctxs)[ctxs->
size()-1]) && (contextNum((*ctxs)[ctxs->
size()-1])->ctx != -1))
01027 {
01028
01029 generateContextStack(ctxNum, contextNum((*ctxs)[ctxs->
size()-1])->ctx,ctxs, prevLine);
01030
return;
01031 }
01032 }
01033 }
01034
else
01035 {
01036
if (ctx == -1)
01037 (*ctxNum)=( (ctxs->
isEmpty() ) ? 0 : (*ctxs)[ctxs->
size()-1]);
01038 }
01039 }
01040 }
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
void Highlight::doHighlight(
QMemArray<short> oCtx,
TextLine *textLine,
bool lineContinue,
01056
QMemArray<signed char>* foldingList)
01057 {
01058
if (!textLine)
01059
return;
01060
01061
if (noHl)
01062 {
01063 textLine->
setAttribs(0,0,textLine->
length());
01064
return;
01065 }
01066
01067
01068
01069 HlContext *context;
01070
01071
01072
01073
int ctxNum;
01074
int prevLine;
01075
01076
QMemArray<short> ctx;
01077 ctx.
duplicate (oCtx);
01078
01079
if ( oCtx.
isEmpty() )
01080 {
01081
01082 ctxNum=0;
01083 context=contextNum(ctxNum);
01084 prevLine=-1;
01085 }
01086
else
01087 {
01088
01089 ctxNum=ctx[oCtx.
size()-1];
01090
01091
01092
01093
01094
01095
if (!(context = contextNum(ctxNum)))
01096 context = contextNum(0);
01097
01098
01099
01100 prevLine=oCtx.
size()-1;
01101
01102
01103 generateContextStack(&ctxNum, context->ctx, &ctx, &prevLine, lineContinue);
01104
01105
01106
01107
if (!(context = contextNum(ctxNum)))
01108 context = contextNum(0);
01109
01110
01111 }
01112
01113
01114
QChar lastChar =
' ';
01115
const QString& text = textLine->
string();
01116 uint len = textLine->
length();
01117
01118
int offset1 = 0;
01119 uint z = 0;
01120 HlItem *item = 0;
01121
bool found =
false;
01122
01123
while (z < len)
01124 {
01125 found =
false;
01126
01127
bool standardStartEnableDetermined =
false;
01128
bool standardStartEnable =
false;
01129
01130
for (item = context->items.first(); item != 0L; item = context->items.next())
01131 {
01132
bool thisStartEnabled =
false;
01133
01134
if (item->alwaysStartEnable())
01135 {
01136 thisStartEnabled =
true;
01137 }
01138
else if (!item->hasCustomStartEnable())
01139 {
01140
if (!standardStartEnableDetermined)
01141 {
01142 standardStartEnable = stdDeliminator.
find(lastChar) != -1;
01143 standardStartEnableDetermined =
true;
01144 }
01145
01146 thisStartEnabled = standardStartEnable;
01147 }
01148
else if (item->startEnable(lastChar))
01149 {
01150 thisStartEnabled =
true;
01151 }
01152
01153
if (thisStartEnabled)
01154 {
01155
int offset2 = item->checkHgl(text, offset1, len-z);
01156
01157
if (offset2 > offset1)
01158 {
01159 textLine->
setAttribs(item->attr,offset1,offset2);
01160
01161
01162
if (item->region)
01163 {
01164
01165
01166
if ( !foldingList->
isEmpty() && ((item->region < 0) && (*foldingList)[foldingList->
size()-1] == -item->region ) )
01167 {
01168 foldingList->
resize (foldingList->
size()-1);
01169 }
01170
else
01171 {
01172 foldingList->
resize (foldingList->
size()+1);
01173 (*foldingList)[foldingList->
size()-1] = item->region;
01174 }
01175
01176 }
01177
01178
if (item->region2)
01179 {
01180
01181
01182
if ( !foldingList->
isEmpty() && ((item->region2 < 0) && (*foldingList)[foldingList->
size()-1] == -item->region2 ) )
01183 {
01184 foldingList->
resize (foldingList->
size()-1);
01185 }
01186
else
01187 {
01188 foldingList->
resize (foldingList->
size()+1);
01189 (*foldingList)[foldingList->
size()-1] = item->region2;
01190 }
01191
01192 }
01193
01194 generateContextStack(&ctxNum, item->ctx, &ctx, &prevLine);
01195
01196
01197
01198
01199 context=contextNum(ctxNum);
01200
01201 z = z + offset2 - offset1 - 1;
01202 offset1 = offset2 - 1;
01203 found =
true;
01204
break;
01205 }
01206 }
01207 }
01208
01209 lastChar = text[offset1];
01210
01211
01212
01213
if (!found)
01214 {
01215
if ( context->fallthrough )
01216 {
01217
01218 generateContextStack(&ctxNum, context->ftctx, &ctx, &prevLine);
01219 context=contextNum(ctxNum);
01220
01221
01222
01223
01224
if (z)
01225 lastChar = text[offset1 - 1];
01226
else
01227 lastChar =
'\\';
01228
continue;
01229 }
01230
else
01231 textLine->
setAttribs(context->attr,offset1,offset1 + 1);
01232 }
01233
01234 offset1++;
01235 z++;
01236 }
01237
01238
if (item==0)
01239 textLine->
setHlLineContinue(
false);
01240
else
01241 textLine->
setHlLineContinue(item->lineContinue());
01242
01243 textLine->
setContext(ctx.
data(), ctx.
size());
01244 }
01245
01246
void Highlight::loadWildcards()
01247 {
01248
KConfig *config = HlManager::self()->getKConfig();
01249 config->
setGroup(
"Highlighting " + iName);
01250
01251 QString extensionString = config->
readEntry(
"Wildcards", iWildcards);
01252
01253
if (extensionSource != extensionString) {
01254 regexpExtensions.clear();
01255 plainExtensions.clear();
01256
01257 extensionSource = extensionString;
01258
01259
static QRegExp sep(
"\\s*;\\s*");
01260
01261
QStringList l =
QStringList::split( sep, extensionSource );
01262
01263
static QRegExp boringExpression(
"\\*\\.[\\d\\w]+");
01264
01265
for( QStringList::Iterator it = l.begin(); it != l.end(); ++it )
01266
if (boringExpression.
exactMatch(*it))
01267 plainExtensions.append((*it).mid(1));
01268
else
01269 regexpExtensions.append(
QRegExp((*it),
true,
true));
01270 }
01271 }
01272
01273
QValueList<QRegExp>& Highlight::getRegexpExtensions()
01274 {
01275
return regexpExtensions;
01276 }
01277
01278
QStringList& Highlight::getPlainExtensions()
01279 {
01280
return plainExtensions;
01281 }
01282
01283 QString Highlight::getMimetypes()
01284 {
01285
KConfig *config = HlManager::self()->getKConfig();
01286 config->
setGroup(
"Highlighting " + iName);
01287
01288
return config->
readEntry(
"Mimetypes", iMimetypes);
01289 }
01290
01291
int Highlight::priority()
01292 {
01293
KConfig *config = HlManager::self()->getKConfig();
01294 config->
setGroup(
"Highlighting " + iName);
01295
01296
return config->
readNumEntry(
"Priority", m_priority);
01297 }
01298
01299 HlData *Highlight::getData()
01300 {
01301
KConfig *config = HlManager::self()->getKConfig();
01302 config->
setGroup(
"Highlighting " + iName);
01303
01304 HlData *hlData =
new HlData(
01305 config->
readEntry(
"Wildcards", iWildcards),
01306 config->
readEntry(
"Mimetypes", iMimetypes),
01307 config->
readEntry(
"Identifier", identifier),
01308 config->
readNumEntry(
"Priority", m_priority));
01309
01310
return hlData;
01311 }
01312
01313
void Highlight::setData(HlData *hlData)
01314 {
01315
KConfig *config = HlManager::self()->getKConfig();
01316 config->
setGroup(
"Highlighting " + iName);
01317
01318 config->
writeEntry(
"Wildcards",hlData->wildcards);
01319 config->
writeEntry(
"Mimetypes",hlData->mimetypes);
01320 config->
writeEntry(
"Priority",hlData->priority);
01321 }
01322
01323
void Highlight::getItemDataList (uint schema,
ItemDataList &list)
01324 {
01325
KConfig *config = HlManager::self()->getKConfig();
01326 config->
setGroup(
"Highlighting " + iName +
" - Schema " + KateFactory::self()->schemaManager()->
name(schema));
01327
01328 list.
clear();
01329 createItemData(list);
01330
01331
for (ItemData *p = list.
first(); p != 0L; p = list.
next())
01332 {
01333
QStringList s = config->
readListEntry(p->name);
01334
01335
01336
if (s.count()>0)
01337 {
01338
01339
while(s.count()<9) s<<
"";
01340 p->clear();
01341
01342 QString tmp=s[0];
if (!tmp.
isEmpty()) p->defStyleNum=tmp.
toInt();
01343
01344 QRgb col;
01345
01346 tmp=s[1];
if (!tmp.
isEmpty()) {
01347 col=tmp.
toUInt(0,16); p->setTextColor(col); }
01348
01349 tmp=s[2];
if (!tmp.
isEmpty()) {
01350 col=tmp.
toUInt(0,16); p->setSelectedTextColor(col); }
01351
01352 tmp=s[3];
if (!tmp.
isEmpty()) p->setBold(tmp!=
"0");
01353
01354 tmp=s[4];
if (!tmp.
isEmpty()) p->setItalic(tmp!=
"0");
01355
01356 tmp=s[5];
if (!tmp.
isEmpty()) p->setStrikeOut(tmp!=
"0");
01357
01358 tmp=s[6];
if (!tmp.
isEmpty()) p->setUnderline(tmp!=
"0");
01359
01360 tmp=s[7];
if (!tmp.
isEmpty()) {
01361 col=tmp.
toUInt(0,16); p->setBGColor(col); }
01362
01363 tmp=s[8];
if (!tmp.
isEmpty()) {
01364 col=tmp.
toUInt(0,16); p->setSelectedBGColor(col); }
01365
01366 }
01367 }
01368 }
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
void Highlight::setItemDataList(uint schema,
ItemDataList &list)
01387 {
01388
KConfig *config = HlManager::self()->getKConfig();
01389 config->
setGroup(
"Highlighting " + iName +
" - Schema " + KateFactory::self()->schemaManager()->
name(schema));
01390
01391
QStringList settings;
01392
01393
for (ItemData *p = list.
first(); p != 0L; p = list.
next())
01394 {
01395 settings.clear();
01396 settings<<
QString::number(p->defStyleNum,10);
01397 settings<<(p->itemSet(KateAttribute::TextColor)?
QString::number(p->textColor().rgb(),16):
"");
01398 settings<<(p->itemSet(KateAttribute::SelectedTextColor)?
QString::number(p->selectedTextColor().rgb(),16):
"");
01399 settings<<(p->itemSet(KateAttribute::Weight)?(p->bold()?
"1":
"0"):
"");
01400 settings<<(p->itemSet(KateAttribute::Italic)?(p->italic()?
"1":
"0"):
"");
01401 settings<<(p->itemSet(KateAttribute::StrikeOut)?(p->strikeOut()?
"1":
"0"):
"");
01402 settings<<(p->itemSet(KateAttribute::Underline)?(p->underline()?
"1":
"0"):
"");
01403 settings<<(p->itemSet(KateAttribute::BGColor)?
QString::number(p->bgColor().rgb(),16):
"");
01404 settings<<(p->itemSet(KateAttribute::SelectedBGColor)?
QString::number(p->selectedBGColor().rgb(),16):
"");
01405 settings<<
"---";
01406 config->
writeEntry(p->name,settings);
01407 }
01408 }
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
void Highlight::use()
01422 {
01423
if (refCount == 0)
01424 init();
01425
01426 refCount++;
01427 }
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
void Highlight::release()
01441 {
01442 refCount--;
01443
01444
if (refCount == 0)
01445
done();
01446 }
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
void Highlight::init()
01460 {
01461
if (noHl)
01462
return;
01463
01464 contextList.clear ();
01465 makeContextList();
01466 }
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
void Highlight::done()
01482 {
01483
if (noHl)
01484
return;
01485
01486 contextList.clear ();
01487 }
01488
01489 HlContext *Highlight::contextNum (uint n)
01490 {
01491
return contextList[n];
01492 }
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
void Highlight::createItemData(
ItemDataList &list)
01509 {
01510
01511
if (noHl)
01512 {
01513 list.
append(
new ItemData(
I18N_NOOP(
"Normal Text"), dsNormal));
01514
return;
01515 }
01516
01517
01518
if (internalIDList.isEmpty())
01519 makeContextList();
01520
01521 list=internalIDList;
01522 }
01523
01524
void Highlight::addToItemDataList()
01525 {
01526
01527 HlManager::self()->syntax->setIdentifier(buildIdentifier);
01528
syntaxContextData *data = HlManager::self()->syntax->getGroupInfo(
"highlighting",
"itemData");
01529
01530
01531
while (HlManager::self()->syntax->nextGroup(data))
01532 {
01533
01534 QString color = HlManager::self()->syntax->groupData(data,QString(
"color"));
01535 QString selColor = HlManager::self()->syntax->groupData(data,QString(
"selColor"));
01536 QString bold = HlManager::self()->syntax->groupData(data,QString(
"bold"));
01537 QString italic = HlManager::self()->syntax->groupData(data,QString(
"italic"));
01538 QString underline = HlManager::self()->syntax->groupData(data,QString(
"underline"));
01539 QString strikeOut = HlManager::self()->syntax->groupData(data,QString(
"strikeOut"));
01540 QString bgColor = HlManager::self()->syntax->groupData(data,QString(
"backgroundColor"));
01541 QString selBgColor = HlManager::self()->syntax->groupData(data,QString(
"selBackgroundColor"));
01542
01543 ItemData* newData =
new ItemData(
01544 buildPrefix+HlManager::self()->syntax->groupData(data,QString(
"name")).simplifyWhiteSpace(),
01545 getDefStyleNum(HlManager::self()->syntax->groupData(data,QString(
"defStyleNum"))));
01546
01547
01548
01549
if (!color.
isEmpty()) newData->setTextColor(
QColor(color));
01550
if (!selColor.
isEmpty()) newData->setSelectedTextColor(
QColor(selColor));
01551
if (!bold.
isEmpty()) newData->setBold(bold==
"true" || bold==
"1");
01552
if (!italic.
isEmpty()) newData->setItalic(italic==
"true" || italic==
"1");
01553
01554
if (!underline.
isEmpty()) newData->setUnderline(underline==
"true" || underline==
"1");
01555
if (!strikeOut.
isEmpty()) newData->setStrikeOut(strikeOut==
"true" || strikeOut==
"1");
01556
if (!bgColor.
isEmpty()) newData->setBGColor(
QColor(bgColor));
01557
if (!selBgColor.
isEmpty()) newData->setSelectedBGColor(
QColor(selBgColor));
01558
01559 internalIDList.append(newData);
01560 }
01561
01562
01563
if (data)
01564 HlManager::self()->syntax->freeGroupInfo(data);
01565 }
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
int Highlight::lookupAttrName(
const QString& name,
ItemDataList &iDl)
01583 {
01584
for (uint i = 0; i < iDl.
count(); i++)
01585
if (iDl.
at(i)->name == buildPrefix+
name)
01586
return i;
01587
01588
kdDebug(13010)<<
"Couldn't resolve itemDataName"<<
endl;
01589
return 0;
01590 }
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611 HlItem *Highlight::createHlItem(
struct syntaxContextData *data,
ItemDataList &iDl,
QStringList *RegionList,
QStringList *ContextNameList)
01612 {
01613
01614
if (noHl)
01615
return 0;
01616
01617
01618 QString dataname=HlManager::self()->syntax->groupItemData(data,QString(
""));
01619
01620
01621 QString tmpAttr=HlManager::self()->syntax->groupItemData(data,QString(
"attribute")).
simplifyWhiteSpace();
01622
int attr;
01623
if (QString(
"%1").
arg(tmpAttr.
toInt())==tmpAttr)
01624 {
01625 errorsAndWarnings+=i18n(
"<B>%1</B>: Deprecated syntax. Attribute (%2) not addressed by symbolic name<BR>").
01626 arg(buildIdentifier).arg(tmpAttr);
01627 attr=tmpAttr.
toInt();
01628 }
01629
else
01630 attr=lookupAttrName(tmpAttr,iDl);
01631
01632
01633
01634
int context;
01635 QString tmpcontext=HlManager::self()->syntax->groupItemData(data,QString(
"context"));
01636
01637
01638 QString unresolvedContext;
01639 context=getIdFromString(ContextNameList, tmpcontext,unresolvedContext);
01640
01641
01642
char chr;
01643
if (! HlManager::self()->syntax->groupItemData(data,QString(
"char")).
isEmpty())
01644 chr= (HlManager::self()->syntax->groupItemData(data,QString(
"char")).
latin1())[0];
01645
else
01646 chr=0;
01647
01648
01649 QString stringdata=HlManager::self()->syntax->groupItemData(data,QString(
"String"));
01650
01651
01652
char chr1;
01653
if (! HlManager::self()->syntax->groupItemData(data,QString(
"char1")).
isEmpty())
01654 chr1= (HlManager::self()->syntax->groupItemData(data,QString(
"char1")).
latin1())[0];
01655
else
01656 chr1=0;
01657
01658
01659
bool insensitive=( HlManager::self()->syntax->groupItemData(data,QString(
"insensitive")).lower() == QString(
"true") );
01660
01661
01662
01663
bool minimal = ( HlManager::self()->syntax->groupItemData(data,QString(
"minimal")).lower() == QString(
"true") );
01664
01665
01666
01667 QString beginRegionStr=HlManager::self()->syntax->groupItemData(data,QString(
"beginRegion"));
01668 QString endRegionStr=HlManager::self()->syntax->groupItemData(data,QString(
"endRegion"));
01669
01670
signed char regionId=0;
01671
signed char regionId2=0;
01672
01673
if (!beginRegionStr.
isEmpty())
01674 {
01675 regionId = RegionList->findIndex(beginRegionStr);
01676
01677
if (regionId==-1)
01678 {
01679 (*RegionList)<<beginRegionStr;
01680 regionId = RegionList->findIndex(beginRegionStr);
01681 }
01682
01683 regionId++;
01684
01685
kdDebug () <<
"########### BEG REG: " << beginRegionStr <<
" NUM: " << regionId <<
endl;
01686 }
01687
01688
if (!endRegionStr.
isEmpty())
01689 {
01690 regionId2 = RegionList->findIndex(endRegionStr);
01691
01692
if (regionId2==-1)
01693 {
01694 (*RegionList)<<endRegionStr;
01695 regionId2 = RegionList->findIndex(endRegionStr);
01696 }
01697
01698 regionId2 = -regionId2 - 1;
01699
01700
kdDebug () <<
"########### END REG: " << endRegionStr <<
" NUM: " << regionId2 <<
endl;
01701 }
01702
01703
01704 HlItem *tmpItem;
01705
01706
if (dataname==
"keyword")
01707 {
01708 HlKeyword *keyword=
new HlKeyword(attr,context,regionId,regionId2,casesensitive,
01709 deliminator);
01710
01711
01712 keyword->addList(HlManager::self()->syntax->finddata(
"highlighting",stringdata));
01713 tmpItem=keyword;
01714 }
else
01715
if (dataname==
"Float") tmpItem= (
new HlFloat(attr,context,regionId,regionId2));
else
01716
if (dataname==
"Int") tmpItem=(
new HlInt(attr,context,regionId,regionId2));
else
01717
if (dataname==
"DetectChar") tmpItem=(
new HlCharDetect(attr,context,regionId,regionId2,chr));
else
01718
if (dataname==
"Detect2Chars") tmpItem=(
new Hl2CharDetect(attr,context,regionId,regionId2,chr,chr1));
else
01719
if (dataname==
"RangeDetect") tmpItem=(
new HlRangeDetect(attr,context,regionId,regionId2, chr, chr1));
else
01720
if (dataname==
"LineContinue") tmpItem=(
new HlLineContinue(attr,context,regionId,regionId2));
else
01721
if (dataname==
"StringDetect") tmpItem=(
new HlStringDetect(attr,context,regionId,regionId2,stringdata,insensitive));
else
01722
if (dataname==
"AnyChar") tmpItem=(
new HlAnyChar(attr,context,regionId,regionId2,stringdata));
else
01723
if (dataname==
"RegExpr") tmpItem=(
new HlRegExpr(attr,context,regionId,regionId2,stringdata, insensitive, minimal));
else
01724
if (dataname==
"HlCChar") tmpItem= (
new HlCChar(attr,context,regionId,regionId2));
else
01725
if (dataname==
"HlCHex") tmpItem= (
new HlCHex(attr,context,regionId,regionId2));
else
01726
if (dataname==
"HlCOct") tmpItem= (
new HlCOct(attr,context,regionId,regionId2));
else
01727
if (dataname==
"HlCFloat") tmpItem= (
new HlCFloat(attr,context,regionId,regionId2));
else
01728
if (dataname==
"HlCStringChar") tmpItem= (
new HlCStringChar(attr,context,regionId,regionId2));
else
01729
01730 {
01731
01732
return 0;
01733 }
01734
01735
if (!unresolvedContext.
isEmpty())
01736 {
01737 unresolvedContextReferences.insert(&(tmpItem->ctx),unresolvedContext);
01738 }
01739
return tmpItem;
01740 }
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
bool Highlight::isInWord(
QChar c)
01754 {
01755
static const QString sq(
"\"'");
01756
return deliminator.find(c) == -1 && sq.
find(c) == -1;
01757 }
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
void Highlight::readCommentConfig()
01772 {
01773 HlManager::self()->syntax->setIdentifier(buildIdentifier);
01774
syntaxContextData *data=HlManager::self()->syntax->getGroupInfo(
"general",
"comment");
01775
01776
if (data)
01777 {
01778
while (HlManager::self()->syntax->nextGroup(data))
01779 {
01780
if (HlManager::self()->syntax->groupData(data,
"name")==
"singleLine")
01781 cslStart=HlManager::self()->syntax->groupData(data,
"start");
01782
01783
if (HlManager::self()->syntax->groupData(data,
"name")==
"multiLine")
01784 {
01785 cmlStart=HlManager::self()->syntax->groupData(data,
"start");
01786 cmlEnd=HlManager::self()->syntax->groupData(data,
"end");
01787 }
01788 }
01789
01790 HlManager::self()->syntax->freeGroupInfo(data);
01791 }
01792
else
01793 {
01794 cslStart =
"";
01795 cmlStart =
"";
01796 cmlEnd =
"";
01797 }
01798 }
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
void Highlight::readGlobalKeywordConfig()
01815 {
01816
01817
kdDebug(13010)<<
"readGlobalKeywordConfig:BEGIN"<<
endl;
01818
01819 HlManager::self()->syntax->setIdentifier(buildIdentifier);
01820
syntaxContextData *data = HlManager::self()->syntax->getConfig(
"general",
"keywords");
01821
01822
if (data)
01823 {
01824
kdDebug(13010)<<
"Found global keyword config"<<
endl;
01825
01826
if (HlManager::self()->syntax->groupItemData(data,QString(
"casesensitive"))!=
"0")
01827 casesensitive=
true;
01828
else
01829 casesensitive=
false;
01830
01831
01832 weakDeliminator=(HlManager::self()->syntax->groupItemData(data,QString(
"weakDeliminator")));
01833
01834
kdDebug(13010)<<
"weak delimiters are: "<<weakDeliminator<<
endl;
01835
01836
01837
for (uint s=0; s < weakDeliminator.length(); s++)
01838 {
01839
int f = deliminator.find (weakDeliminator[s]);
01840
01841
if (f > -1)
01842 deliminator.remove (f, 1);
01843 }
01844
01845 QString addDelim = (HlManager::self()->syntax->groupItemData(data,QString(
"additionalDeliminator")));
01846
01847
if (!addDelim.
isEmpty())
01848 deliminator=deliminator+addDelim;
01849
01850 HlManager::self()->syntax->freeGroupInfo(data);
01851 }
01852
else
01853 {
01854
01855 casesensitive=
true;
01856 weakDeliminator=QString(
"");
01857 }
01858
01859
kdDebug(13010)<<
"readGlobalKeywordConfig:END"<<
endl;
01860
01861
kdDebug(13010)<<
"delimiterCharacters are: "<<deliminator<<
endl;
01862 }
01863
01864
01865
void Highlight::readFoldingConfig()
01866 {
01867
01868
kdDebug(13010)<<
"readfoldignConfig:BEGIN"<<
endl;
01869
01870 HlManager::self()->syntax->setIdentifier(buildIdentifier);
01871
syntaxContextData *data = HlManager::self()->syntax->getConfig(
"general",
"folding");
01872
01873
if (data)
01874 {
01875
kdDebug(13010)<<
"Found global keyword config"<<
endl;
01876
01877
if (HlManager::self()->syntax->groupItemData(data,QString(
"indentationsensitive"))!=
"1")
01878 m_foldingIndentationSensitive=
false;
01879
else
01880 m_foldingIndentationSensitive=
true;
01881
01882 HlManager::self()->syntax->freeGroupInfo(data);
01883 }
01884
else
01885 {
01886
01887 m_foldingIndentationSensitive =
false;
01888 }
01889
01890
kdDebug(13010)<<
"readfoldingConfig:END"<<
endl;
01891
01892
kdDebug(13010)<<
"############################ use indent for fold are: "<<m_foldingIndentationSensitive<<
endl;
01893 }
01894
01895
void Highlight::createContextNameList(
QStringList *ContextNameList,
int ctx0)
01896 {
01897
kdDebug(13010)<<
"creatingContextNameList:BEGIN"<<
endl;
01898
01899
if (ctx0 == 0)
01900 ContextNameList->clear();
01901
01902 HlManager::self()->syntax->setIdentifier(buildIdentifier);
01903
01904
syntaxContextData *data=HlManager::self()->syntax->getGroupInfo(
"highlighting",
"context");
01905
01906
int id=ctx0;
01907
01908
if (data)
01909 {
01910
while (HlManager::self()->syntax->nextGroup(data))
01911 {
01912 QString tmpAttr=HlManager::self()->syntax->groupData(data,QString(
"name")).simplifyWhiteSpace();
01913
if (tmpAttr.
isEmpty())
01914 {
01915 tmpAttr=QString(
"!KATE_INTERNAL_DUMMY! %1").
arg(
id);
01916 errorsAndWarnings +=i18n(
"<B>%1</B>: Deprecated syntax. Context %2 has no symbolic name<BR>").arg(buildIdentifier).arg(
id-ctx0);
01917 }
01918
else tmpAttr=buildPrefix+tmpAttr;
01919 (*ContextNameList)<<tmpAttr;
01920
id++;
01921 }
01922 HlManager::self()->syntax->freeGroupInfo(data);
01923 }
01924
kdDebug(13010)<<
"creatingContextNameList:END"<<
endl;
01925
01926 }
01927
01928
int Highlight::getIdFromString(
QStringList *ContextNameList, QString tmpLineEndContext, QString &unres)
01929 {
01930 unres=
"";
01931
int context;
01932
if ((tmpLineEndContext==
"#stay") || (tmpLineEndContext.
simplifyWhiteSpace().isEmpty())) context=-1;
01933
else if (tmpLineEndContext.
startsWith(
"#pop"))
01934 {
01935 context=-1;
01936
for(;tmpLineEndContext.
startsWith(
"#pop");context--)
01937 {
01938 tmpLineEndContext.
remove(0,4);
01939
kdDebug(13010)<<
"#pop found"<<
endl;
01940 }
01941 }
01942
else
01943
if ( tmpLineEndContext.
startsWith(
"##"))
01944 {
01945 QString tmp=tmpLineEndContext.
right(tmpLineEndContext.
length()-2);
01946
if (!embeddedHls.contains(tmp)) embeddedHls.insert(tmp,EmbeddedHlInfo());
01947 unres=tmp;
01948 context=0;
01949 }
01950
else
01951 {
01952 context=ContextNameList->findIndex(buildPrefix+tmpLineEndContext);
01953
if (context==-1)
01954 {
01955 context=tmpLineEndContext.
toInt();
01956 errorsAndWarnings+=i18n(
"<B>%1</B>:Deprecated syntax. Context %2 not addressed by a symbolic name").arg(buildIdentifier).arg(tmpLineEndContext);
01957 }
01958
01959
01960 }
01961
return context;
01962 }
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
void Highlight::makeContextList()
01978 {
01979
if (noHl)
01980
return;
01981
01982 embeddedHls.clear();
01983 unresolvedContextReferences.clear();
01984 RegionList.clear();
01985 ContextNameList.clear();
01986
01987
01988 embeddedHls.insert(iName,EmbeddedHlInfo());
01989
01990
bool something_changed;
01991
int startctx=0;
01992 building=
true;
01993
do
01994 {
01995
kdDebug(13010)<<
"**************** Outter loop in make ContextList"<<
endl;
01996
kdDebug(13010)<<
"**************** Hl List count:"<<embeddedHls.count()<<
endl;
01997 something_changed=
false;
01998
for (EmbeddedHlInfos::const_iterator it=embeddedHls.begin(); it!=embeddedHls.end();++it)
01999 {
02000
if (!it.data().loaded)
02001 {
02002
kdDebug(13010)<<
"**************** Inner loop in make ContextList"<<
endl;
02003 QString identifierToUse;
02004
kdDebug(13010)<<
"Trying to open highlighting definition file: "<< it.key()<<
endl;
02005
if (iName==it.key()) identifierToUse=identifier;
02006
else
02007 identifierToUse=HlManager::self()->identifierForName(it.key());
02008
02009
kdDebug(13010)<<
"Location is:"<< identifierToUse<<
endl;
02010
02011 buildPrefix=it.key()+
':';
02012
02013
if (identifierToUse.
isEmpty() )
kdDebug()<<
"OHOH, unknown highlighting description referenced"<<
endl;
02014
02015
kdDebug()<<
"setting ("<<it.key()<<
") to loaded"<<
endl;
02016 it=embeddedHls.insert(it.key(),EmbeddedHlInfo(
true,startctx));
02017 buildContext0Offset=startctx;
02018 startctx=addToContextList(identifierToUse,startctx);
02019
if (noHl)
return;
02020 something_changed=
true;
02021
02022 }
02023 }
02024 }
while (something_changed);
02025
02026
02027
02028
02029
02030
kdDebug(13010)<<
"Unresolved contexts, which need attention: "<<unresolvedContextReferences.count()<<
endl;
02031
02032
for (UnresolvedContextReferences::iterator unresIt=unresolvedContextReferences.begin();
02033 unresIt!=unresolvedContextReferences.end();++unresIt)
02034 {
02035
02036 EmbeddedHlInfos::const_iterator hlIt=embeddedHls.find(unresIt.data());
02037
if (hlIt!=embeddedHls.end())
02038 *(unresIt.key())=hlIt.data().context0;
02039 }
02040
02041
02042
02043
02044 handleIncludeRules();
02045
02046 embeddedHls.clear();
02047 unresolvedContextReferences.clear();
02048 RegionList.clear();
02049 ContextNameList.clear();
02050
02051
02052
02053
if (!errorsAndWarnings.isEmpty())
02054
KMessageBox::detailedSorry(0L,i18n(
"There were warning(s) and/or error(s) while parsing the syntax highlighting configuration."), errorsAndWarnings, i18n(
"Kate Syntax Highlight Parser"));
02055
02056
02057 building=
false;
02058 }
02059
02060
void Highlight::handleIncludeRules()
02061 {
02062
02063
02064
kdDebug(13010)<<
"IncludeRules, which need attention: " <<includeRules.count()<<
endl;
02065
if (includeRules.isEmpty())
return;
02066
02067 buildPrefix=
"";
02068 QString dummy;
02069
02070
02071
02072
02073
02074
02075
02076
for (IncludeRules::iterator it=includeRules.begin();it!=includeRules.end();)
02077 {
02078
02079
if ((*it)->incCtx==-1)
02080 {
02081
02082
if ((*it)->incCtxN.isEmpty())
02083 {
02084
02085 IncludeRules::iterator it1=it;
02086 ++it1;
02087
delete (*it);
02088 includeRules.remove(it);
02089 it=it1;
02090 }
02091
else
02092 {
02093
02094 (*it)->incCtx=getIdFromString(&ContextNameList,(*it)->incCtxN,dummy);
02095
kdDebug()<<
"Resolved "<<(*it)->incCtxN<<
" to "<<(*it)->incCtx<<
" for include rule"<<
endl;
02096
02097 }
02098 }
else ++it;
02099 }
02100
02101
02102
02103
02104
02105
while (!includeRules.isEmpty())
02106 handleIncludeRulesRecursive(includeRules.begin(),&includeRules);
02107
02108
02109 }
02110
02111
void Highlight::handleIncludeRulesRecursive(IncludeRules::iterator it,
IncludeRules *list)
02112 {
02113
if (it==list->
end())
return;
02114 IncludeRules::iterator it1=it;
02115
int ctx=(*it1)->ctx;
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
while ((it!=list->
end()) && ((*it)->ctx==ctx))
02126 {
02127 it1=it;
02128 ++it;
02129
02130 }
02131
02132
while ((it1!=list->
end()) && ((*it1)->ctx==ctx))
02133 {
02134
02135
02136
02137
int ctx1=(*it1)->incCtx;
02138
02139
02140
for (IncludeRules::iterator it2=list->
begin();it2!=list->
end();++it2)
02141 {
02142
02143
02144
if ((*it2)->ctx==ctx1)
02145 {
02146
02147
02148 handleIncludeRulesRecursive(it2,list);
02149
break;
02150 }
02151 }
02152
02153
02154 HlContext *dest=contextList[ctx];
02155 HlContext *src=contextList[ctx1];
02156 uint p=(*it1)->pos;
02157
for ( HlItem *c = src->items.first(); c; c=src->items.next(), p++ )
02158 dest->items.insert(p,c);
02159
02160 it=it1;
02161 --it1;
02162
delete (*it);
02163 list->
remove(it);
02164 }
02165 }
02166
02167
int Highlight::addToContextList(
const QString &ident,
int ctx0)
02168 {
02169 buildIdentifier=ident;
02170
syntaxContextData *data, *datasub;
02171 HlItem *c;
02172
02173 QString dummy;
02174
02175
02176
if (!HlManager::self()->syntax->setIdentifier(ident))
02177 {
02178 noHl=
true;
02179
KMessageBox::information(0L,i18n(
"Since there has been an error parsing the highlighting description, this highlighting will be disabled"));
02180
return 0;
02181 }
02182
02183 RegionList<<
"!KateInternal_TopLevel!";
02184 readCommentConfig();
02185 readGlobalKeywordConfig();
02186 readFoldingConfig ();
02187
02188 QString ctxName;
02189
02190
02191 addToItemDataList();
02192
ItemDataList iDl = internalIDList;
02193
02194 createContextNameList(&ContextNameList,ctx0);
02195
02196
kdDebug(13010)<<
"Parsing Context structure"<<
endl;
02197
02198 data=HlManager::self()->syntax->getGroupInfo(
"highlighting",
"context");
02199 uint i=buildContext0Offset;
02200
if (data)
02201 {
02202
while (HlManager::self()->syntax->nextGroup(data))
02203 {
02204
kdDebug(13010)<<
"Found a context in file, building structure now"<<
endl;
02205
02206 QString tmpAttr=HlManager::self()->syntax->groupData(data,QString(
"attribute")).
simplifyWhiteSpace();
02207
int attr;
02208
if (QString(
"%1").
arg(tmpAttr.
toInt())==tmpAttr)
02209 attr=tmpAttr.
toInt();
02210
else
02211 attr=lookupAttrName(tmpAttr,iDl);
02212
02213
02214 ctxName=buildPrefix+HlManager::self()->syntax->groupData(data,QString(
"lineEndContext")).
simplifyWhiteSpace();
02215
02216 QString tmpLineEndContext=HlManager::self()->syntax->groupData(data,QString(
"lineEndContext")).
simplifyWhiteSpace();
02217
int context;
02218
02219 context=getIdFromString(&ContextNameList, tmpLineEndContext,dummy);
02220
02221
02222
bool ft =
false;
02223
int ftc = 0;
02224
if ( i > 0 ) {
02225 QString tmpFt = HlManager::self()->syntax->groupData(data, QString(
"fallthrough") );
02226
if ( tmpFt.
lower() ==
"true" || tmpFt.
toInt() == 1 )
02227 ft =
true;
02228
if ( ft ) {
02229 QString tmpFtc = HlManager::self()->syntax->groupData( data, QString(
"fallthroughContext") );
02230
02231 ftc=getIdFromString(&ContextNameList, tmpFtc,dummy);
02232
if (ftc == -1) ftc =0;
02233
02234
kdDebug(13010)<<
"Setting fall through context (context "<<i<<
"): "<<ftc<<
endl;
02235 }
02236 }
02237
02238
02239 contextList.insert (i,
new HlContext (
02240 attr,
02241 context,
02242 (HlManager::self()->syntax->groupData(data,QString(
"lineBeginContext"))).isEmpty()?-1:
02243 (HlManager::self()->syntax->groupData(data,QString(
"lineBeginContext"))).toInt(),
02244 ft, ftc
02245 ));
02246
02247
02248
02249
while (HlManager::self()->syntax->nextItem(data))
02250 {
02251
02252
02253
02254
02255 QString tag = HlManager::self()->syntax->groupItemData(data,QString(
""));
02256
if ( tag ==
"IncludeRules" ) {
02257 QString incCtx=HlManager::self()->syntax->groupItemData( data, QString(
"context"));
02258
02259
if (incCtx.
startsWith(
"##") || (!incCtx.
startsWith(
"#"))) {
02260
if (!incCtx.
startsWith(
"#")) {
02261 incCtx=buildPrefix+incCtx.
simplifyWhiteSpace();
02262 includeRules.append(
new IncludeRule(i,contextList[i]->items.count(),incCtx));
02263 }
02264
else {
02265
kdDebug()<<
"Cross highlight reference <IncludeRules>"<<
endl;
02266 IncludeRule *ir=
new IncludeRule(i,contextList[i]->items.count());
02267
02268
if (!embeddedHls.contains(incCtx.
right(incCtx.
length()-2)))
02269 embeddedHls.insert(incCtx.
right(incCtx.
length()-2),EmbeddedHlInfo());
02270 unresolvedContextReferences.insert(&(ir->incCtx),
02271 incCtx.
right(incCtx.
length()-2));
02272 includeRules.append(ir);
02273 }
02274 }
02275
continue;
02276 }
02277
#if 0
02278
QString tag = HlManager::self()->syntax->groupItemData(data,QString(
""));
02279
if ( tag ==
"IncludeRules" ) {
02280
02281
int ctxId = getIdFromString(&ContextNameList,
02282 HlManager::self()->syntax->groupItemData( data, QString(
"context")),dummy);
02283
if ( ctxId > -1) {
02284
kdDebug(13010)<<
"makeContextList["<<i<<
"]: including all items of context "<<ctxId<<
endl;
02285
if ( ctxId < (
int) i ) {
02286
for ( c = contextList[ctxId]->items.first(); c; c = contextList[ctxId]->items.next() )
02287 contextList[i]->items.append(c);
02288 }
02289
else
02290
kdDebug(13010)<<
"Context "<<ctxId<<
"not defined. You can not include the rules of an undefined context"<<
endl;
02291 }
02292
continue;
02293 }
02294
#endif
02295
c=createHlItem(data,iDl,&RegionList,&ContextNameList);
02296
if (c)
02297 {
02298 contextList[i]->items.append(c);
02299
02300
02301 datasub=HlManager::self()->syntax->getSubItems(data);
02302
bool tmpbool;
02303
if (tmpbool=HlManager::self()->syntax->nextItem(datasub))
02304 {
02305 c->subItems=
new QPtrList<HlItem>;
02306
for (;tmpbool;tmpbool=HlManager::self()->syntax->nextItem(datasub))
02307 c->subItems->append(createHlItem(datasub,iDl,&RegionList,&ContextNameList));
02308 }
02309 HlManager::self()->syntax->freeGroupInfo(datasub);
02310
02311 }
02312
02313 }
02314 i++;
02315 }
02316 }
02317
02318 HlManager::self()->syntax->freeGroupInfo(data);
02319
if (RegionList.count()!=1) folding=
true;
02320 folding = folding || m_foldingIndentationSensitive;
02321
return i;
02322 }
02323
02324
void Highlight::clearAttributeArrays ()
02325 {
02326
for (
QIntDictIterator< QMemArray<KateAttribute> > it( m_attributeArrays ); it.
current(); ++it )
02327 {
02328
02329
KateAttributeList defaultStyleList;
02330 defaultStyleList.
setAutoDelete(
true);
02331 HlManager::self()->getDefaults(it.
currentKey(), defaultStyleList);
02332
02333
ItemDataList itemDataList;
02334 getItemDataList(it.
currentKey(), itemDataList);
02335
02336 uint nAttribs = itemDataList.
count();
02337
QMemArray<KateAttribute> *array = it.
current();
02338 array->
resize (nAttribs);
02339
02340
for (uint z = 0; z < nAttribs; z++)
02341 {
02342 ItemData *itemData = itemDataList.
at(z);
02343
KateAttribute n = *defaultStyleList.
at(itemData->defStyleNum);
02344
02345
if (itemData && itemData->isSomethingSet())
02346 n += *itemData;
02347
02348 array->
at(z) = n;
02349 }
02350 }
02351 }
02352
02353
QMemArray<KateAttribute> *Highlight::attributes (uint schema)
02354 {
02355
QMemArray<KateAttribute> *array;
02356
02357
02358
if ((array = m_attributeArrays[schema]))
02359
return array;
02360
02361
02362
if (!KateFactory::self()->schemaManager()->validSchema(schema))
02363 {
02364
02365
return attributes (0);
02366 }
02367
02368
02369
KateAttributeList defaultStyleList;
02370 defaultStyleList.
setAutoDelete(
true);
02371 HlManager::self()->getDefaults(schema, defaultStyleList);
02372
02373
ItemDataList itemDataList;
02374 getItemDataList(schema, itemDataList);
02375
02376 uint nAttribs = itemDataList.
count();
02377 array =
new QMemArray<KateAttribute> (nAttribs);
02378
02379
for (uint z = 0; z < nAttribs; z++)
02380 {
02381 ItemData *itemData = itemDataList.
at(z);
02382
KateAttribute n = *defaultStyleList.
at(itemData->defStyleNum);
02383
02384
if (itemData && itemData->isSomethingSet())
02385 n += *itemData;
02386
02387 array->
at(z) = n;
02388 }
02389
02390 m_attributeArrays.insert(schema, array);
02391
02392
return array;
02393 }
02394
02395
void Highlight::getItemDataListCopy (uint schema,
ItemDataList &outlist)
02396 {
02397
ItemDataList itemDataList;
02398 getItemDataList(schema, itemDataList);
02399
02400 outlist.
clear ();
02401 outlist.
setAutoDelete (
true);
02402
for (uint z=0; z < itemDataList.
count(); z++)
02403 outlist.
append (
new ItemData (*itemDataList.
at(z)));
02404 }
02405
02406
02407
02408
02409 HlManager::HlManager()
02410 :
QObject()
02411 , m_config ("katesyntaxhighlightingrc", false, false)
02412 , commonSuffixes (
QStringList::split(";
", ".orig;.new;~;.bak;.BAK
"))
02413
, syntax (new SyntaxDocument())
02414
{
02415
hlList.setAutoDelete(true);
02416
hlDict.setAutoDelete(false);
02417
02418
SyntaxModeList modeList = syntax->modeList();
02419
for (uint i=0; i < modeList.count(); i++)
02420
{
02421
Highlight *hl = new Highlight(modeList.at(i));
02422
02423
uint insert = 0;
02424
for (; insert <= hlList.count(); insert++)
02425
{
02426
if (insert == hlList.count())
02427
break;
02428
02429
if ( QString(hlList.at(insert)->section() + hlList.at(insert)->name()).lower()
02430
> QString(hl->section() + hl->name()).lower() )
02431
break;
02432
}
02433
02434
hlList.insert (insert, hl);
02435
hlDict.insert (hl->name(), hl);
02436
}
02437
02438
// Normal HL
02439
Highlight *hl = new Highlight(0);
02440
hlList.prepend (hl);
02441
hlDict.insert (hl->name(), hl);
02442
}
02443
02444
HlManager::~HlManager()
02445
{
02446
delete syntax;
02447
}
02448
02449
static KStaticDeleter<HlManager> sdHlMan;
02450
02451
HlManager *HlManager::self()
02452
{
02453
if ( !s_self )
02454
sdHlMan.setObject(s_self, new HlManager ());
02455
02456
return s_self;
02457
}
02458
02459
Highlight *HlManager::getHl(int n)
02460
{
02461
if (n < 0 || n >= (int) hlList.count())
02462
n = 0;
02463
02464
return hlList.at(n);
02465
}
02466
02467
int HlManager::nameFind(const QString &name)
02468
{
02469
int z (hlList.count() - 1);
02470
for (; z > 0; z--)
02471
if (hlList.at(z)->name() == name)
02472
return z;
02473
02474
return z;
02475
}
02476
02477
int HlManager::detectHighlighting (KateDocument *doc)
02478
{
02479
int hl = wildcardFind( doc->url().filename() );
02480
02481
if (hl == -1)
02482
{
02483
QByteArray buf (KATE_HL_HOWMANY);
02484
uint bufpos = 0;
02485
for (uint i=0; i < doc->numLines(); i++)
02486
{
02487
QString line = doc->textLine( i );
02488
uint len = line.length() + 1;
02489
02490
if (bufpos + len > KATE_HL_HOWMANY)
02491
len = KATE_HL_HOWMANY - bufpos;
02492
02493
memcpy(&buf[bufpos], (line + "\n
").latin1(), len);
02494
02495
bufpos += len;
02496
02497
if (bufpos >= KATE_HL_HOWMANY)
02498
break;
02499
}
02500
buf.resize( bufpos );
02501
02502
hl = mimeFind (buf);
02503
}
02504
02505
return hl;
02506
}
02507
02508
int HlManager::wildcardFind(const QString &fileName)
02509
{
02510
int result = -1;
02511
if ((result = realWildcardFind(fileName)) != -1)
02512
return result;
02513
02514
int length = fileName.length();
02515
QString backupSuffix = KateDocumentConfig::global()->backupSuffix();
02516
if (fileName.endsWith(backupSuffix)) {
02517
if ((result = realWildcardFind(fileName.left(length - backupSuffix.length()))) != -1)
02518
return result;
02519
}
02520
02521
for (QStringList::Iterator it = commonSuffixes.begin(); it != commonSuffixes.end(); ++it) {
02522
if (*it != backupSuffix && fileName.endsWith(*it)) {
02523
if ((result = realWildcardFind(fileName.left(length - (*it).length()))) != -1)
02524
return result;
02525
}
02526
}
02527
02528
return -1;
02529
}
02530
02531
int HlManager::realWildcardFind(const QString &fileName)
02532
{
02533
static QRegExp sep("\\s*;\\s*
");
02534
02535
QPtrList<Highlight> highlights;
02536
02537
for (Highlight *highlight = hlList.first(); highlight != 0L; highlight = hlList.next()) {
02538
highlight->loadWildcards();
02539
02540
for (QStringList::Iterator it = highlight->getPlainExtensions().begin(); it != highlight->getPlainExtensions().end(); ++it)
02541
if (fileName.endsWith((*it)))
02542
highlights.append(highlight);
02543
02544
for (int i = 0; i < (int)highlight->getRegexpExtensions().count(); i++) {
02545
QRegExp re = highlight->getRegexpExtensions()[i];
02546
if (re.exactMatch(fileName))
02547
highlights.append(highlight);
02548
}
02549
}
02550
02551
if ( !highlights.isEmpty() )
02552
{
02553
int pri = -1;
02554
int hl = -1;
02555
02556
for (Highlight *highlight = highlights.first(); highlight != 0L; highlight = highlights.next())
02557
{
02558
if (highlight->priority() > pri)
02559
{
02560
pri = highlight->priority();
02561
hl = hlList.findRef (highlight);
02562
}
02563
}
02564
02565
return hl;
02566
}
02567
02568
return -1;
02569
}
02570
02571
int HlManager::mimeFind(const QByteArray &contents)
02572
{
02573
static QRegExp sep("\\s*;\\s*
");
02574
02575
int accuracy = 0;
02576
KMimeType::Ptr mt = KMimeType::findByContent( contents, &accuracy );
02577
02578
QPtrList<Highlight> highlights;
02579
02580
for (Highlight *highlight = hlList.first(); highlight != 0L; highlight = hlList.next())
02581
{
02582
QStringList l = QStringList::split( sep, highlight->getMimetypes() );
02583
02584
for( QStringList::Iterator it = l.begin(); it != l.end(); ++it )
02585
{
02586
if ( *it == mt->name() ) // faster than a regexp i guess?
02587
highlights.append (highlight);
02588
}
02589
}
02590
02591
if ( !highlights.isEmpty() )
02592
{
02593
int pri = -1;
02594
int hl = -1;
02595
02596
for (Highlight *highlight = highlights.first(); highlight != 0L; highlight = highlights.next())
02597
{
02598
if (highlight->priority() > pri)
02599
{
02600
pri = highlight->priority();
02601
hl = hlList.findRef (highlight);
02602
}
02603
}
02604
02605
return hl;
02606
}
02607
02608
return -1;
02609
}
02610
02611
uint HlManager::defaultStyles()
02612
{
02613
return 10;
02614
}
02615
02616
QString HlManager::defaultStyleName(int n)
02617
{
02618
static QStringList names;
02619
02620
if (names.isEmpty())
02621
{
02622
names << i18n("Normal
");
02623
names << i18n("Keyword
");
02624
names << i18n("Data Type
");
02625
names << i18n("Decimal/Value
");
02626
names << i18n("Base-N Integer
");
02627
names << i18n("Floating Point
");
02628
names << i18n("Character
");
02629
names << i18n("String
");
02630
names << i18n("Comment
");
02631
names << i18n("Others
");
02632
}
02633
02634
return names[n];
02635
}
02636
02637
void HlManager::getDefaults(uint schema, KateAttributeList &list)
02638
{
02639
list.setAutoDelete(true);
02640
02641
KateAttribute* normal = new KateAttribute();
02642
normal->setTextColor(Qt::black);
02643
normal->setSelectedTextColor(Qt::white);
02644
list.append(normal);
02645
02646
KateAttribute* keyword = new KateAttribute();
02647
keyword->setTextColor(Qt::black);
02648
keyword->setSelectedTextColor(Qt::white);
02649
keyword->setBold(true);
02650
list.append(keyword);
02651
02652
KateAttribute* dataType = new KateAttribute();
02653
dataType->setTextColor(Qt::darkRed);
02654
dataType->setSelectedTextColor(Qt::white);
02655
list.append(dataType);
02656
02657
KateAttribute* decimal = new KateAttribute();
02658
decimal->setTextColor(Qt::blue);
02659
decimal->setSelectedTextColor(Qt::cyan);
02660
list.append(decimal);
02661
02662
KateAttribute* basen = new KateAttribute();
02663
basen->setTextColor(Qt::darkCyan);
02664
basen->setSelectedTextColor(Qt::cyan);
02665
list.append(basen);
02666
02667
KateAttribute* floatAttribute = new KateAttribute();
02668
floatAttribute->setTextColor(Qt::darkMagenta);
02669
floatAttribute->setSelectedTextColor(Qt::cyan);
02670
list.append(floatAttribute);
02671
02672
KateAttribute* charAttribute = new KateAttribute();
02673
charAttribute->setTextColor(Qt::magenta);
02674
charAttribute->setSelectedTextColor(Qt::magenta);
02675
list.append(charAttribute);
02676
02677
KateAttribute* string = new KateAttribute();
02678
string->setTextColor(Qt::red);
02679
string->setSelectedTextColor(Qt::red);
02680
list.append(string);
02681
02682
KateAttribute* comment = new KateAttribute();
02683
comment->setTextColor(Qt::darkGray);
02684
comment->setSelectedTextColor(Qt::gray);
02685
comment->setItalic(true);
02686
list.append(comment);
02687
02688
KateAttribute* others = new KateAttribute();
02689
others->setTextColor(Qt::darkGreen);
02690
others->setSelectedTextColor(Qt::green);
02691
list.append(others);
02692
02693
KConfig *config = HlManager::self()->self()->getKConfig();
02694
config->setGroup("Default Item Styles - Schema
" + KateFactory::self()->schemaManager()->name(schema));
02695
02696
for (uint z = 0; z < defaultStyles(); z++)
02697
{
02698
KateAttribute *i = list.at(z);
02699
QStringList s = config->readListEntry(defaultStyleName(z));
02700
02701
if (!s.isEmpty())
02702
{
02703
while( s.count()<8)
02704
s << "";
02705
02706
QString tmp;
02707
QRgb col;
02708
02709
tmp=s[0]; if (!tmp.isEmpty()) {
02710
col=tmp.toUInt(0,16); i->setTextColor(col); }
02711
02712
tmp=s[1]; if (!tmp.isEmpty()) {
02713
col=tmp.toUInt(0,16); i->setSelectedTextColor(col); }
02714
02715
tmp=s[2]; if (!tmp.isEmpty()) i->setBold(tmp!="0
");
02716
02717
tmp=s[3]; if (!tmp.isEmpty()) i->setItalic(tmp!="0
");
02718
02719
tmp=s[4]; if (!tmp.isEmpty()) i->setStrikeOut(tmp!="0
");
02720
02721
tmp=s[5]; if (!tmp.isEmpty()) i->setUnderline(tmp!="0
");
02722
02723
tmp=s[6]; if (!tmp.isEmpty()) {
02724
col=tmp.toUInt(0,16); i->setBGColor(col); }
02725
02726
tmp=s[7]; if (!tmp.isEmpty()) {
02727
col=tmp.toUInt(0,16); i->setSelectedBGColor(col); }
02728
02729
}
02730
02731
}
02732
}
02733
02734
void HlManager::setDefaults(uint schema, KateAttributeList &list)
02735
{
02736
KConfig *config = HlManager::self()->self()->getKConfig();
02737
config->setGroup("Default Item Styles - Schema
" + KateFactory::self()->schemaManager()->name(schema));
02738
02739
for (uint z = 0; z < defaultStyles(); z++)
02740
{
02741
QStringList settings;
02742
KateAttribute *i = list.at(z);
02743
02744
settings<<(i->itemSet(KateAttribute::TextColor)?QString::number(i->textColor().rgb(),16):"");
02745
settings<<(i->itemSet(KateAttribute::SelectedTextColor)?QString::number(i->selectedTextColor().rgb(),16):"");
02746
settings<<(i->itemSet(KateAttribute::Weight)?(i->bold()?"1
":"0
"):"");
02747
settings<<(i->itemSet(KateAttribute::Italic)?(i->italic()?"1
":"0
"):"");
02748
settings<<(i->itemSet(KateAttribute::StrikeOut)?(i->strikeOut()?"1
":"0
"):"");
02749
settings<<(i->itemSet(KateAttribute::Underline)?(i->underline()?"1
":"0
"):"");
02750
settings<<(i->itemSet(KateAttribute::BGColor)?QString::number(i->bgColor().rgb(),16):"");
02751
settings<<(i->itemSet(KateAttribute::SelectedBGColor)?QString::number(i->selectedBGColor().rgb(),16):"");
02752
settings<<"---
";
02753
02754
config->writeEntry(defaultStyleName(z),settings);
02755
}
02756
02757
emit changed();
02758
}
02759
02760
int HlManager::highlights()
02761
{
02762
return (int) hlList.count();
02763
}
02764
02765
QString HlManager::hlName(int n)
02766
{
02767
return hlList.at(n)->name();
02768
}
02769
02770
QString HlManager::hlSection(int n)
02771
{
02772
return hlList.at(n)->section();
02773
}
02774
02775
QString HlManager::identifierForName(const QString& name)
02776
{
02777
Highlight *hl = 0;
02778
02779
if ((hl = hlDict[name]))
02780
return hl->getIdentifier ();
02781
02782
return QString();
02783
}
02784
//END
02785
02786
void KateViewHighlightAction::init()
02787
{
02788
m_doc = 0;
02789
subMenus.setAutoDelete( true );
02790
02791
connect(popupMenu(),SIGNAL(aboutToShow()),this,SLOT(slotAboutToShow()));
02792
}
02793
02794
void KateViewHighlightAction::updateMenu (Kate::Document *doc)
02795
{
02796
m_doc = doc;
02797
}
02798
02799
void KateViewHighlightAction::slotAboutToShow()
02800
{
02801
Kate::Document *doc=m_doc;
02802
int count = HlManager::self()->highlights();
02803
02804
for (int z=0; z<count; z++)
02805
{
02806
QString hlName = HlManager::self()->hlName (z);
02807
QString hlSection = HlManager::self()->hlSection (z);
02808
02809
if ( !hlSection.isEmpty() && (names.contains(hlName) < 1) )
02810
{
02811
if (subMenusName.contains(hlSection) < 1)
02812
{
02813
subMenusName << hlSection;
02814
QPopupMenu *menu = new QPopupMenu ();
02815
subMenus.append(menu);
02816
popupMenu()->insertItem (hlSection, menu);
02817
}
02818
02819
int m = subMenusName.findIndex (hlSection);
02820
names << hlName;
02821
subMenus.at(m)->insertItem ( hlName, this, SLOT(setHl(int)), 0, z);
02822
}
02823
else if (names.contains(hlName) < 1)
02824
{
02825
names << hlName;
02826
popupMenu()->insertItem ( hlName, this, SLOT(setHl(int)), 0, z);
02827
}
02828
}
02829
02830
if (!doc) return;
02831
02832
for (uint i=0;i<subMenus.count();i++)
02833
{
02834
for (uint i2=0;i2<subMenus.at(i)->count();i2++)
02835
subMenus.at(i)->setItemChecked(subMenus.at(i)->idAt(i2),false);
02836
}
02837
popupMenu()->setItemChecked (0, false);
02838
02839
int i = subMenusName.findIndex (HlManager::self()->hlSection(doc->hlMode()));
02840
if (i >= 0 && subMenus.at(i))
02841
subMenus.at(i)->setItemChecked (doc->hlMode(), true);
02842
else
02843
popupMenu()->setItemChecked (0, true);
02844
}
02845
02846
void KateViewHighlightAction::setHl (int mode)
02847
{
02848
Kate::Document *doc=m_doc;
02849
02850
if (doc)
02851
doc->setHlMode((uint)mode);
02852
}
02853
02854
// kate: space-indent on; indent-width 2; replace-tabs on;