Errors.cpp

Zbigniew Rebacz, 06/23/2014 11:18 PM

Download (9.37 KB)

 
1
#include "ide.h"
2

    
3
bool Ide::FindLineError(const String& ln, FindLineErrorCache& cache, ErrorInfo& f)
4
{
5
        VectorMap<String, String> bm = GetMethodVars(method);
6
        bool is_java = (bm.Get("BUILDER", Null) == "JDK");
7
        const char *s = ln;
8
        while(*s == ' ' || *s == '\t')
9
                s++;
10
        for(; s < ln.End(); s++) {
11
                if(*s != '\"' && (byte)*s >= 32 && *s != '(' && (f.file.GetLength() < 3 || *s != ':'))
12
                        f.file.Cat(*s);
13
                else {
14
                        if(*s == '\"') {
15
                                f.file = Null;
16
                                s++;
17
                                while(*s && *s != '\"')
18
                                        f.file.Cat(*s++);
19
                                if(*s)
20
                                        s++;
21
                        }
22
                        int e = f.file.GetLength();
23
                        while(e > 0 && f.file[e - 1] == ' ')
24
                                e--;
25
                        f.file.Trim(e);
26
                        f.file = TrimLeft(f.file);
27
                        String upp = GetUppDir();
28
                #ifdef PLATFORM_WIN32
29
                        if(f.file[0] == '\\' || f.file[0] == '/')
30
                                f.file = String(upp[0], 1) + ':' + f.file;
31
                #endif
32
                        if(!IsFullPath(f.file) && *f.file != '\\' && *f.file != '/') {
33
                                if(cache.wspc_paths.IsEmpty()) {
34
                                        ::Workspace  wspc;
35
                                        wspc.Scan(main);
36
                                        for(int i = 0; i < wspc.GetCount(); i++)
37
                                                cache.wspc_paths.Add(GetFileDirectory(PackagePath(wspc[i])));
38
                                }
39
                                for(int i = 0; i < cache.wspc_paths.GetCount(); i++) {
40
                                        String path = AppendFileName(cache.wspc_paths[i], f.file);
41
                                        int q = cache.ff.Find(path);
42
                                        if(q >= 0) {
43
                                                if(cache.ff[q]) {
44
                                                        f.file = path;
45
                                                        break;
46
                                                }
47
                                        }
48
                                        else {
49
                                                bool b = false;
50
                                                String ext = ToLower(GetFileExt(path));
51
                                                if(findarg(ext, ".obj", ".lib", ".o", ".so", ".a", ".", "") < 0) {
52
                                                        FindFile ff;
53
                                                        b = ff.Search(path) && ff.IsFile();
54
                                                }
55
                                                cache.ff.Add(path, b);
56
                                                if(b) {
57
                                                        f.file = path;
58
                                                        break;
59
                                                }
60
                                        }
61
                                }
62
                        }
63
                        f.file = FollowCygwinSymlink(f.file);
64
                        if(IsFullPath(f.file) && FileExists(f.file) && IsTextFile(f.file)) {
65
                                while(*s && !IsDigit(*s))
66
                                        s++;
67
                                f.lineno = f.linepos = 0;
68
                                CParser p(s);
69
                                if(p.IsInt())
70
                                        f.lineno = p.ReadInt();
71
                                if(p.Char(':') && p.IsInt()) 
72
                                        f.linepos = p.ReadInt();
73
                                const char *ms = p.GetPtr();
74
                                int pos = ms - ~ln;
75
                                f.kind = ln.Find("error", pos) > 0 ? 1 :
76
                                         ln.Find("warning", pos) > 0 ? 2 :
77
                                         ln.Find("note", pos) > 0 ? 3 : 4;
78
                                const char *hs = ms;
79
                                while(!IsLetter(*hs) && *hs)
80
                                        hs++;
81
                                f.message = *hs ? hs : ms;
82
                                f.message = TrimLeft(f.message);
83
                                Vector<String> conf = SplitFlags(mainconfigparam, true);
84
                                String uppout = GetVar("OUTPUT");
85
                                int upplen = uppout.GetLength();
86
                                if(is_java && f.file.GetLength() > upplen
87
                                && !MemICmp(f.file, uppout, upplen) && f.file[upplen] == DIR_SEP) { // check for preprocessed file
88
                                        FileIn fi(f.file);
89
                                        if(fi.IsOpen())
90
                                        {
91
                                                String fake_file = f.file;
92
                                                int fake_line = 1;
93
                                                int file_line = 1;
94
                                                while(!fi.IsEof())
95
                                                {
96
                                                        String line = fi.GetLine();
97
                                                        const char *p = line;
98
                                                        if(p[0] == '/' && p[1] == '/' && p[2] == '#')
99
                                                        {
100
                                                                p += 3;
101
                                                                if(p[0] == 'l' && p[1] == 'i' && p[2] == 'n' && p[3] == 'e')
102
                                                                        p += 4;
103
                                                                while(*p == ' ' || *p == '\t')
104
                                                                        p++;
105
                                                                if(IsDigit(*p))
106
                                                                {
107
                                                                        fake_line = stou(p, &p);
108
                                                                        while(*p == ' ' || *p == '\t')
109
                                                                                p++;
110
                                                                        if(*p == '\"')
111
                                                                                p++;
112
                                                                        fake_file.Clear();
113
                                                                        while(*p && *p != '\"')
114
                                                                                if(*p == '/')
115
                                                                                {
116
                                                                                        fake_file.Cat('/');
117
                                                                                        if(p[1] == '/')
118
                                                                                                p++;
119
                                                                                        p++;
120
                                                                                }
121
                                                                                else
122
                                                                                        fake_file.Cat(*p++);
123
                                                                }
124
                                                                file_line++;
125
                                                                continue;
126
                                                        }
127
                                                        if(f.lineno <= file_line) {
128
                                                                f.file = fake_file;
129
                                                                f.lineno = fake_line;
130
                                                                f.linepos = 0;
131
                                                                break;
132
                                                        }
133
                                                        file_line++;
134
                                                        fake_line++;
135
                                                }
136
                                        }
137
                                }
138
                                if(f.lineno > 0)
139
                                        return true;
140
                        }
141
                        f.file.Clear();
142
                }
143
        }
144
        return false;
145
}
146

    
147
void Ide::FindError()
148
{
149
        FindLineError(console.GetLine(console.GetCursor()));
150
}
151

    
152
bool Ide::Next(int tab, ArrayCtrl& a, int d)
153
{
154
        if(btabs.GetCursor() == tab) {
155
                int c = a.GetCursor() + d;
156
                if(c >= 0 && c < a.GetCount())
157
                        a.SetCursor(c);
158
                else {
159
                        if(d > 0)
160
                                a.GoBegin();
161
                        else
162
                                a.GoEnd();
163
                }
164
                return true;
165
        }
166
        return false;
167
}
168

    
169
void Ide::FindNextError()
170
{
171
        if(Next(BCONSOLE, error, 1) || Next(BFINDINFILES, ffound, 1))
172
                return;
173
        int ln = console.GetLine(console.GetCursor());
174
        int l = ln;
175
        for(l = ln; l < console.GetLineCount(); l++)
176
                if(FindLineError(l)) return;
177
        for(l = 0; l < ln; l++)
178
                if(FindLineError(l)) return;
179
}
180

    
181
void Ide::FindPrevError() {
182
        if(Next(BCONSOLE, error, -1) || Next(BFINDINFILES, ffound, -1))
183
                return;
184
        int ln = console.GetLine(console.GetCursor());
185
        int l = ln;
186
        One<Host> host = CreateHost(false);
187
        for(l = ln - 2; l >= 0; l--)
188
                if(FindLineError(l)) return;
189
        for(l = console.GetLineCount() - 1; l > ln; l--)
190
                if(FindLineError(l)) return;
191
}
192

    
193
void Ide::ClearErrorEditor()
194
{
195
        if(!mark_lines)
196
                return;
197

    
198
        for(int i = 0; i < filedata.GetCount(); i++) {
199
                ClearErrorEditor(filedata.GetKey(i));
200
        }
201
        
202
        SetErrorFiles(Vector<String>());
203
}
204

    
205
void Ide::ClearErrorEditor(String file)
206
{
207
        if(!mark_lines)
208
                return;
209
        if(file == editfile)
210
                editor.ClearErrors();
211
        else {
212
                FileData& fd = Filedata(file);
213
                ClearErrors(fd.lineinfo);
214
        }
215
}
216

    
217
void Ide::SetErrorEditor()
218
{
219
        if(error.GetCount()) {
220
                SetBottom(BERRORS);
221
//                if(!error.IsCursor())
222
//                        error.GoBegin();
223
        }
224

    
225
        if(!mark_lines)
226
                return;
227

    
228
        bool refresh = false;
229
        String    hfile;
230
        EditorBar hbar;
231
        Vector<String> errorfiles;
232
        FindLineErrorCache cache;
233
        for(int i = 0; i < console.GetLineCount(); i++) {
234
                ErrorInfo f;
235
                if(FindLineError(console.GetUtf8Line(i), cache, f)) {
236
                        String file = NormalizePath(f.file);
237
                #ifdef PLATFORM_WIN32
238
                        errorfiles.Add(ToLower(file));
239
                #else
240
                        errorfiles.Add(file);
241
                #endif
242
                        if(editfile == file) {
243
                                editor.SetError(f.lineno - 1, f.kind);
244
                                refresh = true;
245
                        }
246
                        else {
247
                                if(hfile != file) {
248
                                        if(hfile.GetCount())
249
                                                Filedata(hfile).lineinfo = hbar.GetLineInfo();
250
                                        hbar.SetLineInfo(Filedata(file).lineinfo, -1);
251
                                        hfile = file;
252
                                }
253
                                hbar.SetError(f.lineno - 1, f.kind);
254
                        }
255
                }
256
        }
257
        if(hfile.GetCount())
258
                Filedata(hfile).lineinfo = hbar.GetLineInfo();
259
        if(refresh)
260
                editor.RefreshFrame();
261
        SetErrorFiles(errorfiles);
262
}
263

    
264
void Ide::GoToError(const ErrorInfo& f)
265
{
266
        if(IsNull(f.file))
267
                return;
268
        String file = NormalizePath(f.file);
269
        editastext.FindAdd(file);
270
        EditFile(file);
271
        editor.SetCursor(editor.GetPos(editor.GetLineNo(f.lineno - 1), max(f.linepos - 1, 0)));
272
        editor.CenterCursor();
273
        editor.SetFocus();
274
        Sync();
275
}
276

    
277
bool Ide::FindLineError(int l) {
278
        ErrorInfo f;
279
        FindLineErrorCache cache;
280
        if(FindLineError(console.GetUtf8Line(l), cache, f)) {
281
                GoToError(f);
282
                console.SetSelection(console.GetPos(l), console.GetPos(l + 1));
283
                if(btabs.GetCursor() != BCONSOLE && btabs.GetCursor() != BFINDINFILES)
284
                        ShowConsole();
285
                return true;
286
        }
287
        return false;
288
}
289

    
290
void Ide::ConsoleLine(const String& line)
291
{
292
        ErrorInfo f;
293
        if(FindLineError(line, error_cache, f)) {
294
                if(findarg(f.kind, 1, 2) >= 0 || error.GetCount() == 0) {
295
                        error.Add(GetFileName(f.file), f.lineno,
296
                                  AttrText(f.message)
297
                                  .NormalPaper(HighlightSetup::GetHlStyle(f.kind == 1 ? HighlightSetup::PAPER_ERROR
298
                                                                                      : HighlightSetup::PAPER_WARNING).color),
299
                                  RawToValue(f));
300
                        return;
301
                }
302
        }
303
        else {
304
                f.lineno = Null;
305
                f.file = Null;
306
                f.message = TrimLeft(line);
307
        }
308
        AddNote(f);
309
}
310

    
311
void Ide::AddNote(const ErrorInfo& f)
312
{
313
        int cnt = error.GetCount();
314
        if(cnt == 0)
315
                return;
316
        ValueArray n = error.Get(cnt - 1, "NOTES");
317
        n.Add(RawToValue(f));
318
        error.Set(cnt - 1, "NOTES", n);
319
}
320

    
321
void Ide::ShowNote()
322
{
323
        if(notes.IsCursor())
324
                GoToError(ValueTo<ErrorInfo>(notes.Get("INFO")));
325
}
326

    
327
void Ide::ShowFound()
328
{
329
        if(ffound.IsCursor() && ffound.GetCursor() < ffound.GetCount() - 1)
330
                GoToError(ValueTo<ErrorInfo>(ffound.Get("INFO")));
331
}
332

    
333
void Ide::ShowError()
334
{
335
        notes.Clear();
336
        if(error.IsCursor()) {
337
                ValueArray n = error.Get("NOTES");
338
                for(int i = 0; i < n.GetCount(); i++) {
339
                        const ErrorInfo& f = ValueTo<ErrorInfo>(n[i]);
340
                        notes.Add(GetFileName(f.file), f.lineno, f.message, n[i]);
341
                }
342
                GoToError(ValueTo<ErrorInfo>(error.Get("INFO")));
343
        }        
344
}
345

    
346
void Ide::FoundDisplay::Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const
347
{
348
        String s = q;
349
        if(*s == '\1') {
350
                Vector<String> h = Split(s, '\1');
351
                if(h.GetCount() < 4)
352
                        return;
353
                One<EditorSyntax> es = EditorSyntax::Create(h[0]);
354
                es->IgnoreErrors();
355
                WString ln = h[3].ToWString();
356
                Vector<LineEdit::Highlight> hln;
357
                hln.SetCount(ln.GetCount() + 1);
358
                for(int i = 0; i < ln.GetCount(); i++) {
359
                        LineEdit::Highlight& h = hln[i];
360
                        h.paper = paper;
361
                        h.ink = SColorText();
362
                        h.chr = ln[i];
363
                        h.font = StdFont();
364
                }
365
                HighlightOutput hl(hln);
366
                es->Highlight(ln.Begin(), ln.End(), hl, NULL, 0, 0);
367
                int fcy = GetStdFontCy();
368
                int y = r.top + (r.GetHeight() - fcy) / 2;
369
                int x = r.left;
370
                w.DrawRect(r, paper);
371
                int sl = utf8len(~h[3], atoi(h[1]));
372
                int sh = utf8len(~h[3] + sl, atoi(h[2])) + sl;
373
                for(int i = 0; i < hln.GetCount(); i++) {
374
                        Font fnt = StdFont();
375
                        LineEdit::Highlight& h = hln[i];
376
                        fnt.Bold(h.font.IsBold());
377
                        fnt.Italic(h.font.IsItalic());
378
                        fnt.Underline(h.font.IsUnderline());
379
                        int cw = fnt[h.chr];
380
                        if(h.chr == '\t')
381
                                cw = 4 * fnt[' '];
382
                        if(i >= sl && i < sh && !(style & (CURSOR|SELECT|READONLY)))
383
                                w.DrawRect(x, y, cw, fcy, HighlightSetup::GetHlStyle(HighlightSetup::PAPER_SELWORD).color);
384
                        if(h.chr != '\t')
385
                                w.DrawText(x, y, &h.chr, fnt, h.ink, 1);
386
                        x += cw;
387
                }
388
        }
389
        else
390
                StdDisplay().Paint(w, r, q, ink, paper, style);
391
}