TDE core libraries
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

katehighlight.cpp 100KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473
  1. /* This file is part of the KDE libraries
  2. Copyright (C) 2003, 2004 Anders Lund <anders@alweb.dk>
  3. Copyright (C) 2003 Hamish Rodda <rodda@kde.org>
  4. Copyright (C) 2001,2002 Joseph Wenninger <jowenn@kde.org>
  5. Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
  6. Copyright (C) 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de>
  7. This library is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU Library General Public
  9. License version 2 as published by the Free Software Foundation.
  10. This library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. Library General Public License for more details.
  14. You should have received a copy of the GNU Library General Public License
  15. along with this library; see the file COPYING.LIB. If not, write to
  16. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  17. Boston, MA 02110-1301, USA.
  18. */
  19. //BEGIN INCLUDES
  20. #include "katehighlight.h"
  21. #include "katehighlight.moc"
  22. #include "katetextline.h"
  23. #include "katedocument.h"
  24. #include "katesyntaxdocument.h"
  25. #include "katerenderer.h"
  26. #include "katefactory.h"
  27. #include "kateschema.h"
  28. #include "kateconfig.h"
  29. #include <tdeconfig.h>
  30. #include <tdeglobal.h>
  31. #include <kinstance.h>
  32. #include <kmimetype.h>
  33. #include <tdelocale.h>
  34. #include <kregexp.h>
  35. #include <tdepopupmenu.h>
  36. #include <tdeglobalsettings.h>
  37. #include <kdebug.h>
  38. #include <kstandarddirs.h>
  39. #include <tdemessagebox.h>
  40. #include <kstaticdeleter.h>
  41. #include <tdeapplication.h>
  42. #include <tqstringlist.h>
  43. #include <tqtextstream.h>
  44. //END
  45. //BEGIN defines
  46. // same as in kmimemagic, no need to feed more data
  47. #define KATE_HL_HOWMANY 1024
  48. // min. x seconds between two dynamic contexts reset
  49. static const int KATE_DYNAMIC_CONTEXTS_RESET_DELAY = 30 * 1000;
  50. // x is a TQString. if x is "true" or "1" this expression returns "true"
  51. #define IS_TRUE(x) x.lower() == TQString("true") || x.toInt() == 1
  52. //END defines
  53. //BEGIN Prviate HL classes
  54. inline bool kateInsideString (const TQString &str, TQChar ch)
  55. {
  56. const TQChar *unicode = str.unicode();
  57. const uint len = str.length();
  58. for (uint i=0; i < len; i++)
  59. if (unicode[i] == ch)
  60. return true;
  61. return false;
  62. }
  63. class KateHlItem
  64. {
  65. public:
  66. KateHlItem(int attribute, int context,signed char regionId, signed char regionId2);
  67. virtual ~KateHlItem();
  68. public:
  69. // caller must keep in mind: LEN > 0 is a must !!!!!!!!!!!!!!!!!!!!!1
  70. // Now, the function returns the offset detected, or 0 if no match is found.
  71. // bool linestart isn't needed, this is equivalent to offset == 0.
  72. virtual int checkHgl(const TQString& text, int offset, int len) = 0;
  73. virtual bool lineContinue(){return false;}
  74. virtual TQStringList *capturedTexts() {return 0;}
  75. virtual KateHlItem *clone(const TQStringList *) {return this;}
  76. static void dynamicSubstitute(TQString& str, const TQStringList *args);
  77. TQMemArray<KateHlItem*> subItems;
  78. int attr;
  79. int ctx;
  80. signed char region;
  81. signed char region2;
  82. bool lookAhead;
  83. bool dynamic;
  84. bool dynamicChild;
  85. bool firstNonSpace;
  86. bool onlyConsume;
  87. int column;
  88. // start enable flags, nicer than the virtual methodes
  89. // saves function calls
  90. bool alwaysStartEnable;
  91. bool customStartEnable;
  92. };
  93. class KateHlContext
  94. {
  95. public:
  96. KateHlContext(const TQString &_hlId, int attribute, int lineEndContext,int _lineBeginContext,
  97. bool _fallthrough, int _fallthroughContext, bool _dynamic,bool _noIndentationBasedFolding);
  98. virtual ~KateHlContext();
  99. KateHlContext *clone(const TQStringList *args);
  100. TQValueVector<KateHlItem*> items;
  101. TQString hlId; ///< A unique highlight identifier. Used to look up correct properties.
  102. int attr;
  103. int ctx;
  104. int lineBeginContext;
  105. /** @internal anders: possible escape if no rules matches.
  106. false unless 'fallthrough="1|true"' (insensitive)
  107. if true, go to ftcxt w/o eating of string.
  108. ftctx is "fallthroughContext" in xml files, valid values are int or #pop[..]
  109. see in KateHighlighting::doHighlight */
  110. bool fallthrough;
  111. int ftctx; // where to go after no rules matched
  112. bool dynamic;
  113. bool dynamicChild;
  114. bool noIndentationBasedFolding;
  115. };
  116. class KateEmbeddedHlInfo
  117. {
  118. public:
  119. KateEmbeddedHlInfo() {loaded=false;context0=-1;}
  120. KateEmbeddedHlInfo(bool l, int ctx0) {loaded=l;context0=ctx0;}
  121. public:
  122. bool loaded;
  123. int context0;
  124. };
  125. class KateHlIncludeRule
  126. {
  127. public:
  128. KateHlIncludeRule(int ctx_=0, uint pos_=0, const TQString &incCtxN_="", bool incAttrib=false)
  129. : ctx(ctx_)
  130. , pos( pos_)
  131. , incCtxN( incCtxN_ )
  132. , includeAttrib( incAttrib )
  133. {
  134. incCtx=-1;
  135. }
  136. //KateHlIncludeRule(int ctx_, uint pos_, bool incAttrib) {ctx=ctx_;pos=pos_;incCtx=-1;incCtxN="";includeAttrib=incAttrib}
  137. public:
  138. int ctx;
  139. uint pos;
  140. int incCtx;
  141. TQString incCtxN;
  142. bool includeAttrib;
  143. };
  144. class KateHlCharDetect : public KateHlItem
  145. {
  146. public:
  147. KateHlCharDetect(int attribute, int context,signed char regionId,signed char regionId2, TQChar);
  148. virtual int checkHgl(const TQString& text, int offset, int len);
  149. virtual KateHlItem *clone(const TQStringList *args);
  150. private:
  151. TQChar sChar;
  152. };
  153. class KateHl2CharDetect : public KateHlItem
  154. {
  155. public:
  156. KateHl2CharDetect(int attribute, int context, signed char regionId,signed char regionId2, TQChar ch1, TQChar ch2);
  157. KateHl2CharDetect(int attribute, int context,signed char regionId,signed char regionId2, const TQChar *ch);
  158. virtual int checkHgl(const TQString& text, int offset, int len);
  159. virtual KateHlItem *clone(const TQStringList *args);
  160. private:
  161. TQChar sChar1;
  162. TQChar sChar2;
  163. };
  164. class KateHlStringDetect : public KateHlItem
  165. {
  166. public:
  167. KateHlStringDetect(int attribute, int context, signed char regionId,signed char regionId2, const TQString &, bool inSensitive=false);
  168. virtual int checkHgl(const TQString& text, int offset, int len);
  169. virtual KateHlItem *clone(const TQStringList *args);
  170. private:
  171. const TQString str;
  172. const int strLen;
  173. const bool _inSensitive;
  174. };
  175. class KateHlRangeDetect : public KateHlItem
  176. {
  177. public:
  178. KateHlRangeDetect(int attribute, int context, signed char regionId,signed char regionId2, TQChar ch1, TQChar ch2);
  179. virtual int checkHgl(const TQString& text, int offset, int len);
  180. private:
  181. TQChar sChar1;
  182. TQChar sChar2;
  183. };
  184. class KateHlKeyword : public KateHlItem
  185. {
  186. public:
  187. KateHlKeyword(int attribute, int context,signed char regionId,signed char regionId2, bool insensitive, const TQString& delims);
  188. virtual ~KateHlKeyword ();
  189. void addList(const TQStringList &);
  190. virtual int checkHgl(const TQString& text, int offset, int len);
  191. private:
  192. TQMemArray< TQDict<bool>* > dict;
  193. bool _insensitive;
  194. const TQString& deliminators;
  195. int minLen;
  196. int maxLen;
  197. };
  198. class KateHlInt : public KateHlItem
  199. {
  200. public:
  201. KateHlInt(int attribute, int context, signed char regionId,signed char regionId2);
  202. virtual int checkHgl(const TQString& text, int offset, int len);
  203. };
  204. class KateHlFloat : public KateHlItem
  205. {
  206. public:
  207. KateHlFloat(int attribute, int context, signed char regionId,signed char regionId2);
  208. virtual ~KateHlFloat () {}
  209. virtual int checkHgl(const TQString& text, int offset, int len);
  210. };
  211. class KateHlCFloat : public KateHlFloat
  212. {
  213. public:
  214. KateHlCFloat(int attribute, int context, signed char regionId,signed char regionId2);
  215. virtual int checkHgl(const TQString& text, int offset, int len);
  216. int checkIntHgl(const TQString& text, int offset, int len);
  217. };
  218. class KateHlCOct : public KateHlItem
  219. {
  220. public:
  221. KateHlCOct(int attribute, int context, signed char regionId,signed char regionId2);
  222. virtual int checkHgl(const TQString& text, int offset, int len);
  223. };
  224. class KateHlCHex : public KateHlItem
  225. {
  226. public:
  227. KateHlCHex(int attribute, int context, signed char regionId,signed char regionId2);
  228. virtual int checkHgl(const TQString& text, int offset, int len);
  229. };
  230. class KateHlLineContinue : public KateHlItem
  231. {
  232. public:
  233. KateHlLineContinue(int attribute, int context, signed char regionId,signed char regionId2);
  234. virtual bool endEnable(TQChar c) {return c == '\0';}
  235. virtual int checkHgl(const TQString& text, int offset, int len);
  236. virtual bool lineContinue(){return true;}
  237. };
  238. class KateHlCStringChar : public KateHlItem
  239. {
  240. public:
  241. KateHlCStringChar(int attribute, int context, signed char regionId,signed char regionId2);
  242. virtual int checkHgl(const TQString& text, int offset, int len);
  243. };
  244. class KateHlCChar : public KateHlItem
  245. {
  246. public:
  247. KateHlCChar(int attribute, int context,signed char regionId,signed char regionId2);
  248. virtual int checkHgl(const TQString& text, int offset, int len);
  249. };
  250. class KateHlAnyChar : public KateHlItem
  251. {
  252. public:
  253. KateHlAnyChar(int attribute, int context, signed char regionId,signed char regionId2, const TQString& charList);
  254. virtual int checkHgl(const TQString& text, int offset, int len);
  255. private:
  256. const TQString _charList;
  257. };
  258. class KateHlRegExpr : public KateHlItem
  259. {
  260. public:
  261. KateHlRegExpr(int attribute, int context,signed char regionId,signed char regionId2 ,TQString expr, bool insensitive, bool minimal);
  262. ~KateHlRegExpr() { delete Expr; };
  263. virtual int checkHgl(const TQString& text, int offset, int len);
  264. virtual TQStringList *capturedTexts();
  265. virtual KateHlItem *clone(const TQStringList *args);
  266. private:
  267. TQRegExp *Expr;
  268. bool handlesLinestart;
  269. TQString _regexp;
  270. bool _insensitive;
  271. bool _minimal;
  272. };
  273. class KateHlDetectSpaces : public KateHlItem
  274. {
  275. public:
  276. KateHlDetectSpaces (int attribute, int context,signed char regionId,signed char regionId2)
  277. : KateHlItem(attribute,context,regionId,regionId2) {}
  278. virtual int checkHgl(const TQString& text, int offset, int len)
  279. {
  280. int len2 = offset + len;
  281. while ((offset < len2) && text[offset].isSpace()) offset++;
  282. return offset;
  283. }
  284. };
  285. class KateHlDetectIdentifier : public KateHlItem
  286. {
  287. public:
  288. KateHlDetectIdentifier (int attribute, int context,signed char regionId,signed char regionId2)
  289. : KateHlItem(attribute,context,regionId,regionId2) { alwaysStartEnable = false; }
  290. virtual int checkHgl(const TQString& text, int offset, int len)
  291. {
  292. // first char should be a letter or underscore
  293. if ( text[offset].isLetter() || text[offset] == TQChar ('_') )
  294. {
  295. // memorize length
  296. int len2 = offset+len;
  297. // one char seen
  298. offset++;
  299. // now loop for all other thingies
  300. while (
  301. (offset < len2)
  302. && (text[offset].isLetterOrNumber() || (text[offset] == TQChar ('_')))
  303. )
  304. offset++;
  305. return offset;
  306. }
  307. return 0;
  308. }
  309. };
  310. //END
  311. //BEGIN STATICS
  312. KateHlManager *KateHlManager::s_self = 0;
  313. static const bool trueBool = true;
  314. static const TQString stdDeliminator = TQString (" \t.():!+,-<=>%&*/;?[]^{|}~\\");
  315. //END
  316. //BEGIN NON MEMBER FUNCTIONS
  317. static KateHlItemData::ItemStyles getDefStyleNum(TQString name)
  318. {
  319. if (name=="dsNormal") return KateHlItemData::dsNormal;
  320. else if (name=="dsKeyword") return KateHlItemData::dsKeyword;
  321. else if (name=="dsDataType") return KateHlItemData::dsDataType;
  322. else if (name=="dsDecVal") return KateHlItemData::dsDecVal;
  323. else if (name=="dsBaseN") return KateHlItemData::dsBaseN;
  324. else if (name=="dsFloat") return KateHlItemData::dsFloat;
  325. else if (name=="dsChar") return KateHlItemData::dsChar;
  326. else if (name=="dsString") return KateHlItemData::dsString;
  327. else if (name=="dsComment") return KateHlItemData::dsComment;
  328. else if (name=="dsOthers") return KateHlItemData::dsOthers;
  329. else if (name=="dsAlert") return KateHlItemData::dsAlert;
  330. else if (name=="dsFunction") return KateHlItemData::dsFunction;
  331. else if (name=="dsRegionMarker") return KateHlItemData::dsRegionMarker;
  332. else if (name=="dsError") return KateHlItemData::dsError;
  333. return KateHlItemData::dsNormal;
  334. }
  335. //END
  336. //BEGIN KateHlItem
  337. KateHlItem::KateHlItem(int attribute, int context,signed char regionId,signed char regionId2)
  338. : attr(attribute),
  339. ctx(context),
  340. region(regionId),
  341. region2(regionId2),
  342. lookAhead(false),
  343. dynamic(false),
  344. dynamicChild(false),
  345. firstNonSpace(false),
  346. onlyConsume(false),
  347. column (-1),
  348. alwaysStartEnable (true),
  349. customStartEnable (false)
  350. {
  351. }
  352. KateHlItem::~KateHlItem()
  353. {
  354. //kdDebug(13010)<<"In hlItem::~KateHlItem()"<<endl;
  355. for (uint i=0; i < subItems.size(); i++)
  356. delete subItems[i];
  357. }
  358. void KateHlItem::dynamicSubstitute(TQString &str, const TQStringList *args)
  359. {
  360. for (uint i = 0; i < str.length() - 1; ++i)
  361. {
  362. if (str[i] == '%')
  363. {
  364. char c = str[i + 1].latin1();
  365. if (c == '%')
  366. str.replace(i, 1, "");
  367. else if (c >= '0' && c <= '9')
  368. {
  369. if ((uint)(c - '0') < args->size())
  370. {
  371. str.replace(i, 2, (*args)[c - '0']);
  372. i += ((*args)[c - '0']).length() - 1;
  373. }
  374. else
  375. {
  376. str.replace(i, 2, "");
  377. --i;
  378. }
  379. }
  380. }
  381. }
  382. }
  383. //END
  384. //BEGIN KateHlCharDetect
  385. KateHlCharDetect::KateHlCharDetect(int attribute, int context, signed char regionId,signed char regionId2, TQChar c)
  386. : KateHlItem(attribute,context,regionId,regionId2)
  387. , sChar(c)
  388. {
  389. }
  390. int KateHlCharDetect::checkHgl(const TQString& text, int offset, int /*len*/)
  391. {
  392. if (text[offset] == sChar)
  393. return offset + 1;
  394. return 0;
  395. }
  396. KateHlItem *KateHlCharDetect::clone(const TQStringList *args)
  397. {
  398. char c = sChar.latin1();
  399. if (c < '0' || c > '9' || (unsigned)(c - '0') >= args->size())
  400. return this;
  401. KateHlCharDetect *ret = new KateHlCharDetect(attr, ctx, region, region2, (*args)[c - '0'][0]);
  402. ret->dynamicChild = true;
  403. return ret;
  404. }
  405. //END
  406. //BEGIN KateHl2CharDetect
  407. KateHl2CharDetect::KateHl2CharDetect(int attribute, int context, signed char regionId,signed char regionId2, TQChar ch1, TQChar ch2)
  408. : KateHlItem(attribute,context,regionId,regionId2)
  409. , sChar1 (ch1)
  410. , sChar2 (ch2)
  411. {
  412. }
  413. int KateHl2CharDetect::checkHgl(const TQString& text, int offset, int len)
  414. {
  415. if ((len >= 2) && text[offset++] == sChar1 && text[offset++] == sChar2)
  416. return offset;
  417. return 0;
  418. }
  419. KateHlItem *KateHl2CharDetect::clone(const TQStringList *args)
  420. {
  421. char c1 = sChar1.latin1();
  422. char c2 = sChar2.latin1();
  423. if (c1 < '0' || c1 > '9' || (unsigned)(c1 - '0') >= args->size())
  424. return this;
  425. if (c2 < '0' || c2 > '9' || (unsigned)(c2 - '0') >= args->size())
  426. return this;
  427. KateHl2CharDetect *ret = new KateHl2CharDetect(attr, ctx, region, region2, (*args)[c1 - '0'][0], (*args)[c2 - '0'][0]);
  428. ret->dynamicChild = true;
  429. return ret;
  430. }
  431. //END
  432. //BEGIN KateHlStringDetect
  433. KateHlStringDetect::KateHlStringDetect(int attribute, int context, signed char regionId,signed char regionId2,const TQString &s, bool inSensitive)
  434. : KateHlItem(attribute, context,regionId,regionId2)
  435. , str(inSensitive ? s.upper() : s)
  436. , strLen (str.length())
  437. , _inSensitive(inSensitive)
  438. {
  439. }
  440. int KateHlStringDetect::checkHgl(const TQString& text, int offset, int len)
  441. {
  442. if (len < strLen)
  443. return 0;
  444. if (_inSensitive)
  445. {
  446. for (int i=0; i < strLen; i++)
  447. if (text[offset++].upper() != str[i])
  448. return 0;
  449. return offset;
  450. }
  451. else
  452. {
  453. for (int i=0; i < strLen; i++)
  454. if (text[offset++] != str[i])
  455. return 0;
  456. return offset;
  457. }
  458. return 0;
  459. }
  460. KateHlItem *KateHlStringDetect::clone(const TQStringList *args)
  461. {
  462. TQString newstr = str;
  463. dynamicSubstitute(newstr, args);
  464. if (newstr == str)
  465. return this;
  466. KateHlStringDetect *ret = new KateHlStringDetect(attr, ctx, region, region2, newstr, _inSensitive);
  467. ret->dynamicChild = true;
  468. return ret;
  469. }
  470. //END
  471. //BEGIN KateHlRangeDetect
  472. KateHlRangeDetect::KateHlRangeDetect(int attribute, int context, signed char regionId,signed char regionId2, TQChar ch1, TQChar ch2)
  473. : KateHlItem(attribute,context,regionId,regionId2)
  474. , sChar1 (ch1)
  475. , sChar2 (ch2)
  476. {
  477. }
  478. int KateHlRangeDetect::checkHgl(const TQString& text, int offset, int len)
  479. {
  480. if (text[offset] == sChar1)
  481. {
  482. do
  483. {
  484. offset++;
  485. len--;
  486. if (len < 1) return 0;
  487. }
  488. while (text[offset] != sChar2);
  489. return offset + 1;
  490. }
  491. return 0;
  492. }
  493. //END
  494. //BEGIN KateHlKeyword
  495. KateHlKeyword::KateHlKeyword (int attribute, int context, signed char regionId,signed char regionId2, bool insensitive, const TQString& delims)
  496. : KateHlItem(attribute,context,regionId,regionId2)
  497. , _insensitive(insensitive)
  498. , deliminators(delims)
  499. , minLen (0xFFFFFF)
  500. , maxLen (0)
  501. {
  502. alwaysStartEnable = false;
  503. customStartEnable = true;
  504. }
  505. KateHlKeyword::~KateHlKeyword ()
  506. {
  507. for (uint i=0; i < dict.size(); ++i)
  508. delete dict[i];
  509. }
  510. void KateHlKeyword::addList(const TQStringList& list)
  511. {
  512. for(uint i=0; i < list.count(); ++i)
  513. {
  514. int len = list[i].length();
  515. if (minLen > len)
  516. minLen = len;
  517. if (maxLen < len)
  518. maxLen = len;
  519. if ((uint)len >= dict.size())
  520. {
  521. uint oldSize = dict.size();
  522. dict.resize (len+1);
  523. for (uint m=oldSize; m < dict.size(); ++m)
  524. dict[m] = 0;
  525. }
  526. if (!dict[len])
  527. dict[len] = new TQDict<bool> (17, !_insensitive);
  528. dict[len]->insert(list[i], &trueBool);
  529. }
  530. }
  531. int KateHlKeyword::checkHgl(const TQString& text, int offset, int len)
  532. {
  533. int offset2 = offset;
  534. int wordLen = 0;
  535. while ((len > wordLen) && !kateInsideString (deliminators, text[offset2]))
  536. {
  537. offset2++;
  538. wordLen++;
  539. if (wordLen > maxLen) return 0;
  540. }
  541. if (wordLen < minLen) return 0;
  542. if ( dict[wordLen] && dict[wordLen]->find(TQConstString(text.unicode() + offset, wordLen).string()) )
  543. return offset2;
  544. return 0;
  545. }
  546. //END
  547. //BEGIN KateHlInt
  548. KateHlInt::KateHlInt(int attribute, int context, signed char regionId,signed char regionId2)
  549. : KateHlItem(attribute,context,regionId,regionId2)
  550. {
  551. alwaysStartEnable = false;
  552. }
  553. int KateHlInt::checkHgl(const TQString& text, int offset, int len)
  554. {
  555. int offset2 = offset;
  556. while ((len > 0) && text[offset2].isDigit())
  557. {
  558. offset2++;
  559. len--;
  560. }
  561. if (offset2 > offset)
  562. {
  563. if (len > 0)
  564. {
  565. for (uint i=0; i < subItems.size(); i++)
  566. {
  567. if ( (offset = subItems[i]->checkHgl(text, offset2, len)) )
  568. return offset;
  569. }
  570. }
  571. return offset2;
  572. }
  573. return 0;
  574. }
  575. //END
  576. //BEGIN KateHlFloat
  577. KateHlFloat::KateHlFloat(int attribute, int context, signed char regionId,signed char regionId2)
  578. : KateHlItem(attribute,context, regionId,regionId2)
  579. {
  580. alwaysStartEnable = false;
  581. }
  582. int KateHlFloat::checkHgl(const TQString& text, int offset, int len)
  583. {
  584. bool b = false;
  585. bool p = false;
  586. while ((len > 0) && text[offset].isDigit())
  587. {
  588. offset++;
  589. len--;
  590. b = true;
  591. }
  592. if ((len > 0) && (p = (text[offset] == '.')))
  593. {
  594. offset++;
  595. len--;
  596. while ((len > 0) && text[offset].isDigit())
  597. {
  598. offset++;
  599. len--;
  600. b = true;
  601. }
  602. }
  603. if (!b)
  604. return 0;
  605. if ((len > 0) && ((text[offset] & 0xdf) == 'E'))
  606. {
  607. offset++;
  608. len--;
  609. }
  610. else
  611. {
  612. if (!p)
  613. return 0;
  614. else
  615. {
  616. if (len > 0)
  617. {
  618. for (uint i=0; i < subItems.size(); i++)
  619. {
  620. int offset2 = subItems[i]->checkHgl(text, offset, len);
  621. if (offset2)
  622. return offset2;
  623. }
  624. }
  625. return offset;
  626. }
  627. }
  628. if ((len > 0) && (text[offset] == '-' || text[offset] =='+'))
  629. {
  630. offset++;
  631. len--;
  632. }
  633. b = false;
  634. while ((len > 0) && text[offset].isDigit())
  635. {
  636. offset++;
  637. len--;
  638. b = true;
  639. }
  640. if (b)
  641. {
  642. if (len > 0)
  643. {
  644. for (uint i=0; i < subItems.size(); i++)
  645. {
  646. int offset2 = subItems[i]->checkHgl(text, offset, len);
  647. if (offset2)
  648. return offset2;
  649. }
  650. }
  651. return offset;
  652. }
  653. return 0;
  654. }
  655. //END
  656. //BEGIN KateHlCOct
  657. KateHlCOct::KateHlCOct(int attribute, int context, signed char regionId,signed char regionId2)
  658. : KateHlItem(attribute,context,regionId,regionId2)
  659. {
  660. alwaysStartEnable = false;
  661. }
  662. int KateHlCOct::checkHgl(const TQString& text, int offset, int len)
  663. {
  664. if (text[offset] == '0')
  665. {
  666. offset++;
  667. len--;
  668. int offset2 = offset;
  669. while ((len > 0) && (text.at(offset2) >= TQChar('0') && text.at(offset2) <= TQChar('7')))
  670. {
  671. offset2++;
  672. len--;
  673. }
  674. if (offset2 > offset)
  675. {
  676. if ((len > 0) && ((text[offset2] & 0xdf) == 'L' || (text[offset] & 0xdf) == 'U' ))
  677. offset2++;
  678. return offset2;
  679. }
  680. }
  681. return 0;
  682. }
  683. //END
  684. //BEGIN KateHlCHex
  685. KateHlCHex::KateHlCHex(int attribute, int context,signed char regionId,signed char regionId2)
  686. : KateHlItem(attribute,context,regionId,regionId2)
  687. {
  688. alwaysStartEnable = false;
  689. }
  690. int KateHlCHex::checkHgl(const TQString& text, int offset, int len)
  691. {
  692. if ((len > 1) && (text[offset++] == '0') && ((text[offset++] & 0xdf) == 'X' ))
  693. {
  694. len -= 2;
  695. int offset2 = offset;
  696. while ((len > 0) && (text[offset2].isDigit() || ((text[offset2] & 0xdf) >= 'A' && (text[offset2] & 0xdf) <= 'F')))
  697. {
  698. offset2++;
  699. len--;
  700. }
  701. if (offset2 > offset)
  702. {
  703. if ((len > 0) && ((text[offset2] & 0xdf) == 'L' || (text[offset2] & 0xdf) == 'U' ))
  704. offset2++;
  705. return offset2;
  706. }
  707. }
  708. return 0;
  709. }
  710. //END
  711. //BEGIN KateHlCFloat
  712. KateHlCFloat::KateHlCFloat(int attribute, int context, signed char regionId,signed char regionId2)
  713. : KateHlFloat(attribute,context,regionId,regionId2)
  714. {
  715. alwaysStartEnable = false;
  716. }
  717. int KateHlCFloat::checkIntHgl(const TQString& text, int offset, int len)
  718. {
  719. int offset2 = offset;
  720. while ((len > 0) && text[offset].isDigit()) {
  721. offset2++;
  722. len--;
  723. }
  724. if (offset2 > offset)
  725. return offset2;
  726. return 0;
  727. }
  728. int KateHlCFloat::checkHgl(const TQString& text, int offset, int len)
  729. {
  730. int offset2 = KateHlFloat::checkHgl(text, offset, len);
  731. if (offset2)
  732. {
  733. if ((text[offset2] & 0xdf) == 'F' )
  734. offset2++;
  735. return offset2;
  736. }
  737. else
  738. {
  739. offset2 = checkIntHgl(text, offset, len);
  740. if (offset2 && ((text[offset2] & 0xdf) == 'F' ))
  741. return ++offset2;
  742. else
  743. return 0;
  744. }
  745. }
  746. //END
  747. //BEGIN KateHlAnyChar
  748. KateHlAnyChar::KateHlAnyChar(int attribute, int context, signed char regionId,signed char regionId2, const TQString& charList)
  749. : KateHlItem(attribute, context,regionId,regionId2)
  750. , _charList(charList)
  751. {
  752. }
  753. int KateHlAnyChar::checkHgl(const TQString& text, int offset, int)
  754. {
  755. if (kateInsideString (_charList, text[offset]))
  756. return ++offset;
  757. return 0;
  758. }
  759. //END
  760. //BEGIN KateHlRegExpr
  761. KateHlRegExpr::KateHlRegExpr( int attribute, int context, signed char regionId,signed char regionId2, TQString regexp, bool insensitive, bool minimal)
  762. : KateHlItem(attribute, context, regionId,regionId2)
  763. , handlesLinestart (regexp.startsWith("^"))
  764. , _regexp(regexp)
  765. , _insensitive(insensitive)
  766. , _minimal(minimal)
  767. {
  768. if (!handlesLinestart)
  769. regexp.prepend("^");
  770. Expr = new TQRegExp(regexp, !_insensitive);
  771. Expr->setMinimal(_minimal);
  772. }
  773. int KateHlRegExpr::checkHgl(const TQString& text, int offset, int /*len*/)
  774. {
  775. if (offset && handlesLinestart)
  776. return 0;
  777. int offset2 = Expr->search( text, offset, TQRegExp::CaretAtOffset );
  778. if (offset2 == -1) return 0;
  779. return (offset + Expr->matchedLength());
  780. }
  781. TQStringList *KateHlRegExpr::capturedTexts()
  782. {
  783. return new TQStringList(Expr->capturedTexts());
  784. }
  785. KateHlItem *KateHlRegExpr::clone(const TQStringList *args)
  786. {
  787. TQString regexp = _regexp;
  788. TQStringList escArgs = *args;
  789. for (TQStringList::Iterator it = escArgs.begin(); it != escArgs.end(); ++it)
  790. {
  791. (*it).replace(TQRegExp("(\\W)"), "\\\\1");
  792. }
  793. dynamicSubstitute(regexp, &escArgs);
  794. if (regexp == _regexp)
  795. return this;
  796. // kdDebug (13010) << "clone regexp: " << regexp << endl;
  797. KateHlRegExpr *ret = new KateHlRegExpr(attr, ctx, region, region2, regexp, _insensitive, _minimal);
  798. ret->dynamicChild = true;
  799. return ret;
  800. }
  801. //END
  802. //BEGIN KateHlLineContinue
  803. KateHlLineContinue::KateHlLineContinue(int attribute, int context, signed char regionId,signed char regionId2)
  804. : KateHlItem(attribute,context,regionId,regionId2) {
  805. }
  806. int KateHlLineContinue::checkHgl(const TQString& text, int offset, int len)
  807. {
  808. if ((len == 1) && (text[offset] == '\\'))
  809. return ++offset;
  810. return 0;
  811. }
  812. //END
  813. //BEGIN KateHlCStringChar
  814. KateHlCStringChar::KateHlCStringChar(int attribute, int context,signed char regionId,signed char regionId2)
  815. : KateHlItem(attribute,context,regionId,regionId2) {
  816. }
  817. // checks for C escaped chars \n and escaped hex/octal chars
  818. static int checkEscapedChar(const TQString& text, int offset, int& len)
  819. {
  820. int i;
  821. if (text[offset] == '\\' && len > 1)
  822. {
  823. offset++;
  824. len--;
  825. switch(text[offset])
  826. {
  827. case 'a': // checks for control chars
  828. case 'b': // we want to fall through
  829. case 'e':
  830. case 'f':
  831. case 'n':
  832. case 'r':
  833. case 't':
  834. case 'v':
  835. case '\'':
  836. case '\"':
  837. case '?' : // added ? ANSI C classifies this as an escaped char
  838. case '\\':
  839. offset++;
  840. len--;
  841. break;
  842. case 'x': // if it's like \xff
  843. offset++; // eat the x
  844. len--;
  845. // these for loops can probably be
  846. // replaced with something else but
  847. // for right now they work
  848. // check for hexdigits
  849. for (i = 0; (len > 0) && (i < 2) && (static_cast<const char>(text.at(offset)) >= '0' && static_cast<const char>(text.at(offset)) <= '9' || (text[offset] & 0xdf) >= 'A' && (text[offset] & 0xdf) <= 'F'); i++)
  850. {
  851. offset++;
  852. len--;
  853. }
  854. if (i == 0)
  855. return 0; // takes care of case '\x'
  856. break;
  857. case '0': case '1': case '2': case '3' :
  858. case '4': case '5': case '6': case '7' :
  859. for (i = 0; (len > 0) && (i < 3) && (static_cast<const char>(text.at(offset)) >= '0' && static_cast<const char>(text.at(offset)) <= '7'); i++)
  860. {
  861. offset++;
  862. len--;
  863. }
  864. break;
  865. default:
  866. return 0;
  867. }
  868. return offset;
  869. }
  870. return 0;
  871. }
  872. int KateHlCStringChar::checkHgl(const TQString& text, int offset, int len)
  873. {
  874. return checkEscapedChar(text, offset, len);
  875. }
  876. //END
  877. //BEGIN KateHlCChar
  878. KateHlCChar::KateHlCChar(int attribute, int context,signed char regionId,signed char regionId2)
  879. : KateHlItem(attribute,context,regionId,regionId2) {
  880. }
  881. int KateHlCChar::checkHgl(const TQString& text, int offset, int len)
  882. {
  883. if ((len > 1) && (text[offset] == '\'') && (text[offset+1] != '\''))
  884. {
  885. int oldl;
  886. oldl = len;
  887. len--;
  888. int offset2 = checkEscapedChar(text, offset + 1, len);
  889. if (!offset2)
  890. {
  891. if (oldl > 2)
  892. {
  893. offset2 = offset + 2;
  894. len = oldl - 2;
  895. }
  896. else
  897. {
  898. return 0;
  899. }
  900. }
  901. if ((len > 0) && (text[offset2] == '\''))
  902. return ++offset2;
  903. }
  904. return 0;
  905. }
  906. //END
  907. //BEGIN KateHl2CharDetect
  908. KateHl2CharDetect::KateHl2CharDetect(int attribute, int context, signed char regionId,signed char regionId2, const TQChar *s)
  909. : KateHlItem(attribute,context,regionId,regionId2) {
  910. sChar1 = s[0];
  911. sChar2 = s[1];
  912. }
  913. //END KateHl2CharDetect
  914. KateHlItemData::KateHlItemData(const TQString name, int defStyleNum)
  915. : name(name), defStyleNum(defStyleNum) {
  916. }
  917. KateHlData::KateHlData(const TQString &wildcards, const TQString &mimetypes, const TQString &identifier, int priority)
  918. : wildcards(wildcards), mimetypes(mimetypes), identifier(identifier), priority(priority)
  919. {
  920. }
  921. //BEGIN KateHlContext
  922. KateHlContext::KateHlContext (const TQString &_hlId, int attribute, int lineEndContext, int _lineBeginContext, bool _fallthrough,
  923. int _fallthroughContext, bool _dynamic, bool _noIndentationBasedFolding)
  924. {
  925. hlId = _hlId;
  926. attr = attribute;
  927. ctx = lineEndContext;
  928. lineBeginContext = _lineBeginContext;
  929. fallthrough = _fallthrough;
  930. ftctx = _fallthroughContext;
  931. dynamic = _dynamic;
  932. dynamicChild = false;
  933. noIndentationBasedFolding=_noIndentationBasedFolding;
  934. if (_noIndentationBasedFolding) kdDebug(13010)<<TQString("**********************_noIndentationBasedFolding is TRUE*****************")<<endl;
  935. }
  936. KateHlContext *KateHlContext::clone(const TQStringList *args)
  937. {
  938. KateHlContext *ret = new KateHlContext(hlId, attr, ctx, lineBeginContext, fallthrough, ftctx, false,noIndentationBasedFolding);
  939. for (uint n=0; n < items.size(); ++n)
  940. {
  941. KateHlItem *item = items[n];
  942. KateHlItem *i = (item->dynamic ? item->clone(args) : item);
  943. ret->items.append(i);
  944. }
  945. ret->dynamicChild = true;
  946. return ret;
  947. }
  948. KateHlContext::~KateHlContext()
  949. {
  950. if (dynamicChild)
  951. {
  952. for (uint n=0; n < items.size(); ++n)
  953. {
  954. if (items[n]->dynamicChild)
  955. delete items[n];
  956. }
  957. }
  958. }
  959. //END
  960. //BEGIN KateHighlighting
  961. KateHighlighting::KateHighlighting(const KateSyntaxModeListItem *def) : refCount(0)
  962. {
  963. m_attributeArrays.setAutoDelete (true);
  964. errorsAndWarnings = "";
  965. building=false;
  966. noHl = false;
  967. m_foldingIndentationSensitive = false;
  968. folding=false;
  969. internalIDList.setAutoDelete(true);
  970. if (def == 0)
  971. {
  972. noHl = true;
  973. iName = "None"; // not translated internal name (for config and more)
  974. iNameTranslated = i18n("None"); // user visible name
  975. iSection = "";
  976. m_priority = 0;
  977. iHidden = false;
  978. m_additionalData.insert( "none", new HighlightPropertyBag );
  979. m_additionalData["none"]->deliminator = stdDeliminator;
  980. m_additionalData["none"]->wordWrapDeliminator = stdDeliminator;
  981. m_hlIndex[0] = "none";
  982. }
  983. else
  984. {
  985. iName = def->name;
  986. iNameTranslated = def->nameTranslated;
  987. iSection = def->section;
  988. iHidden = def->hidden;
  989. iWildcards = def->extension;
  990. iMimetypes = def->mimetype;
  991. identifier = def->identifier;
  992. iVersion=def->version;
  993. iAuthor=def->author;
  994. iLicense=def->license;
  995. m_priority=def->priority.toInt();
  996. }
  997. deliminator = stdDeliminator;
  998. }
  999. KateHighlighting::~KateHighlighting()
  1000. {
  1001. // cu contexts
  1002. for (uint i=0; i < m_contexts.size(); ++i)
  1003. delete m_contexts[i];
  1004. m_contexts.clear ();
  1005. }
  1006. void KateHighlighting::generateContextStack(int *ctxNum, int ctx, TQMemArray<short>* ctxs, int *prevLine)
  1007. {
  1008. //kdDebug(13010)<<TQString("Entering generateContextStack with %1").arg(ctx)<<endl;
  1009. while (true)
  1010. {
  1011. if (ctx >= 0)
  1012. {
  1013. (*ctxNum) = ctx;
  1014. ctxs->resize (ctxs->size()+1, TQGArray::SpeedOptim);
  1015. (*ctxs)[ctxs->size()-1]=(*ctxNum);
  1016. return;
  1017. }
  1018. else
  1019. {
  1020. if (ctx == -1)
  1021. {
  1022. (*ctxNum)=( (ctxs->isEmpty() ) ? 0 : (*ctxs)[ctxs->size()-1]);
  1023. }
  1024. else
  1025. {
  1026. int size = ctxs->size() + ctx + 1;
  1027. if (size > 0)
  1028. {
  1029. ctxs->resize (size, TQGArray::SpeedOptim);
  1030. (*ctxNum)=(*ctxs)[size-1];
  1031. }
  1032. else
  1033. {
  1034. ctxs->resize (0, TQGArray::SpeedOptim);
  1035. (*ctxNum)=0;
  1036. }
  1037. ctx = 0;
  1038. if ((*prevLine) >= (int)(ctxs->size()-1))
  1039. {
  1040. *prevLine=ctxs->size()-1;
  1041. if ( ctxs->isEmpty() )
  1042. return;
  1043. KateHlContext *c = contextNum((*ctxs)[ctxs->size()-1]);
  1044. if (c && (c->ctx != -1))
  1045. {
  1046. //kdDebug(13010)<<"PrevLine > size()-1 and ctx!=-1)"<<endl;
  1047. ctx = c->ctx;
  1048. continue;
  1049. }
  1050. }
  1051. }
  1052. return;
  1053. }
  1054. }
  1055. }
  1056. /**
  1057. * Creates a new dynamic context or reuse an old one if it has already been created.
  1058. */
  1059. int KateHighlighting::makeDynamicContext(KateHlContext *model, const TQStringList *args)
  1060. {
  1061. QPair<KateHlContext *, TQString> key(model, args->front());
  1062. short value;
  1063. if (dynamicCtxs.contains(key))
  1064. value = dynamicCtxs[key];
  1065. else
  1066. {
  1067. kdDebug(13010) << "new stuff: " << startctx << endl;
  1068. KateHlContext *newctx = model->clone(args);
  1069. m_contexts.push_back (newctx);
  1070. value = startctx++;
  1071. dynamicCtxs[key] = value;
  1072. KateHlManager::self()->incDynamicCtxs();
  1073. }
  1074. // kdDebug(13010) << "Dynamic context: using context #" << value << " (for model " << model << " with args " << *args << ")" << endl;
  1075. return value;
  1076. }
  1077. /**
  1078. * Drop all dynamic contexts. Shall be called with extreme care, and shall be immediatly
  1079. * followed by a full HL invalidation.
  1080. */
  1081. void KateHighlighting::dropDynamicContexts()
  1082. {
  1083. for (uint i=base_startctx; i < m_contexts.size(); ++i)
  1084. delete m_contexts[i];
  1085. m_contexts.resize (base_startctx);
  1086. dynamicCtxs.clear();
  1087. startctx = base_startctx;
  1088. }
  1089. /**
  1090. * Parse the text and fill in the context array and folding list array
  1091. *
  1092. * @param prevLine The previous line, the context array is picked up from that if present.
  1093. * @param textLine The text line to parse
  1094. * @param foldingList will be filled
  1095. * @param ctxChanged will be set to reflect if the context changed
  1096. */
  1097. void KateHighlighting::doHighlight ( KateTextLine *prevLine,
  1098. KateTextLine *textLine,
  1099. TQMemArray<uint>* foldingList,
  1100. bool *ctxChanged )
  1101. {
  1102. if (!textLine)
  1103. return;
  1104. if (noHl)
  1105. {
  1106. if (textLine->length() > 0)
  1107. memset (textLine->attributes(), 0, textLine->length());
  1108. return;
  1109. }
  1110. // duplicate the ctx stack, only once !
  1111. TQMemArray<short> ctx;
  1112. ctx.duplicate (prevLine->ctxArray());
  1113. int ctxNum = 0;
  1114. int previousLine = -1;
  1115. KateHlContext *context;
  1116. if (ctx.isEmpty())
  1117. {
  1118. // If the stack is empty, we assume to be in Context 0 (Normal)
  1119. context = contextNum(ctxNum);
  1120. }
  1121. else
  1122. {
  1123. // There does an old context stack exist -> find the context at the line start
  1124. ctxNum = ctx[ctx.size()-1]; //context ID of the last character in the previous line
  1125. //kdDebug(13010) << "\t\tctxNum = " << ctxNum << " contextList[ctxNum] = " << contextList[ctxNum] << endl; // ellis
  1126. //if (lineContinue) kdDebug(13010)<<TQString("The old context should be %1").arg((int)ctxNum)<<endl;
  1127. if (!(context = contextNum(ctxNum)))
  1128. context = contextNum(0);
  1129. //kdDebug(13010)<<"test1-2-1-text2"<<endl;
  1130. previousLine=ctx.size()-1; //position of the last context ID of th previous line within the stack
  1131. // hl continue set or not ???
  1132. if (prevLine->hlLineContinue())
  1133. {
  1134. prevLine--;
  1135. }
  1136. else
  1137. {
  1138. generateContextStack(&ctxNum, context->ctx, &ctx, &previousLine); //get stack ID to use
  1139. if (!(context = contextNum(ctxNum)))
  1140. context = contextNum(0);
  1141. }
  1142. //kdDebug(13010)<<"test1-2-1-text4"<<endl;
  1143. //if (lineContinue) kdDebug(13010)<<TQString("The new context is %1").arg((int)ctxNum)<<endl;
  1144. }
  1145. // text, for programming convenience :)
  1146. TQChar lastChar = ' ';
  1147. const TQString& text = textLine->string();
  1148. const int len = textLine->length();
  1149. // calc at which char the first char occurs, set it to length of line if never
  1150. const int firstChar = textLine->firstChar();
  1151. const int startNonSpace = (firstChar == -1) ? len : firstChar;
  1152. // last found item
  1153. KateHlItem *item = 0;
  1154. // loop over the line, offset gives current offset
  1155. int offset = 0;
  1156. while (offset < len)
  1157. {
  1158. bool anItemMatched = false;
  1159. bool standardStartEnableDetermined = false;
  1160. bool customStartEnableDetermined = false;
  1161. uint index = 0;
  1162. for (item = context->items.empty() ? 0 : context->items[0]; item; item = (++index < context->items.size()) ? context->items[index] : 0 )
  1163. {
  1164. // does we only match if we are firstNonSpace?
  1165. if (item->firstNonSpace && (offset > startNonSpace))
  1166. continue;
  1167. // have we a column specified? if yes, only match at this column
  1168. if ((item->column != -1) && (item->column != offset))
  1169. continue;
  1170. if (!item->alwaysStartEnable)
  1171. {
  1172. if (item->customStartEnable)
  1173. {
  1174. if (customStartEnableDetermined || kateInsideString (m_additionalData[context->hlId]->deliminator, lastChar))
  1175. customStartEnableDetermined = true;
  1176. else
  1177. continue;
  1178. }
  1179. else
  1180. {
  1181. if (standardStartEnableDetermined || kateInsideString (stdDeliminator, lastChar))
  1182. standardStartEnableDetermined = true;
  1183. else
  1184. continue;
  1185. }
  1186. }
  1187. int offset2 = item->checkHgl(text, offset, len-offset);
  1188. if (offset2 <= offset)
  1189. continue;
  1190. // BUG 144599: Ignore a context change that would push the same context
  1191. // without eating anything... this would be an infinite loop!
  1192. if ( item->lookAhead && item->ctx == ctxNum )
  1193. continue;
  1194. if (item->region2)
  1195. {
  1196. // kdDebug(13010)<<TQString("Region mark 2 detected: %1").arg(item->region2)<<endl;
  1197. if ( !foldingList->isEmpty() && ((item->region2 < 0) && (*foldingList)[foldingList->size()-2] == -item->region2 ) )
  1198. {
  1199. foldingList->resize (foldingList->size()-2, TQGArray::SpeedOptim);
  1200. }
  1201. else
  1202. {
  1203. foldingList->resize (foldingList->size()+2, TQGArray::SpeedOptim);
  1204. (*foldingList)[foldingList->size()-2] = (uint)item->region2;
  1205. if (item->region2<0) //check not really needed yet
  1206. (*foldingList)[foldingList->size()-1] = offset2;
  1207. else
  1208. (*foldingList)[foldingList->size()-1] = offset;
  1209. }
  1210. }
  1211. if (item->region)
  1212. {
  1213. // kdDebug(13010)<<TQString("Region mark detected: %1").arg(item->region)<<endl;
  1214. /* if ( !foldingList->isEmpty() && ((item->region < 0) && (*foldingList)[foldingList->size()-1] == -item->region ) )
  1215. {
  1216. foldingList->resize (foldingList->size()-1, TQGArray::SpeedOptim);
  1217. }
  1218. else*/
  1219. {
  1220. foldingList->resize (foldingList->size()+2, TQGArray::SpeedOptim);
  1221. (*foldingList)[foldingList->size()-2] = item->region;
  1222. if (item->region<0) //check not really needed yet
  1223. (*foldingList)[foldingList->size()-1] = offset2;
  1224. else
  1225. (*foldingList)[foldingList->size()-1] = offset;
  1226. }
  1227. }
  1228. // regenerate context stack if needed
  1229. if (item->ctx != -1)
  1230. {
  1231. generateContextStack (&ctxNum, item->ctx, &ctx, &previousLine);
  1232. context = contextNum(ctxNum);
  1233. }
  1234. // dynamic context: substitute the model with an 'instance'
  1235. if (context->dynamic)
  1236. {
  1237. TQStringList *lst = item->capturedTexts();
  1238. if (lst != 0)
  1239. {
  1240. // Replace the top of the stack and the current context
  1241. int newctx = makeDynamicContext(context, lst);
  1242. if (ctx.size() > 0)
  1243. ctx[ctx.size() - 1] = newctx;
  1244. ctxNum = newctx;
  1245. context = contextNum(ctxNum);
  1246. }
  1247. delete lst;
  1248. }
  1249. // dominik: look ahead w/o changing offset?
  1250. if (!item->lookAhead)
  1251. {
  1252. if (offset2 > len)
  1253. offset2 = len;
  1254. // even set attributes ;)
  1255. memset ( textLine->attributes()+offset
  1256. , item->onlyConsume ? context->attr : item->attr
  1257. , offset2-offset);
  1258. offset = offset2;
  1259. lastChar = text[offset-1];
  1260. }
  1261. anItemMatched = true;
  1262. break;
  1263. }
  1264. // something matched, continue loop
  1265. if (anItemMatched)
  1266. continue;
  1267. // nothing found: set attribute of one char
  1268. // anders: unless this context does not want that!
  1269. if ( context->fallthrough )
  1270. {
  1271. // set context to context->ftctx.
  1272. generateContextStack(&ctxNum, context->ftctx, &ctx, &previousLine); //regenerate context stack
  1273. context=contextNum(ctxNum);
  1274. //kdDebug(13010)<<"context num after fallthrough at col "<<z<<": "<<ctxNum<<endl;
  1275. // the next is nessecary, as otherwise keyword (or anything using the std delimitor check)
  1276. // immediately after fallthrough fails. Is it bad?
  1277. // jowenn, can you come up with a nicer way to do this?
  1278. /* if (offset)
  1279. lastChar = text[offset - 1];
  1280. else
  1281. lastChar = '\\';*/
  1282. continue;
  1283. }
  1284. else
  1285. {
  1286. *(textLine->attributes() + offset) = context->attr;
  1287. lastChar = text[offset];
  1288. offset++;
  1289. }
  1290. }
  1291. // has the context stack changed ?
  1292. if (ctx == textLine->ctxArray())
  1293. {
  1294. if (ctxChanged)
  1295. (*ctxChanged) = false;
  1296. }
  1297. else
  1298. {
  1299. if (ctxChanged)
  1300. (*ctxChanged) = true;
  1301. // assign ctx stack !
  1302. textLine->setContext(ctx);
  1303. }
  1304. // write hl continue flag
  1305. textLine->setHlLineContinue (item && item->lineContinue());
  1306. if (m_foldingIndentationSensitive) {
  1307. bool noindent=false;
  1308. for(int i=ctx.size()-1; i>=0; --i) {
  1309. if (contextNum(ctx[i])->noIndentationBasedFolding) {
  1310. noindent=true;
  1311. break;
  1312. }
  1313. }
  1314. textLine->setNoIndentBasedFolding(noindent);
  1315. }
  1316. }
  1317. void KateHighlighting::loadWildcards()
  1318. {
  1319. TDEConfig *config = KateHlManager::self()->getTDEConfig();
  1320. config->setGroup("Highlighting " + iName);
  1321. TQString extensionString = config->readEntry("Wildcards", iWildcards);
  1322. if (extensionSource != extensionString) {
  1323. regexpExtensions.clear();
  1324. plainExtensions.clear();
  1325. extensionSource = extensionString;
  1326. static TQRegExp sep("\\s*;\\s*");
  1327. TQStringList l = TQStringList::split( sep, extensionSource );
  1328. static TQRegExp boringExpression("\\*\\.[\\d\\w]+");
  1329. for( TQStringList::Iterator it = l.begin(); it != l.end(); ++it )
  1330. if (boringExpression.exactMatch(*it))
  1331. plainExtensions.append((*it).mid(1));
  1332. else
  1333. regexpExtensions.append(TQRegExp((*it), true, true));
  1334. }
  1335. }
  1336. TQValueList<TQRegExp>& KateHighlighting::getRegexpExtensions()
  1337. {
  1338. return regexpExtensions;
  1339. }
  1340. TQStringList& KateHighlighting::getPlainExtensions()
  1341. {
  1342. return plainExtensions;
  1343. }
  1344. TQString KateHighlighting::getMimetypes()
  1345. {
  1346. TDEConfig *config = KateHlManager::self()->getTDEConfig();
  1347. config->setGroup("Highlighting " + iName);
  1348. return config->readEntry("Mimetypes", iMimetypes);
  1349. }
  1350. int KateHighlighting::priority()
  1351. {
  1352. TDEConfig *config = KateHlManager::self()->getTDEConfig();
  1353. config->setGroup("Highlighting " + iName);
  1354. return config->readNumEntry("Priority", m_priority);
  1355. }
  1356. KateHlData *KateHighlighting::getData()
  1357. {
  1358. TDEConfig *config = KateHlManager::self()->getTDEConfig();
  1359. config->setGroup("Highlighting " + iName);
  1360. KateHlData *hlData = new KateHlData(
  1361. config->readEntry("Wildcards", iWildcards),
  1362. config->readEntry("Mimetypes", iMimetypes),
  1363. config->readEntry("Identifier", identifier),
  1364. config->readNumEntry("Priority", m_priority));
  1365. return hlData;
  1366. }
  1367. void KateHighlighting::setData(KateHlData *hlData)
  1368. {
  1369. TDEConfig *config = KateHlManager::self()->getTDEConfig();
  1370. config->setGroup("Highlighting " + iName);
  1371. config->writeEntry("Wildcards",hlData->wildcards);
  1372. config->writeEntry("Mimetypes",hlData->mimetypes);
  1373. config->writeEntry("Priority",hlData->priority);
  1374. }
  1375. void KateHighlighting::getKateHlItemDataList (uint schema, KateHlItemDataList &list)
  1376. {
  1377. TDEConfig *config = KateHlManager::self()->getTDEConfig();
  1378. config->setGroup("Highlighting " + iName + " - Schema " + KateFactory::self()->schemaManager()->name(schema));
  1379. list.clear();
  1380. createKateHlItemData(list);
  1381. for (KateHlItemData *p = list.first(); p != 0L; p = list.next())
  1382. {
  1383. TQStringList s = config->readListEntry(p->name);
  1384. // kdDebug(13010)<<p->name<<s.count()<<endl;
  1385. if (s.count()>0)
  1386. {
  1387. while(s.count()<9) s<<"";
  1388. p->clear();
  1389. TQString tmp=s[0]; if (!tmp.isEmpty()) p->defStyleNum=tmp.toInt();
  1390. QRgb col;
  1391. tmp=s[1]; if (!tmp.isEmpty()) {
  1392. col=tmp.toUInt(0,16); p->setTextColor(col); }
  1393. tmp=s[2]; if (!tmp.isEmpty()) {
  1394. col=tmp.toUInt(0,16); p->setSelectedTextColor(col); }
  1395. tmp=s[3]; if (!tmp.isEmpty()) p->setBold(tmp!="0");
  1396. tmp=s[4]; if (!tmp.isEmpty()) p->setItalic(tmp!="0");
  1397. tmp=s[5]; if (!tmp.isEmpty()) p->setStrikeOut(tmp!="0");
  1398. tmp=s[6]; if (!tmp.isEmpty()) p->setUnderline(tmp!="0");
  1399. tmp=s[7]; if (!tmp.isEmpty()) {
  1400. col=tmp.toUInt(0,16); p->setBGColor(col); }
  1401. tmp=s[8]; if (!tmp.isEmpty()) {
  1402. col=tmp.toUInt(0,16); p->setSelectedBGColor(col); }
  1403. }
  1404. }
  1405. }
  1406. /**
  1407. * Saves the KateHlData attribute definitions to the config file.
  1408. *
  1409. * @param schema The id of the schema group to save
  1410. * @param list KateHlItemDataList containing the data to be used
  1411. */
  1412. void KateHighlighting::setKateHlItemDataList(uint schema, KateHlItemDataList &list)
  1413. {
  1414. TDEConfig *config = KateHlManager::self()->getTDEConfig();
  1415. config->setGroup("Highlighting " + iName + " - Schema "
  1416. + KateFactory::self()->schemaManager()->name(schema));
  1417. TQStringList settings;
  1418. for (KateHlItemData *p = list.first(); p != 0L; p = list.next())
  1419. {
  1420. settings.clear();
  1421. settings<<TQString::number(p->defStyleNum,10);
  1422. settings<<(p->itemSet(KateAttribute::TextColor)?TQString::number(p->textColor().rgb(),16):"");
  1423. settings<<(p->itemSet(KateAttribute::SelectedTextColor)?TQString::number(p->selectedTextColor().rgb(),16):"");
  1424. settings<<(p->itemSet(KateAttribute::Weight)?(p->bold()?"1":"0"):"");
  1425. settings<<(p->itemSet(KateAttribute::Italic)?(p->italic()?"1":"0"):"");
  1426. settings<<(p->itemSet(KateAttribute::StrikeOut)?(p->strikeOut()?"1":"0"):"");
  1427. settings<<(p->itemSet(KateAttribute::Underline)?(p->underline()?"1":"0"):"");
  1428. settings<<(p->itemSet(KateAttribute::BGColor)?TQString::number(p->bgColor().rgb(),16):"");
  1429. settings<<(p->itemSet(KateAttribute::SelectedBGColor)?TQString::number(p->selectedBGColor().rgb(),16):"");
  1430. settings<<"---";
  1431. config->writeEntry(p->name,settings);
  1432. }
  1433. }
  1434. /**
  1435. * Increase the usage count, and trigger initialization if needed.
  1436. */
  1437. void KateHighlighting::use()
  1438. {
  1439. if (refCount == 0)
  1440. init();
  1441. refCount++;
  1442. }
  1443. /**
  1444. * Decrease the usage count, and trigger cleanup if needed.
  1445. */
  1446. void KateHighlighting::release()
  1447. {
  1448. refCount--;
  1449. if (refCount == 0)
  1450. done();
  1451. }
  1452. /**
  1453. * Initialize a context for the first time.
  1454. */
  1455. void KateHighlighting::init()
  1456. {
  1457. if (noHl)
  1458. return;
  1459. // cu contexts
  1460. for (uint i=0; i < m_contexts.size(); ++i)
  1461. delete m_contexts[i];
  1462. m_contexts.clear ();
  1463. makeContextList();
  1464. }
  1465. /**
  1466. * If the there is no document using the highlighting style free the complete
  1467. * context structure.
  1468. */
  1469. void KateHighlighting::done()
  1470. {
  1471. if (noHl)
  1472. return;
  1473. // cu contexts
  1474. for (uint i=0; i < m_contexts.size(); ++i)
  1475. delete m_contexts[i];
  1476. m_contexts.clear ();
  1477. internalIDList.clear();
  1478. }
  1479. /**
  1480. * KateHighlighting - createKateHlItemData
  1481. * This function reads the itemData entries from the config file, which specifies the
  1482. * default attribute styles for matched items/contexts.
  1483. *
  1484. * @param list A reference to the internal list containing the parsed default config
  1485. */
  1486. void KateHighlighting::createKateHlItemData(KateHlItemDataList &list)
  1487. {
  1488. // If no highlighting is selected we need only one default.
  1489. if (noHl)
  1490. {
  1491. list.append(new KateHlItemData(i18n("Normal Text"), KateHlItemData::dsNormal));
  1492. return;
  1493. }
  1494. // If the internal list isn't already available read the config file
  1495. if (internalIDList.isEmpty())
  1496. makeContextList();
  1497. list=internalIDList;
  1498. }
  1499. /**
  1500. * Adds the styles of the currently parsed highlight to the itemdata list
  1501. */
  1502. void KateHighlighting::addToKateHlItemDataList()
  1503. {
  1504. //Tell the syntax document class which file we want to parse and which data group
  1505. KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
  1506. KateSyntaxContextData *data = KateHlManager::self()->syntax->getGroupInfo("highlighting","itemData");
  1507. //begin with the real parsing
  1508. while (KateHlManager::self()->syntax->nextGroup(data))
  1509. {
  1510. // read all attributes
  1511. TQString color = KateHlManager::self()->syntax->groupData(data,TQString("color"));
  1512. TQString selColor = KateHlManager::self()->syntax->groupData(data,TQString("selColor"));
  1513. TQString bold = KateHlManager::self()->syntax->groupData(data,TQString("bold"));
  1514. TQString italic = KateHlManager::self()->syntax->groupData(data,TQString("italic"));
  1515. TQString underline = KateHlManager::self()->syntax->groupData(data,TQString("underline"));
  1516. TQString strikeOut = KateHlManager::self()->syntax->groupData(data,TQString("strikeOut"));
  1517. TQString bgColor = KateHlManager::self()->syntax->groupData(data,TQString("backgroundColor"));
  1518. TQString selBgColor = KateHlManager::self()->syntax->groupData(data,TQString("selBackgroundColor"));
  1519. KateHlItemData* newData = new KateHlItemData(
  1520. buildPrefix+KateHlManager::self()->syntax->groupData(data,TQString("name")).simplifyWhiteSpace(),
  1521. getDefStyleNum(KateHlManager::self()->syntax->groupData(data,TQString("defStyleNum"))));
  1522. /* here the custom style overrides are specified, if needed */
  1523. if (!color.isEmpty()) newData->setTextColor(TQColor(color));
  1524. if (!selColor.isEmpty()) newData->setSelectedTextColor(TQColor(selColor));
  1525. if (!bold.isEmpty()) newData->setBold( IS_TRUE(bold) );
  1526. if (!italic.isEmpty()) newData->setItalic( IS_TRUE(italic) );
  1527. // new attributes for the new rendering view
  1528. if (!underline.isEmpty()) newData->setUnderline( IS_TRUE(underline) );
  1529. if (!strikeOut.isEmpty()) newData->setStrikeOut( IS_TRUE(strikeOut) );
  1530. if (!bgColor.isEmpty()) newData->setBGColor(TQColor(bgColor));
  1531. if (!selBgColor.isEmpty()) newData->setSelectedBGColor(TQColor(selBgColor));
  1532. internalIDList.append(newData);
  1533. }
  1534. //clean up
  1535. if (data)
  1536. KateHlManager::self()->syntax->freeGroupInfo(data);
  1537. }
  1538. /**
  1539. * KateHighlighting - lookupAttrName
  1540. * This function is a helper for makeContextList and createKateHlItem. It looks the given
  1541. * attribute name in the itemData list up and returns it's index
  1542. *
  1543. * @param name the attribute name to lookup
  1544. * @param iDl the list containing all available attributes
  1545. *
  1546. * @return The index of the attribute, or 0 if the attribute isn't found
  1547. */
  1548. int KateHighlighting::lookupAttrName(const TQString& name, KateHlItemDataList &iDl)
  1549. {
  1550. for (uint i = 0; i < iDl.count(); i++)
  1551. if (iDl.at(i)->name == buildPrefix+name)
  1552. return i;
  1553. kdDebug(13010)<<"Couldn't resolve itemDataName:"<<name<<endl;
  1554. return 0;
  1555. }
  1556. /**
  1557. * KateHighlighting - createKateHlItem
  1558. * This function is a helper for makeContextList. It parses the xml file for
  1559. * information.
  1560. *
  1561. * @param data Data about the item read from the xml file
  1562. * @param iDl List of all available itemData entries.
  1563. * Needed for attribute name->index translation
  1564. * @param RegionList list of code folding region names
  1565. * @param ContextNameList list of context names
  1566. *
  1567. * @return A pointer to the newly created item object
  1568. */
  1569. KateHlItem *KateHighlighting::createKateHlItem(KateSyntaxContextData *data,
  1570. KateHlItemDataList &iDl,
  1571. TQStringList *RegionList,
  1572. TQStringList *ContextNameList)
  1573. {
  1574. // No highlighting -> exit
  1575. if (noHl)
  1576. return 0;
  1577. // get the (tagname) itemd type
  1578. TQString dataname=KateHlManager::self()->syntax->groupItemData(data,TQString(""));
  1579. // code folding region handling:
  1580. TQString beginRegionStr=KateHlManager::self()->syntax->groupItemData(data,TQString("beginRegion"));
  1581. TQString endRegionStr=KateHlManager::self()->syntax->groupItemData(data,TQString("endRegion"));
  1582. signed char regionId=0;
  1583. signed char regionId2=0;
  1584. if (!beginRegionStr.isEmpty())
  1585. {
  1586. regionId = RegionList->findIndex(beginRegionStr);
  1587. if (regionId==-1) // if the region name doesn't already exist, add it to the list
  1588. {
  1589. (*RegionList)<<beginRegionStr;
  1590. regionId = RegionList->findIndex(beginRegionStr);
  1591. }
  1592. regionId++;
  1593. kdDebug(13010) << "########### BEG REG: " << beginRegionStr << " NUM: " << regionId << endl;
  1594. }
  1595. if (!endRegionStr.isEmpty())
  1596. {
  1597. regionId2 = RegionList->findIndex(endRegionStr);
  1598. if (regionId2==-1) // if the region name doesn't already exist, add it to the list
  1599. {
  1600. (*RegionList)<<endRegionStr;
  1601. regionId2 = RegionList->findIndex(endRegionStr);
  1602. }
  1603. regionId2 = -regionId2 - 1;
  1604. kdDebug(13010) << "########### END REG: " << endRegionStr << " NUM: " << regionId2 << endl;
  1605. }
  1606. int attr = 0;
  1607. TQString tmpAttr=KateHlManager::self()->syntax->groupItemData(data,TQString("attribute")).simplifyWhiteSpace();
  1608. bool onlyConsume = tmpAttr.isEmpty();
  1609. // only relevant for non consumer
  1610. if (!onlyConsume)
  1611. {
  1612. if (TQString("%1").arg(tmpAttr.toInt())==tmpAttr)
  1613. {
  1614. errorsAndWarnings+=i18n(
  1615. "<B>%1</B>: Deprecated syntax. Attribute (%2) not addressed by symbolic name<BR>").
  1616. arg(buildIdentifier).arg(tmpAttr);
  1617. attr=tmpAttr.toInt();
  1618. }
  1619. else
  1620. attr=lookupAttrName(tmpAttr,iDl);
  1621. }
  1622. // Info about context switch
  1623. int context = -1;
  1624. TQString unresolvedContext;
  1625. TQString tmpcontext=KateHlManager::self()->syntax->groupItemData(data,TQString("context"));
  1626. if (!tmpcontext.isEmpty())
  1627. context=getIdFromString(ContextNameList, tmpcontext,unresolvedContext);
  1628. // Get the char parameter (eg DetectChar)
  1629. char chr;
  1630. if (! KateHlManager::self()->syntax->groupItemData(data,TQString("char")).isEmpty())
  1631. chr= (KateHlManager::self()->syntax->groupItemData(data,TQString("char")).latin1())[0];
  1632. else
  1633. chr=0;
  1634. // Get the String parameter (eg. StringDetect)
  1635. TQString stringdata=KateHlManager::self()->syntax->groupItemData(data,TQString("String"));
  1636. // Get a second char parameter (char1) (eg Detect2Chars)
  1637. char chr1;
  1638. if (! KateHlManager::self()->syntax->groupItemData(data,TQString("char1")).isEmpty())
  1639. chr1= (KateHlManager::self()->syntax->groupItemData(data,TQString("char1")).latin1())[0];
  1640. else
  1641. chr1=0;
  1642. // Will be removed eventually. Atm used for StringDetect, keyword and RegExp
  1643. const TQString & insensitive_str = KateHlManager::self()->syntax->groupItemData(data,TQString("insensitive"));
  1644. bool insensitive = IS_TRUE( insensitive_str );
  1645. // for regexp only
  1646. bool minimal = IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,TQString("minimal")) );
  1647. // dominik: look ahead and do not change offset. so we can change contexts w/o changing offset1.
  1648. bool lookAhead = IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,TQString("lookAhead")) );
  1649. bool dynamic= IS_TRUE(KateHlManager::self()->syntax->groupItemData(data,TQString("dynamic")) );
  1650. bool firstNonSpace = IS_TRUE(KateHlManager::self()->syntax->groupItemData(data,TQString("firstNonSpace")) );
  1651. int column = -1;
  1652. TQString colStr = KateHlManager::self()->syntax->groupItemData(data,TQString("column"));
  1653. if (!colStr.isEmpty())
  1654. column = colStr.toInt();
  1655. //Create the item corresponding to it's type and set it's parameters
  1656. KateHlItem *tmpItem;
  1657. if (dataname=="keyword")
  1658. {
  1659. bool keywordInsensitive = insensitive_str.isEmpty() ? !casesensitive : insensitive;
  1660. KateHlKeyword *keyword=new KateHlKeyword(attr,context,regionId,regionId2,keywordInsensitive,
  1661. m_additionalData[ buildIdentifier ]->deliminator);
  1662. //Get the entries for the keyword lookup list
  1663. keyword->addList(KateHlManager::self()->syntax->finddata("highlighting",stringdata));
  1664. tmpItem=keyword;
  1665. }
  1666. else if (dataname=="Float") tmpItem= (new KateHlFloat(attr,context,regionId,regionId2));
  1667. else if (dataname=="Int") tmpItem=(new KateHlInt(attr,context,regionId,regionId2));
  1668. else if (dataname=="DetectChar") tmpItem=(new KateHlCharDetect(attr,context,regionId,regionId2,chr));
  1669. else if (dataname=="Detect2Chars") tmpItem=(new KateHl2CharDetect(attr,context,regionId,regionId2,chr,chr1));
  1670. else if (dataname=="RangeDetect") tmpItem=(new KateHlRangeDetect(attr,context,regionId,regionId2, chr, chr1));
  1671. else if (dataname=="LineContinue") tmpItem=(new KateHlLineContinue(attr,context,regionId,regionId2));
  1672. else if (dataname=="StringDetect") tmpItem=(new KateHlStringDetect(attr,context,regionId,regionId2,stringdata,insensitive));
  1673. else if (dataname=="AnyChar") tmpItem=(new KateHlAnyChar(attr,context,regionId,regionId2,stringdata));
  1674. else if (dataname=="RegExpr") tmpItem=(new KateHlRegExpr(attr,context,regionId,regionId2,stringdata, insensitive, minimal));
  1675. else if (dataname=="HlCChar") tmpItem= ( new KateHlCChar(attr,context,regionId,regionId2));
  1676. else if (dataname=="HlCHex") tmpItem= (new KateHlCHex(attr,context,regionId,regionId2));
  1677. else if (dataname=="HlCOct") tmpItem= (new KateHlCOct(attr,context,regionId,regionId2));
  1678. else if (dataname=="HlCFloat") tmpItem= (new KateHlCFloat(attr,context,regionId,regionId2));
  1679. else if (dataname=="HlCStringChar") tmpItem= (new KateHlCStringChar(attr,context,regionId,regionId2));
  1680. else if (dataname=="DetectSpaces") tmpItem= (new KateHlDetectSpaces(attr,context,regionId,regionId2));
  1681. else if (dataname=="DetectIdentifier") tmpItem= (new KateHlDetectIdentifier(attr,context,regionId,regionId2));
  1682. else
  1683. {
  1684. // oops, unknown type. Perhaps a spelling error in the xml file
  1685. return 0;
  1686. }
  1687. // set lookAhead & dynamic properties
  1688. tmpItem->lookAhead = lookAhead;
  1689. tmpItem->dynamic = dynamic;
  1690. tmpItem->firstNonSpace = firstNonSpace;
  1691. tmpItem->column = column;
  1692. tmpItem->onlyConsume = onlyConsume;
  1693. if (!unresolvedContext.isEmpty())
  1694. {
  1695. unresolvedContextReferences.insert(&(tmpItem->ctx),unresolvedContext);
  1696. }
  1697. return tmpItem;
  1698. }
  1699. TQString KateHighlighting::hlKeyForAttrib( int i ) const
  1700. {
  1701. // find entry. This is faster than TQMap::find. m_hlIndex always has an entry
  1702. // for key '0' (it is "none"), so the result is always valid.
  1703. int k = 0;
  1704. TQMap<int,TQString>::const_iterator it = m_hlIndex.constEnd();
  1705. while ( it != m_hlIndex.constBegin() )
  1706. {
  1707. --it;
  1708. k = it.key();
  1709. if ( i >= k )
  1710. break;
  1711. }
  1712. return it.data();
  1713. }
  1714. bool KateHighlighting::isInWord( TQChar c, int attrib ) const
  1715. {
  1716. return m_additionalData[ hlKeyForAttrib( attrib ) ]->deliminator.find(c) < 0
  1717. && !c.isSpace() && c != '"' && c != '\'';
  1718. }
  1719. bool KateHighlighting::canBreakAt( TQChar c, int attrib ) const
  1720. {
  1721. static const TQString& sq = TDEGlobal::staticQString("\"'");
  1722. return (m_additionalData[ hlKeyForAttrib( attrib ) ]->wordWrapDeliminator.find(c) != -1) && (sq.find(c) == -1);
  1723. }
  1724. signed char KateHighlighting::commentRegion(int attr) const {
  1725. TQString commentRegion=m_additionalData[ hlKeyForAttrib( attr ) ]->multiLineRegion;
  1726. return (commentRegion.isEmpty()?0:(commentRegion.toShort()));
  1727. }
  1728. bool KateHighlighting::canComment( int startAttrib, int endAttrib ) const
  1729. {
  1730. TQString k = hlKeyForAttrib( startAttrib );
  1731. return ( k == hlKeyForAttrib( endAttrib ) &&
  1732. ( ( !m_additionalData[k]->multiLineCommentStart.isEmpty() && !m_additionalData[k]->multiLineCommentEnd.isEmpty() ) ||
  1733. ! m_additionalData[k]->singleLineCommentMarker.isEmpty() ) );
  1734. }
  1735. TQString KateHighlighting::getCommentStart( int attrib ) const
  1736. {
  1737. return m_additionalData[ hlKeyForAttrib( attrib) ]->multiLineCommentStart;
  1738. }
  1739. TQString KateHighlighting::getCommentEnd( int attrib ) const
  1740. {
  1741. return m_additionalData[ hlKeyForAttrib( attrib ) ]->multiLineCommentEnd;
  1742. }
  1743. TQString KateHighlighting::getCommentSingleLineStart( int attrib ) const
  1744. {
  1745. return m_additionalData[ hlKeyForAttrib( attrib) ]->singleLineCommentMarker;
  1746. }
  1747. KateHighlighting::CSLPos KateHighlighting::getCommentSingleLinePosition( int attrib ) const
  1748. {
  1749. return m_additionalData[ hlKeyForAttrib( attrib) ]->singleLineCommentPosition;
  1750. }
  1751. /**
  1752. * Helper for makeContextList. It parses the xml file for
  1753. * information, how single or multi line comments are marked
  1754. */
  1755. void KateHighlighting::readCommentConfig()
  1756. {
  1757. KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
  1758. KateSyntaxContextData *data=KateHlManager::self()->syntax->getGroupInfo("general","comment");
  1759. TQString cmlStart="", cmlEnd="", cmlRegion="", cslStart="";
  1760. CSLPos cslPosition=CSLPosColumn0;
  1761. if (data)
  1762. {
  1763. while (KateHlManager::self()->syntax->nextGroup(data))
  1764. {
  1765. if (KateHlManager::self()->syntax->groupData(data,"name")=="singleLine")
  1766. {
  1767. cslStart=KateHlManager::self()->syntax->groupData(data,"start");
  1768. TQString cslpos=KateHlManager::self()->syntax->groupData(data,"position");
  1769. if (cslpos=="afterwhitespace")
  1770. cslPosition=CSLPosAfterWhitespace;
  1771. else
  1772. cslPosition=CSLPosColumn0;
  1773. }
  1774. else if (KateHlManager::self()->syntax->groupData(data,"name")=="multiLine")
  1775. {
  1776. cmlStart=KateHlManager::self()->syntax->groupData(data,"start");
  1777. cmlEnd=KateHlManager::self()->syntax->groupData(data,"end");
  1778. cmlRegion=KateHlManager::self()->syntax->groupData(data,"region");
  1779. }
  1780. }
  1781. KateHlManager::self()->syntax->freeGroupInfo(data);
  1782. }
  1783. m_additionalData[buildIdentifier]->singleLineCommentMarker = cslStart;
  1784. m_additionalData[buildIdentifier]->singleLineCommentPosition = cslPosition;
  1785. m_additionalData[buildIdentifier]->multiLineCommentStart = cmlStart;
  1786. m_additionalData[buildIdentifier]->multiLineCommentEnd = cmlEnd;
  1787. m_additionalData[buildIdentifier]->multiLineRegion = cmlRegion;
  1788. }
  1789. /**
  1790. * Helper for makeContextList. It parses the xml file for information,
  1791. * if keywords should be treated case(in)sensitive and creates the keyword
  1792. * delimiter list. Which is the default list, without any given weak deliminiators
  1793. */
  1794. void KateHighlighting::readGlobalKeywordConfig()
  1795. {
  1796. deliminator = stdDeliminator;
  1797. // Tell the syntax document class which file we want to parse
  1798. kdDebug(13010)<<"readGlobalKeywordConfig:BEGIN"<<endl;
  1799. KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
  1800. KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","keywords");
  1801. if (data)
  1802. {
  1803. kdDebug(13010)<<"Found global keyword config"<<endl;
  1804. if ( IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,TQString("casesensitive")) ) )
  1805. casesensitive=true;
  1806. else
  1807. casesensitive=false;
  1808. //get the weak deliminators
  1809. weakDeliminator=(KateHlManager::self()->syntax->groupItemData(data,TQString("weakDeliminator")));
  1810. kdDebug(13010)<<"weak delimiters are: "<<weakDeliminator<<endl;
  1811. // remove any weakDelimitars (if any) from the default list and store this list.
  1812. for (uint s=0; s < weakDeliminator.length(); s++)
  1813. {
  1814. int f = deliminator.find (weakDeliminator[s]);
  1815. if (f > -1)
  1816. deliminator.remove (f, 1);
  1817. }
  1818. TQString addDelim = (KateHlManager::self()->syntax->groupItemData(data,TQString("additionalDeliminator")));
  1819. if (!addDelim.isEmpty())
  1820. deliminator=deliminator+addDelim;
  1821. KateHlManager::self()->syntax->freeGroupInfo(data);
  1822. }
  1823. else
  1824. {
  1825. //Default values
  1826. casesensitive=true;
  1827. weakDeliminator=TQString("");
  1828. }
  1829. kdDebug(13010)<<"readGlobalKeywordConfig:END"<<endl;
  1830. kdDebug(13010)<<"delimiterCharacters are: "<<deliminator<<endl;
  1831. m_additionalData[buildIdentifier]->deliminator = deliminator;
  1832. }
  1833. /**
  1834. * Helper for makeContextList. It parses the xml file for any wordwrap
  1835. * deliminators, characters * at which line can be broken. In case no keyword
  1836. * tag is found in the xml file, the wordwrap deliminators list defaults to the
  1837. * standard denominators. In case a keyword tag is defined, but no
  1838. * wordWrapDeliminator attribute is specified, the deliminator list as computed
  1839. * in readGlobalKeywordConfig is used.
  1840. *
  1841. * @return the computed delimiter string.
  1842. */
  1843. void KateHighlighting::readWordWrapConfig()
  1844. {
  1845. // Tell the syntax document class which file we want to parse
  1846. kdDebug(13010)<<"readWordWrapConfig:BEGIN"<<endl;
  1847. KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
  1848. KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","keywords");
  1849. TQString wordWrapDeliminator = stdDeliminator;
  1850. if (data)
  1851. {
  1852. kdDebug(13010)<<"Found global keyword config"<<endl;
  1853. wordWrapDeliminator = (KateHlManager::self()->syntax->groupItemData(data,TQString("wordWrapDeliminator")));
  1854. //when no wordWrapDeliminator is defined use the deliminator list
  1855. if ( wordWrapDeliminator.length() == 0 ) wordWrapDeliminator = deliminator;
  1856. kdDebug(13010) << "word wrap deliminators are " << wordWrapDeliminator << endl;
  1857. KateHlManager::self()->syntax->freeGroupInfo(data);
  1858. }
  1859. kdDebug(13010)<<"readWordWrapConfig:END"<<endl;
  1860. m_additionalData[buildIdentifier]->wordWrapDeliminator = wordWrapDeliminator;
  1861. }
  1862. void KateHighlighting::readIndentationConfig()
  1863. {
  1864. m_indentation = "";
  1865. KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
  1866. KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","indentation");
  1867. if (data)
  1868. {
  1869. m_indentation = (KateHlManager::self()->syntax->groupItemData(data,TQString("mode")));
  1870. KateHlManager::self()->syntax->freeGroupInfo(data);
  1871. }
  1872. }
  1873. void KateHighlighting::readFoldingConfig()
  1874. {
  1875. // Tell the syntax document class which file we want to parse
  1876. kdDebug(13010)<<"readfoldignConfig:BEGIN"<<endl;
  1877. KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
  1878. KateSyntaxContextData *data = KateHlManager::self()->syntax->getConfig("general","folding");
  1879. if (data)
  1880. {
  1881. kdDebug(13010)<<"Found global keyword config"<<endl;
  1882. if ( IS_TRUE( KateHlManager::self()->syntax->groupItemData(data,TQString("indentationsensitive")) ) )
  1883. m_foldingIndentationSensitive=true;
  1884. else
  1885. m_foldingIndentationSensitive=false;
  1886. KateHlManager::self()->syntax->freeGroupInfo(data);
  1887. }
  1888. else
  1889. {
  1890. //Default values
  1891. m_foldingIndentationSensitive = false;
  1892. }
  1893. kdDebug(13010)<<"readfoldingConfig:END"<<endl;
  1894. kdDebug(13010)<<"############################ use indent for fold are: "<<m_foldingIndentationSensitive<<endl;
  1895. }
  1896. void KateHighlighting::createContextNameList(TQStringList *ContextNameList,int ctx0)
  1897. {
  1898. kdDebug(13010)<<"creatingContextNameList:BEGIN"<<endl;
  1899. if (ctx0 == 0)
  1900. ContextNameList->clear();
  1901. KateHlManager::self()->syntax->setIdentifier(buildIdentifier);
  1902. KateSyntaxContextData *data=KateHlManager::self()->syntax->getGroupInfo("highlighting","context");
  1903. int id=ctx0;
  1904. if (data)
  1905. {
  1906. while (KateHlManager::self()->syntax->nextGroup(data))
  1907. {
  1908. TQString tmpAttr=KateHlManager::self()->syntax->groupData(data,TQString("name")).simplifyWhiteSpace();
  1909. if (tmpAttr.isEmpty())
  1910. {
  1911. tmpAttr=TQString("!KATE_INTERNAL_DUMMY! %1").arg(id);
  1912. errorsAndWarnings +=i18n("<B>%1</B>: Deprecated syntax. Context %2 has no symbolic name<BR>").arg(buildIdentifier).arg(id-ctx0);
  1913. }
  1914. else tmpAttr=buildPrefix+tmpAttr;
  1915. (*ContextNameList)<<tmpAttr;
  1916. id++;
  1917. }
  1918. KateHlManager::self()->syntax->freeGroupInfo(data);
  1919. }
  1920. kdDebug(13010)<<"creatingContextNameList:END"<<endl;
  1921. }
  1922. int KateHighlighting::getIdFromString(TQStringList *ContextNameList, TQString tmpLineEndContext, /*NO CONST*/ TQString &unres)
  1923. {
  1924. unres="";
  1925. int context;
  1926. if ((tmpLineEndContext=="#stay") || (tmpLineEndContext.simplifyWhiteSpace().isEmpty()))
  1927. context=-1;
  1928. else if (tmpLineEndContext.startsWith("#pop"))
  1929. {
  1930. context=-1;
  1931. for(;tmpLineEndContext.startsWith("#pop");context--)
  1932. {
  1933. tmpLineEndContext.remove(0,4);
  1934. kdDebug(13010)<<"#pop found"<<endl;
  1935. }
  1936. }
  1937. else if ( tmpLineEndContext.contains("##"))
  1938. {
  1939. int o = tmpLineEndContext.find("##");
  1940. // FIXME at least with 'foo##bar'-style contexts the rules are picked up
  1941. // but the default attribute is not
  1942. TQString tmp=tmpLineEndContext.mid(o+2);
  1943. if (!embeddedHls.contains(tmp)) embeddedHls.insert(tmp,KateEmbeddedHlInfo());
  1944. unres=tmp+':'+tmpLineEndContext.left(o);
  1945. context=0;
  1946. }
  1947. else
  1948. {
  1949. context=ContextNameList->findIndex(buildPrefix+tmpLineEndContext);
  1950. if (context==-1)
  1951. {
  1952. context=tmpLineEndContext.toInt();
  1953. errorsAndWarnings+=i18n(
  1954. "<B>%1</B>:Deprecated syntax. Context %2 not addressed by a symbolic name"
  1955. ).arg(buildIdentifier).arg(tmpLineEndContext);
  1956. }
  1957. //#warning restructure this the name list storage.
  1958. // context=context+buildContext0Offset;
  1959. }
  1960. return context;
  1961. }
  1962. /**
  1963. * The most important initialization function for each highlighting. It's called
  1964. * each time a document gets a highlighting style assigned. parses the xml file
  1965. * and creates a corresponding internal structure
  1966. */
  1967. void KateHighlighting::makeContextList()
  1968. {
  1969. if (noHl) // if this a highlighting for "normal texts" only, tere is no need for a context list creation
  1970. return;
  1971. embeddedHls.clear();
  1972. unresolvedContextReferences.clear();
  1973. RegionList.clear();
  1974. ContextNameList.clear();
  1975. // prepare list creation. To reuse as much code as possible handle this
  1976. // highlighting the same way as embedded onces
  1977. embeddedHls.insert(iName,KateEmbeddedHlInfo());
  1978. bool something_changed;
  1979. // the context "0" id is 0 for this hl, all embedded context "0"s have offsets
  1980. startctx=base_startctx=0;
  1981. // inform everybody that we are building the highlighting contexts and itemlists
  1982. building=true;
  1983. do
  1984. {
  1985. kdDebug(13010)<<"**************** Outer loop in make ContextList"<<endl;
  1986. kdDebug(13010)<<"**************** Hl List count:"<<embeddedHls.count()<<endl;
  1987. something_changed=false; //assume all "embedded" hls have already been loaded
  1988. for (KateEmbeddedHlInfos::const_iterator it=embeddedHls.begin(); it!=embeddedHls.end();++it)
  1989. {
  1990. if (!it.data().loaded) // we found one, we still have to load
  1991. {
  1992. kdDebug(13010)<<"**************** Inner loop in make ContextList"<<endl;
  1993. TQString identifierToUse;
  1994. kdDebug(13010)<<"Trying to open highlighting definition file: "<< it.key()<<endl;
  1995. if (iName==it.key()) // the own identifier is known
  1996. identifierToUse=identifier;
  1997. else // all others have to be looked up
  1998. identifierToUse=KateHlManager::self()->identifierForName(it.key());
  1999. kdDebug(13010)<<"Location is:"<< identifierToUse<<endl;
  2000. buildPrefix=it.key()+':'; // attribute names get prefixed by the names
  2001. // of the highlighting definitions they belong to
  2002. if (identifierToUse.isEmpty() )
  2003. kdDebug(13010)<<"OHOH, unknown highlighting description referenced"<<endl;
  2004. kdDebug(13010)<<"setting ("<<it.key()<<") to loaded"<<endl;
  2005. //mark hl as loaded
  2006. it=embeddedHls.insert(it.key(),KateEmbeddedHlInfo(true,startctx));
  2007. //set class member for context 0 offset, so we don't need to pass it around
  2008. buildContext0Offset=startctx;
  2009. //parse one hl definition file
  2010. startctx=addToContextList(identifierToUse,startctx);
  2011. if (noHl) return; // an error occurred
  2012. base_startctx = startctx;
  2013. something_changed=true; // something has been loaded
  2014. }
  2015. }
  2016. } while (something_changed); // as long as there has been another file parsed
  2017. // repeat everything, there could be newly added embedded hls.
  2018. // at this point all needed highlighing (sub)definitions are loaded. It's time
  2019. // to resolve cross file references (if there are any)
  2020. kdDebug(13010)<<"Unresolved contexts, which need attention: "<<unresolvedContextReferences.count()<<endl;
  2021. //optimize this a littlebit
  2022. for (KateHlUnresolvedCtxRefs::iterator unresIt=unresolvedContextReferences.begin();
  2023. unresIt!=unresolvedContextReferences.end();++unresIt)
  2024. {
  2025. TQString incCtx = unresIt.data();
  2026. kdDebug(13010)<<"Context "<<incCtx<<" is unresolved"<<endl;
  2027. // only resolve '##Name' contexts here; handleKateHlIncludeRules() can figure
  2028. // out 'Name##Name'-style inclusions, but we screw it up
  2029. if (incCtx.endsWith(":")) {
  2030. kdDebug(13010)<<"Looking up context0 for ruleset "<<incCtx<<endl;
  2031. incCtx = incCtx.left(incCtx.length()-1);
  2032. //try to find the context0 id for a given unresolvedReference
  2033. KateEmbeddedHlInfos::const_iterator hlIt=embeddedHls.find(incCtx);
  2034. if (hlIt!=embeddedHls.end())
  2035. *(unresIt.key())=hlIt.data().context0;
  2036. }
  2037. }
  2038. // eventually handle KateHlIncludeRules items, if they exist.
  2039. // This has to be done after the cross file references, because it is allowed
  2040. // to include the context0 from a different definition, than the one the rule
  2041. // belongs to
  2042. handleKateHlIncludeRules();
  2043. embeddedHls.clear(); //save some memory.
  2044. unresolvedContextReferences.clear(); //save some memory
  2045. RegionList.clear(); // I think you get the idea ;)
  2046. ContextNameList.clear();
  2047. // if there have been errors show them
  2048. if (!errorsAndWarnings.isEmpty())
  2049. KMessageBox::detailedSorry(0L,i18n(
  2050. "There were warning(s) and/or error(s) while parsing the syntax "
  2051. "highlighting configuration."),
  2052. errorsAndWarnings, i18n("Kate Syntax Highlighting Parser"));
  2053. // we have finished
  2054. building=false;
  2055. }
  2056. void KateHighlighting::handleKateHlIncludeRules()
  2057. {
  2058. // if there are noe include rules to take care of, just return
  2059. kdDebug(13010)<<"KateHlIncludeRules, which need attention: " <<includeRules.count()<<endl;
  2060. if (includeRules.isEmpty()) return;
  2061. buildPrefix="";
  2062. TQString dummy;
  2063. // By now the context0 references are resolved, now more or less only inner
  2064. // file references are resolved. If we decide that arbitrary inclusion is
  2065. // needed, this doesn't need to be changed, only the addToContextList
  2066. // method.
  2067. //resolove context names
  2068. for (KateHlIncludeRules::iterator it=includeRules.begin();it!=includeRules.end();)
  2069. {
  2070. if ((*it)->incCtx==-1) // context unresolved ?
  2071. {
  2072. if ((*it)->incCtxN.isEmpty())
  2073. {
  2074. // no context name given, and no valid context id set, so this item is
  2075. // going to be removed
  2076. KateHlIncludeRules::iterator it1=it;
  2077. ++it1;
  2078. delete (*it);
  2079. includeRules.remove(it);
  2080. it=it1;
  2081. }
  2082. else
  2083. {
  2084. // resolve name to id
  2085. (*it)->incCtx=getIdFromString(&ContextNameList,(*it)->incCtxN,dummy);
  2086. kdDebug(13010)<<"Resolved "<<(*it)->incCtxN<< " to "<<(*it)->incCtx<<" for include rule"<<endl;
  2087. // It would be good to look here somehow, if the result is valid
  2088. }
  2089. }
  2090. else ++it; //nothing to do, already resolved (by the cross defintion reference resolver)
  2091. }
  2092. // now that all KateHlIncludeRule items should be valid and completely resolved,
  2093. // do the real inclusion of the rules.
  2094. // recursiveness is needed, because context 0 could include context 1, which
  2095. // itself includes context 2 and so on.
  2096. // In that case we have to handle context 2 first, then 1, 0
  2097. //TODO: catch circular references: eg 0->1->2->3->1
  2098. while (!includeRules.isEmpty())
  2099. handleKateHlIncludeRulesRecursive(includeRules.begin(),&includeRules);
  2100. }
  2101. void KateHighlighting::handleKateHlIncludeRulesRecursive(KateHlIncludeRules::iterator it, KateHlIncludeRules *list)
  2102. {
  2103. if (it==list->end()) return; //invalid iterator, shouldn't happen, but better have a rule prepared ;)
  2104. KateHlIncludeRules::iterator it1=it;
  2105. int ctx=(*it1)->ctx;
  2106. // find the last entry for the given context in the KateHlIncludeRules list
  2107. // this is need if one context includes more than one. This saves us from
  2108. // updating all insert positions:
  2109. // eg: context 0:
  2110. // pos 3 - include context 2
  2111. // pos 5 - include context 3
  2112. // During the building of the includeRules list the items are inserted in
  2113. // ascending order, now we need it descending to make our life easier.
  2114. while ((it!=list->end()) && ((*it)->ctx==ctx))
  2115. {
  2116. it1=it;
  2117. ++it;
  2118. }
  2119. // iterate over each include rule for the context the function has been called for.
  2120. while ((it1!=list->end()) && ((*it1)->ctx==ctx))
  2121. {
  2122. int ctx1=(*it1)->incCtx;
  2123. //let's see, if the the included context includes other contexts
  2124. for (KateHlIncludeRules::iterator it2=list->begin();it2!=list->end();++it2)
  2125. {
  2126. if ((*it2)->ctx==ctx1)
  2127. {
  2128. //yes it does, so first handle that include rules, since we want to
  2129. // include those subincludes too
  2130. handleKateHlIncludeRulesRecursive(it2,list);
  2131. break;
  2132. }
  2133. }
  2134. // if the context we want to include had sub includes, they are already inserted there.
  2135. KateHlContext *dest=m_contexts[ctx];
  2136. KateHlContext *src=m_contexts[ctx1];
  2137. // kdDebug(3010)<<"linking included rules from "<<ctx<<" to "<<ctx1<<endl;
  2138. // If so desired, change the dest attribute to the one of the src.
  2139. // Required to make commenting work, if text matched by the included context
  2140. // is a different highlight than the host context.
  2141. if ( (*it1)->includeAttrib )
  2142. dest->attr = src->attr;
  2143. // insert the included context's rules starting at position p
  2144. int p=(*it1)->pos;
  2145. // remember some stuff
  2146. int oldLen = dest->items.size();
  2147. uint itemsToInsert = src->items.size();
  2148. // resize target
  2149. dest->items.resize (oldLen + itemsToInsert);
  2150. // move old elements
  2151. for (int i=oldLen-1; i >= p; --i)
  2152. dest->items[i+itemsToInsert] = dest->items[i];
  2153. // insert new stuff
  2154. for (uint i=0; i < itemsToInsert; ++i )
  2155. dest->items[p+i] = src->items[i];
  2156. it=it1; //backup the iterator
  2157. --it1; //move to the next entry, which has to be take care of
  2158. delete (*it); //free the already handled data structure
  2159. list->remove(it); // remove it from the list
  2160. }
  2161. }
  2162. /**
  2163. * Add one highlight to the contextlist.
  2164. *
  2165. * @return the number of contexts after this is added.
  2166. */
  2167. int KateHighlighting::addToContextList(const TQString &ident, int ctx0)
  2168. {
  2169. kdDebug(13010)<<"=== Adding hl with ident '"<<ident<<"'"<<endl;
  2170. buildIdentifier=ident;
  2171. KateSyntaxContextData *data, *datasub;
  2172. KateHlItem *c;
  2173. TQString dummy;
  2174. // Let the syntax document class know, which file we'd like to parse
  2175. if (!KateHlManager::self()->syntax->setIdentifier(ident))
  2176. {
  2177. noHl=true;
  2178. KMessageBox::information(0L,i18n(
  2179. "Since there has been an error parsing the highlighting description, "
  2180. "this highlighting will be disabled"));
  2181. return 0;
  2182. }
  2183. // only read for the own stuff
  2184. if (identifier == ident)
  2185. {
  2186. readIndentationConfig ();
  2187. }
  2188. RegionList<<"!KateInternal_TopLevel!";
  2189. m_hlIndex[internalIDList.count()] = ident;
  2190. m_additionalData.insert( ident, new HighlightPropertyBag );
  2191. // fill out the propertybag
  2192. readCommentConfig();
  2193. readGlobalKeywordConfig();
  2194. readWordWrapConfig();
  2195. readFoldingConfig ();
  2196. TQString ctxName;
  2197. // This list is needed for the translation of the attribute parameter,
  2198. // if the itemData name is given instead of the index
  2199. addToKateHlItemDataList();
  2200. KateHlItemDataList iDl = internalIDList;
  2201. createContextNameList(&ContextNameList,ctx0);
  2202. kdDebug(13010)<<"Parsing Context structure"<<endl;
  2203. //start the real work
  2204. data=KateHlManager::self()->syntax->getGroupInfo("highlighting","context");
  2205. uint i=buildContext0Offset;
  2206. if (data)
  2207. {
  2208. while (KateHlManager::self()->syntax->nextGroup(data))
  2209. {
  2210. kdDebug(13010)<<"Found a context in file, building structure now"<<endl;
  2211. //BEGIN - Translation of the attribute parameter
  2212. TQString tmpAttr=KateHlManager::self()->syntax->groupData(data,TQString("attribute")).simplifyWhiteSpace();
  2213. int attr;
  2214. if (TQString("%1").arg(tmpAttr.toInt())==tmpAttr)
  2215. attr=tmpAttr.toInt();
  2216. else
  2217. attr=lookupAttrName(tmpAttr,iDl);
  2218. //END - Translation of the attribute parameter
  2219. ctxName=buildPrefix+KateHlManager::self()->syntax->groupData(data,TQString("lineEndContext")).simplifyWhiteSpace();
  2220. TQString tmpLineEndContext=KateHlManager::self()->syntax->groupData(data,TQString("lineEndContext")).simplifyWhiteSpace();
  2221. int context;
  2222. context=getIdFromString(&ContextNameList, tmpLineEndContext,dummy);
  2223. TQString tmpNIBF = KateHlManager::self()->syntax->groupData(data, TQString("noIndentationBasedFolding") );
  2224. bool noIndentationBasedFolding=IS_TRUE(tmpNIBF);
  2225. //BEGIN get fallthrough props
  2226. bool ft = false;
  2227. int ftc = 0; // fallthrough context
  2228. if ( i > 0 ) // fallthrough is not smart in context 0
  2229. {
  2230. TQString tmpFt = KateHlManager::self()->syntax->groupData(data, TQString("fallthrough") );
  2231. if ( IS_TRUE(tmpFt) )
  2232. ft = true;
  2233. if ( ft )
  2234. {
  2235. TQString tmpFtc = KateHlManager::self()->syntax->groupData( data, TQString("fallthroughContext") );
  2236. ftc=getIdFromString(&ContextNameList, tmpFtc,dummy);
  2237. if (ftc == -1) ftc =0;
  2238. kdDebug(13010)<<"Setting fall through context (context "<<i<<"): "<<ftc<<endl;
  2239. }
  2240. }
  2241. //END falltrhough props
  2242. bool dynamic = false;
  2243. TQString tmpDynamic = KateHlManager::self()->syntax->groupData(data, TQString("dynamic") );
  2244. if ( tmpDynamic.lower() == "true" || tmpDynamic.toInt() == 1 )
  2245. dynamic = true;
  2246. KateHlContext *ctxNew = new KateHlContext (
  2247. ident,
  2248. attr,
  2249. context,
  2250. (KateHlManager::self()->syntax->groupData(data,TQString("lineBeginContext"))).isEmpty()?-1:
  2251. (KateHlManager::self()->syntax->groupData(data,TQString("lineBeginContext"))).toInt(),
  2252. ft, ftc, dynamic,noIndentationBasedFolding);
  2253. m_contexts.push_back (ctxNew);
  2254. kdDebug(13010) << "INDEX: " << i << " LENGTH " << m_contexts.size()-1 << endl;
  2255. //Let's create all items for the context
  2256. while (KateHlManager::self()->syntax->nextItem(data))
  2257. {
  2258. // kdDebug(13010)<< "In make Contextlist: Item:"<<endl;
  2259. // KateHlIncludeRules : add a pointer to each item in that context
  2260. // TODO add a attrib includeAttrib
  2261. TQString tag = KateHlManager::self()->syntax->groupItemData(data,TQString(""));
  2262. if ( tag == "IncludeRules" ) //if the new item is an Include rule, we have to take special care
  2263. {
  2264. TQString incCtx = KateHlManager::self()->syntax->groupItemData( data, TQString("context"));
  2265. TQString incAttrib = KateHlManager::self()->syntax->groupItemData( data, TQString("includeAttrib"));
  2266. bool includeAttrib = IS_TRUE( incAttrib );
  2267. // only context refernces of type Name, ##Name, and Subname##Name are allowed
  2268. if (incCtx.startsWith("##") || (!incCtx.startsWith("#")))
  2269. {
  2270. int incCtxi = incCtx.find("##");
  2271. //#stay, #pop is not interesting here
  2272. if (incCtxi >= 0)
  2273. {
  2274. TQString incSet = incCtx.mid(incCtxi + 2);
  2275. TQString incCtxN = incSet + ":" + incCtx.left(incCtxi);
  2276. //a cross highlighting reference
  2277. kdDebug(13010)<<"Cross highlight reference <IncludeRules>, context "<<incCtxN<<endl;
  2278. KateHlIncludeRule *ir=new KateHlIncludeRule(i,m_contexts[i]->items.count(),incCtxN,includeAttrib);
  2279. //use the same way to determine cross hl file references as other items do
  2280. if (!embeddedHls.contains(incSet))
  2281. embeddedHls.insert(incSet,KateEmbeddedHlInfo());
  2282. else
  2283. kdDebug(13010)<<"Skipping embeddedHls.insert for "<<incCtxN<<endl;
  2284. unresolvedContextReferences.insert(&(ir->incCtx), incCtxN);
  2285. includeRules.append(ir);
  2286. }
  2287. else
  2288. {
  2289. // a local reference -> just initialize the include rule structure
  2290. incCtx=buildPrefix+incCtx.simplifyWhiteSpace();
  2291. includeRules.append(new KateHlIncludeRule(i,m_contexts[i]->items.count(),incCtx, includeAttrib));
  2292. }
  2293. }
  2294. continue;
  2295. }
  2296. // TODO -- can we remove the block below??
  2297. #if 0
  2298. TQString tag = KateHlManager::self()->syntax->groupKateHlItemData(data,TQString(""));
  2299. if ( tag == "IncludeRules" ) {
  2300. // attrib context: the index (jowenn, i think using names here
  2301. // would be a cool feat, goes for mentioning the context in
  2302. // any item. a map or dict?)
  2303. int ctxId = getIdFromString(&ContextNameList,
  2304. KateHlManager::self()->syntax->groupKateHlItemData( data, TQString("context")),dummy); // the index is *required*
  2305. if ( ctxId > -1) { // we can even reuse rules of 0 if we want to:)
  2306. kdDebug(13010)<<"makeContextList["<<i<<"]: including all items of context "<<ctxId<<endl;
  2307. if ( ctxId < (int) i ) { // must be defined
  2308. for ( c = m_contexts[ctxId]->items.first(); c; c = m_contexts[ctxId]->items.next() )
  2309. m_contexts[i]->items.append(c);
  2310. }
  2311. else
  2312. kdDebug(13010)<<"Context "<<ctxId<<"not defined. You can not include the rules of an undefined context"<<endl;
  2313. }
  2314. continue; // while nextItem
  2315. }
  2316. #endif
  2317. c=createKateHlItem(data,iDl,&RegionList,&ContextNameList);
  2318. if (c)
  2319. {
  2320. m_contexts[i]->items.append(c);
  2321. // Not supported completely atm and only one level. Subitems.(all have
  2322. // to be matched to at once)
  2323. datasub=KateHlManager::self()->syntax->getSubItems(data);
  2324. bool tmpbool;
  2325. if (tmpbool=KateHlManager::self()->syntax->nextItem(datasub))
  2326. {
  2327. for (;tmpbool;tmpbool=KateHlManager::self()->syntax->nextItem(datasub))
  2328. {
  2329. c->subItems.resize (c->subItems.size()+1);
  2330. c->subItems[c->subItems.size()-1] = createKateHlItem(datasub,iDl,&RegionList,&ContextNameList);
  2331. } }
  2332. KateHlManager::self()->syntax->freeGroupInfo(datasub);
  2333. // end of sublevel
  2334. }
  2335. }
  2336. i++;
  2337. }
  2338. }
  2339. KateHlManager::self()->syntax->freeGroupInfo(data);
  2340. if (RegionList.count()!=1)
  2341. folding=true;
  2342. folding = folding || m_foldingIndentationSensitive;
  2343. //BEGIN Resolve multiline region if possible
  2344. if (!m_additionalData[ ident ]->multiLineRegion.isEmpty()) {
  2345. long commentregionid=RegionList.findIndex( m_additionalData[ ident ]->multiLineRegion );
  2346. if (-1==commentregionid) {
  2347. errorsAndWarnings+=i18n(
  2348. "<B>%1</B>: Specified multiline comment region (%2) could not be resolved<BR>"
  2349. ).arg(buildIdentifier).arg( m_additionalData[ ident ]->multiLineRegion );
  2350. m_additionalData[ ident ]->multiLineRegion = TQString();
  2351. kdDebug(13010)<<"ERROR comment region attribute could not be resolved"<<endl;
  2352. } else {
  2353. m_additionalData[ ident ]->multiLineRegion=TQString::number(commentregionid+1);
  2354. kdDebug(13010)<<"comment region resolved to:"<<m_additionalData[ ident ]->multiLineRegion<<endl;
  2355. }
  2356. }
  2357. //END Resolve multiline region if possible
  2358. return i;
  2359. }
  2360. void KateHighlighting::clearAttributeArrays ()
  2361. {
  2362. for ( TQIntDictIterator< TQMemArray<KateAttribute> > it( m_attributeArrays ); it.current(); ++it )
  2363. {
  2364. // k, schema correct, let create the data
  2365. KateAttributeList defaultStyleList;
  2366. defaultStyleList.setAutoDelete(true);
  2367. KateHlManager::self()->getDefaults(it.currentKey(), defaultStyleList);
  2368. KateHlItemDataList itemDataList;
  2369. getKateHlItemDataList(it.currentKey(), itemDataList);
  2370. uint nAttribs = itemDataList.count();
  2371. TQMemArray<KateAttribute> *array = it.current();
  2372. array->resize (nAttribs);
  2373. for (uint z = 0; z < nAttribs; z++)
  2374. {
  2375. KateHlItemData *itemData = itemDataList.at(z);
  2376. KateAttribute n = *defaultStyleList.at(itemData->defStyleNum);
  2377. if (itemData && itemData->isSomethingSet())
  2378. n += *itemData;
  2379. array->at(z) = n;
  2380. }
  2381. }
  2382. }
  2383. TQMemArray<KateAttribute> *KateHighlighting::attributes (uint schema)
  2384. {
  2385. TQMemArray<KateAttribute> *array;
  2386. // found it, allready floating around
  2387. if ((array = m_attributeArrays[schema]))
  2388. return array;
  2389. // ohh, not found, check if valid schema number
  2390. if (!KateFactory::self()->schemaManager()->validSchema(schema))
  2391. {
  2392. // uhh, not valid :/, stick with normal default schema, it's always there !
  2393. return attributes (0);
  2394. }
  2395. // k, schema correct, let create the data
  2396. KateAttributeList defaultStyleList;
  2397. defaultStyleList.setAutoDelete(true);
  2398. KateHlManager::self()->getDefaults(schema, defaultStyleList);
  2399. KateHlItemDataList itemDataList;
  2400. getKateHlItemDataList(schema, itemDataList);
  2401. uint nAttribs = itemDataList.count();
  2402. array = new TQMemArray<KateAttribute> (nAttribs);
  2403. for (uint z = 0; z < nAttribs; z++)
  2404. {
  2405. KateHlItemData *itemData = itemDataList.at(z);
  2406. KateAttribute n = *defaultStyleList.at(itemData->defStyleNum);
  2407. if (itemData && itemData->isSomethingSet())
  2408. n += *itemData;
  2409. array->at(z) = n;
  2410. }
  2411. m_attributeArrays.insert(schema, array);
  2412. return array;
  2413. }
  2414. void KateHighlighting::getKateHlItemDataListCopy (uint schema, KateHlItemDataList &outlist)
  2415. {
  2416. KateHlItemDataList itemDataList;
  2417. getKateHlItemDataList(schema, itemDataList);
  2418. outlist.clear ();
  2419. outlist.setAutoDelete (true);
  2420. for (uint z=0; z < itemDataList.count(); z++)
  2421. outlist.append (new KateHlItemData (*itemDataList.at(z)));
  2422. }
  2423. //END
  2424. //BEGIN KateHlManager
  2425. KateHlManager::KateHlManager()
  2426. : TQObject()
  2427. , m_config ("katesyntaxhighlightingrc", false, false)
  2428. , commonSuffixes (TQStringList::split(";", ".orig;.new;~;.bak;.BAK"))
  2429. , syntax (new KateSyntaxDocument())
  2430. , dynamicCtxsCount(0)
  2431. , forceNoDCReset(false)
  2432. {
  2433. hlList.setAutoDelete(true);
  2434. hlDict.setAutoDelete(false);
  2435. KateSyntaxModeList modeList = syntax->modeList();
  2436. for (uint i=0; i < modeList.count(); i++)
  2437. {
  2438. KateHighlighting *hl = new KateHighlighting(modeList[i]);
  2439. uint insert = 0;
  2440. for (; insert <= hlList.count(); insert++)
  2441. {
  2442. if (insert == hlList.count())
  2443. break;
  2444. if ( TQString(hlList.at(insert)->section() + hlList.at(insert)->nameTranslated()).lower()
  2445. > TQString(hl->section() + hl->nameTranslated()).lower() )
  2446. break;
  2447. }
  2448. hlList.insert (insert, hl);
  2449. hlDict.insert (hl->name(), hl);
  2450. }
  2451. // Normal HL
  2452. KateHighlighting *hl = new KateHighlighting(0);
  2453. hlList.prepend (hl);
  2454. hlDict.insert (hl->name(), hl);
  2455. lastCtxsReset.start();
  2456. }
  2457. KateHlManager::~KateHlManager()
  2458. {
  2459. delete syntax;
  2460. }
  2461. static KStaticDeleter<KateHlManager> sdHlMan;
  2462. KateHlManager *KateHlManager::self()
  2463. {
  2464. if ( !s_self )
  2465. sdHlMan.setObject(s_self, new KateHlManager ());
  2466. return s_self;
  2467. }
  2468. KateHighlighting *KateHlManager::getHl(int n)
  2469. {
  2470. if (n < 0 || n >= (int) hlList.count())
  2471. n = 0;
  2472. return hlList.at(n);
  2473. }
  2474. int KateHlManager::nameFind(const TQString &name)
  2475. {
  2476. int z (hlList.count() - 1);
  2477. for (; z > 0; z--)
  2478. if (hlList.at(z)->name() == name)
  2479. return z;
  2480. return z;
  2481. }
  2482. int KateHlManager::detectHighlighting (KateDocument *doc)
  2483. {
  2484. int hl = wildcardFind( doc->url().filename() );
  2485. if ( hl < 0 )
  2486. hl = mimeFind ( doc );
  2487. return hl;
  2488. }
  2489. int KateHlManager::wildcardFind(const TQString &fileName)
  2490. {
  2491. int result = -1;
  2492. if ((result = realWildcardFind(fileName)) != -1)
  2493. return result;
  2494. int length = fileName.length();
  2495. TQString backupSuffix = KateDocumentConfig::global()->backupSuffix();
  2496. if (fileName.endsWith(backupSuffix)) {
  2497. if ((result = realWildcardFind(fileName.left(length - backupSuffix.length()))) != -1)
  2498. return result;
  2499. }
  2500. for (TQStringList::Iterator it = commonSuffixes.begin(); it != commonSuffixes.end(); ++it) {
  2501. if (*it != backupSuffix && fileName.endsWith(*it)) {
  2502. if ((result = realWildcardFind(fileName.left(length - (*it).length()))) != -1)
  2503. return result;
  2504. }
  2505. }
  2506. return -1;
  2507. }
  2508. int KateHlManager::realWildcardFind(const TQString &fileName)
  2509. {
  2510. static TQRegExp sep("\\s*;\\s*");
  2511. TQPtrList<KateHighlighting> highlights;
  2512. for (KateHighlighting *highlight = hlList.first(); highlight != 0L; highlight = hlList.next()) {
  2513. highlight->loadWildcards();
  2514. for (TQStringList::Iterator it = highlight->getPlainExtensions().begin(); it != highlight->getPlainExtensions().end(); ++it)
  2515. if (fileName.endsWith((*it)))
  2516. highlights.append(highlight);
  2517. for (int i = 0; i < (int)highlight->getRegexpExtensions().count(); i++) {
  2518. TQRegExp re = highlight->getRegexpExtensions()[i];
  2519. if (re.exactMatch(fileName))
  2520. highlights.append(highlight);
  2521. }
  2522. }
  2523. if ( !highlights.isEmpty() )
  2524. {
  2525. int pri = -1;
  2526. int hl = -1;
  2527. for (KateHighlighting *highlight = highlights.first(); highlight != 0L; highlight = highlights.next())
  2528. {
  2529. if (highlight->priority() > pri)
  2530. {
  2531. pri = highlight->priority();
  2532. hl = hlList.findRef (highlight);
  2533. }
  2534. }
  2535. return hl;
  2536. }
  2537. return -1;
  2538. }
  2539. int KateHlManager::mimeFind( KateDocument *doc )
  2540. {
  2541. static TQRegExp sep("\\s*;\\s*");
  2542. KMimeType::Ptr mt = doc->mimeTypeForContent();
  2543. TQPtrList<KateHighlighting> highlights;
  2544. for (KateHighlighting *highlight = hlList.first(); highlight != 0L; highlight = hlList.next())
  2545. {
  2546. TQStringList l = TQStringList::split( sep, highlight->getMimetypes() );
  2547. for( TQStringList::Iterator it = l.begin(); it != l.end(); ++it )
  2548. {
  2549. if ( *it == mt->name() ) // faster than a regexp i guess?
  2550. highlights.append (highlight);
  2551. }
  2552. }
  2553. if ( !highlights.isEmpty() )
  2554. {
  2555. int pri = -1;
  2556. int hl = -1;
  2557. for (KateHighlighting *highlight = highlights.first(); highlight != 0L; highlight = highlights.next())
  2558. {
  2559. if (highlight->priority() > pri)
  2560. {
  2561. pri = highlight->priority();
  2562. hl = hlList.findRef (highlight);
  2563. }
  2564. }
  2565. return hl;
  2566. }
  2567. return -1;
  2568. }
  2569. uint KateHlManager::defaultStyles()
  2570. {
  2571. return 14;
  2572. }
  2573. TQString KateHlManager::defaultStyleName(int n, bool translateNames)
  2574. {
  2575. static TQStringList names;
  2576. static TQStringList translatedNames;
  2577. if (names.isEmpty())
  2578. {
  2579. names << "Normal";
  2580. names << "Keyword";
  2581. names << "Data Type";
  2582. names << "Decimal/Value";
  2583. names << "Base-N Integer";
  2584. names << "Floating Point";
  2585. names << "Character";
  2586. names << "String";
  2587. names << "Comment";
  2588. names << "Others";
  2589. names << "Alert";
  2590. names << "Function";
  2591. // this next one is for denoting the beginning/end of a user defined folding region
  2592. names << "Region Marker";
  2593. // this one is for marking invalid input
  2594. names << "Error";
  2595. translatedNames << i18n("Normal");
  2596. translatedNames << i18n("Keyword");
  2597. translatedNames << i18n("Data Type");
  2598. translatedNames << i18n("Decimal/Value");
  2599. translatedNames << i18n("Base-N Integer");
  2600. translatedNames << i18n("Floating Point");
  2601. translatedNames << i18n("Character");
  2602. translatedNames << i18n("String");
  2603. translatedNames << i18n("Comment");
  2604. translatedNames << i18n("Others");
  2605. translatedNames << i18n("Alert");
  2606. translatedNames << i18n("Function");
  2607. // this next one is for denoting the beginning/end of a user defined folding region
  2608. translatedNames << i18n("Region Marker");
  2609. // this one is for marking invalid input
  2610. translatedNames << i18n("Error");
  2611. }
  2612. return translateNames ? translatedNames[n] : names[n];
  2613. }
  2614. void KateHlManager::getDefaults(uint schema, KateAttributeList &list)
  2615. {
  2616. list.setAutoDelete(true);
  2617. KateAttribute* normal = new KateAttribute();
  2618. normal->setTextColor(Qt::black);
  2619. normal->setSelectedTextColor(Qt::white);
  2620. list.append(normal);
  2621. KateAttribute* keyword = new KateAttribute();
  2622. keyword->setTextColor(Qt::black);
  2623. keyword->setSelectedTextColor(Qt::white);
  2624. keyword->setBold(true);
  2625. list.append(keyword);
  2626. KateAttribute* dataType = new KateAttribute();
  2627. dataType->setTextColor(Qt::darkRed);
  2628. dataType->setSelectedTextColor(Qt::white);
  2629. list.append(dataType);
  2630. KateAttribute* decimal = new KateAttribute();
  2631. decimal->setTextColor(Qt::blue);
  2632. decimal->setSelectedTextColor(Qt::cyan);
  2633. list.append(decimal);
  2634. KateAttribute* basen = new KateAttribute();
  2635. basen->setTextColor(Qt::darkCyan);
  2636. basen->setSelectedTextColor(Qt::cyan);
  2637. list.append(basen);
  2638. KateAttribute* floatAttribute = new KateAttribute();
  2639. floatAttribute->setTextColor(Qt::darkMagenta);
  2640. floatAttribute->setSelectedTextColor(Qt::cyan);
  2641. list.append(floatAttribute);
  2642. KateAttribute* charAttribute = new KateAttribute();
  2643. charAttribute->setTextColor(Qt::magenta);
  2644. charAttribute->setSelectedTextColor(Qt::magenta);
  2645. list.append(charAttribute);
  2646. KateAttribute* string = new KateAttribute();
  2647. string->setTextColor(TQColor("#D00"));
  2648. string->setSelectedTextColor(Qt::red);
  2649. list.append(string);
  2650. KateAttribute* comment = new KateAttribute();
  2651. comment->setTextColor(Qt::darkGray);
  2652. comment->setSelectedTextColor(Qt::gray);
  2653. comment->setItalic(true);
  2654. list.append(comment);
  2655. KateAttribute* others = new KateAttribute();
  2656. others->setTextColor(Qt::darkGreen);
  2657. others->setSelectedTextColor(Qt::green);
  2658. list.append(others);
  2659. KateAttribute* alert = new KateAttribute();
  2660. alert->setTextColor(Qt::black);
  2661. alert->setSelectedTextColor( TQColor("#FCC") );
  2662. alert->setBold(true);
  2663. alert->setBGColor( TQColor("#FCC") );
  2664. list.append(alert);
  2665. KateAttribute* functionAttribute = new KateAttribute();
  2666. functionAttribute->setTextColor(Qt::darkBlue);
  2667. functionAttribute->setSelectedTextColor(Qt::white);
  2668. list.append(functionAttribute);
  2669. KateAttribute* regionmarker = new KateAttribute();
  2670. regionmarker->setTextColor(Qt::white);
  2671. regionmarker->setBGColor(Qt::gray);
  2672. regionmarker->setSelectedTextColor(Qt::gray);
  2673. list.append(regionmarker);
  2674. KateAttribute* error = new KateAttribute();
  2675. error->setTextColor(Qt::red);
  2676. error->setUnderline(true);
  2677. error->setSelectedTextColor(Qt::red);
  2678. list.append(error);
  2679. TDEConfig *config = KateHlManager::self()->self()->getTDEConfig();
  2680. config->setGroup("Default Item Styles - Schema " + KateFactory::self()->schemaManager()->name(schema));
  2681. for (uint z = 0; z < defaultStyles(); z++)
  2682. {
  2683. KateAttribute *i = list.at(z);
  2684. TQStringList s = config->readListEntry(defaultStyleName(z));
  2685. if (!s.isEmpty())
  2686. {
  2687. while( s.count()<8)
  2688. s << "";
  2689. TQString tmp;
  2690. QRgb col;
  2691. tmp=s[0]; if (!tmp.isEmpty()) {
  2692. col=tmp.toUInt(0,16); i->setTextColor(col); }
  2693. tmp=s[1]; if (!tmp.isEmpty()) {
  2694. col=tmp.toUInt(0,16); i->setSelectedTextColor(col); }
  2695. tmp=s[2]; if (!tmp.isEmpty()) i->setBold(tmp!="0");
  2696. tmp=s[3]; if (!tmp.isEmpty()) i->setItalic(tmp!="0");
  2697. tmp=s[4]; if (!tmp.isEmpty()) i->setStrikeOut(tmp!="0");
  2698. tmp=s[5]; if (!tmp.isEmpty()) i->setUnderline(tmp!="0");
  2699. tmp=s[6]; if (!tmp.isEmpty()) {
  2700. if ( tmp != "-" )
  2701. {
  2702. col=tmp.toUInt(0,16);
  2703. i->setBGColor(col);
  2704. }
  2705. else
  2706. i->clearAttribute(KateAttribute::BGColor);
  2707. }
  2708. tmp=s[7]; if (!tmp.isEmpty()) {
  2709. if ( tmp != "-" )
  2710. {
  2711. col=tmp.toUInt(0,16);
  2712. i->setSelectedBGColor(col);
  2713. }
  2714. else
  2715. i->clearAttribute(KateAttribute::SelectedBGColor);
  2716. }
  2717. }
  2718. }
  2719. }
  2720. void KateHlManager::setDefaults(uint schema, KateAttributeList &list)
  2721. {
  2722. TDEConfig *config = KateHlManager::self()->self()->getTDEConfig();
  2723. config->setGroup("Default Item Styles - Schema " + KateFactory::self()->schemaManager()->name(schema));
  2724. for (uint z = 0; z < defaultStyles(); z++)
  2725. {
  2726. TQStringList settings;
  2727. KateAttribute *i = list.at(z);
  2728. settings<<(i->itemSet(KateAttribute::TextColor)?TQString::number(i->textColor().rgb(),16):"");
  2729. settings<<(i->itemSet(KateAttribute::SelectedTextColor)?TQString::number(i->selectedTextColor().rgb(),16):"");
  2730. settings<<(i->itemSet(KateAttribute::Weight)?(i->bold()?"1":"0"):"");
  2731. settings<<(i->itemSet(KateAttribute::Italic)?(i->italic()?"1":"0"):"");
  2732. settings<<(i->itemSet(KateAttribute::StrikeOut)?(i->strikeOut()?"1":"0"):"");
  2733. settings<<(i->itemSet(KateAttribute::Underline)?(i->underline()?"1":"0"):"");
  2734. settings<<(i->itemSet(KateAttribute::BGColor)?TQString::number(i->bgColor().rgb(),16):"-");
  2735. settings<<(i->itemSet(KateAttribute::SelectedBGColor)?TQString::number(i->selectedBGColor().rgb(),16):"-");
  2736. settings<<"---";
  2737. config->writeEntry(defaultStyleName(z),settings);
  2738. }
  2739. emit changed();
  2740. }
  2741. int KateHlManager::highlights()
  2742. {
  2743. return (int) hlList.count();
  2744. }
  2745. TQString KateHlManager::hlName(int n)
  2746. {
  2747. return hlList.at(n)->name();
  2748. }
  2749. TQString KateHlManager::hlNameTranslated(int n)
  2750. {
  2751. return hlList.at(n)->nameTranslated();
  2752. }
  2753. TQString KateHlManager::hlSection(int n)
  2754. {
  2755. return hlList.at(n)->section();
  2756. }
  2757. bool KateHlManager::hlHidden(int n)
  2758. {
  2759. return hlList.at(n)->hidden();
  2760. }
  2761. TQString KateHlManager::identifierForName(const TQString& name)
  2762. {
  2763. KateHighlighting *hl = 0;
  2764. if ((hl = hlDict[name]))
  2765. return hl->getIdentifier ();
  2766. return TQString();
  2767. }
  2768. bool KateHlManager::resetDynamicCtxs()
  2769. {
  2770. if (forceNoDCReset)
  2771. return false;
  2772. if (lastCtxsReset.elapsed() < KATE_DYNAMIC_CONTEXTS_RESET_DELAY)
  2773. return false;
  2774. KateHighlighting *hl;
  2775. for (hl = hlList.first(); hl; hl = hlList.next())
  2776. hl->dropDynamicContexts();
  2777. dynamicCtxsCount = 0;
  2778. lastCtxsReset.start();
  2779. return true;
  2780. }
  2781. //END
  2782. //BEGIN KateHighlightAction
  2783. void KateViewHighlightAction::init()
  2784. {
  2785. m_doc = 0;
  2786. subMenus.setAutoDelete( true );
  2787. connect(popupMenu(),TQT_SIGNAL(aboutToShow()),this,TQT_SLOT(slotAboutToShow()));
  2788. }
  2789. void KateViewHighlightAction::updateMenu (Kate::Document *doc)
  2790. {
  2791. m_doc = doc;
  2792. }
  2793. void KateViewHighlightAction::slotAboutToShow()
  2794. {
  2795. Kate::Document *doc=m_doc;
  2796. int count = KateHlManager::self()->highlights();
  2797. for (int z=0; z<count; z++)
  2798. {
  2799. TQString hlName = KateHlManager::self()->hlNameTranslated (z);
  2800. TQString hlSection = KateHlManager::self()->hlSection (z);
  2801. if (!KateHlManager::self()->hlHidden(z))
  2802. {
  2803. if ( !hlSection.isEmpty() && (names.contains(hlName) < 1) )
  2804. {
  2805. if (subMenusName.contains(hlSection) < 1)
  2806. {
  2807. subMenusName << hlSection;
  2808. TQPopupMenu *menu = new TQPopupMenu ();
  2809. subMenus.append(menu);
  2810. popupMenu()->insertItem ( '&' + hlSection, menu);
  2811. }
  2812. int m = subMenusName.findIndex (hlSection);
  2813. names << hlName;
  2814. subMenus.at(m)->insertItem ( '&' + hlName, this, TQT_SLOT(setHl(int)), 0, z);
  2815. }
  2816. else if (names.contains(hlName) < 1)
  2817. {
  2818. names << hlName;
  2819. popupMenu()->insertItem ( '&' + hlName, this, TQT_SLOT(setHl(int)), 0, z);
  2820. }
  2821. }
  2822. }
  2823. if (!doc) return;
  2824. for (uint i=0;i<subMenus.count();i++)
  2825. {
  2826. for (uint i2=0;i2<subMenus.at(i)->count();i2++)
  2827. {
  2828. subMenus.at(i)->setItemChecked(subMenus.at(i)->idAt(i2),false);
  2829. }
  2830. }
  2831. popupMenu()->setItemChecked (0, false);
  2832. int i = subMenusName.findIndex (KateHlManager::self()->hlSection(doc->hlMode()));
  2833. if (i >= 0 && subMenus.at(i))
  2834. subMenus.at(i)->setItemChecked (doc->hlMode(), true);
  2835. else
  2836. popupMenu()->setItemChecked (0, true);
  2837. }
  2838. void KateViewHighlightAction::setHl (int mode)
  2839. {
  2840. Kate::Document *doc=m_doc;
  2841. if (doc)
  2842. doc->setHlMode((uint)mode);
  2843. }
  2844. //END KateViewHighlightAction
  2845. // kate: space-indent on; indent-width 2; replace-tabs on;