~damien-moore/+junk/codeblocks

« back to all changes in this revision

Viewing changes to src/plugins/compilergcc/depslib/src/headers.c

  • Committer: Damien Moore
  • Date: 2013-10-11 14:25:27 UTC
  • Revision ID: damienlmoore@gmail.com-20131011142527-w13ki0x8yjd7973d
copy of Code::Blocks repo based on SVN rev 9395

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * -= Copyright 2005 Tim Baker (treectrl@hotmail.com) =-
 
3
 *
 
4
 * This file is part of depslib.
 
5
 *
 
6
 * License is hereby granted to use this software and distribute it
 
7
 * freely, as long as this copyright notice is retained and modifications 
 
8
 * are clearly marked.
 
9
 *
 
10
 * ALL WARRANTIES ARE HEREBY DISCLAIMED.
 
11
 * 
 
12
 * Modifications:
 
13
 * - D support (search for "D support")
 
14
 * - Depth level counting (needed for D support)
 
15
 * - Simple optimization by avoiding regexec most of the time
 
16
 * - Special cache keys for source files (needed for D support)
 
17
 */
 
18
#include "jam.h"
 
19
#include "alloc.h"
 
20
#include "hash.h"
 
21
#include "lists.h"
 
22
#include "newstr.h"
 
23
#include "regexp.h"
 
24
#include "headers.h"
 
25
#ifdef USE_CACHE
 
26
#include "cache.h"
 
27
#endif
 
28
 
 
29
#include "depslib.h" /* for struct depsStats */
 
30
extern struct depsStats g_stats;
 
31
 
 
32
struct hash *headerhash = 0;
 
33
static regexp *hdrre = 0;
 
34
/*D support*/
 
35
static regexp *dimpre = 0;
 
36
 
 
37
LIST *headers1(const char *file, int depth)
 
38
{
 
39
        FILE *f;
 
40
        regexp *re;
 
41
        LIST *result = 0;
 
42
        char buf[1024];
 
43
        int fnlen=strlen(file);
 
44
        
 
45
        /*D support */
 
46
        int dMode=0;
 
47
        int dState=0;
 
48
        if(file[fnlen-2] == '.' && file[fnlen-1] == 'd')
 
49
        {
 
50
                dMode=1;
 
51
                if( DEBUG_HEADER )
 
52
                        printf("D file detected\n");
 
53
        }
 
54
 
 
55
        /* C::B patch: Debug usage of root folder */
 
56
        if( DEBUG_HEADER )
 
57
            printf("header open %s\n", file);
 
58
 
 
59
        if (!(f = fopen(file, "r")))
 
60
                return result;
 
61
 
 
62
        if( DEBUG_HEADER )
 
63
            printf("header scan %s\n", file);
 
64
 
 
65
        if (!hdrre)
 
66
                hdrre = my_regcomp("^[  ]*#[    ]*include[      ]*([<\"])([^\">]*)([\">]).*$");
 
67
        re = hdrre;
 
68
        
 
69
        /* D support */
 
70
        if(dMode)
 
71
        {
 
72
                if(!dimpre)
 
73
                        dimpre = my_regcomp(
 
74
                                "^.*import[ \t]*([[A-Za-z_ \t]+=[ \t]*)?([A-Za-z_\\.]+)(\\:.+)?;.*$");
 
75
                re = dimpre;
 
76
        }
 
77
        
 
78
        while (fgets(buf, sizeof(buf), f))
 
79
        {
 
80
                /* D support */
 
81
                if(dMode)
 
82
                {
 
83
                        if(dState == 0)
 
84
                        {
 
85
                                if(strstr(buf, "public"))
 
86
                                        dState=1;
 
87
                        }
 
88
                        if(dState >= 1)
 
89
                        {
 
90
                                if(strchr(buf, '{'))
 
91
                                        ++dState;
 
92
                                if(strchr(buf, '}'))
 
93
                                        --dState;
 
94
                        }
 
95
                }
 
96
                
 
97
                /* Simple reduction of regex overhead */
 
98
                if(strstr(buf, dMode ? "import" : "include"))
 
99
                        if (my_regexec(re, buf))
 
100
                        {
 
101
                                char buf2[MAXSYM];
 
102
 
 
103
                                /* FIXME: don't add duplicate headers*/
 
104
                                if(!dMode && re->startp[3])
 
105
                                {
 
106
                                        int l = re->endp[3] - re->startp[1];
 
107
                                        memcpy(buf2, re->startp[1], l);
 
108
                                        buf2[l] = '\0';
 
109
                                }
 
110
                                /* D support */
 
111
                                else if(re->startp[2])
 
112
                                {
 
113
                                        if(depth > 0)
 
114
                                        {
 
115
                                                /* private import? */
 
116
                                                if(dState == 0)
 
117
                                                        continue;
 
118
                                        }
 
119
                                        
 
120
                                        buf2[0] = '<';
 
121
                                        const char* p;
 
122
                                        int j = 0;
 
123
                                        for(p = re->startp[2];p < re->endp[2];++p)
 
124
                                        {
 
125
                                                char c=*p;
 
126
                                                ++j;
 
127
                                                if(c == '.')
 
128
                                                        buf2[j] = '/';
 
129
                                                else buf2[j] = c;
 
130
                                        }
 
131
                                        buf2[++j]='.';
 
132
                                        buf2[++j]='d';
 
133
                                        buf2[++j]='>';
 
134
                                        buf2[++j] = '\0';
 
135
                                }
 
136
                                result = list_new(result, buf2, 0);
 
137
 
 
138
                                if (DEBUG_HEADER)
 
139
                                        printf("header found: %s\n", buf2);
 
140
                        }
 
141
                
 
142
                /* D support */
 
143
                if(dMode)
 
144
                {
 
145
                        if(dState == 1)
 
146
                        {
 
147
                                if(strchr(buf, ';'))
 
148
                                        dState=0;
 
149
                                
 
150
                                if(strchr(buf, '}'))
 
151
                                        dState=0;
 
152
                        }
 
153
                }
 
154
        }
 
155
 
 
156
        fclose(f);
 
157
 
 
158
        g_stats.scanned++;
 
159
 
 
160
        return result;
 
161
}
 
162
 
 
163
static ALLOC *hdralloc = 0;
 
164
 
 
165
HEADERS *headerentry(HEADERS *chain, HEADER *header)
 
166
{
 
167
        HEADERS *c;
 
168
 
 
169
#if 1
 
170
        if (!hdralloc)
 
171
                hdralloc = alloc_init(sizeof(HEADERS), 64);
 
172
        c = (HEADERS *) alloc_enter(hdralloc);
 
173
#else
 
174
        c = (HEADERS *)malloc(sizeof(HEADERS));
 
175
#endif
 
176
        c->header = header;
 
177
 
 
178
        if (!chain) chain = c;
 
179
        else chain->tail->next = c;
 
180
        chain->tail = c;
 
181
        c->next = 0;
 
182
 
 
183
        return chain;
 
184
}
 
185
 
 
186
HEADER *headersDepth(const char *t, time_t time, int depth)
 
187
{
 
188
        HEADER hdr, *h = &hdr;
 
189
        LIST *l;
 
190
        const char* cachekey=t;
 
191
 
 
192
        /* D support (doesn't affect C(++), because a source file is never included) */
 
193
        if(depth == 0)
 
194
        {
 
195
                cachekey=malloc(strlen(t)+sizeof("source:"));
 
196
                strcpy((char*)cachekey,"source:");
 
197
                strcpy((char*)cachekey+7,t);
 
198
        }
 
199
        
 
200
        if (!headerhash)
 
201
                headerhash = hashinit(sizeof(HEADER), "headers");
 
202
 
 
203
        h->key = cachekey;
 
204
        h->includes = 0;
 
205
        h->time = time;
 
206
        h->headers = 0;
 
207
        h->newest = 0;
 
208
        if (!hashenter(headerhash, (HASHDATA **)&h))
 
209
                return h;
 
210
 
 
211
        h->key = newstr(t);
 
212
#ifdef USE_CACHE
 
213
        if (!cache_check(cachekey, time, &h->includes))
 
214
        {
 
215
                h->includes = headers1(t, depth);
 
216
                cache_enter(cachekey, time, h->includes);
 
217
        }
 
218
#else
 
219
        h->includes = headers1(t, depth);
 
220
#endif
 
221
        if(depth == 0)
 
222
                free((char*)cachekey);
 
223
 
 
224
        l = h->includes;
 
225
        while (l)
 
226
        {
 
227
                const char *t2 = search(t, l->string, &time);
 
228
                if (time)
 
229
                        h->headers = headerentry(h->headers, headersDepth(t2, time, depth+1));
 
230
                l = list_next(l);
 
231
        }
 
232
 
 
233
        return h;
 
234
}
 
235
 
 
236
HEADER *headers(const char *t, time_t time)
 
237
{
 
238
        return headersDepth(t, time, 0);
 
239
}
 
240
 
 
241
void headernewest(HEADER *h)
 
242
{
 
243
        HEADERS *hs = h->headers;
 
244
 
 
245
        if (h->newest)
 
246
                return;
 
247
        h->newest = h;
 
248
        while (hs)
 
249
        {
 
250
                headernewest(hs->header);
 
251
                if (hs->header->newest->time > h->newest->time)
 
252
                        h->newest = hs->header->newest;
 
253
                hs = hs->next;
 
254
        }
 
255
}
 
256
 
 
257
void donehdrs(void)
 
258
{
 
259
        my_redone(hdrre);
 
260
        hdrre = 0;
 
261
        /* D support */
 
262
        my_redone(dimpre);
 
263
        dimpre = 0;
 
264
        hashdone(headerhash);
 
265
        headerhash = 0;
 
266
        alloc_free(hdralloc);
 
267
        hdralloc = 0;
 
268
}