Minor edits of Template Wildcards table:
[geany-mirror.git] / tagmanager / vhdl.c
blobe0f7cfc024e2df43490be0045fdeb79e4137f7d2
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_ALIAS
48 } vhdlKind;
50 typedef struct {
51 const char *keyword;
52 vhdlKind kind;
53 } keywordAssoc;
56 * DATA DEFINITIONS
58 static int Ungetc;
59 static int Lang_vhdl;
60 static jmp_buf Exception;
61 static vString* Name=NULL;
62 static vString* Lastname=NULL;
63 static vString* Keyword=NULL;
64 static vString* TagName=NULL;
66 static kindOption VhdlKinds [] = {
67 { TRUE, 'c', "variable", "constants" },
68 { TRUE, 't', "typedef", "types" },
69 { TRUE, 'v', "variable", "variables" },
70 { TRUE, 'a', "atribute", "atributes" },
71 { TRUE, 's', "variable", "signals" },
72 { TRUE, 'f', "function", "functions" },
73 { TRUE, 'p', "function", "procedure" },
74 { TRUE, 'k', "member", "components" },
75 { TRUE, 'l', "namespace", "packages" },
76 { TRUE, 'm', "member", "process" },
77 { TRUE, 'n', "class", "entity" },
78 { TRUE, 'o', "struct", "architecture" },
79 { TRUE, 'u', "port", "ports" },
80 { TRUE, 'v', "typedef", "alias" }
83 static keywordAssoc VhdlKeywordTable [] = {
84 { "constant", K_CONSTANT },
85 { "variable", K_VARIABLE },
86 { "type", K_TYPE },
87 { "subtype", K_TYPE },
88 { "signal", K_SIGNAL },
89 { "function", K_FUNCTION },
90 { "procedure", K_PROCEDURE },
91 { "component", K_COMPONENT },
92 { "package", K_PACKAGE },
93 { "process", K_PROCESS },
94 { "entity", K_ENTITY },
95 { "architecture", K_ARCHITECTURE },
96 { "inout", K_PORT },
97 { "in", K_PORT },
98 { "out", K_PORT },
99 { "alias", K_ALIAS }
104 * FUNCTION DEFINITIONS
107 static void initialize (const langType language)
109 size_t i;
110 const size_t count = sizeof (VhdlKeywordTable) /
111 sizeof (VhdlKeywordTable [0]);
112 Lang_vhdl = language;
113 for (i = 0 ; i < count ; ++i)
115 const keywordAssoc* const p = &VhdlKeywordTable [i];
116 addKeyword (p->keyword, language, (int) p->kind);
120 static void vUngetc (int c)
122 Assert (Ungetc == '\0');
123 Ungetc = c;
126 static int vGetc (void)
128 int c;
129 if (Ungetc == '\0')
130 c = fileGetc ();
131 else
133 c = Ungetc;
134 Ungetc = '\0';
136 if (c == '-')
138 int c2 = fileGetc ();
139 if (c2 == EOF)
140 longjmp (Exception, (int) ExceptionEOF);
141 else if (c2 == '-') /* strip comment until end-of-line */
144 c = fileGetc ();
145 while (c != '\n' && c != EOF);
147 else
148 Ungetc = c2;
150 if (c == EOF)
151 longjmp (Exception, (int) ExceptionEOF);
152 return c;
155 static boolean isIdentifierCharacter (const int c)
157 return (boolean)(isalnum (c) || c == '_' || c == '`');
160 static int skipWhite (int c)
162 while (c==' ')
163 c = vGetc ();
164 return c;
167 static boolean readIdentifier (vString *const name, int c)
169 vStringClear (name);
170 if (isIdentifierCharacter (c))
172 while (isIdentifierCharacter (c))
174 vStringPut (name, c);
175 c = vGetc ();
177 vUngetc (c);
178 vStringTerminate (name);
180 return (boolean)(name->length > 0);
183 static void tagNameList (const vhdlKind kind, int c)
185 Assert (isIdentifierCharacter (c));
186 if (isIdentifierCharacter (c))
188 readIdentifier (TagName, c);
189 makeSimpleTag (TagName, VhdlKinds, kind);
190 vUngetc (c);
194 static void findTag (vString *const name)
196 int c = '\0';
197 vhdlKind kind;
198 vStringCopyToLower (Keyword, name);
199 kind = (vhdlKind)lookupKeyword (vStringValue (Keyword), Lang_vhdl);
200 if (kind == K_UNDEFINED)
202 c = skipWhite (vGetc ());
203 vStringCopyS(Lastname,vStringValue(name));
204 if (c == ':')
206 c = skipWhite (vGetc ());
207 if (isIdentifierCharacter (c))
209 readIdentifier (name, c);
210 vStringCopyToLower (Keyword, name);
211 lookupKeyword (vStringValue (Keyword), Lang_vhdl);
212 kind = (vhdlKind)lookupKeyword (vStringValue (Keyword), Lang_vhdl);
213 if (kind == K_PROCESS || kind == K_PORT)
215 makeSimpleTag (Lastname, VhdlKinds, kind);
218 } else {
219 vUngetc (c);
222 else
224 if (kind == K_SIGNAL) {
225 while (c!=':') {
226 c = skipWhite (vGetc ());
227 if (c==',')
228 c = vGetc ();
229 if (isIdentifierCharacter (c))
230 tagNameList (kind, c);
231 else
232 break;
233 c = vGetc ();
236 else if (kind == K_PROCESS) {
237 vStringCopyS(TagName,"unnamed");
238 makeSimpleTag (TagName, VhdlKinds, kind);
239 } else {
240 c = skipWhite (vGetc ());
241 if (c=='\"')
242 c = vGetc ();
243 if (isIdentifierCharacter (c))
244 tagNameList (kind, c);
249 static void findVhdlTags (void)
251 volatile boolean newStatement = TRUE;
252 volatile int c = '\0';
253 exception_t exception = (exception_t) setjmp (Exception);
254 Name = vStringNew ();
255 Lastname = vStringNew ();
256 Keyword = vStringNew ();
257 TagName = vStringNew ();
259 if (exception == ExceptionNone) while (c != EOF)
261 c = vGetc ();
262 switch (c)
264 case ';':
265 case '\n':
266 newStatement = TRUE;
267 break;
269 case ' ':
270 case '\t':
271 break;
273 default:
274 if (newStatement && readIdentifier (Name, c)) {
275 findTag (Name);
277 newStatement = FALSE;
278 break;
281 vStringDelete (Name);
282 vStringDelete (Lastname);
283 vStringDelete (Keyword);
284 vStringDelete (TagName);
287 extern parserDefinition* VhdlParser (void)
289 static const char *const extensions [] = { "vhdl", "vhd", NULL };
290 parserDefinition* def = parserNew ("Vhdl");
291 def->kinds = VhdlKinds;
292 def->kindCount = KIND_COUNT (VhdlKinds);
293 def->extensions = extensions;
294 def->parser = findVhdlTags;
295 def->initialize = initialize;
296 return def;
299 /* vi:set tabstop=8 shiftwidth=4: */