]> andersk Git - splint.git/blame - src/flagMarkerList.c
Readded files.
[splint.git] / src / flagMarkerList.c
CommitLineData
616915dd 1/*
2** LCLint - annotation-assisted static program checker
3** Copyright (C) 1994-2000 University of Virginia,
4** Massachusetts Institute of Technology
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** This program is distributed in the hope that it will be useful, but
12** WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14** General Public License for more details.
15**
16** The GNU General Public License is available from http://www.gnu.org/ or
17** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18** MA 02111-1307, USA.
19**
20** For information on lclint: lclint-request@cs.virginia.edu
21** To report a bug: lclint-bug@cs.virginia.edu
22** For more information: http://lclint.cs.virginia.edu
23*/
24/*
25** flagMarkerList.c
26**
27** based on list_template.c
28**
29** where T has T_equal (or change this) and T_unparse
30**
31** invariant: flagMarker's are listed in order
32*/
33
34# include "lclintMacros.nf"
35# include "basic.h"
36
37flagMarkerList
38 flagMarkerList_new ()
39{
40 flagMarkerList s = (flagMarkerList) dmalloc (sizeof (*s));
41
42 s->nelements = 0;
43 s->nspace = flagMarkerListBASESIZE;
44 s->elements = (flagMarker *)
45 dmalloc (sizeof (*s->elements) * flagMarkerListBASESIZE);
46
47 return (s);
48}
49
50static void
51flagMarkerList_grow (flagMarkerList s)
52{
53 int i;
54 flagMarker *newelements;
55
56 s->nspace += flagMarkerListBASESIZE;
57
58 newelements = (flagMarker *) dmalloc (sizeof (*newelements)
59 * (s->nelements + s->nspace));
60
61 for (i = 0; i < s->nelements; i++)
62 {
63 newelements[i] = s->elements[i];
64 }
65
66 sfree (s->elements);
67 s->elements = newelements;
68}
69
70void flagMarkerList_add (flagMarkerList s, flagMarker fm)
71{
72 int i = s->nelements - 1;
73
74
75 if (i > 0)
76 {
77 flagMarker last = s->elements[i];
78
79
80 if (flagMarker_isIgnoreCount (last))
81 {
82 if (!flagMarker_isIgnoreOff (fm))
83 {
84 if (flagMarker_isLocalSet (fm))
85 {
86 llforceerror
87 (FLG_WARNFLAGS,
88 cstring_makeLiteral ("Cannot set flag inside ignore "
89 "count region."),
90 flagMarker_getLoc (fm));
91 llgenindentmsg
92 (cstring_makeLiteral ("Ignore count region starts"),
93 flagMarker_getLoc (last));
94
95 }
96 else
97 {
98 if (flagMarker_isIgnoreOn (fm))
99 {
100 llforceerror
101 (FLG_WARNFLAGS,
102 cstring_makeLiteral ("Cannot nest ignore regions."),
103 flagMarker_getLoc (fm));
104 llgenindentmsg
105 (cstring_makeLiteral ("Previous ignore region starts"),
106 flagMarker_getLoc (last));
107 }
108 }
109
110 flagMarker_free (fm);
111 return;
112 }
113 }
114 else
115 {
116 if (flagMarker_isIgnoreOff (last))
117 {
118 flagMarker nlast = s->elements [i - 1];
119
120 if (flagMarker_isIgnoreCount (nlast))
121 {
122 if (fileloc_sameFile (flagMarker_getLoc (fm),
123 flagMarker_getLoc (last))
124 && fileloc_notAfter (flagMarker_getLoc (fm),
125 flagMarker_getLoc (last)))
126 {
127 if (flagMarker_isLocalSet (fm))
128 {
129 llforceerror
130 (FLG_WARNFLAGS,
131 cstring_makeLiteral ("Cannot set flag inside ignore "
132 "count region."),
133 flagMarker_getLoc (fm));
134 llgenindentmsg
135 (cstring_makeLiteral ("Ignore count region starts"),
136 flagMarker_getLoc (nlast));
137
138 }
139 else
140 {
141 if (flagMarker_isIgnoreOn (fm))
142 {
143 llforceerror
144 (FLG_WARNFLAGS,
145 cstring_makeLiteral ("Cannot nest ignore regions."),
146 flagMarker_getLoc (fm));
147 llgenindentmsg
148 (cstring_makeLiteral ("Previous ignore region starts"),
149 flagMarker_getLoc (nlast));
150 }
151 }
152
153 flagMarker_free (fm);
154 return;
155 }
156 }
157 }
158 }
159 }
160
161
162 /*
163 ** all this code is necessary to check the invariant is preserved
164 */
165
166 while (i > 0
167 && !flagMarker_sameFile (s->elements[i],
168 flagMarker_getLoc (fm)))
169 {
170 i--;
171 }
172
173 /*
174 ** reprocessing header file, okay to be out of order
175 */
176
177 if (i >= 0 && !fileloc_isHeader (flagMarker_getLoc (fm)))
178 {
179
180 /*
181 llassert (!flagMarker_beforeMarker (s->elements[i],
182 flagMarker_getLoc (fm)));
183 */
184 }
185
186 if (s->nspace <= 0)
187 {
188 flagMarkerList_grow (s);
189 }
190
191 s->nspace--;
192 s->elements[s->nelements] = fm;
193 s->nelements++;
194 }
195
196void flagMarkerList_checkSuppressCounts (flagMarkerList s)
197{
198 int nexpected = 0;
199 int nsuppressed = 0;
200 fileloc loc = fileloc_undefined;
201 bool inCount = FALSE;
202 int i;
203
204
205 for (i = 0; i < s->nelements; i++)
206 {
207 flagMarker current = s->elements[i];
208
209 if (flagMarker_isIgnoreCount (current))
210 {
211 llassert (!inCount);
212 inCount = TRUE;
213 nexpected = flagMarker_getCount (current);
214 loc = flagMarker_getLoc (current);
215 nsuppressed = 0;
216 }
217 else if (flagMarker_isIgnoreOff (current))
218 {
219 if (inCount)
220 {
221 inCount = FALSE;
222 llassert (fileloc_isDefined (loc));
223
224 if (nexpected > 0 && nexpected != nsuppressed)
225 {
226 llforceerror
227 (FLG_SUPCOUNTS,
228 message
229 ("Line expects to suppress %d error%p, found %d error%p",
230 nexpected, nsuppressed),
231 loc);
232 }
233 }
234 }
235 else if (flagMarker_isSuppress (current))
236 {
237 nsuppressed++;
238 }
239 else
240 {
241 ;
242 }
243 }
244
245 llassert (!inCount);
246}
247
248static void flagMarkerList_splice (flagMarkerList s,
249 int index,
250 /*@keep@*/ flagMarker fm)
251{
252 fileloc loc = flagMarker_getLoc (fm);
253 fileloc beforeloc, afterloc;
254 int i;
255
256 llassert (index >= 0 && (index + 1 < s->nelements));
257
258 beforeloc = flagMarker_getLoc (s->elements[index]);
259 afterloc = flagMarker_getLoc (s->elements[index + 1]);;
260
261 llassert (fileloc_sameFile (beforeloc, loc));
262 llassert (fileloc_sameFile (afterloc, loc));
263
264 if (s->nspace <= 0)
265 {
266 flagMarkerList_grow (s);
267 }
268
269 for (i = s->nelements; i > index + 1; i--)
270 {
271 s->elements[i] = s->elements[i - 1];
272 }
273
274 s->elements[index + 1] = fm;
275 s->nelements++;
276 s->nspace--;
277
278 }
279
280/*@only@*/ cstring
281flagMarkerList_unparse (flagMarkerList s)
282{
283 int i;
284 cstring st = cstring_makeLiteral ("[");
285
286 for (i = 0; i < s->nelements; i++)
287 {
288 if (i == 0)
289 {
290 st = message ("%q %q", st, flagMarker_unparse (s->elements[i]));
291 }
292 else
293 st = message ("%q, %q", st, flagMarker_unparse (s->elements[i]));
294 }
295
296 st = message ("%q ]", st);
297 return st;
298}
299
300void
301flagMarkerList_free (flagMarkerList s)
302{
303 int i;
304 for (i = 0; i < s->nelements; i++)
305 {
306 flagMarker_free (s->elements[i]);
307 }
308
309 sfree (s->elements);
310 sfree (s);
311}
312
313/*
314** returns YES iff
315** > in ignore region (there is an ignore ON marker not followed by OFF)
316** > code is OFF (-)
317**
318** returns NO iff
319** > not in ignore region
320** > code is ON (+)
321**
322** returns MAYBE iff
323** > not in ignore region
324** > code is unset or =
325**
326** requires: invariant for flagMarkerList:
327** flagMarker's are sorted by line and col
328*/
329
330static int
331flagMarkerList_lastBeforeLoc (flagMarkerList s, fileloc loc)
332{
333 int i;
334
335 for (i = s->nelements - 1; i >= 0; i--)
336 {
337 flagMarker current = s->elements[i];
338
339 if (fileloc_sameFile (current->loc, loc)
340 && (!flagMarker_beforeMarker (current, loc)))
341 {
342 return i;
343 }
344/*
345 if (flagMarker_sameFile (current, loc)
346 && (!flagMarker_beforeMarker (current, loc)))
347 {
348 return i;
349 }
350*/
351 }
352
353 return -1;
354}
355
356ynm
357flagMarkerList_suppressError (flagMarkerList s, flagcode code, fileloc loc)
358{
359 int i;
360 bool ignoreOff = FALSE;
361 bool nameChecksOff = FALSE;
362 bool flagOff = FALSE;
363 ynm flagSet = MAYBE;
364 bool islib = FALSE;
365 bool isNameChecksFlag = flagcode_isNameChecksFlag (code);
366
367 if (fileloc_isLib (loc))
368 {
369 i = s->nelements - 1;
370 islib = TRUE;
371 }
372 else
373 {
374 i = flagMarkerList_lastBeforeLoc (s, loc);
375 }
376
377
378 if (i < 0)
379 {
380 return MAYBE;
381 }
382
383 /*
384 ** Go backwards through the remaining flagMarkers in this file.
385 */
386
387 for (; i >= 0; i--)
388 {
389 flagMarker current = s->elements[i];
390
391
392 if (!islib && !flagMarker_sameFile (current, loc))
393 {
394 break;
395 }
396
397 if (flagMarker_isIgnoreOff (current))
398 {
399 ignoreOff = TRUE;
400 }
401 else if (flagMarker_isIgnoreOn (current))
402 {
403 if (!ignoreOff)
404 {
405 return YES;
406 }
407 }
408 else if (flagMarker_isIgnoreCount (current))
409 {
410 if (!ignoreOff)
411 {
412 flagMarkerList_splice (s, i,
413 flagMarker_createSuppress (code, loc));
414 return YES;
415 }
416 }
417 else if (flagMarker_isLocalSet (current))
418 {
419
420 if (!flagOff && flagMarker_getCode (current) == code)
421 {
422 ynm set = flagMarker_getSet (current);
423
424 if (ynm_isOff (set))
425 {
426 return YES;
427 }
428 else
429 {
430 if (ynm_isOn (set))
431 {
432 flagOff = TRUE;
433 flagSet = NO;
434 }
435 else
436 {
437 flagOff = TRUE;
438 flagSet = MAYBE;
439 }
440
441 if (ignoreOff)
442 {
443 if (isNameChecksFlag && !nameChecksOff)
444 {
445 ;
446 }
447 else
448 {
449 return flagSet;
450 }
451 }
452 }
453 }
454
455 if (flagMarker_getCode (current) == FLG_NAMECHECKS
456 && !nameChecksOff && isNameChecksFlag)
457 {
458 ynm set = flagMarker_getSet (current);
459
460 if (ynm_isOff (set))
461 {
462 return YES;
463 }
464 else
465 {
466 if (ynm_isOn (set))
467 {
468 nameChecksOff = TRUE;
469 flagSet = NO;
470 }
471 else
472 {
473 nameChecksOff = TRUE;
474 flagSet = MAYBE;
475 }
476
477 if (ignoreOff && flagOff)
478 {
479 return flagSet;
480 }
481 }
482 }
483 }
484 else
485 {
486 llassert (flagMarker_isSuppress (current));
487 }
488 }
489
490 return flagSet;
491}
492
493bool
494flagMarkerList_inIgnore (flagMarkerList s, fileloc loc)
495{
496 int i;
497
498 if (fileloc_isLib (loc))
499 {
500 return FALSE;
501 }
502
503 i = flagMarkerList_lastBeforeLoc (s, loc);
504
505 /*
506 ** Go backwards through the remaining flagMarkers in this file.
507 */
508
509 for (; i >= 0; i--)
510 {
511 flagMarker current = s->elements[i];
512
513 if (!flagMarker_sameFile (current, loc))
514 {
515 break;
516 }
517
518 if (flagMarker_isIgnoreOff (current))
519 {
520 return FALSE;;
521 }
522 else if (flagMarker_isIgnoreOn (current))
523 {
524 return TRUE;
525 }
526 else if (flagMarker_isIgnoreCount (current))
527 {
528 flagMarkerList_splice (s, i,
529 flagMarker_createSuppress (SKIP_FLAG, loc));
530 return TRUE;
531 }
532 else
533 {
534 llassert (flagMarker_isLocalSet (current)
535 || flagMarker_isSuppress (current));
536 }
537 }
538
539 return FALSE;
540}
541
This page took 0.118348 seconds and 5 git commands to generate.