Handle template expressions that may use the << or >> operators
[arduino-ctags.git] / gir.c
blob517472b640b62b0d6d4fbfadc7c1deb393f7f001
1 #include "general.h" /* must always come first */
2 #include "debug.h"
3 #include "entry.h"
4 #include "keyword.h"
5 #include "parse.h"
6 #include "read.h"
7 #include "routines.h"
8 #include "string.h"
9 #include "vstring.h"
10 #include <glib.h>
11 #include <assert.h>
12 #include <libxml/xmlmemory.h>
13 #include <libxml/parser.h>
14 #include <libxml/tree.h>
15 #include "ctags-utils.h"
17 static kindOption Kinds [] = {
18 { TRUE, 'f', "function", "functions"},
19 { TRUE, 'c', "class", "classes"},
20 { TRUE, 'm', "method", "methods"},
21 { TRUE, 'p', "property", "properties"},
22 { TRUE, 'v', "variable", "global variables"}
25 static void
26 initialize (const langType language)
30 static void
31 parse_function (xmlNode *node, const gchar *parent)
33 xmlNode *i, *k;
34 gchar *name;
35 tagEntryInfo *tag;
37 g_assert (node != NULL);
39 name = (gchar*)xmlGetProp (node, (xmlChar*)"name");
40 if (!name)
41 return;
43 tag = (tagEntryInfo*)malloc (sizeof (tagEntryInfo));
44 initTagEntry (tag, name);
45 get_file_pos (node->line, &tag->filePosition, File.fp);
46 tag->lineNumber = node->line;
47 tag->isFileScope = 1;
48 tag->kindName = "function";
49 tag->kind = 'f';
50 if (parent) {
51 tag->kindName = "member";
52 tag->kind = 'm';
53 tag->extensionFields.scope[0] = "class";
54 tag->extensionFields.scope[1] = parent;
57 for (i = node->children; i; i = i->next)
59 if (!i->name)
60 continue;
61 if (strcmp ((const gchar*)i->name, "return-value") == 0)
63 for (k = i->children; k; k = k->next)
65 const gchar *tmp;
66 if (!k->name)
67 continue;
68 tmp = (const gchar*)xmlGetProp (k, (const xmlChar*)"name");
69 if (!tmp)
70 continue;
71 tag->extensionFields.returnType = tmp;
74 if (strcmp ((const gchar*)i->name, "parameters") == 0)
76 for (k = i->children; k; k = k->next)
78 /*TODO: const gchar *name;
79 if (!k->name)
80 continue;
81 name = (const gchar*)xmlGetProp (node, (const xmlChar*)"name");
82 if (!name)
83 continue;
84 tmp = g_new (Argument, 1);
85 tmp->name = g_strdup (name);
86 tmp->types = NULL;
87 ret->args = g_list_append (ret->args, tmp);*/
91 makeTagEntry (tag);
94 static void makeTags (xmlNode *node, const gchar *parent);
96 static void
97 parse_class (xmlNode *node)
99 xmlNode *i;
100 gchar *name;
102 g_assert (node);
104 name = (gchar*)xmlGetProp (node, (const xmlChar*)"name");
105 if (!name)
106 return;
108 tagEntryInfo *tag = (tagEntryInfo*)malloc (sizeof (tagEntryInfo));
109 initTagEntry (tag, name);
110 tag->isFileScope = 1;
111 tag->kindName = "class";
112 tag->kind = 'c';
113 get_file_pos (node->line, &tag->filePosition, File.fp);
114 tag->lineNumber = node->line;
115 makeTagEntry (tag);
117 for (i = node->children; i; i = i->next)
119 makeTags (i, name);
123 static void
124 makeTags (xmlNode *node, const gchar *parent)
126 g_assert (node != NULL);
127 g_assert (node->name != NULL);
129 if (strcmp ((const gchar*)node->name, "text") == 0
130 || strcmp ((const gchar*)node->name, "implements") == 0)
131 return;
132 if (strcmp ((const gchar*)node->name, "enumeration") == 0
133 || strcmp ((const gchar*)node->name, "union") == 0
134 || strcmp ((const gchar*)node->name, "namespace") == 0
135 || strcmp ((const gchar*)node->name, "class") == 0
136 || strcmp ((const gchar*)node->name, "record") == 0
137 || strcmp ((const gchar*)node->name, "bitfield") == 0
138 || strcmp ((const gchar*)node->name, "interface") == 0)
140 parse_class (node);
141 return;
143 if (strcmp ((const gchar*)node->name, "function") == 0 || strcmp ((const gchar*)node->name, "method") == 0
144 || strcmp ((const gchar*)node->name, "callback") == 0
145 || strcmp ((const gchar*)node->name, "constructor") == 0)
147 parse_function (node, parent);
148 return;
150 if (strcmp ((const gchar*)node->name, "alias") == 0 ||
151 strcmp ((const gchar*)node->name, "constant") == 0 ||
152 strcmp ((const gchar*)node->name, "signal") == 0 ||
153 strcmp ((const gchar*)node->name, "field") == 0 ||
154 strcmp ((const gchar*)node->name, "property") == 0 ||
155 strcmp ((const gchar*)node->name, "member") == 0)
157 gchar *name = (gchar*)xmlGetProp (node, (const xmlChar*)"name");
158 if (!name)
159 return;
160 tagEntryInfo *tag = (tagEntryInfo*)malloc (sizeof (tagEntryInfo));
161 initTagEntry (tag, name);
162 tag->isFileScope = 1;
163 tag->kindName = "variable";
164 tag->kind = 'v';
165 get_file_pos (node->line, &tag->filePosition, File.fp);
166 tag->lineNumber = node->line;
167 if (parent) {
168 tag->kindName = "member";
169 tag->kind = 'm';
170 tag->extensionFields.scope[0] = "class";
171 tag->extensionFields.scope[1] = parent;
173 makeTagEntry (tag);
174 return;
178 static void
179 findTags (void)
181 xmlNode *i;
182 xmlDocPtr doc = xmlParseFile(getInputFileName());
183 xmlNode *root;
185 if (doc == NULL) {
186 g_warning ("could not parse file");
188 root = xmlDocGetRootElement(doc);
189 for (i = root->children; i; i = i->next)
191 xmlNode *j;
192 if (!i->name)
193 continue;
194 if (strcmp ((const char*)i->name, "namespace") !=0)
195 continue;
196 for (j = i->children; j; j = j->next)
198 makeTags (j, NULL);
203 extern parserDefinition*
204 GirParser (void)
206 static const char *const extensions [] = { "gir", NULL };
207 parserDefinition *const def = parserNew ("GObject-Introspection");
208 def->extensions = extensions;
210 def->kinds = Kinds;
211 def->kindCount = KIND_COUNT (Kinds);
212 def->parser = findTags;
213 def->initialize = initialize;
215 return def;