Browse Source

Implement parsing functions for the function list. C files are parsed using Exuberant Ctags (http://ctags.sourceforge.net). Assembly files are parsed for labels by hand.

git-svn-id: file:///var/svn/tigccpp/trunk@696 9552661e-59e3-4036-b4f2-dbe53926924f
kevinkofler 18 years ago
parent
commit
145b0759c9
4 changed files with 152 additions and 4 deletions
  1. 4 2
      ktigcc/KTIGCC.prj
  2. 4 2
      ktigcc/ktigcc.pro
  3. 104 0
      ktigcc/parsing.cpp
  4. 40 0
      ktigcc/parsing.h

+ 4 - 2
ktigcc/KTIGCC.prj

@@ -78,7 +78,8 @@ module.include.files=\
 	srcfile.h\
 	tiemu.h\
 	tiemu_stub.h\
-	callbacks.h
+	callbacks.h\
+	parsing.h
 
 module.source.name=.
 module.source.type=
@@ -97,7 +98,8 @@ module.source.files=\
 	errorlist.ui\
 	programoutput.ui\
 	tiemu_stub.cpp\
-	callbacks.cpp
+	callbacks.cpp\
+	parsing.cpp
 
 module.pixmap.name=.
 module.pixmap.type=

+ 4 - 2
ktigcc/ktigcc.pro

@@ -11,13 +11,15 @@ HEADERS	+= tpr.h \
 	srcfile.h \
 	tiemu.h \
 	tiemu_stub.h \
-	callbacks.h
+	callbacks.h \
+	parsing.h
 
 SOURCES	+= ktigcc.cpp \
 	preferences.cpp \
 	tpr.cpp \
 	tiemu_stub.cpp \
-	callbacks.cpp
+	callbacks.cpp \
+	parsing.cpp
 
 FORMS	= srcfilewin.ui \
 	projectoptions.ui \

+ 104 - 0
ktigcc/parsing.cpp

@@ -0,0 +1,104 @@
+/*
+   ktigcc - TIGCC IDE for KDE
+
+   Copyright (C) 2006 Kevin Kofler
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+*/
+
+// This file handles parsing of source files for the function list and for
+// completion purposes.
+
+#include "parsing.h"
+#include "ktigcc.h"
+#include <qstringlist.h>
+#include <qtextcodec.h>
+#include <kprocio.h>
+#include <kmessagebox.h>
+#include <unistd.h>
+
+SourceFileFunctions getCFunctions(const QString &text)
+{
+  // Parse C using Exuberant Ctags (http://ctags.sourceforge.net).
+  SourceFileFunctions result;
+  write_temp_file("parser_temp_source.c",text,0);
+  {
+    // The QTextCodec has to be passed explicitly, or it will default to
+    // ISO-8859-1 regardless of the locale, which is just broken.
+    KProcIO procio(QTextCodec::codecForLocale());
+    // Use MergedStderr instead of Stderr so the messages get ordered
+    // properly.
+    procio.setComm(static_cast<KProcess::Communication>(
+      KProcess::Stdout|KProcess::MergedStderr));
+    procio.setWorkingDirectory(tempdir);
+    procio<<"ctags"<<"-f"<<"-"<<"-n"<<"-u"<<"-h"<<".h"<<"--language-force=C"
+           <<"--C-kinds=pf"<<"--fields=k"<<"parser_temp_source.c";
+    if (!procio.start()) {
+      delete_temp_file("parser_temp_source.c");
+      KMessageBox::error(0,"Could not run ctags.\nThis feature requires "
+                           "Exuberant Ctags, which can be obtained from: "
+                           "http://ctags.sourceforge.net");
+      return result;
+    }
+    QString line;
+    int ret;
+    while ((ret=procio.readln(line))>=0 || procio.isRunning()) {
+      if (ret>=0) {
+        QStringList columns=QStringList::split('\t',line,TRUE);
+        QString identifier=columns[0];
+        QString linenoString=columns[2];
+        int semicolonPos=linenoString.find(';');
+        if (semicolonPos>=0) linenoString.truncate(semicolonPos);
+        int lineno=linenoString.toInt()-1;
+        QString kind=columns[3];
+        SourceFileFunctions::Iterator it=result.find(identifier);
+        if (kind=="p") {
+          if (it==result.end())
+            result.append(SourceFileFunction(identifier,lineno,-1));
+        } else if (kind=="f") {
+          if (it==result.end())
+            result.append(SourceFileFunction(identifier,-1,lineno));
+          else
+            (*it).implementationLine=lineno;
+        } else qWarning("Invalid result from ctags.");
+      } else usleep(1000);
+    }
+  }
+  delete_temp_file("parser_temp_source.c");
+  return SourceFileFunctions(); // Not implemented yet.
+}  
+
+SourceFileFunctions getASMFunctions(const QString &text)
+{
+  // Parse ASM by hand.
+  QStringList lines=QStringList::split('\n',text,TRUE);
+  unsigned lineno=0;
+  SourceFileFunctions result;
+  for (QStringList::Iterator it=lines.begin(); it!=lines.end(); ++it,++lineno) {
+    QString line=*it;
+    if (line.isEmpty()) continue;
+    QString identifier;
+    unsigned col=0, l=line.length();
+    while (col<l) {
+      QChar c=line[col++];
+      if ((c>='A'&&c<='Z')||(c>='a'&&c<='z')||(c>='0'&&c<='9')||c=='_'||c=='$')
+        identifier.append(c);
+      else
+        break;
+    }
+    if (line[col-1]==':') result.append(SourceFileFunction(identifier,-1,lineno));
+  }
+  return result;
+}

+ 40 - 0
ktigcc/parsing.h

@@ -0,0 +1,40 @@
+/*
+   ktigcc - TIGCC IDE for KDE
+
+   Copyright (C) 2006 Kevin Kofler
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+*/
+
+#pragma once
+
+#include <qstring.h>
+#include <qvaluelist.h>
+struct SourceFileFunction {
+  SourceFileFunction() : name(), implementationLine(-1), prototypeLine(-1) {}
+  SourceFileFunction(const QString &n) :
+    name(n), implementationLine(-1), prototypeLine(-1) {}
+  SourceFileFunction(const QString &n, int i, int p) :
+    name(n), implementationLine(i), prototypeLine(p) {}
+  bool operator==(const SourceFileFunction &other) const
+    {return name==other.name;}
+  QString name;
+  int implementationLine;
+  int prototypeLine;
+};
+typedef QValueList<SourceFileFunction> SourceFileFunctions;
+SourceFileFunctions getCFunctions(const QString &text);
+SourceFileFunctions getASMFunctions(const QString &text);
+#define getFunctions(text,isasm) (((isasm)?getCFunctions:getASMFunctions)((text)))