~ubuntu-branches/ubuntu/utopic/exuberant-ctags/utopic

« back to all changes in this revision

Viewing changes to verilog.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2006-07-31 09:09:12 UTC
  • mfrom: (1.1.1 upstream) (2.1.1 edgy)
  • Revision ID: james.westby@ubuntu.com-20060731090912-rxe2jt8nz6g2k2zx
Tags: 1:5.6-1
* New upstream release (closes: #374097).
* Fix accidentally-unrendered line in ctags(1) (closes: #271323).
* Policy version 3.7.2: no changes required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
*   $Id: verilog.c,v 1.3 2003/07/17 04:31:49 darren Exp $
 
2
*   $Id: verilog.c,v 1.4 2006/05/30 04:37:13 darren Exp $
3
3
4
4
*   Copyright (c) 2003, Darren Hiebert
5
5
10
10
*   (Hardware Description Language).
11
11
12
12
*   Language definition documents:
13
 
*       http://www.eg.bucknell.edu/~cs320/1995-fall/verilog-manual.html
14
 
*       http://www.sutherland-hdl.com/on-line_ref_guide/vlog_ref_top.html
15
 
*       http://home.europa.com/~celiac/VerilogBNF.html
16
 
*       http://eesun.free.fr/DOC/VERILOG/verilog_manual1.html
 
13
*       http://www.eg.bucknell.edu/~cs320/1995-fall/verilog-manual.html
 
14
*       http://www.sutherland-hdl.com/on-line_ref_guide/vlog_ref_top.html
 
15
*       http://home.europa.com/~celiac/VerilogBNF.html
 
16
*       http://eesun.free.fr/DOC/VERILOG/verilog_manual1.html
17
17
*/
18
18
 
19
19
/*
20
20
 *   INCLUDE FILES
21
21
 */
22
 
#include "general.h"    /* must always come first */
 
22
#include "general.h"  /* must always come first */
23
23
 
24
24
#include <string.h>
25
25
#include <setjmp.h>
36
36
typedef enum eException { ExceptionNone, ExceptionEOF } exception_t;
37
37
 
38
38
typedef enum {
39
 
    K_UNDEFINED = -1,
40
 
    K_CONSTANT,
41
 
    K_EVENT,
42
 
    K_FUNCTION,
43
 
    K_MODULE,
44
 
    K_NET,
45
 
    K_PORT,
46
 
    K_REGISTER,
47
 
    K_TASK
 
39
        K_UNDEFINED = -1,
 
40
        K_CONSTANT,
 
41
        K_EVENT,
 
42
        K_FUNCTION,
 
43
        K_MODULE,
 
44
        K_NET,
 
45
        K_PORT,
 
46
        K_REGISTER,
 
47
        K_TASK
48
48
} verilogKind;
49
49
 
50
50
typedef struct {
51
 
    const char *keyword;
52
 
    verilogKind kind;
 
51
        const char *keyword;
 
52
        verilogKind kind;
53
53
} keywordAssoc;
54
54
 
55
55
/*
71
71
};
72
72
 
73
73
static keywordAssoc VerilogKeywordTable [] = {
74
 
    { "`define",   K_CONSTANT },
75
 
    { "event",     K_EVENT },
76
 
    { "function",  K_FUNCTION },
77
 
    { "inout",     K_PORT },
78
 
    { "input",     K_PORT },
79
 
    { "integer",   K_REGISTER },
80
 
    { "module",    K_MODULE },
81
 
    { "output",    K_PORT },
82
 
    { "parameter", K_CONSTANT },
83
 
    { "real",      K_REGISTER },
84
 
    { "realtime",  K_REGISTER },
85
 
    { "reg",       K_REGISTER },
86
 
    { "specparam", K_CONSTANT },
87
 
    { "supply0",   K_NET },
88
 
    { "supply1",   K_NET },
89
 
    { "task",      K_TASK },
90
 
    { "time",      K_REGISTER },
91
 
    { "tri0",      K_NET },
92
 
    { "tri1",      K_NET },
93
 
    { "triand",    K_NET },
94
 
    { "tri",       K_NET },
95
 
    { "trior",     K_NET },
96
 
    { "trireg",    K_NET },
97
 
    { "wand",      K_NET },
98
 
    { "wire",      K_NET },
99
 
    { "wor",       K_NET }
 
74
        { "`define",   K_CONSTANT },
 
75
        { "event",     K_EVENT },
 
76
        { "function",  K_FUNCTION },
 
77
        { "inout",     K_PORT },
 
78
        { "input",     K_PORT },
 
79
        { "integer",   K_REGISTER },
 
80
        { "module",    K_MODULE },
 
81
        { "output",    K_PORT },
 
82
        { "parameter", K_CONSTANT },
 
83
        { "real",      K_REGISTER },
 
84
        { "realtime",  K_REGISTER },
 
85
        { "reg",       K_REGISTER },
 
86
        { "specparam", K_CONSTANT },
 
87
        { "supply0",   K_NET },
 
88
        { "supply1",   K_NET },
 
89
        { "task",      K_TASK },
 
90
        { "time",      K_REGISTER },
 
91
        { "tri0",      K_NET },
 
92
        { "tri1",      K_NET },
 
93
        { "triand",    K_NET },
 
94
        { "tri",       K_NET },
 
95
        { "trior",     K_NET },
 
96
        { "trireg",    K_NET },
 
97
        { "wand",      K_NET },
 
98
        { "wire",      K_NET },
 
99
        { "wor",       K_NET }
100
100
};
101
101
 
102
102
/*
105
105
 
106
106
static void initialize (const langType language)
107
107
{
108
 
    size_t i;
109
 
    const size_t count = sizeof (VerilogKeywordTable) /
110
 
                         sizeof (VerilogKeywordTable [0]);
111
 
    Lang_verilog = language;
112
 
    for (i = 0  ;  i < count  ;  ++i)
113
 
    {
114
 
        const keywordAssoc* const p = &VerilogKeywordTable [i];
115
 
        addKeyword (p->keyword, language, (int) p->kind);
116
 
    }
 
108
        size_t i;
 
109
        const size_t count = 
 
110
                        sizeof (VerilogKeywordTable) / sizeof (VerilogKeywordTable [0]);
 
111
        Lang_verilog = language;
 
112
        for (i = 0  ;  i < count  ;  ++i)
 
113
        {
 
114
                const keywordAssoc* const p = &VerilogKeywordTable [i];
 
115
                addKeyword (p->keyword, language, (int) p->kind);
 
116
        }
117
117
}
118
118
 
119
119
static void vUngetc (int c)
120
120
{
121
 
    Assert (Ungetc == '\0');
122
 
    Ungetc = c;
 
121
        Assert (Ungetc == '\0');
 
122
        Ungetc = c;
123
123
}
124
124
 
125
125
static int vGetc (void)
126
126
{
127
 
    int c;
128
 
    if (Ungetc == '\0')
129
 
        c = fileGetc ();
130
 
    else
131
 
    {
132
 
        c = Ungetc;
133
 
        Ungetc = '\0';
134
 
    }
135
 
    if (c == '/')
136
 
    {
137
 
        int c2 = fileGetc ();
138
 
        if (c2 == EOF)
139
 
            longjmp (Exception, (int) ExceptionEOF);
140
 
        else if (c2 == '/')   /* strip comment until end-of-line */
141
 
        {
142
 
            do
 
127
        int c;
 
128
        if (Ungetc == '\0')
143
129
                c = fileGetc ();
144
 
            while (c != '\n'  &&  c != EOF);
145
 
        }
146
 
        else if (c2 == '*')    /* strip block comment */
147
 
        {
148
 
            do
149
 
            {
 
130
        else
 
131
        {
 
132
                c = Ungetc;
 
133
                Ungetc = '\0';
 
134
        }
 
135
        if (c == '/')
 
136
        {
 
137
                int c2 = fileGetc ();
 
138
                if (c2 == EOF)
 
139
                        longjmp (Exception, (int) ExceptionEOF);
 
140
                else if (c2 == '/')  /* strip comment until end-of-line */
 
141
                {
 
142
                        do
 
143
                                c = fileGetc ();
 
144
                        while (c != '\n'  &&  c != EOF);
 
145
                }
 
146
                else if (c2 == '*')  /* strip block comment */
 
147
                {
 
148
                        do
 
149
                        {
 
150
                                do
 
151
                                        c = fileGetc ();
 
152
                                while (c != '*'  &&  c != EOF);
 
153
                                if (c != EOF)
 
154
                                        c = fileGetc ();
 
155
                        } while (c != '/'  &&  c != EOF);
 
156
                        if (c != EOF)
 
157
                                c = ' ';  /* comment equivalent to white space */
 
158
                }
 
159
                else
 
160
                        Ungetc = c2;
 
161
        }
 
162
        else if (c == '"')  /* strip string contents */
 
163
        {
 
164
                int c2;
150
165
                do
151
 
                    c = fileGetc ();
152
 
                while (c != '*'  &&  c != EOF);
153
 
                if (c != EOF)
154
 
                    c = fileGetc ();
155
 
            } while (c != '/'  &&  c != EOF);
156
 
            if (c != EOF)
157
 
                c = ' ';      /* comment equivalent to white space */
 
166
                        c2 = fileGetc ();
 
167
                while (c2 != '"'  &&  c2 != EOF);
 
168
                c = '@';
158
169
        }
159
 
        else
160
 
            Ungetc = c2;
161
 
    }
162
 
    else if (c == '"')        /* strip string contents */
163
 
    {
164
 
        int c2;
165
 
        do
166
 
            c2 = fileGetc ();
167
 
        while (c2 != '"'  &&  c2 != EOF);
168
 
        c = '@';
169
 
    }
170
 
    if (c == EOF)
171
 
        longjmp (Exception, (int) ExceptionEOF);
172
 
    return c;
 
170
        if (c == EOF)
 
171
                longjmp (Exception, (int) ExceptionEOF);
 
172
        return c;
173
173
}
174
174
 
175
175
static boolean isIdentifierCharacter (const int c)
176
176
{
177
 
    return (boolean)(isalnum (c)  ||  c == '_'  ||  c == '`');
 
177
        return (boolean)(isalnum (c)  ||  c == '_'  ||  c == '`');
178
178
}
179
179
 
180
180
static int skipWhite (int c)
181
181
{
182
 
    while (isspace (c))
183
 
        c = vGetc ();
184
 
    return c;
 
182
        while (isspace (c))
 
183
                c = vGetc ();
 
184
        return c;
185
185
}
186
186
 
187
187
static int skipPastMatch (const char *const pair)
188
188
{
189
 
    const int begin = pair [0], end = pair [1];
190
 
    int matchLevel = 1;
191
 
    int c;
192
 
    do
193
 
    {
194
 
        c = vGetc ();
195
 
        if (c == begin)
196
 
            ++matchLevel;
197
 
        else if (c == end)
198
 
            --matchLevel;
199
 
    }
200
 
    while (matchLevel > 0);
201
 
    return vGetc ();
 
189
        const int begin = pair [0], end = pair [1];
 
190
        int matchLevel = 1;
 
191
        int c;
 
192
        do
 
193
        {
 
194
                c = vGetc ();
 
195
                if (c == begin)
 
196
                        ++matchLevel;
 
197
                else if (c == end)
 
198
                        --matchLevel;
 
199
        }
 
200
        while (matchLevel > 0);
 
201
        return vGetc ();
202
202
}
203
203
 
204
204
static boolean readIdentifier (vString *const name, int c)
205
205
{
206
 
    vStringClear (name);
207
 
    if (isIdentifierCharacter (c))
208
 
    {
209
 
        while (isIdentifierCharacter (c))
 
206
        vStringClear (name);
 
207
        if (isIdentifierCharacter (c))
210
208
        {
211
 
            vStringPut (name, c);
212
 
            c = vGetc ();
 
209
                while (isIdentifierCharacter (c))
 
210
                {
 
211
                        vStringPut (name, c);
 
212
                        c = vGetc ();
 
213
                }
 
214
                vUngetc (c);
 
215
                vStringTerminate (name);
213
216
        }
 
217
        return (boolean)(name->length > 0);
 
218
}
 
219
 
 
220
static void tagNameList (const verilogKind kind, int c)
 
221
{
 
222
        vString *name = vStringNew ();
 
223
        boolean repeat;
 
224
        Assert (isIdentifierCharacter (c));
 
225
        do
 
226
        { 
 
227
                repeat = FALSE;
 
228
                if (isIdentifierCharacter (c))
 
229
                {
 
230
                        readIdentifier (name, c);
 
231
                        makeSimpleTag (name, VerilogKinds, kind);
 
232
                }
 
233
                else
 
234
                        break;
 
235
                c = skipWhite (vGetc ());
 
236
                if (c == '[')
 
237
                        c = skipPastMatch ("[]");
 
238
                c = skipWhite (c);
 
239
                if (c == '=')
 
240
                {
 
241
                        if (c == '{')
 
242
                                skipPastMatch ("{}");
 
243
                        else
 
244
                        {
 
245
                                do
 
246
                                        c = vGetc ();
 
247
                                while (c != ','  &&  c != ';');
 
248
                        }
 
249
                }
 
250
                if (c == ',')
 
251
                {
 
252
                        c = skipWhite (vGetc ());
 
253
                        repeat = TRUE;
 
254
                }
 
255
                else
 
256
                        repeat = FALSE;
 
257
        } while (repeat);
 
258
        vStringDelete (name);
214
259
        vUngetc (c);
215
 
        vStringTerminate (name);
216
 
    }
217
 
    return (boolean)(name->length > 0);
218
 
}
219
 
 
220
 
static void tagNameList (const verilogKind kind, int c)
221
 
{
222
 
    vString *name = vStringNew ();
223
 
    boolean repeat;
224
 
    Assert (isIdentifierCharacter (c));
225
 
    do
226
 
    { 
227
 
        repeat = FALSE;
228
 
        if (isIdentifierCharacter (c))
229
 
        {
230
 
            readIdentifier (name, c);
231
 
            makeSimpleTag (name, VerilogKinds, kind);
232
 
        }
233
 
        else
234
 
            break;
235
 
        c = skipWhite (vGetc ());
236
 
        if (c == '[')
237
 
            c = skipPastMatch ("[]");
238
 
        c = skipWhite (c);
239
 
        if (c == '=')
240
 
        {
241
 
            if (c == '{')
242
 
                skipPastMatch ("{}");
243
 
            else
244
 
            {
245
 
                do
246
 
                    c = vGetc ();
247
 
                while (c != ','  &&  c != ';');
248
 
            }
249
 
        }
250
 
        if (c == ',')
251
 
        {
252
 
            c = skipWhite (vGetc ());
253
 
            repeat = TRUE;
254
 
        }
255
 
        else
256
 
            repeat = FALSE;
257
 
    } while (repeat);
258
 
    vStringDelete (name);
259
 
    vUngetc (c);
260
260
}
261
261
 
262
262
static void findTag (vString *const name)
263
263
{
264
 
    const verilogKind kind = (verilogKind)
265
 
            lookupKeyword (vStringValue (name), Lang_verilog);
266
 
    if (kind != K_UNDEFINED)
267
 
    {
268
 
        int c = skipWhite (vGetc ());
269
 
 
270
 
        /* Many keywords can have bit width.
271
 
        *   reg [3:0] net_name;
272
 
        *   inout [(`DBUSWIDTH-1):0] databus;
273
 
        */
274
 
        if (c == '(')
275
 
            c = skipPastMatch ("()");
276
 
        c = skipWhite (c);
277
 
        if (c == '[')
278
 
            c = skipPastMatch ("[]");
279
 
        c = skipWhite (c);
280
 
        if (c == '#')
 
264
        const verilogKind kind = (verilogKind)
 
265
                        lookupKeyword (vStringValue (name), Lang_verilog);
 
266
        if (kind != K_UNDEFINED)
281
267
        {
282
 
            c = vGetc ();
283
 
            if (c == '(')
284
 
                c = skipPastMatch ("()");
 
268
                int c = skipWhite (vGetc ());
 
269
 
 
270
                /* Many keywords can have bit width.
 
271
                *   reg [3:0] net_name;
 
272
                *   inout [(`DBUSWIDTH-1):0] databus;
 
273
                */
 
274
                if (c == '(')
 
275
                        c = skipPastMatch ("()");
 
276
                c = skipWhite (c);
 
277
                if (c == '[')
 
278
                        c = skipPastMatch ("[]");
 
279
                c = skipWhite (c);
 
280
                if (c == '#')
 
281
                {
 
282
                        c = vGetc ();
 
283
                        if (c == '(')
 
284
                                c = skipPastMatch ("()");
 
285
                }
 
286
                c = skipWhite (c);
 
287
                if (isIdentifierCharacter (c))
 
288
                        tagNameList (kind, c);
285
289
        }
286
 
        c = skipWhite (c);
287
 
        if (isIdentifierCharacter (c))
288
 
            tagNameList (kind, c);
289
 
    }
290
290
}
291
291
 
292
292
static void findVerilogTags (void)
293
293
{
294
 
    vString *const name = vStringNew ();
295
 
    volatile boolean newStatement = TRUE;
296
 
    volatile int c = '\0';
297
 
    exception_t exception = (exception_t) setjmp (Exception);
 
294
        vString *const name = vStringNew ();
 
295
        volatile boolean newStatement = TRUE;
 
296
        volatile int c = '\0';
 
297
        exception_t exception = (exception_t) setjmp (Exception);
298
298
 
299
 
    if (exception == ExceptionNone) while (c != EOF)
300
 
    {
301
 
        c = vGetc ();
302
 
        switch (c)
 
299
        if (exception == ExceptionNone) while (c != EOF)
303
300
        {
304
 
            case ';':
305
 
            case '\n':
306
 
                newStatement = TRUE;
307
 
                break;
308
 
 
309
 
            case ' ':
310
 
            case '\t':
311
 
                break;
312
 
 
313
 
            default:
314
 
                if (newStatement && readIdentifier (name, c))
315
 
                    findTag (name);
316
 
                newStatement = FALSE;
317
 
                break;
 
301
                c = vGetc ();
 
302
                switch (c)
 
303
                {
 
304
                        case ';':
 
305
                        case '\n':
 
306
                                newStatement = TRUE;
 
307
                                break;
 
308
 
 
309
                        case ' ':
 
310
                        case '\t':
 
311
                                break;
 
312
 
 
313
                        default:
 
314
                                if (newStatement && readIdentifier (name, c))
 
315
                                        findTag (name);
 
316
                                newStatement = FALSE;
 
317
                                break;
 
318
                }
318
319
        }
319
 
    }
320
 
    vStringDelete (name);
 
320
        vStringDelete (name);
321
321
}
322
322
 
323
323
extern parserDefinition* VerilogParser (void)
324
324
{
325
 
    static const char *const extensions [] = { "v", NULL };
326
 
    parserDefinition* def = parserNew ("Verilog");
327
 
    def->kinds      = VerilogKinds;
328
 
    def->kindCount  = KIND_COUNT (VerilogKinds);
329
 
    def->extensions = extensions;
330
 
    def->parser     = findVerilogTags;
331
 
    def->initialize = initialize;
332
 
    return def;
 
325
        static const char *const extensions [] = { "v", NULL };
 
326
        parserDefinition* def = parserNew ("Verilog");
 
327
        def->kinds      = VerilogKinds;
 
328
        def->kindCount  = KIND_COUNT (VerilogKinds);
 
329
        def->extensions = extensions;
 
330
        def->parser     = findVerilogTags;
 
331
        def->initialize = initialize;
 
332
        return def;
333
333
}
334
334
 
335
 
/* vi:set tabstop=8 shiftwidth=4: */
 
335
/* vi:set tabstop=4 shiftwidth=4: */