SF.net SVN: geany: [867] trunk
eht16 at users.sourceforge.net
eht16 at xxxxx
Fri Oct 6 22:13:30 UTC 2006
Revision: 867
http://svn.sourceforge.net/geany/?rev=867&view=rev
Author: eht16
Date: 2006-10-06 15:13:24 -0700 (Fri, 06 Oct 2006)
Log Message:
-----------
Improved Python parser to support nested classes.
Modified Paths:
--------------
trunk/ChangeLog
trunk/tagmanager/python.c
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2006-10-04 19:14:57 UTC (rev 866)
+++ trunk/ChangeLog 2006-10-06 22:13:24 UTC (rev 867)
@@ -1,3 +1,8 @@
+2006-10-06 Enrico Tröger <enrico.troeger at uvena.de>
+
+ * tagmanager/python.c: Improved Python parser to support nested classes.
+
+
2006-10-04 Enrico Tröger <enrico.troeger at uvena.de>
* src/ui_utils.c, src/main.c, src/document.c, src/callbacks.c:
Modified: trunk/tagmanager/python.c
===================================================================
--- trunk/tagmanager/python.c 2006-10-04 19:14:57 UTC (rev 866)
+++ trunk/tagmanager/python.c 2006-10-06 22:13:24 UTC (rev 867)
@@ -13,7 +13,7 @@
* INCLUDE FILES
*/
#include "general.h" /* must always come first */
-
+#include <glib.h>
#include <string.h>
#include "parse.h"
@@ -33,21 +33,55 @@
{ TRUE, 'm', "member", "methods" }
};
+typedef struct _lastClass {
+ gchar *name;
+ gint indent;
+} lastClass;
+
/*
* FUNCTION DEFINITIONS
*/
+
+// remove all previous classes with more indent than the current one
+static GList *clean_class_list(GList *list, gint indent)
+{
+ GList *tmp, *tmp2;
+
+ tmp = g_list_first(list);
+ while (tmp != NULL)
+ {
+ if (((lastClass*)tmp->data)->indent >= indent)
+ {
+ g_free(((lastClass*)tmp->data)->name);
+ g_free(tmp->data);
+ tmp2 = tmp->next;
+
+ list = g_list_remove(list, tmp->data);
+ tmp = tmp2;
+ }
+ else
+ {
+ tmp = tmp->next;
+ }
+ }
+
+ return list;
+}
+
+
static void findPythonTags (void)
{
+ GList *parents = NULL, *tmp; // list of classes which are around the token
vString *name = vStringNew ();
- vString *lastClass = vStringNew();
+ gint indent;
const unsigned char *line;
boolean inMultilineString = FALSE;
while ((line = fileReadLine ()) != NULL)
{
const unsigned char *cp = line;
-
+ indent = 0;
while (*cp != '\0')
{
if (*cp=='"' &&
@@ -62,33 +96,60 @@
inMultilineString = (boolean) !inMultilineString;
cp += 3;
}
- if (inMultilineString || isspace ((int) *cp))
+
+ if (inMultilineString)
++cp;
+ else if (isspace ((int) *cp))
+ {
+ cp++;
+ // count indentation amount of current line
+ indent++;
+ /// TODO should be improved by separating between tabs and spaces but to do this we
+ /// have to know the tabulator width which is set in geany and not available here
+ }
else if (*cp == '#')
break;
else if (strncmp ((const char*) cp, "class", (size_t) 5) == 0)
{
- cp += 5;
- if (isspace ((int) *cp))
- {
- while (isspace ((int) *cp))
- ++cp;
- while (isalnum ((int) *cp) || *cp == '_')
- {
- vStringPut (name, (int) *cp);
- ++cp;
- }
- vStringTerminate (name);
- makeSimpleTag (name, PythonKinds, K_CLASS);
- vStringCopy (lastClass, name);
- vStringClear (name);
- }
+ cp += 5;
+ if (isspace ((int) *cp))
+ {
+ GList *last = g_list_last(parents);
+ lastClass *lastclass = NULL;
+ lastClass *newclass = g_new(lastClass, 1);
+
+ if (last != NULL) lastclass = last->data;
+
+ while (isspace ((int) *cp))
+ ++cp;
+ while (isalnum ((int) *cp) || *cp == '_')
+ {
+ vStringPut (name, (int) *cp);
+ ++cp;
+ }
+ vStringTerminate (name);
+
+ parents = clean_class_list(parents, indent);
+
+ newclass->name = g_strdup(vStringValue(name));
+ newclass->indent = indent;
+ parents = g_list_append(parents, newclass);
+ makeSimpleTag (name, PythonKinds, K_CLASS);
+ vStringClear (name);
+ }
}
else if (strncmp ((const char*) cp, "def", (size_t) 3) == 0)
{
cp += 3;
if (isspace ((int) *cp))
{
+ GList *last;
+ lastClass *lastclass = NULL;
+
+ parents = clean_class_list(parents, indent);
+ last = g_list_last(parents);
+ if (last != NULL) lastclass = last->data;
+
while (isspace ((int) *cp))
++cp;
while (isalnum ((int) *cp) || *cp == '_')
@@ -97,12 +158,11 @@
++cp;
}
vStringTerminate (name);
- if (!isspace(*line) || vStringLength(lastClass) <= 0)
+ if (!isspace(*line) || lastclass == NULL || strlen(lastclass->name) <= 0)
makeSimpleTag (name, PythonKinds, K_FUNCTION);
else
makeSimpleScopedTag (name, PythonKinds, K_METHOD,
- PythonKinds[K_CLASS].name,
- vStringValue(lastClass), "public");
+ PythonKinds[K_CLASS].name, lastclass->name, "public");
vStringClear (name);
}
}
@@ -115,7 +175,19 @@
}
}
vStringDelete (name);
- vStringDelete (lastClass);
+
+ // clear the remaining elements in the list
+ tmp = g_list_first(parents);
+ while (tmp != NULL)
+ {
+ if (tmp->data)
+ {
+ g_free(((lastClass*)tmp->data)->name);
+ g_free(tmp->data);
+ }
+ tmp = tmp->next;
+ }
+ g_list_free(parents);
}
extern parserDefinition* PythonParser (void)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Commits
mailing list