Updated Spanish translation
[anjuta-git-plugin.git] / tagmanager / python.c
blob7bf115519dfaffd57894b9ff64a20097f088bfb7
1 /*
2 * $Id$
4 * Copyright (c) 2000-2003, Darren Hiebert
6 * This source code is released for free distribution under the terms of the
7 * GNU General Public License.
9 * This module contains functions for generating tags for Python language
10 * files.
13 * INCLUDE FILES
15 #include "general.h" /* must always come first */
17 #include <string.h>
19 #include "entry.h"
20 #include "options.h"
21 #include "read.h"
22 #include "routines.h"
23 #include "vstring.h"
26 * DATA DEFINITIONS
28 typedef enum {
29 K_CLASS, K_FUNCTION, K_MEMBER
30 } pythonKind;
32 static kindOption PythonKinds[] = {
33 {TRUE, 'c', "class", "classes"},
34 {TRUE, 'f', "function", "functions"},
35 {TRUE, 'm', "member", "class members"}
39 * FUNCTION DEFINITIONS
41 /* tagEntryInfo and vString should be preinitialized/preallocated but not
42 * necessary. If successful you will find class name in vString
45 static boolean isIdentifierFirstCharacter (int c)
47 return (boolean) (isalpha (c) || c == '_');
50 static boolean isIdentifierCharacter (int c)
52 return (boolean) (isalnum (c) || c == '_');
55 static void makeFunctionTag (vString *const function, vString *const class)
57 tagEntryInfo tag;
58 initTagEntry (&tag, vStringValue (function));
59 if (vStringLength (class) > 0)
61 tag.kindName = "member";
62 tag.kind = 'm';
63 tag.extensionFields.scope [0] = "class";
64 tag.extensionFields.scope [1] = vStringValue (class);
66 else
68 tag.kindName = "function";
69 tag.kind = 'f';
71 if (strncmp (vStringValue (function), "__", 2) == 0 &&
72 strcmp (vStringValue (function), "__init__") != 0)
74 tag.extensionFields.access = "private";
75 tag.isFileScope = TRUE;
77 else
79 tag.extensionFields.access = "public";
81 makeTagEntry (&tag);
82 if (vStringLength (class) > 0 && Option.include.qualifiedTags)
84 vString *tagname = vStringNew ();
85 vStringCat (tagname, class);
86 vStringPut (tagname, '.');
87 vStringCat (tagname, function);
88 tag.name = vStringValue (tagname);
89 makeTagEntry (&tag);
90 vStringDelete (tagname);
94 static void makeClassTag (vString *const class, vString *const inheritance)
96 tagEntryInfo tag;
97 initTagEntry (&tag, vStringValue (class));
98 tag.kindName = "class";
99 tag.kind = 'c';
100 tag.extensionFields.inheritance = vStringValue (inheritance);
101 makeTagEntry (&tag);
104 static const unsigned char *skipSpace (const unsigned char *cp)
106 while (isspace ((int) *cp))
107 ++cp;
108 return cp;
111 static const unsigned char *parseIdentifier (
112 const unsigned char *cp, vString *const identifier)
114 vStringClear (identifier);
115 while (isIdentifierCharacter ((int) *cp))
117 vStringPut (identifier, (int) *cp);
118 ++cp;
120 vStringTerminate (identifier);
121 return cp;
124 static void parseClass (const unsigned char *cp, vString *const class)
126 vString *const inheritance = vStringNew ();
127 vStringClear (inheritance);
128 cp = parseIdentifier (cp, class);
129 cp = skipSpace (cp);
130 if (*cp == '(')
132 ++cp;
133 while (*cp != ')' && *cp != '\0')
135 vStringPut (inheritance, *cp);
136 ++cp;
138 vStringTerminate (inheritance);
140 makeClassTag (class, inheritance);
141 vStringDelete (inheritance);
144 static void parseFunction (const unsigned char *cp, vString *const class)
146 vString *const identifier = vStringNew ();
147 cp = parseIdentifier (cp, identifier);
148 makeFunctionTag (identifier, class);
149 vStringDelete (identifier);
152 static void findPythonTags (void)
154 vString *const class = vStringNew ();
155 vString *const identifier = vStringNew ();
156 const unsigned char *line;
157 int class_indent = 0;
158 boolean longStringLiteral = FALSE;
160 while ((line = fileReadLine ()) != NULL)
162 const unsigned char *cp = line;
163 int indent;
165 cp = skipSpace (cp);
166 indent = cp - line;
168 if (*cp == '#' || *cp == '\0') /* skip comment or blank line */
169 continue;
171 if (longStringLiteral)
173 cp = (const unsigned char*) strstr ((const char*) cp, "\"\"\"");
174 if (cp == NULL)
175 continue;
176 else
178 longStringLiteral = FALSE;
179 cp += 3;
182 if (isIdentifierFirstCharacter ((int) *cp))
184 if (indent <= class_indent)
185 vStringClear (class);
187 cp = parseIdentifier (cp, identifier);
188 if (isspace ((int) *cp))
190 cp = skipSpace (cp);
191 if (strcmp (vStringValue (identifier), "def") == 0)
192 parseFunction (cp, class);
193 else if (strcmp (vStringValue (identifier), "class") == 0)
195 parseClass (cp, class);
196 class_indent = indent;
200 if ((cp = (const unsigned char*) strstr ((const char*)cp, "\"\"\"")) != NULL)
202 cp += 3;
203 cp = (const unsigned char*) strstr ((const char*) cp, "\"\"\"");
204 if (cp == NULL)
205 longStringLiteral = TRUE;
208 vStringDelete (identifier);
209 vStringDelete (class);
212 extern parserDefinition *PythonParser (void)
214 static const char *const extensions[] = { "py", "python", NULL };
215 parserDefinition *def = parserNew ("Python");
216 def->kinds = PythonKinds;
217 def->kindCount = KIND_COUNT (PythonKinds);
218 def->extensions = extensions;
219 def->parser = findPythonTags;
220 return def;
223 /* vi:set tabstop=4 shiftwidth=4: */