Merge pull request #482 from philippwiesemann/fix-typos-po-de
[geany-mirror.git] / tagmanager / ctags / vhdl.c
blob7e67bc3df8126a24a2027515ce85f4318cbe93f9
1 /*
2 * $Id: vhdl.c,v 1.0 2005/11/05
4 * Copyright (c) 2005, Klaus Dannecker
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 the Vhdl HDL
10 * (Hardware Description Language).
15 * INCLUDE FILES
17 #include "general.h" /* must always come first */
19 #include <string.h>
20 #include <setjmp.h>
22 #include "keyword.h"
23 #include "parse.h"
24 #include "read.h"
25 #include "vstring.h"
28 * DATA DECLARATIONS
30 typedef enum eException { ExceptionNone, ExceptionEOF } exception_t;
32 typedef enum {
33 K_UNDEFINED = -1,
34 K_CONSTANT,
35 K_TYPE,
36 K_VARIABLE,
37 K_ATRIBUTE,
38 K_SIGNAL,
39 K_FUNCTION,
40 K_PROCEDURE,
41 K_COMPONENT,
42 K_PACKAGE,
43 K_PROCESS,
44 K_ENTITY,
45 K_ARCHITECTURE,
46 K_PORT,
47 K_BLOCK,
48 K_ALIAS
49 } vhdlKind;
51 typedef struct {
52 const char *keyword;
53 vhdlKind kind;
54 } keywordAssoc;
57 * DATA DEFINITIONS
59 static int Ungetc;
60 static int Lang_vhdl;
61 static jmp_buf Exception;
62 static vString* Name=NULL;
63 static vString* Lastname=NULL;
64 static vString* Keyword=NULL;
65 static vString* TagName=NULL;
67 static kindOption VhdlKinds [] = {
68 { TRUE, 'c', "variable", "constants" },
69 { TRUE, 't', "typedef", "types" },
70 { TRUE, 'v', "variable", "variables" },
71 { TRUE, 'a', "atribute", "atributes" },
72 { TRUE, 's', "variable", "signals" },
73 { TRUE, 'f', "function", "functions" },
74 { TRUE, 'p', "function", "procedure" },
75 { TRUE, 'k', "member", "components" },
76 { TRUE, 'l', "namespace", "packages" },
77 { TRUE, 'm', "member", "process" },
78 { TRUE, 'n', "class", "entity" },
79 { TRUE, 'o', "struct", "architecture" },
80 { TRUE, 'u', "port", "ports" },
81 { TRUE, 'b', "member", "blocks" },
82 { TRUE, 'v', "typedef", "alias" }
85 static keywordAssoc VhdlKeywordTable [] = {
86 { "constant", K_CONSTANT },
87 { "variable", K_VARIABLE },
88 { "type", K_TYPE },
89 { "subtype", K_TYPE },
90 { "signal", K_SIGNAL },
91 { "function", K_FUNCTION },
92 { "procedure", K_PROCEDURE },
93 { "component", K_COMPONENT },
94 { "package", K_PACKAGE },
95 { "process", K_PROCESS },
96 { "entity", K_ENTITY },
97 { "architecture", K_ARCHITECTURE },
98 { "inout", K_PORT },
99 { "in", K_PORT },
100 { "out", K_PORT },
101 { "block", K_BLOCK },
102 { "alias", K_ALIAS }
107 * FUNCTION DEFINITIONS
110 static void initialize (const langType language)
112 size_t i;
113 const size_t count = sizeof (VhdlKeywordTable) /
114 sizeof (VhdlKeywordTable [0]);
115 Lang_vhdl = language;
116 for (i = 0 ; i < count ; ++i)
118 const keywordAssoc* const p = &VhdlKeywordTable [i];
119 addKeyword (p->keyword, language, (int) p->kind);
123 static void vUngetc (int c)
125 Assert (Ungetc == '\0');
126 Ungetc = c;
129 static int vGetc (void)
131 int c;
132 if (Ungetc == '\0')
133 c = fileGetc ();
134 else
136 c = Ungetc;
137 Ungetc = '\0';
139 if (c == '-')
141 int c2 = fileGetc ();
142 if (c2 == EOF)
143 longjmp (Exception, (int) ExceptionEOF);
144 else if (c2 == '-') /* strip comment until end-of-line */
147 c = fileGetc ();
148 while (c != '\n' && c != EOF);
150 else
151 Ungetc = c2;
153 if (c == EOF)
154 longjmp (Exception, (int) ExceptionEOF);
155 return c;
158 static boolean isIdentifierCharacter (const int c)
160 return (boolean)(isalnum (c) || c == '_' || c == '`');
163 static int skipWhite (int c)
165 while (c==' ')
166 c = vGetc ();
167 return c;
170 static boolean readIdentifier (vString *const name, int c)
172 vStringClear (name);
173 if (isIdentifierCharacter (c))
175 while (isIdentifierCharacter (c))
177 vStringPut (name, c);
178 c = vGetc ();
180 vUngetc (c);
181 vStringTerminate (name);
183 return (boolean)(name->length > 0);
186 static void tagNameList (const vhdlKind kind, int c)
188 Assert (isIdentifierCharacter (c));
189 if (isIdentifierCharacter (c))
191 readIdentifier (TagName, c);
192 makeSimpleTag (TagName, VhdlKinds, kind);
196 static void findTag (vString *const name)
198 int c = '\0';
199 vhdlKind kind;
200 vStringCopyToLower (Keyword, name);
201 kind = (vhdlKind)lookupKeyword (vStringValue (Keyword), Lang_vhdl);
202 if (kind == K_UNDEFINED)
204 c = skipWhite (vGetc ());
205 vStringCopyS(Lastname,vStringValue(name));
206 if (c == ':')
208 c = skipWhite (vGetc ());
209 if (isIdentifierCharacter (c))
211 readIdentifier (name, c);
212 vStringCopyToLower (Keyword, name);
213 lookupKeyword (vStringValue (Keyword), Lang_vhdl);
214 kind = (vhdlKind)lookupKeyword (vStringValue (Keyword), Lang_vhdl);
215 if (kind == K_PROCESS || kind == K_BLOCK || kind == K_PORT)
217 makeSimpleTag (Lastname, VhdlKinds, kind);
220 } else {
221 vUngetc (c);
224 else
226 if (kind == K_SIGNAL) {
227 while (c!=':') {
228 c = skipWhite (vGetc ());
229 if (c==',')
230 c = vGetc ();
231 if (isIdentifierCharacter (c))
232 tagNameList (kind, c);
233 else
234 break;
235 c = vGetc ();
238 else if (kind == K_PROCESS || kind == K_BLOCK) {
239 vStringCopyS(TagName,"unnamed");
240 makeSimpleTag (TagName, VhdlKinds, kind);
241 } else {
242 c = skipWhite (vGetc ());
243 if (c=='\"')
244 c = vGetc ();
245 if (isIdentifierCharacter (c))
246 tagNameList (kind, c);
251 static void findVhdlTags (void)
253 volatile boolean newStatement = TRUE;
254 volatile int c = '\0';
255 exception_t exception = (exception_t) setjmp (Exception);
256 Name = vStringNew ();
257 Lastname = vStringNew ();
258 Keyword = vStringNew ();
259 TagName = vStringNew ();
261 if (exception == ExceptionNone) while (c != EOF)
263 c = vGetc ();
264 switch (c)
266 case ';':
267 case '\n':
268 newStatement = TRUE;
269 break;
271 case ' ':
272 case '\t':
273 break;
275 default:
276 if (newStatement && readIdentifier (Name, c)) {
277 findTag (Name);
279 newStatement = FALSE;
280 break;
283 vStringDelete (Name);
284 vStringDelete (Lastname);
285 vStringDelete (Keyword);
286 vStringDelete (TagName);
289 extern parserDefinition* VhdlParser (void)
291 static const char *const extensions [] = { "vhdl", "vhd", NULL };
292 parserDefinition* def = parserNew ("Vhdl");
293 def->kinds = VhdlKinds;
294 def->kindCount = KIND_COUNT (VhdlKinds);
295 def->extensions = extensions;
296 def->parser = findVhdlTags;
297 def->initialize = initialize;
298 return def;
301 /* vi:set tabstop=8 shiftwidth=4: */