~ubuntu-branches/ubuntu/jaunty/geany/jaunty

« back to all changes in this revision

Viewing changes to tagmanager/make.c

  • Committer: Bazaar Package Importer
  • Author(s): Gauvain Pocentek
  • Date: 2008-05-09 20:40:06 UTC
  • mfrom: (1.1.7 upstream) (3.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080509204006-9fu737rfvapfj7pn
Tags: 0.14-1ubuntu1
* Merge from debian unstable, remaining changes:
  - patches/20_add_debdiff_as_diff_type.dpatch:
    Also recognize .dpatch files as diff's
  - debian/geany.xpm:
    Replace icon with a .xpm of the new one
  - Modify Maintainer value to match the DebianMaintainerField
    specification.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
 
2
*   $Id: make.c 2497 2008-04-17 18:06:31Z eht16 $
2
3
*
3
 
*   Copyright (c) 2000-2001, Darren Hiebert
 
4
*   Copyright (c) 2000-2005, Darren Hiebert
4
5
*
5
6
*   This source code is released for free distribution under the terms of the
6
7
*   GNU General Public License.
11
12
/*
12
13
*   INCLUDE FILES
13
14
*/
14
 
#include "general.h"    /* must always come first */
 
15
#include "general.h"  /* must always come first */
15
16
 
 
17
#include <stdio.h>
 
18
#include <string.h>
16
19
#include <ctype.h>
17
20
 
 
21
#include "options.h"
18
22
#include "parse.h"
19
23
#include "read.h"
20
24
#include "vstring.h"
23
27
*   DATA DEFINITIONS
24
28
*/
25
29
typedef enum {
26
 
    K_MACRO
 
30
        K_MACRO, K_TARGET
27
31
} shKind;
28
32
 
29
33
static kindOption MakeKinds [] = {
30
 
    { TRUE, 'm', "macro", "macros"}
 
34
        { TRUE, 'm', "macro",  "macros"},
 
35
        { TRUE, 't', "function", "targets"}
31
36
};
32
37
 
33
38
/*
34
39
*   FUNCTION DEFINITIONS
35
40
*/
36
41
 
 
42
static int nextChar (void)
 
43
{
 
44
        int c = fileGetc ();
 
45
        if (c == '\\')
 
46
        {
 
47
                c = fileGetc ();
 
48
                if (c == '\n')
 
49
                        c = fileGetc ();
 
50
        }
 
51
        return c;
 
52
}
 
53
 
 
54
static void skipLine (void)
 
55
{
 
56
        int c;
 
57
        do
 
58
                c = nextChar ();
 
59
        while (c != EOF  &&  c != '\n');
 
60
        if (c == '\n')
 
61
                fileUngetc (c);
 
62
}
 
63
 
 
64
static int skipToNonWhite (void)
 
65
{
 
66
        int c;
 
67
        do
 
68
                c = nextChar ();
 
69
        while (c != '\n' && isspace (c));
 
70
        return c;
 
71
}
 
72
 
37
73
static boolean isIdentifier (int c)
38
74
{
39
 
    return (boolean)(isalnum (c)  ||  c == '_');
 
75
        return (boolean)(c != '\0' && (isalnum (c)  ||  strchr (".-_/", c) != NULL));
 
76
}
 
77
 
 
78
static boolean isSpecialTarget (vString *const name)
 
79
{
 
80
        size_t i = 0;
 
81
        /* All special targets begin with '.'. */
 
82
        if (vStringChar (name, i++) != '.') {
 
83
                return FALSE;
 
84
        }
 
85
        while (i < vStringLength (name)) {
 
86
                char ch = vStringChar (name, i++);
 
87
                if (ch != '_' && !isupper (ch))
 
88
                {
 
89
                        return FALSE;
 
90
                }
 
91
        }
 
92
        return TRUE;
 
93
}
 
94
 
 
95
static void newTarget (vString *const name)
 
96
{
 
97
        /* Ignore GNU Make's "special targets". */
 
98
        if  (isSpecialTarget (name))
 
99
        {
 
100
                return;
 
101
        }
 
102
        makeSimpleTag (name, MakeKinds, K_TARGET);
 
103
}
 
104
 
 
105
static void newMacro (vString *const name)
 
106
{
 
107
        makeSimpleTag (name, MakeKinds, K_MACRO);
 
108
}
 
109
 
 
110
static void newMacroFromDefine (vString *const name)
 
111
{
 
112
        /* name is something like "define JAVAHPP_RULE", find the space and jump to the next char */
 
113
        vStringCopyS (name, strchr (vStringValue (name), ' ') + 1);
 
114
        makeSimpleTag (name, MakeKinds, K_MACRO);
 
115
}
 
116
 
 
117
static void readIdentifier (const int first, vString *const id)
 
118
{
 
119
        int c = first;
 
120
        int c_prev = first;
 
121
        int c_next = first;
 
122
        vStringClear (id);
 
123
        while (isIdentifier (c) || c == ' ')
 
124
        {
 
125
                c_next = nextChar ();
 
126
                if (c == ' ') {
 
127
                        /* add the space character only if the previous and
 
128
                         * next character are valid identifiers */
 
129
                        if (isIdentifier (c_prev) && isIdentifier (c_next))
 
130
                                vStringPut (id, c);
 
131
                }
 
132
                else {
 
133
                        vStringPut (id, c);
 
134
                }
 
135
                c_prev = c;
 
136
                c = c_next;
 
137
        }
 
138
        fileUngetc (c);
 
139
        vStringTerminate (id);
 
140
}
 
141
 
 
142
static void skipToMatch (const char *const pair)
 
143
{
 
144
        const int begin = pair [0], end = pair [1];
 
145
        const unsigned long inputLineNumber = getInputLineNumber ();
 
146
        int matchLevel = 1;
 
147
        int c = '\0';
 
148
 
 
149
        while (matchLevel > 0)
 
150
        {
 
151
                c = nextChar ();
 
152
                if (c == begin)
 
153
                        ++matchLevel;
 
154
                else if (c == end)
 
155
                        --matchLevel;
 
156
                else if (c == '\n')
 
157
                        break;
 
158
        }
 
159
        if (c == EOF)
 
160
                verbose ("%s: failed to find match for '%c' at line %lu\n",
 
161
                                getInputFileName (), begin, inputLineNumber);
40
162
}
41
163
 
42
164
static void findMakeTags (void)
43
165
{
44
 
    vString *name = vStringNew ();
45
 
    const unsigned char *line;
46
 
 
47
 
    while ((line = fileReadLine ()) != NULL)
48
 
    {
49
 
        const unsigned char* cp = line;
50
 
        boolean possible = TRUE;
51
 
 
52
 
        while (isspace ((int) *cp))
53
 
            ++cp;
54
 
        if (*cp == '#')
55
 
            continue;
56
 
 
57
 
        while (*cp != '\0')
 
166
        vString *name = vStringNew ();
 
167
        boolean newline = TRUE;
 
168
        boolean in_define = FALSE;
 
169
        boolean in_rule = FALSE;
 
170
        boolean variable_possible = TRUE;
 
171
        int c;
 
172
 
 
173
        while ((c = nextChar ()) != EOF)
58
174
        {
59
 
            /*  We look for any sequence of identifier characters following
60
 
             *  either a white space or a colon and followed by either = or :=
61
 
             */
62
 
            if (possible && isIdentifier ((int) *cp))
63
 
            {
64
 
                while (isIdentifier ((int) *cp))
65
 
                {
66
 
                    vStringPut (name, (int) *cp);
67
 
                    ++cp;
68
 
                }
69
 
                vStringTerminate (name);
70
 
                while (isspace ((int) *cp))
71
 
                    ++cp;
72
 
                if ( *cp == ':')
73
 
                    ++cp;
74
 
                if ( *cp == '=')
75
 
                    makeSimpleTag (name, MakeKinds, K_MACRO);
76
 
                vStringClear (name);
77
 
            }
78
 
            else if (isspace ((int) *cp) ||  *cp == ':')
79
 
                possible = TRUE;
80
 
            else
81
 
                possible = FALSE;
82
 
            if (*cp != '\0')
83
 
                ++cp;
 
175
                if (newline)
 
176
                {
 
177
                        if (in_rule)
 
178
                        {
 
179
                                if (c == '\t')
 
180
                                {
 
181
                                        skipLine ();  /* skip rule */
 
182
                                        continue;
 
183
                                }
 
184
                                else
 
185
                                        in_rule = FALSE;
 
186
                        }
 
187
                        variable_possible = (boolean)(!in_rule);
 
188
                        newline = FALSE;
 
189
                }
 
190
                if (c == '\n')
 
191
                        newline = TRUE;
 
192
                else if (isspace (c))
 
193
                        continue;
 
194
                else if (c == '#')
 
195
                        skipLine ();
 
196
                else if (c == '(')
 
197
                        skipToMatch ("()");
 
198
                else if (c == '{')
 
199
                        skipToMatch ("{}");
 
200
                else if (c == ':')
 
201
                {
 
202
                        variable_possible = TRUE;
 
203
                        in_rule = TRUE;
 
204
                }
 
205
                else if (variable_possible && isIdentifier (c))
 
206
                {
 
207
                        readIdentifier (c, name);
 
208
                        if (strncmp (vStringValue (name), "endef", 5) == 0)
 
209
                                in_define = FALSE;
 
210
                        else if (in_define)
 
211
                                skipLine ();
 
212
                        else if (strncmp (vStringValue (name), "define", 6) == 0  &&
 
213
                                isIdentifier (c))
 
214
                        {
 
215
                                in_define = TRUE;
 
216
                                c = skipToNonWhite ();
 
217
                                newMacroFromDefine (name);
 
218
                                skipLine ();
 
219
                        }
 
220
                        else {
 
221
                                c = skipToNonWhite ();
 
222
                                if (strchr (":?+", c) != NULL)
 
223
                                {
 
224
                                        boolean append = (boolean)(c == '+');
 
225
                                        boolean was_colon = (c == ':');
 
226
                                        c = nextChar ();
 
227
                                        if (was_colon)
 
228
                                        {
 
229
                                                if (c == '=')
 
230
                                                {
 
231
                                                        newMacro (name);
 
232
                                                        in_rule = FALSE;
 
233
                                                        skipLine ();
 
234
                                                }
 
235
                                                else
 
236
                                                {
 
237
                                                        in_rule = TRUE;
 
238
                                                        newTarget (name);
 
239
                                                }
 
240
                                        }
 
241
                                        else if (append)
 
242
                                        {
 
243
                                                skipLine ();
 
244
                                                continue;
 
245
                                        }
 
246
                                        else
 
247
                                        {
 
248
                                                fileUngetc (c);
 
249
                                        }
 
250
                                }
 
251
                                else if (c == '=')
 
252
                                {
 
253
                                        newMacro (name);
 
254
                                        in_rule = FALSE;
 
255
                                        skipLine ();
 
256
                                }
 
257
                                else
 
258
                                {
 
259
                                        fileUngetc (c);
 
260
                                }
 
261
                        }
 
262
                }
 
263
                else
 
264
                        variable_possible = FALSE;
84
265
        }
85
 
    }
86
 
    vStringDelete (name);
 
266
        vStringDelete (name);
87
267
}
88
268
 
89
269
extern parserDefinition* MakefileParser (void)
90
270
{
91
 
    static const char *const patterns [] = { "[Mm]akefile", NULL };
92
 
    static const char *const extensions [] = { "mak", "mk", NULL };
93
 
    parserDefinition* const def = parserNew ("Make");
94
 
    def->kinds      = MakeKinds;
95
 
    def->kindCount  = KIND_COUNT (MakeKinds);
96
 
    def->patterns   = patterns;
97
 
    def->extensions = extensions;
98
 
    def->parser     = findMakeTags;
99
 
    return def;
 
271
        static const char *const patterns [] = { "[Mm]akefile", NULL };
 
272
        static const char *const extensions [] = { "mak", "mk", NULL };
 
273
        parserDefinition* const def = parserNew ("Make");
 
274
        def->kinds      = MakeKinds;
 
275
        def->kindCount  = KIND_COUNT (MakeKinds);
 
276
        def->patterns   = patterns;
 
277
        def->extensions = extensions;
 
278
        def->parser     = findMakeTags;
 
279
        return def;
100
280
}
101
281
 
102
 
/* vi:set tabstop=8 shiftwidth=4: */
 
282
/* vi:set tabstop=4 shiftwidth=4: */