소스 검색

Remove Joey's old skeleton for an XML syntax file generator, it was really broken beyond repair.
Start XML syntax file generator. The resulting files are not usable yet.


git-svn-id: file:///var/svn/tigccpp/trunk@778 9552661e-59e3-4036-b4f2-dbe53926924f

kevinkofler 18 년 전
부모
커밋
10692b1650
2개의 변경된 파일203개의 추가작업 그리고 91개의 파일을 삭제
  1. 1 3
      ktigcc/ktigcc.cpp
  2. 202 88
      ktigcc/preferences.cpp

+ 1 - 3
ktigcc/ktigcc.cpp

@@ -200,9 +200,7 @@ void clear_temp_dir(void)
 
 void force_qt_assistant_page(int n)
 {
-  char *home=getenv("HOME");
-  char fname[strlen(home)+20];
-  sprintf(fname,"%s/.qt/qt_assistantrc",home);
+  QString fname=QDir::homeDirPath()+"/.qt/qt_assistantrc";
   FILE *f=fopen(fname,"r+b");
   if (!f) f=fopen(fname,"w+b");
   if (!f) exit(1);

+ 202 - 88
ktigcc/preferences.cpp

@@ -30,6 +30,9 @@
 #include <qtextcodec.h>
 #include <qcolor.h>
 #include <qfont.h>
+#include <qdom.h> 
+#include <qcstring.h> 
+#include <qdir.h> 
 #include <kconfig.h>
 #include "ktigcc.h"
 #include "preferences.h"
@@ -38,105 +41,217 @@
 
 TIGCCPrefs preferences;
 
-//these macros return 0 on success.
-#define syn_XMLStart(f) (fputs( \
-    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \
-    "<!DOCTYPE language SYSTEM \"language.dtd\">\n" \
-    "<!-- Syntax highlighting information autogenerated by KTIGCC. -->\n" \
-    "<language version=\"1.11\" kateversion=\"2.4\" name=\"Scheme\" section=\"Scripts\" extensions=\"*.scm;*.ss;*.scheme;*.guile\" mimetype=\"text/x-scheme\" author=\"KTIGCC\" license=\"LGPL\">\n" \
-,(f))==EOF)
-#define syn_XMLEnd(f) (fputs("</language>\n",(f))==EOF)
-
-void stringReplaceItems(QString &dest,const QString &oldStr,const QString &newStr,unsigned long start,unsigned long maxoccurances)
+static void genAllCaseVariants(QString keyword, unsigned pos,
+                               QStringList &stringList)
 {
-    unsigned long o;
-    unsigned long len=oldStr.length();
-    o=0;
-    while ((start=dest.find(oldStr,start))!=0xFFFFFFFF&&(--maxoccurances))
-    {
-        dest.replace(start,len,newStr);
-        start+=len;
+  // WARNING: Exponential complexity in the keyword length. Yuck!
+  // Blame Kate's lack of flexibility.
+  // Also note that this just LOOKS like a functional recursion, there ARE side
+  // effects.
+  QChar c=keyword[pos];
+  if (c.isNull())
+    stringList.append(keyword);
+  else {
+    QChar upper=c.upper();
+    QChar lower=c.lower();
+    if (lower==upper)
+      genAllCaseVariants(keyword,pos+1,stringList);
+    else {
+      keyword[pos]=upper;
+      genAllCaseVariants(keyword,pos+1,stringList);
+      keyword[pos]=lower;
+      genAllCaseVariants(keyword,pos+1,stringList);
+      keyword[pos]=c;
     }
+  }
 }
 
-QString syn_encodeString(const QString &str)
+static void writeSyntaxXML(const Syn_SettingsForDoc &synprefs,
+                           const QString &name, const QString &internalName)
 {
-    QString ret=str;
-    stringReplaceItems(ret,"&","&#38;",0,0xFFFFFFFF);
-    stringReplaceItems(ret,"\n","&#10;",0,0xFFFFFFFF);
-    stringReplaceItems(ret,"\r","&#13;",0,0xFFFFFFFF);
-    stringReplaceItems(ret,"<","&#60;",0,0xFFFFFFFF);
-    stringReplaceItems(ret,">","&#62;",0,0xFFFFFFFF);
-    return ret;
-}
+  // Create XML document.
+  QDomDocument doc("language");
+  QDomElement root=doc.createElement("language");
+  doc.appendChild(root);
 
-//returns 0 on success
-int syn_XMLStrList(FILE *f,const QString &name,const QStringList &clist)
-{
-    unsigned long i,e;
-    if (fprintf(f,"<list name=\"%s\">\n",smartAscii(syn_encodeString(name)))==EOF)
-      return 1;
-    e=clist.count();
-    for (i=0;i<e;i++)
-    {
-        if (fprintf(f,"<item> %s </item>\n",smartAscii(syn_encodeString(clist[i])))==EOF)
-            return 1;
+  // Work around bad interfaces...
+  #define ADD_ATTR(node,aname,aval) do { \
+    QDomAttr newattr=doc.createAttribute((aname)); \
+    newattr.setValue((aval)); \
+    (node).setAttributeNode(newattr); \
+  } while(0)
+  #define ADD_TEXT(node,text) do { \
+    QDomText newtext=doc.createTextNode((text)); \
+    (node).appendChild(newtext); \
+  } while(0)
+  #define CHILD_NODE(child,node,chname) \
+    QDomElement child=doc.createElement((chname));\
+    (node).appendChild(child)
+
+  bool allWordListsCaseInsensitive=TRUE;
+  for (QValueList<Syn_WordList>::ConstIterator it=synprefs.wordLists.begin();
+       it!=synprefs.wordLists.end(); ++it) {
+    const Syn_WordList &wordList=*it;
+    if (wordList.caseSensitive) allWordListsCaseInsensitive=FALSE;
+  }
+
+  ADD_ATTR(root,"name",name);
+  ADD_ATTR(root,"section","KTIGCC");
+  ADD_ATTR(root,"extensions","");
+  ADD_ATTR(root,"version","1.00");
+  ADD_ATTR(root,"kateversion","2.4");
+  ADD_ATTR(root,"author","KTIGCC (autogenerated)");
+  ADD_ATTR(root,"license","GPL");
+
+  CHILD_NODE(highlighting,root,"highlighting");
+  CHILD_NODE(general,root,"general");
+
+  for (QValueList<Syn_WordList>::ConstIterator it=synprefs.wordLists.begin();
+       it!=synprefs.wordLists.end(); ++it) {
+    const Syn_WordList &wordList=*it;
+    CHILD_NODE(list,highlighting,"list");
+    ADD_ATTR(list,"name",wordList.name);
+    QStringList stringList;
+    if (wordList.caseSensitive || allWordListsCaseInsensitive)
+      stringList=wordList.list;
+    else {
+      // This is really ugly. Why can't Kate allow me to specify
+      // case-sensitivity per word list?
+      for (QStringList::ConstIterator it=wordList.list.begin();
+           it!=wordList.list.end(); ++it) {
+        const QString &keyword=*it;
+        // This is bad, but I need to cap time, memory and disk space
+        // requirements somewhere.
+        if (keyword.length()<=10)
+          genAllCaseVariants(keyword,0,stringList);
+        else
+          stringList.append(keyword);
+      }
     }
-    if (fputs("</list>\n",f)==EOF)
-      return 1;
-    return 0;
-}
+    for (QStringList::ConstIterator it=stringList.begin(); it!=stringList.end();
+         ++it) {
+      const QString &keyword=*it;
+      CHILD_NODE(item,list,"item");
+      ADD_TEXT(item,keyword);
+    }
+  }
 
-//returns 0 on success,-1 on file couldn't be created, and 1 if file couldn't be written to correctly.
-int SynToXML(Syn_SettingsForDoc &syn __attribute__((unused)),const QString &destFileName)
-{
-    FILE *f=fopen(destFileName,"wb");
-    if (!f)
-        return -1;
-    syn_XMLStart(f);
-    if (fputs("<highlighting>\n",f)==EOF)
-      return 1;
-    if (fputs("<list name=\"symbols\">\n"
-             "<item> &#60; </item>\n" //for '<'
-             "<item> { </item>\n"
-             "<item> [ </item>\n"
-             "<item> ( </item>\n"
-             "<item> ) </item>\n"
-             "<item> ] </item>\n"
-             "<item> } </item>\n"
-             "<item> &#62; </item>\n" //for '>'
-             "<item> ; </item>\n"
-             "<item> : </item>\n"
-             "<item> , </item>\n"
-             "<item> . </item>\n"
-             "<item> = </item>\n"
-             "<item> + </item>\n"
-             "<item> - </item>\n"
-             "<item> * </item>\n"
-             "<item> / </item>\n"
-             "<item> \\ </item>\n"
-             "<item> | </item>\n"
-             "<item> \" </item>\n"
-             "<item> \' </item>\n"
-             "<item> ! </item>\n"
-             "<item> ? </item>\n"
-             "<item> &#38; </item>\n" //for '&'
-             "<item> % </item>\n"
-             "<item> # </item>\n"
-             "<item> @ </item>\n"
-             "<item> ^ </item>\n"
-             "<item> ~ </item>\n"
-             "</list>\n"
-    ,f)==EOF)
-      return 1;
-    
-    syn_XMLEnd(f);
-    return 0;
+  CHILD_NODE(contexts,highlighting,"contexts");
+  CHILD_NODE(defaultContext,contexts,"context");
+  ADD_ATTR(defaultContext,"name","Default");
+  ADD_ATTR(defaultContext,"attribute","Normal");
+  ADD_ATTR(defaultContext,"lineEndContext","#stay");
+  for (QValueList<Syn_CustomStyle>::ConstIterator it=synprefs.customStyles.begin();
+       it!=synprefs.customStyles.end(); ++it) {
+    const Syn_CustomStyle &customStyle=*it;
+    switch (customStyle.beginning.length()) {
+      case 0: // Ignore these ones altogether.
+        break;
+      case 1:
+        {
+          CHILD_NODE(detectCustomStyle,defaultContext,"DetectChar");
+          ADD_ATTR(detectCustomStyle,"attribute",customStyle.name);
+          ADD_ATTR(detectCustomStyle,"context",customStyle.name);
+          if (customStyle.lineStartOnly)
+            ADD_ATTR(detectCustomStyle,"firstNonSpace","true");
+          ADD_ATTR(detectCustomStyle,"char",customStyle.beginning.left(1));
+        }
+        break;
+      case 2:
+        {
+          CHILD_NODE(detectCustomStyle,defaultContext,"Detect2Chars");
+          ADD_ATTR(detectCustomStyle,"attribute",customStyle.name);
+          ADD_ATTR(detectCustomStyle,"context",customStyle.name);
+          if (customStyle.lineStartOnly)
+            ADD_ATTR(detectCustomStyle,"firstNonSpace","true");
+          ADD_ATTR(detectCustomStyle,"char",customStyle.beginning.left(1));
+          ADD_ATTR(detectCustomStyle,"char1",customStyle.beginning.mid(1,1));
+        }
+        break;
+      default:
+        {
+          CHILD_NODE(detectCustomStyle,defaultContext,"StringDetect");
+          ADD_ATTR(detectCustomStyle,"attribute",customStyle.name);
+          ADD_ATTR(detectCustomStyle,"context",customStyle.name);
+          if (customStyle.lineStartOnly)
+            ADD_ATTR(detectCustomStyle,"firstNonSpace","true");
+          ADD_ATTR(detectCustomStyle,"String",customStyle.beginning);
+        }
+        break;
+    }
+  }
+  for (QValueList<Syn_WordList>::ConstIterator it=synprefs.wordLists.begin();
+       it!=synprefs.wordLists.end(); ++it) {
+    const Syn_WordList &wordList=*it;
+    CHILD_NODE(detectWordList,defaultContext,"keyword");
+    ADD_ATTR(detectWordList,"attribute",wordList.name);
+    ADD_ATTR(detectWordList,"context","#stay");
+    ADD_ATTR(detectWordList,"String",wordList.name);
+  }
+  CHILD_NODE(numFloat,defaultContext,"Float");
+  ADD_ATTR(numFloat,"attribute","Number");
+  ADD_ATTR(numFloat,"context","#stay");
+  CHILD_NODE(numFloatSuffix,numFloat,"AnyChar");
+  ADD_ATTR(numFloatSuffix,"String","fF");
+  ADD_ATTR(numFloatSuffix,"attribute","Number");
+  ADD_ATTR(numFloatSuffix,"context","#stay");
+  CHILD_NODE(numOct,defaultContext,"HlCOct");
+  ADD_ATTR(numOct,"attribute","Number");
+  ADD_ATTR(numOct,"context","#stay");
+  CHILD_NODE(numHex,defaultContext,"HlCHex");
+  ADD_ATTR(numHex,"attribute","Number");
+  ADD_ATTR(numHex,"context","#stay");
+  CHILD_NODE(numBin,defaultContext,"RegExpr");
+  ADD_ATTR(numBin,"String","0b[01]+(ULL|LUL|LLU|UL|LU|LL|U|L)?");
+  ADD_ATTR(numBin,"insensitive","TRUE");
+  ADD_ATTR(numBin,"attribute","Number");
+  ADD_ATTR(numBin,"context","#stay");
+  CHILD_NODE(numDec,defaultContext,"Int");
+  ADD_ATTR(numDec,"attribute","Number");
+  ADD_ATTR(numDec,"context","#stay");
+  QString suffixes[8]={"ULL","LUL","LLU","UL","LU","LL","U","L"};
+  for (int i=0; i<8; i++) {
+    CHILD_NODE(numDecSuffix,numDec,"StringDetect");
+    ADD_ATTR(numDecSuffix,"attribute","Number");
+    ADD_ATTR(numDecSuffix,"context","#stay");
+    ADD_ATTR(numDecSuffix,"String",suffixes[i]);
+    ADD_ATTR(numDecSuffix,"insensitive","TRUE");
+  }
+  CHILD_NODE(symbols,defaultContext,"AnyChar");
+  ADD_ATTR(symbols,"String","<{[()]}>;:,.=+-*/\\|\"\'!?&%#@^~");
+  ADD_ATTR(symbols,"attribute","Symbol");
+  ADD_ATTR(symbols,"context","#stay");
+  
+
+  CHILD_NODE(keywords,general,"keywords");
+  ADD_ATTR(keywords,"casesensitive",allWordListsCaseInsensitive?"0":"1");
+  ADD_ATTR(keywords,"additionalDeliminator","\'\"@");
+
+  #undef ADD_ATTR
+  #undef ADD_TEXT
+  #undef CHILD_NODE
+
+  // Write it to disk.
+  std::FILE *f=std::fopen(QString("%1/.kde/share/apps/katepart/syntax/ktigcc%2.xml")
+                          .arg(QDir::homeDirPath()).arg(internalName),"w");
+  if (f) {
+    if (fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+              "<!-- Syntax highlighting description autogenerated by KTIGCC.\n"
+              "     All changes to this file will be lost! -->\n",f)<0) {
+      fclose(f);
+      return;
+    }
+    (void) fputs(doc.toCString(2),f);
+    fclose(f);
+  }
 }
 
 static void updateSyntaxXML(void)
 {
-  
+  writeSyntaxXML(preferences.synC,"C","c");
+  writeSyntaxXML(preferences.synS,"GNU As","s");
+  writeSyntaxXML(preferences.synASM,"A68k","asm");
+  writeSyntaxXML(preferences.synQLL,"Quill","qll");
 }
 
 static bool loadSyntaxPreference(Syn_SettingsForDoc &synprefs, const QString &group)
@@ -148,7 +263,6 @@ static bool loadSyntaxPreference(Syn_SettingsForDoc &synprefs, const QString &gr
   synprefs.symbolColor=pconfig->readColorEntry("Symbol Color");
   if (!synprefs.symbolColor.isValid()) return FALSE;
   unsigned numParenthesisColors=pconfig->readUnsignedNumEntry("Num Parenthesis Colors");
-  if (!numParenthesisColors) return FALSE;
   for (unsigned i=0; i<numParenthesisColors; i++) {
     QColor parenthesisColor=pconfig->readColorEntry(QString("Parenthesis Color %1").arg(i));
     if (!parenthesisColor.isValid()) return FALSE;