00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "katehighlight.h"
00023 #include "katetextline.h"
00024 #include "katedocument.h"
00025 #include "katesyntaxdocument.h"
00026
00027 #include "kglobal.h"
00028
00029
00030 #include "klocale.h"
00031
00032 #include "kglobalsettings.h"
00033 #include "kdebug.h"
00034 #include "kstddirs.h"
00035
00036
00037 #include <opie2/odebug.h>
00038 #include <qpe/config.h>
00039
00040
00041 #include <qtextstream.h>
00042
00043
00044 #include <string.h>
00045
00046
00047 HlManager *HlManager::s_pSelf = 0;
00048
00049 enum Item_styles { dsNormal,dsKeyword,dsDataType,dsDecVal,dsBaseN,dsFloat,dsChar,dsString,dsComment,dsOthers};
00050
00051 static bool trueBool = true;
00052 static QString stdDeliminator = QString ("!%&()*+,-./:;<=>?[]^{|}~ \t\\");
00053
00054 int getDefStyleNum(QString name)
00055 {
00056 if (name=="dsNormal") return dsNormal;
00057 if (name=="dsKeyword") return dsKeyword;
00058 if (name=="dsDataType") return dsDataType;
00059 if (name=="dsDecVal") return dsDecVal;
00060 if (name=="dsBaseN") return dsBaseN;
00061 if (name=="dsFloat") return dsFloat;
00062 if (name=="dsChar") return dsChar;
00063 if (name=="dsString") return dsString;
00064 if (name=="dsComment") return dsComment;
00065 if (name=="dsOthers") return dsOthers;
00066
00067 return dsNormal;
00068 }
00069
00070 bool ustrchr(const QChar *s, uint len, QChar c)
00071 {
00072 for (int z=0; z < len; z++)
00073 {
00074 if (*s == c) return true;
00075 s++;
00076 }
00077
00078 return false;
00079 }
00080
00081 HlItem::HlItem(int attribute, int context)
00082 : attr(attribute), ctx(context) {subItems=0;
00083 }
00084
00085 HlItem::~HlItem()
00086 {
00087
00088 if (subItems!=0) {subItems->setAutoDelete(true); subItems->clear(); delete subItems;}
00089 }
00090
00091 bool HlItem::startEnable(QChar c)
00092 {
00093 return true;
00094 }
00095
00096 HlCharDetect::HlCharDetect(int attribute, int context, QChar c)
00097 : HlItem(attribute,context), sChar(c) {
00098 }
00099
00100 const QChar *HlCharDetect::checkHgl(const QChar *str, int len, bool) {
00101 if (*str == sChar) return str + 1;
00102 return 0L;
00103 }
00104
00105 Hl2CharDetect::Hl2CharDetect(int attribute, int context, QChar ch1, QChar ch2)
00106 : HlItem(attribute,context) {
00107 sChar1 = ch1;
00108 sChar2 = ch2;
00109 }
00110
00111 const QChar *Hl2CharDetect::checkHgl(const QChar *str, int len, bool) {
00112 if (str[0] == sChar1 && str[1] == sChar2) return str + 2;
00113 return 0L;
00114 }
00115
00116 HlStringDetect::HlStringDetect(int attribute, int context, const QString &s, bool inSensitive)
00117 : HlItem(attribute, context), str(inSensitive ? s.upper():s), _inSensitive(inSensitive) {
00118 }
00119
00120 HlStringDetect::~HlStringDetect() {
00121 }
00122
00123 const QChar *HlStringDetect::checkHgl(const QChar *s, int len, bool) {
00124 if (!_inSensitive) {if (memcmp(s, str.unicode(), str.length()*sizeof(QChar)) == 0) return s + str.length();}
00125 else
00126 {
00127 QString tmp=QString(s,str.length()).upper();
00128 if (tmp==str) return s+str.length();
00129 }
00130 return 0L;
00131 }
00132
00133
00134 HlRangeDetect::HlRangeDetect(int attribute, int context, QChar ch1, QChar ch2)
00135 : HlItem(attribute,context) {
00136 sChar1 = ch1;
00137 sChar2 = ch2;
00138 }
00139
00140 const QChar *HlRangeDetect::checkHgl(const QChar *s, int len, bool) {
00141 if (*s == sChar1)
00142 {
00143 do
00144 {
00145 s++;
00146 len--;
00147 if (len == 0) return 0L;
00148 }
00149 while (*s != sChar2);
00150
00151 return s + 1;
00152 }
00153 return 0L;
00154 }
00155
00156 HlKeyword::HlKeyword (int attribute, int context,bool casesensitive, const QChar *deliminator, uint deliLen)
00157 : HlItem(attribute,context), dict (113, casesensitive)
00158 {
00159 deliminatorChars = deliminator;
00160 deliminatorLen = deliLen;
00161 _caseSensitive=casesensitive;
00162 }
00163
00164 HlKeyword::~HlKeyword() {
00165 }
00166
00167 bool HlKeyword::startEnable(QChar c)
00168 {
00169 return ustrchr(deliminatorChars, deliminatorLen, c);
00170 }
00171
00172
00173
00174 void HlKeyword::addWord(const QString &word)
00175 {
00176 words.append(word);
00177 dict.insert(word,&trueBool);
00178 }
00179
00180 void HlKeyword::addList(const QStringList& list)
00181 {
00182
00183 words+=list;
00184 for(uint i=0;i<list.count();i++) dict.insert(list[i], &trueBool);
00185 }
00186
00187 const QChar *HlKeyword::checkHgl(const QChar *s, int len, bool b)
00188 {
00189 if (len == 0) return 0L;
00190
00191 const QChar *s2 = s;
00192
00193 while ( (len > 0) && (!ustrchr(deliminatorChars, deliminatorLen, *s2)) )
00194 {
00195 s2++;
00196 len--;
00197 }
00198
00199 if (s2 == s) return 0L;
00200
00201 QString lookup = QString(s,s2-s);
00202
00203 if ( dict.find(lookup) ) return s2;
00204 return 0L;
00205 }
00206
00207 HlInt::HlInt(int attribute, int context)
00208 : HlItem(attribute,context) {
00209 }
00210
00211 const QChar *HlInt::checkHgl(const QChar *str, int len, bool) {
00212 const QChar *s,*s1;
00213
00214 s = str;
00215 while (s->isDigit()) s++;
00216 if (s > str)
00217 {
00218 if (subItems)
00219 {
00220 for (HlItem *it=subItems->first();it;it=subItems->next())
00221 {
00222 s1=it->checkHgl(s, len, false);
00223 if (s1) return s1;
00224 }
00225 }
00226 return s;
00227 }
00228 return 0L;
00229 }
00230
00231 HlFloat::HlFloat(int attribute, int context)
00232 : HlItem(attribute,context) {
00233 }
00234
00235 const QChar *HlFloat::checkHgl(const QChar *s, int len, bool) {
00236 bool b, p;
00237 const QChar *s1;
00238
00239 b = false;
00240 while (s->isDigit()){
00241 s++;
00242 b = true;
00243 }
00244 if (p = (*s == '.')) {
00245 s++;
00246 while (s->isDigit()) {
00247 s++;
00248 b = true;
00249 }
00250 }
00251 if (!b) return 0L;
00252 if ((*s&0xdf) == 'E') s++;
00253 else
00254 if (!p) return 0L;
00255 else
00256 {
00257 if (subItems)
00258 {
00259 for (HlItem *it=subItems->first();it;it=subItems->next())
00260 {
00261 s1=it->checkHgl(s, len, false);
00262 if (s1) return s1;
00263 }
00264 }
00265 return s;
00266 }
00267 if ((*s == '-')||(*s =='+')) s++;
00268 b = false;
00269 while (s->isDigit()) {
00270 s++;
00271 b = true;
00272 }
00273 if (b)
00274 {
00275 if (subItems)
00276 {
00277 for (HlItem *it=subItems->first();it;it=subItems->next())
00278 {
00279 s1=it->checkHgl(s, len, false);
00280 if (s1) return s1;
00281 }
00282 }
00283 return s;
00284 }
00285 else return 0L;
00286 }
00287
00288
00289 HlCInt::HlCInt(int attribute, int context)
00290 : HlInt(attribute,context) {
00291 }
00292
00293 const QChar *HlCInt::checkHgl(const QChar *s, int len, bool lineStart) {
00294
00295
00296 s = HlInt::checkHgl(s, len, lineStart);
00297 if (s != 0L) {
00298 int l = 0;
00299 int u = 0;
00300 const QChar *str;
00301
00302 do {
00303 str = s;
00304 if ((*s&0xdf) == 'L' ) {
00305 l++;
00306 if (l > 2) return 0L;
00307 s++;
00308 }
00309 if ((*s&0xdf) == 'U' ){
00310 u++;
00311 if (u > 1) return 0L;
00312 s++;
00313 }
00314 } while (s != str);
00315 }
00316 return s;
00317 }
00318
00319 HlCOct::HlCOct(int attribute, int context)
00320 : HlItem(attribute,context) {
00321 }
00322
00323 const QChar *HlCOct::checkHgl(const QChar *str, int len, bool) {
00324 const QChar *s;
00325
00326 if (*str == '0') {
00327 str++;
00328 s = str;
00329 while (*s >= '0' && *s <= '7') s++;
00330 if (s > str) {
00331 if ((*s&0xdf) == 'L' || (*s&0xdf) == 'U' ) s++;
00332 return s;
00333 }
00334 }
00335 return 0L;
00336 }
00337
00338 HlCHex::HlCHex(int attribute, int context)
00339 : HlItem(attribute,context) {
00340 }
00341
00342 const QChar *HlCHex::checkHgl(const QChar *str, int len, bool) {
00343 const QChar *s=str;
00344 #if 0
00345 int i;
00346 for (i=0;(*s)!='\0';s++,i++);
00347 QString line(str,i);
00348 QRegExp3 rx("0[xX][a-fA-F\\d]+[UuLl]?");
00349 int pos=rx.search(line,0);
00350 if(pos > -1) return str+rx.matchedLength();
00351 else
00352 return 0L;
00353
00354 #else
00355 if (str[0] == '0' && ((str[1]&0xdf) == 'X' )) {
00356 str += 2;
00357 s = str;
00358 while (s->isDigit() || ((*s&0xdf) >= 'A' && (*s&0xdf) <= 'F') ) s++;
00359 if (s > str) {
00360 if ((*s&0xdf) == 'L' || (*s&0xdf) == 'U' ) s++;
00361 return s;
00362 }
00363 }
00364 return 0L;
00365 #endif
00366 }
00367
00368 HlCFloat::HlCFloat(int attribute, int context)
00369 : HlFloat(attribute,context) {
00370 }
00371
00372 const QChar *HlCFloat::checkHgl(const QChar *s, int len, bool lineStart) {
00373
00374 s = HlFloat::checkHgl(s, len, lineStart);
00375 if (s && ((*s&0xdf) == 'F' )) s++;
00376 return s;
00377 }
00378
00379 HlAnyChar::HlAnyChar(int attribute, int context, const QChar* charList, uint len)
00380 : HlItem(attribute, context) {
00381 _charList=charList;
00382 _charListLen=len;
00383 }
00384
00385 const QChar *HlAnyChar::checkHgl(const QChar *s, int len, bool)
00386 {
00387 if (ustrchr(_charList, _charListLen, *s)) return s +1;
00388 return 0L;
00389 }
00390
00391 HlRegExpr::HlRegExpr(int attribute, int context,QString regexp)
00392 : HlItem(attribute, context) {
00393
00394 handlesLinestart=regexp.startsWith("^");
00395 if(!handlesLinestart) regexp.prepend("^");
00396 Expr=new QRegExp3(regexp);
00397 }
00398
00399 const QChar *HlRegExpr::checkHgl(const QChar *s, int len, bool lineStart)
00400 {
00401 if ((!lineStart) && handlesLinestart) return 0;
00402
00403 QString line(s,len);
00404 int pos = Expr->search( line, 0 );
00405 if (pos==-1) return 0L;
00406 else
00407 return (s+Expr->matchedLength());
00408 };
00409
00410
00411 HlLineContinue::HlLineContinue(int attribute, int context)
00412 : HlItem(attribute,context) {
00413 }
00414
00415 const QChar *HlLineContinue::checkHgl(const QChar *s, int len, bool) {
00416
00417 if ((s[0].latin1() == '\\') && (len == 1))
00418 {
00419 return s + 1;
00420 }
00421 return 0L;
00422 }
00423
00424
00425 HlCStringChar::HlCStringChar(int attribute, int context)
00426 : HlItem(attribute,context) {
00427 }
00428
00429
00430 const QChar *checkCharHexOct(const QChar *str) {
00431 const QChar *s;
00432 s=str;
00433 int n;
00434 if (*s == 'x') {
00435 n = 0;
00436 do {
00437 s++;
00438 n *= 16;
00439 if (s->isDigit()) n += *s - '0';
00440 else if ((*s&0xdf) >= 'A' && (*s&0xdf) <= 'F') n += (*s&0xdf) - 'A' + 10;
00441
00442 else break;
00443 if (n >= 256) return 0L;
00444 } while (true);
00445 if (s - str == 1) return 0L;
00446 } else {
00447 if (!(*s >= '0' && *s <= '7')) return 0L;
00448 n = *s - '0';
00449 do {
00450 s++;
00451 n *= 8;
00452 if (*s >= '0' && *s <= '7') n += *s - '0'; else break;
00453 if (n >= 256) return s;
00454 } while (s - str < 3);
00455 }
00456 return s;
00457 }
00458
00459 const QChar *checkEscapedChar(const QChar *s, int len) {
00460 int i;
00461 if (s[0] == '\\' && (len > 1) ) {
00462 s++;
00463 switch(*s){
00464 case 'a':
00465 case 'b':
00466 case 'e':
00467 case 'f':
00468
00469 case 'n':
00470 case 'r':
00471 case 't':
00472 case 'v':
00473 case '\'':
00474 case '\"':
00475 case '?' :
00476 case '\\': s++;
00477 break;
00478 case 'x':
00479 s++;
00480
00481
00482
00483
00484 for(i=0;i<2 &&(*s >= '0' && *s <= '9' || (*s&0xdf) >= 'A' && (*s&0xdf) <= 'F');i++,s++);
00485 if(i==0) return 0L;
00486 break;
00487
00488 case '0': case '1': case '2': case '3' :
00489 case '4': case '5': case '6': case '7' :
00490 for(i=0;i < 3 &&(*s >='0'&& *s<='7');i++,s++);
00491 break;
00492 default: return 0L;
00493 }
00494 return s;
00495 }
00496 return 0L;
00497 }
00498
00499 const QChar *HlCStringChar::checkHgl(const QChar *str, int len, bool) {
00500 return checkEscapedChar(str, len);
00501 }
00502
00503
00504 HlCChar::HlCChar(int attribute, int context)
00505 : HlItem(attribute,context) {
00506 }
00507
00508 const QChar *HlCChar::checkHgl(const QChar *str, int len, bool) {
00509 const QChar *s;
00510
00511 if ((len > 1) && (str[0] == '\'') && (str[1] != '\''))
00512 {
00513 s = checkEscapedChar(&str[1], len);
00514 if (!s) s = &str[2];
00515 if (*s == '\'') return s + 1;
00516 }
00517 return 0L;
00518 }
00519
00520
00521
00522 ItemStyle::ItemStyle() : selCol(Qt::white), bold(false), italic(false) {
00523 }
00524
00525 ItemStyle::ItemStyle(const QColor &col, const QColor &selCol,
00526 bool bold, bool italic)
00527 : col(col), selCol(selCol), bold(bold), italic(italic) {
00528 }
00529
00530 ItemData::ItemData(const QString name, int defStyleNum)
00531 : name(name), defStyleNum(defStyleNum), defStyle(true) {
00532 }
00533
00534 ItemData::ItemData(const QString name, int defStyleNum,
00535 const QColor &col, const QColor &selCol, bool bold, bool italic)
00536 : ItemStyle(col,selCol,bold,italic), name(name), defStyleNum(defStyleNum),
00537 defStyle(false) {
00538 }
00539
00540 HlData::HlData(const QString &wildcards, const QString &mimetypes, const QString &identifier)
00541 : wildcards(wildcards), mimetypes(mimetypes), identifier(identifier) {
00542
00543
00544 }
00545
00546 HlContext::HlContext(int attribute, int lineEndContext, int _lineBeginContext)
00547 : attr(attribute), ctx(lineEndContext),lineBeginContext(_lineBeginContext) {
00548 items.setAutoDelete(true);
00549 }
00550
00551 Hl2CharDetect::Hl2CharDetect(int attribute, int context, const QChar *s)
00552 : HlItem(attribute,context) {
00553 sChar1 = s[0];
00554 sChar2 = s[1];
00555 }
00556
00557 Highlight::Highlight(syntaxModeListItem *def) : refCount(0)
00558 {
00559 noHl = false;
00560
00561 if (def == 0)
00562 {
00563 noHl = true;
00564 iName = I18N_NOOP("Normal");
00565 iSection = "";
00566 }
00567 else
00568 {
00569 iName = def->name;
00570 iSection = def->section;
00571 iWildcards = def->extension;
00572 iMimetypes = def->mimetype;
00573 identifier = def->identifier;
00574 }
00575 deliminator = stdDeliminator;
00576 deliminatorChars = deliminator.unicode();
00577 deliminatorLen = deliminator.length();
00578 }
00579
00580 Highlight::~Highlight()
00581 {
00582 }
00583
00584 int Highlight::doHighlight(int ctxNum, TextLine *textLine)
00585 {
00586 if (noHl)
00587 {
00588 textLine->setAttribs(0,0,textLine->length());
00589 textLine->setAttr(0);
00590 return 0;
00591 }
00592
00593 HlContext *context;
00594 const QChar *s2;
00595 HlItem *item;
00596
00597 context = contextList[ctxNum];
00598 if (context->lineBeginContext!=-1)
00599 {
00600 ctxNum=context->lineBeginContext;
00601 context=contextList[ctxNum];
00602 }
00603
00604 QChar lastChar = ' ';
00605
00606
00607 const QChar *str = textLine->getText();
00608
00609
00610 const QChar *s1 = textLine->firstNonSpace();
00611 uint z = textLine->firstChar();
00612
00613
00614 uint len = textLine->length();
00615
00616 bool found = false;
00617 while (z < len)
00618 {
00619 found = false;
00620
00621 for (item = context->items.first(); item != 0L; item = context->items.next())
00622 {
00623 if (item->startEnable(lastChar))
00624 {
00625 s2 = item->checkHgl(s1, len-z, z==0);
00626 if (s2 > s1)
00627 {
00628 odebug << "An item has been detected" << oendl;
00629 textLine->setAttribs(item->attr,s1 - str,s2 - str);
00630 ctxNum = item->ctx;
00631 context = contextList[ctxNum];
00632 z = z + s2 - s1 - 1;
00633 s1 = s2 - 1;
00634 found = true;
00635 break;
00636 }
00637 }
00638 }
00639
00640
00641 if (!found)
00642 textLine->setAttribs(context->attr,s1 - str,s1 - str + 1);
00643
00644 lastChar = *s1;
00645 s1++;
00646 z++;
00647 }
00648
00649
00650 textLine->setAttr(context->attr);
00651
00652
00653 return context->ctx;
00654 }
00655
00656 KateConfig *Highlight::getKateConfig() {
00657 KateConfig *config;
00658 config=KGlobal::config();
00659 config->setGroup(iName + QString(" Highlight"));
00660 return config;
00661 }
00662
00663 QString Highlight::getWildcards() {
00664 KateConfig *config;
00665
00666 config = getKateConfig();
00667
00668
00669 return config->readEntry("Wildcards", iWildcards);
00670 }
00671
00672
00673 QString Highlight::getMimetypes() {
00674 KateConfig *config;
00675
00676 config = getKateConfig();
00677
00678 return config->readEntry("Mimetypes", iMimetypes);
00679 }
00680
00681
00682 HlData *Highlight::getData() {
00683 KateConfig *config;
00684 HlData *hlData;
00685
00686 config = getKateConfig();
00687
00688
00689
00690
00691 hlData = new HlData(
00692 config->readEntry("Wildcards", iWildcards),
00693 config->readEntry("Mimetypes", iMimetypes),
00694 config->readEntry("Identifier", identifier));
00695 getItemDataList(hlData->itemDataList, config);
00696 return hlData;
00697 }
00698
00699 void Highlight::setData(HlData *hlData) {
00700 KateConfig *config;
00701
00702 config = getKateConfig();
00703
00704
00705
00706
00707 config->writeEntry("Wildcards",hlData->wildcards);
00708 config->writeEntry("Mimetypes",hlData->mimetypes);
00709
00710 setItemDataList(hlData->itemDataList,config);
00711 }
00712
00713 void Highlight::getItemDataList(ItemDataList &list) {
00714 KateConfig *config;
00715
00716 config = getKateConfig();
00717 getItemDataList(list, config);
00718 }
00719
00720 void Highlight::getItemDataList(ItemDataList &list, KateConfig *config) {
00721 ItemData *p;
00722 QString s;
00723 QRgb col, selCol;
00724
00725 list.clear();
00726
00727 createItemData(list);
00728
00729 for (p = list.first(); p != 0L; p = list.next()) {
00730 s = config->readEntry(p->name);
00731 if (!s.isEmpty()) {
00732 sscanf(s.latin1(),"%d,%X,%X,%d,%d", &p->defStyle,&col,&selCol,&p->bold,&p->italic);
00733 p->col.setRgb(col);
00734 p->selCol.setRgb(selCol);
00735 }
00736 }
00737 }
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755 void Highlight::setItemDataList(ItemDataList &list, KateConfig *config) {
00756 ItemData *p;
00757 QString s;
00758
00759 for (p = list.first(); p != 0L; p = list.next()) {
00760 s.sprintf("%d,%X,%X,%d,%d",
00761 p->defStyle,p->col.rgb(),p->selCol.rgb(),p->bold,p->italic);
00762 config->writeEntry(p->name,s);
00763 }
00764 }
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778 void Highlight::use()
00779 {
00780 if (refCount == 0) init();
00781 refCount++;
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796 void Highlight::release()
00797 {
00798 refCount--;
00799 if (refCount == 0) done();
00800 }
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813 void Highlight::init()
00814 {
00815 if (noHl)
00816 return;
00817
00818 for (int z = 0; z < nContexts; z++) contextList[z] = 0L;
00819 makeContextList();
00820 }
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835 void Highlight::done()
00836 {
00837 if (noHl)
00838 return;
00839
00840 for (int z = 0; z < nContexts; z++) delete contextList[z];
00841 }
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 void Highlight::createItemData(ItemDataList &list)
00859 {
00860 odebug << "Highlight::createItemData" << oendl;
00861
00862
00863 if (noHl)
00864 {
00865 list.append(new ItemData(I18N_NOOP("Normal Text"), dsNormal));
00866 return;
00867 }
00868
00869 QString color;
00870 QString selColor;
00871 QString bold;
00872 QString italic;
00873
00874
00875 if (internalIDList.count()==0)
00876 {
00877
00878 internalIDList.setAutoDelete(true);
00879 syntaxContextData *data;
00880
00881 odebug << "Trying to read itemData section" << oendl;
00882
00883
00884 HlManager::self()->syntax->setIdentifier(identifier);
00885 data=HlManager::self()->syntax->getGroupInfo("highlighting","itemData");
00886
00887 while (HlManager::self()->syntax->nextGroup(data))
00888 {
00889 odebug << "Setting up one itemData element" << oendl;
00890
00891 color=HlManager::self()->syntax->groupData(data,QString("color"));
00892 selColor=HlManager::self()->syntax->groupData(data,QString("selColor"));
00893 bold=HlManager::self()->syntax->groupData(data,QString("bold"));
00894 italic=HlManager::self()->syntax->groupData(data,QString("italic"));
00895
00896 if ( (!color.isEmpty()) && (!selColor.isEmpty()) && (!bold.isEmpty()) && (!italic.isEmpty()))
00897 {
00898
00899 internalIDList.append(new ItemData(
00900 HlManager::self()->syntax->groupData(data,QString("name")).simplifyWhiteSpace(),
00901 getDefStyleNum(HlManager::self()->syntax->groupData(data,QString("defStyleNum"))),
00902 QColor(color),QColor(selColor),(bold=="true") || (bold=="1"), (italic=="true") || (italic=="1")
00903 ));
00904 }
00905 else
00906 {
00907
00908 internalIDList.append(new ItemData(
00909 HlManager::self()->syntax->groupData(data,QString("name")).simplifyWhiteSpace(),
00910 getDefStyleNum(HlManager::self()->syntax->groupData(data,QString("defStyleNum")))));
00911
00912 }
00913 }
00914
00915 if (data) HlManager::self()->syntax->freeGroupInfo(data);
00916 }
00917
00918
00919 list=internalIDList;
00920 }
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938 int Highlight::lookupAttrName(const QString& name, ItemDataList &iDl)
00939 {
00940 for (int i=0;i<iDl.count();i++)
00941 {
00942 if (iDl.at(i)->name==name) return i;
00943 }
00944 kdDebug(13010)<<"Couldn't resolve itemDataName"<<endl;
00945 return 0;
00946 }
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966 HlItem *Highlight::createHlItem(syntaxContextData *data, ItemDataList &iDl)
00967 {
00968
00969 if (noHl)
00970 return 0;
00971
00972
00973 QString dataname=HlManager::self()->syntax->groupItemData(data,QString(""));
00974
00975
00976 QString tmpAttr=HlManager::self()->syntax->groupItemData(data,QString("attribute")).simplifyWhiteSpace();
00977 int attr;
00978 if (QString("%1").arg(tmpAttr.toInt())==tmpAttr)
00979 attr=tmpAttr.toInt();
00980 else
00981 attr=lookupAttrName(tmpAttr,iDl);
00982
00983
00984
00985 int context=((HlManager::self()->syntax->groupItemData(data,QString("context"))).toInt());
00986
00987
00988 char chr;
00989 if (! HlManager::self()->syntax->groupItemData(data,QString("char")).isEmpty())
00990 chr= (HlManager::self()->syntax->groupItemData(data,QString("char")).latin1())[0];
00991 else
00992 chr=0;
00993
00994
00995 QString stringdata=HlManager::self()->syntax->groupItemData(data,QString("String"));
00996
00997
00998 char chr1;
00999 if (! HlManager::self()->syntax->groupItemData(data,QString("char1")).isEmpty())
01000 chr1= (HlManager::self()->syntax->groupItemData(data,QString("char1")).latin1())[0];
01001 else
01002 chr1=0;
01003
01004
01005 bool insensitive=(HlManager::self()->syntax->groupItemData(data,QString("insensitive"))==QString("TRUE"));
01006
01007
01008
01009 if (dataname=="keyword")
01010 {
01011 HlKeyword *keyword=new HlKeyword(attr,context,casesensitive,
01012 deliminatorChars, deliminatorLen);
01013
01014
01015 keyword->addList(HlManager::self()->syntax->finddata("highlighting",stringdata));
01016 return keyword;
01017 } else
01018 if (dataname=="Float") return (new HlFloat(attr,context)); else
01019 if (dataname=="Int") return(new HlInt(attr,context)); else
01020 if (dataname=="DetectChar") return(new HlCharDetect(attr,context,chr)); else
01021 if (dataname=="Detect2Chars") return(new Hl2CharDetect(attr,context,chr,chr1)); else
01022 if (dataname=="RangeDetect") return(new HlRangeDetect(attr,context, chr, chr1)); else
01023 if (dataname=="LineContinue") return(new HlLineContinue(attr,context)); else
01024 if (dataname=="StringDetect") return(new HlStringDetect(attr,context,stringdata,insensitive)); else
01025 if (dataname=="AnyChar") return(new HlAnyChar(attr,context,stringdata.unicode(), stringdata.length())); else
01026 if (dataname=="RegExpr") return(new HlRegExpr(attr,context,stringdata)); else
01027 if(dataname=="HlCChar") return ( new HlCChar(attr,context));else
01028 if(dataname=="HlCHex") return (new HlCHex(attr,context));else
01029 if(dataname=="HlCOct") return (new HlCOct(attr,context)); else
01030 if(dataname=="HlCStringChar") return (new HlCStringChar(attr,context)); else
01031
01032 {
01033
01034 return 0;
01035 }
01036
01037
01038 }
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051 bool Highlight::isInWord(QChar c)
01052 {
01053 return !ustrchr(deliminatorChars, deliminatorLen, c);
01054 }
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070 void Highlight::readCommentConfig()
01071 {
01072
01073 cslStart = "";
01074 HlManager::self()->syntax->setIdentifier(identifier);
01075
01076 syntaxContextData *data=HlManager::self()->syntax->getGroupInfo("general","comment");
01077 if (data)
01078 {
01079
01080 while (HlManager::self()->syntax->nextGroup(data))
01081 {
01082
01083 if (HlManager::self()->syntax->groupData(data,"name")=="singleLine")
01084 cslStart=HlManager::self()->syntax->groupData(data,"start");
01085 if (HlManager::self()->syntax->groupData(data,"name")=="multiLine")
01086 {
01087 cmlStart=HlManager::self()->syntax->groupData(data,"start");
01088 cmlEnd=HlManager::self()->syntax->groupData(data,"end");
01089 }
01090 }
01091 HlManager::self()->syntax->freeGroupInfo(data);
01092 }
01093
01094 }
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110 void Highlight::readGlobalKeywordConfig()
01111 {
01112
01113 HlManager::self()->syntax->setIdentifier(identifier);
01114
01115
01116 syntaxContextData * data=HlManager::self()->syntax->getConfig("general","keywords");
01117 if (data)
01118 {
01119 kdDebug(13010)<<"Found global keyword config"<<endl;
01120
01121 if (HlManager::self()->syntax->groupItemData(data,QString("casesensitive"))!="0")
01122 casesensitive=true; else {casesensitive=false; kdDebug(13010)<<"Turning on case insensitiveness"<<endl;}
01123
01124 weakDeliminator=(!HlManager::self()->syntax->groupItemData(data,QString("weakDeliminator")));
01125
01126
01127 int f;
01128 for (int s=0; s < weakDeliminator.length(); s++)
01129 {
01130 f = 0;
01131 f = deliminator.find (weakDeliminator[s]);
01132
01133 if (f > -1)
01134 deliminator.remove (f, 1);
01135 }
01136
01137 deliminatorChars = deliminator.unicode();
01138 deliminatorLen = deliminator.length();
01139
01140 HlManager::self()->syntax->freeGroupInfo(data);
01141 }
01142 else
01143 {
01144
01145 casesensitive=true;
01146 weakDeliminator=QString("");
01147 }
01148
01149 }
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165 void Highlight::makeContextList()
01166 {
01167 if (noHl)
01168 return;
01169
01170 HlKeyword *keyword=0, *dataType=0;
01171 syntaxContextData *data, *datasub;
01172 HlItem *c;
01173
01174 readCommentConfig();
01175 readGlobalKeywordConfig();
01176
01177
01178 HlManager::self()->syntax->setIdentifier(identifier);
01179
01180
01181 ItemDataList iDl;
01182 createItemData(iDl);
01183
01184
01185 data=HlManager::self()->syntax->getGroupInfo("highlighting","context");
01186 int i=0;
01187 if (data)
01188 {
01189 while (HlManager::self()->syntax->nextGroup(data))
01190 {
01191
01192
01193 QString tmpAttr=HlManager::self()->syntax->groupData(data,QString("attribute")).simplifyWhiteSpace();
01194 int attr;
01195 if (QString("%1").arg(tmpAttr.toInt())==tmpAttr)
01196 attr=tmpAttr.toInt();
01197 else
01198 attr=lookupAttrName(tmpAttr,iDl);
01199
01200
01201 contextList[i]=new HlContext(
01202 attr,
01203 (HlManager::self()->syntax->groupData(data,QString("lineEndContext"))).toInt(),
01204 (HlManager::self()->syntax->groupData(data,QString("lineBeginContext"))).isEmpty()?-1:
01205 (HlManager::self()->syntax->groupData(data,QString("lineBeginContext"))).toInt());
01206
01207
01208
01209 while (HlManager::self()->syntax->nextItem(data))
01210 {
01211
01212 c=createHlItem(data,iDl);
01213 if (c)
01214 {
01215 contextList[i]->items.append(c);
01216
01217
01218 datasub=HlManager::self()->syntax->getSubItems(data);
01219 bool tmpbool;
01220 if (tmpbool=HlManager::self()->syntax->nextItem(datasub))
01221 {
01222 c->subItems=new QList<HlItem>;
01223 for (;tmpbool;tmpbool=HlManager::self()->syntax->nextItem(datasub))
01224 c->subItems->append(createHlItem(datasub,iDl));
01225 }
01226 HlManager::self()->syntax->freeGroupInfo(datasub);
01227
01228 }
01229
01230 }
01231 i++;
01232 }
01233 }
01234
01235 HlManager::self()->syntax->freeGroupInfo(data);
01236
01237
01238 }
01239
01240 HlManager::HlManager() : QObject(0L)
01241 {
01242 syntax = new SyntaxDocument();
01243 SyntaxModeList modeList = syntax->modeList();
01244
01245 hlList.setAutoDelete(true);
01246 hlList.append(new Highlight(0));
01247
01248 uint i=0;
01249 while (i < modeList.count())
01250 {
01251 hlList.append(new Highlight(modeList.at(i)));
01252 i++;
01253 }
01254 }
01255
01256 HlManager::~HlManager() {
01257 if(syntax) delete syntax;
01258 }
01259
01260 HlManager *HlManager::self()
01261 {
01262 if ( !s_pSelf )
01263 s_pSelf = new HlManager;
01264 return s_pSelf;
01265 }
01266
01267 Highlight *HlManager::getHl(int n) {
01268 if (n < 0 || n >= (int) hlList.count()) n = 0;
01269 return hlList.at(n);
01270 }
01271
01272 int HlManager::defaultHl() {
01273 KateConfig *config;
01274 config = KGlobal::config();
01275 config->setGroup("General Options");
01276
01277 #warning fixme return nameFind(config->readEntry("Highlight"));
01278
01279 }
01280
01281
01282 int HlManager::nameFind(const QString &name) {
01283 int z;
01284
01285 for (z = hlList.count() - 1; z > 0; z--) {
01286 if (hlList.at(z)->iName == name) break;
01287 }
01288 return z;
01289 }
01290
01291 int HlManager::wildcardFind(const QString &fileName) {
01292 Highlight *highlight;
01293 int p1, p2;
01294 QString w;
01295 for (highlight = hlList.first(); highlight != 0L; highlight = hlList.next()) {
01296 p1 = 0;
01297 w = highlight->getWildcards();
01298 while (p1 < (int) w.length()) {
01299 p2 = w.find(';',p1);
01300 if (p2 == -1) p2 = w.length();
01301 if (p1 < p2) {
01302 QRegExp regExp(w.mid(p1,p2 - p1),true,true);
01303 if (regExp.match(fileName) == 0) return hlList.at();
01304 }
01305 p1 = p2 + 1;
01306 }
01307 }
01308 return -1;
01309 }
01310
01311
01312 int HlManager::makeAttribs(Highlight *highlight, Attribute *a, int maxAttribs) {
01313 ItemStyleList defaultStyleList;
01314 ItemStyle *defaultStyle;
01315 ItemDataList itemDataList;
01316 ItemData *itemData;
01317 int nAttribs, z;
01318
01319 odebug << "HlManager::makeAttribs" << oendl;
01320
01321 defaultStyleList.setAutoDelete(true);
01322 getDefaults(defaultStyleList);
01323
01324
01325 highlight->getItemDataList(itemDataList);
01326 nAttribs = itemDataList.count();
01327 for (z = 0; z < nAttribs; z++) {
01328 odebug << "HlManager::makeAttribs: createing one attribute definition" << oendl;
01329 itemData = itemDataList.at(z);
01330 if (itemData->defStyle) {
01331
01332 defaultStyle = defaultStyleList.at(itemData->defStyleNum);
01333 a[z].col = defaultStyle->col;
01334 a[z].selCol = defaultStyle->selCol;
01335 a[z].bold = defaultStyle->bold;
01336 a[z].italic = defaultStyle->italic;
01337 } else {
01338
01339 a[z].col = itemData->col;
01340 a[z].selCol = itemData->selCol;
01341 a[z].bold = itemData->bold;
01342 a[z].italic = itemData->italic;
01343 }
01344 }
01345
01346 for (; z < maxAttribs; z++) {
01347 a[z].col = black;
01348 a[z].selCol = black;
01349 a[z].bold = defaultStyle->bold;
01350 a[z].italic = defaultStyle->italic;
01351 }
01352 return nAttribs;
01353 }
01354
01355 int HlManager::defaultStyles() {
01356 return 10;
01357 }
01358
01359 QString HlManager::defaultStyleName(int n)
01360 {
01361 static QStringList names;
01362
01363 if (names.isEmpty())
01364 {
01365 names << i18n("Normal");
01366 names << i18n("Keyword");
01367 names << i18n("Data Type");
01368 names << i18n("Decimal/Value");
01369 names << i18n("Base-N Integer");
01370 names << i18n("Floating Point");
01371 names << i18n("Character");
01372 names << i18n("String");
01373 names << i18n("Comment");
01374 names << i18n("Others");
01375 }
01376
01377 return names[n];
01378 }
01379
01380 void HlManager::getDefaults(ItemStyleList &list) {
01381 KateConfig *config;
01382 int z;
01383 ItemStyle *i;
01384 QString s;
01385 QRgb col, selCol;
01386
01387 list.setAutoDelete(true);
01388
01389 list.append(new ItemStyle(black,white,false,false));
01390 list.append(new ItemStyle(black,white,true,false));
01391 list.append(new ItemStyle(darkRed,white,false,false));
01392 list.append(new ItemStyle(blue,cyan,false,false));
01393 list.append(new ItemStyle(darkCyan,cyan,false,false));
01394 list.append(new ItemStyle(darkMagenta,cyan,false,false));
01395 list.append(new ItemStyle(magenta,magenta,false,false));
01396 list.append(new ItemStyle(red,red,false,false));
01397 list.append(new ItemStyle(darkGray,gray,false,true));
01398 list.append(new ItemStyle(darkGreen,green,false,false));
01399
01400 #warning fixme
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414 }
01415
01416 void HlManager::setDefaults(ItemStyleList &list) {
01417 KateConfig *config;
01418 int z;
01419 ItemStyle *i;
01420 char s[64];
01421 #warning fixme
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431 emit changed();
01432 }
01433
01434
01435 int HlManager::highlights() {
01436 return (int) hlList.count();
01437 }
01438
01439 QString HlManager::hlName(int n) {
01440 return hlList.at(n)->iName;
01441 }
01442
01443 QString HlManager::hlSection(int n) {
01444 return hlList.at(n)->iSection;
01445 }
01446
01447 void HlManager::getHlDataList(HlDataList &list) {
01448 int z;
01449
01450 for (z = 0; z < (int) hlList.count(); z++) {
01451 list.append(hlList.at(z)->getData());
01452 }
01453 }
01454
01455 void HlManager::setHlDataList(HlDataList &list) {
01456 int z;
01457
01458 for (z = 0; z < (int) hlList.count(); z++) {
01459 hlList.at(z)->setData(list.at(z));
01460 }
01461
01462 emit changed();
01463 }