~ubuntu-branches/ubuntu/raring/geany/raring-proposed

« back to all changes in this revision

Viewing changes to tagmanager/basic.c

  • Committer: Bazaar Package Importer
  • Author(s): Damián Viano
  • Date: 2008-05-02 11:37:45 UTC
  • mfrom: (1.2.1 upstream) (9 hardy)
  • mto: (3.2.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: james.westby@ubuntu.com-20080502113745-xzp4g6dmovrpoj17
Tags: 0.14-1
New upstream release (Closes: #478126)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *   $Id: basic.c 2287 2008-02-27 13:17:29Z eht16 $
 
3
 *
 
4
 *   Copyright (c) 2000-2006, Darren Hiebert, Elias Pschernig
 
5
 *
 
6
 *   This source code is released for free distribution under the terms of the
 
7
 *   GNU General Public License.
 
8
 *
 
9
 *   This module contains functions for generating tags for BlitzBasic
 
10
 *   (BlitzMax), PureBasic and FreeBasic language files. For now, this is kept
 
11
 *   quite simple - but feel free to ask for more things added any time -
 
12
 *   patches are of course most welcome.
 
13
 */
 
14
 
 
15
/*
 
16
 *   INCLUDE FILES
 
17
 */
 
18
#include "general.h" /* must always come first */
 
19
 
 
20
#include <string.h>
 
21
 
 
22
#include "parse.h"
 
23
#include "read.h"
 
24
#include "vstring.h"
 
25
 
 
26
/*
 
27
 *   DATA DEFINITIONS
 
28
 */
 
29
typedef enum {
 
30
        K_CONST,
 
31
        K_FUNCTION,
 
32
        K_LABEL,
 
33
        K_TYPE,
 
34
        K_VARIABLE,
 
35
        K_ENUM
 
36
} BasicKind;
 
37
 
 
38
typedef struct {
 
39
        char const *token;
 
40
        BasicKind kind;
 
41
} KeyWord;
 
42
 
 
43
static kindOption BasicKinds[] = {
 
44
        {TRUE, 'c', "macro", "constants"},
 
45
        {TRUE, 'f', "function", "functions"},
 
46
        {TRUE, 'l', "namespace", "labels"},
 
47
        {TRUE, 't', "struct", "types"},
 
48
        {TRUE, 'v', "variable", "variables"},
 
49
        {TRUE, 'g', "externvar", "enumerations"}
 
50
};
 
51
 
 
52
static KeyWord freebasic_keywords[] = {
 
53
        {"dim", K_VARIABLE}, /* must always be the first */
 
54
        {"common", K_VARIABLE}, /* must always be the second */
 
55
        {"const", K_CONST}, /* must always be the third */
 
56
        {"function", K_FUNCTION},
 
57
        {"sub", K_FUNCTION},
 
58
        {"private sub", K_FUNCTION},
 
59
        {"public sub", K_FUNCTION},
 
60
        {"private function", K_FUNCTION},
 
61
        {"public function", K_FUNCTION},
 
62
        {"type", K_TYPE},
 
63
        {"enum", K_ENUM},
 
64
        {NULL, 0}
 
65
};
 
66
 
 
67
/*
 
68
 *   FUNCTION DEFINITIONS
 
69
 */
 
70
 
 
71
/* Match the name of a dim or const starting at pos. */
 
72
static int extract_dim (char const *pos, vString * name, BasicKind kind)
 
73
{
 
74
        while (isspace (*pos))
 
75
                pos++;
 
76
 
 
77
        vStringClear (name);
 
78
 
 
79
        if (strncasecmp (pos, "shared", 6) == 0)
 
80
                pos += 6; /* skip keyword "shared" */
 
81
 
 
82
        while (isspace (*pos))
 
83
                pos++;
 
84
 
 
85
        /* capture "dim as String str" */
 
86
        if (strncasecmp (pos, "as", 2) == 0)
 
87
        {
 
88
                        pos += 2; /* skip keyword "as" */
 
89
 
 
90
                while (isspace (*pos))
 
91
                        pos++;
 
92
                while (!isspace (*pos)) /* skip next part which is a type */
 
93
                        pos++;
 
94
                while (isspace (*pos))
 
95
                        pos++;
 
96
                /* now we are at the name */
 
97
        }
 
98
 
 
99
        /* capture "dim as foo ptr bar" */
 
100
        if (strncasecmp (pos, "ptr", 3) == 0)
 
101
        {
 
102
                pos += 3; /* skip keyword "ptr" */
 
103
 
 
104
                while (isspace (*pos))
 
105
                        pos++;
 
106
        }
 
107
 
 
108
        for (; *pos && !isspace (*pos) && *pos != '(' && *pos != ',' && *pos != '='; pos++)
 
109
                vStringPut (name, *pos);
 
110
        vStringTerminate (name);
 
111
        makeSimpleTag (name, BasicKinds, kind);
 
112
 
 
113
        /* if the line contains a ',', we have multiple declarations */
 
114
        while (*pos && strchr (pos, ','))
 
115
        {
 
116
                /* skip all we don't need(e.g. "..., new_array(5), " we skip "(5)") */
 
117
                while (*pos != ',' && *pos != '\'')
 
118
                        pos++;
 
119
 
 
120
                if (*pos == '\'')
 
121
                        return 0; /* break if we are in a comment */
 
122
 
 
123
                while (isspace (*pos) || *pos == ',')
 
124
                        pos++;
 
125
 
 
126
                if (*pos == '\'')
 
127
                        return 0; /* break if we are in a comment */
 
128
 
 
129
                vStringClear (name);
 
130
                for (; *pos && !isspace (*pos) && *pos != '(' && *pos != ',' && *pos != '='; pos++)
 
131
                        vStringPut (name, *pos);
 
132
                vStringTerminate (name);
 
133
                makeSimpleTag (name, BasicKinds, kind);
 
134
        }
 
135
 
 
136
        vStringDelete (name);
 
137
        return 1;
 
138
}
 
139
 
 
140
/* Match the name of a tag (function, variable, type, ...) starting at pos. */
 
141
static char const *extract_name (char const *pos, vString * name)
 
142
{
 
143
        while (isspace (*pos))
 
144
                pos++;
 
145
        vStringClear (name);
 
146
        for (; *pos && !isspace (*pos) && *pos != '(' && *pos != ',' && *pos != '='; pos++)
 
147
                vStringPut (name, *pos);
 
148
        vStringTerminate (name);
 
149
        return pos;
 
150
}
 
151
 
 
152
/* Match a keyword starting at p (case insensitive). */
 
153
static int match_keyword (const char *p, KeyWord const *kw)
 
154
{
 
155
        vString *name;
 
156
        size_t i;
 
157
        int j;
 
158
        for (i = 0; i < strlen (kw->token); i++)
 
159
        {
 
160
                if (tolower (p[i]) != kw->token[i])
 
161
                        return 0;
 
162
        }
 
163
        name = vStringNew ();
 
164
        p += i;
 
165
        if (kw == &freebasic_keywords[0] ||
 
166
                kw == &freebasic_keywords[1] ||
 
167
                kw == &freebasic_keywords[2])
 
168
                return extract_dim (p, name, kw->kind); /* extract_dim adds the found tag(s) */
 
169
 
 
170
        for (j = 0; j < 1; j++)
 
171
        {
 
172
                p = extract_name (p, name);
 
173
        }
 
174
        makeSimpleTag (name, BasicKinds, kw->kind);
 
175
        vStringDelete (name);
 
176
 
 
177
        return 1;
 
178
}
 
179
 
 
180
/* Match a "label:" style label. */
 
181
static void match_colon_label (char const *p)
 
182
{
 
183
        char const *end = p + strlen (p) - 1;
 
184
        while (isspace (*end))
 
185
                end--;
 
186
        if (*end == ':')
 
187
        {
 
188
                vString *name = vStringNew ();
 
189
                vStringNCatS (name, p, end - p);
 
190
                makeSimpleTag (name, BasicKinds, K_LABEL);
 
191
                vStringDelete (name);
 
192
        }
 
193
}
 
194
 
 
195
static void findBasicTags (void)
 
196
{
 
197
        const char *line;
 
198
        KeyWord *keywords;
 
199
 
 
200
        keywords = freebasic_keywords;
 
201
 
 
202
        while ((line = (const char *) fileReadLine ()) != NULL)
 
203
        {
 
204
                const char *p = line;
 
205
                KeyWord const *kw;
 
206
 
 
207
                while (isspace (*p))
 
208
                        p++;
 
209
 
 
210
                /* Empty line? */
 
211
                if (!*p)
 
212
                        continue;
 
213
 
 
214
                /* In Basic, keywords always are at the start of the line. */
 
215
                for (kw = keywords; kw->token; kw++)
 
216
                        if (match_keyword (p, kw)) break;
 
217
 
 
218
                /* Is it a label? */
 
219
                match_colon_label (p);
 
220
        }
 
221
}
 
222
 
 
223
parserDefinition *FreeBasicParser (void)
 
224
{
 
225
        static char const *extensions[] = { "bas", "bi", "bb", "pb", NULL };
 
226
        parserDefinition *def = parserNew ("FreeBasic");
 
227
        def->kinds = BasicKinds;
 
228
        def->kindCount = KIND_COUNT (BasicKinds);
 
229
        def->extensions = extensions;
 
230
        def->parser = findBasicTags;
 
231
        return def;
 
232
}
 
233
 
 
234
/* vi:set tabstop=4 shiftwidth=4: */