00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 # include "lclintMacros.nf"
00035 # include "basic.h"
00036
00037 flagMarkerList
00038 flagMarkerList_new ()
00039 {
00040 flagMarkerList s = (flagMarkerList) dmalloc (sizeof (*s));
00041
00042 s->nelements = 0;
00043 s->nspace = flagMarkerListBASESIZE;
00044 s->elements = (flagMarker *)
00045 dmalloc (sizeof (*s->elements) * flagMarkerListBASESIZE);
00046
00047 return (s);
00048 }
00049
00050 static void
00051 flagMarkerList_grow (flagMarkerList s)
00052 {
00053 int i;
00054 flagMarker *newelements;
00055
00056 s->nspace += flagMarkerListBASESIZE;
00057
00058 newelements = (flagMarker *) dmalloc (sizeof (*newelements)
00059 * (s->nelements + s->nspace));
00060
00061 for (i = 0; i < s->nelements; i++)
00062 {
00063 newelements[i] = s->elements[i];
00064 }
00065
00066 sfree (s->elements);
00067 s->elements = newelements;
00068 }
00069
00070 void flagMarkerList_add (flagMarkerList s, flagMarker fm)
00071 {
00072 int i = s->nelements - 1;
00073
00074
00075 if (i > 0)
00076 {
00077 flagMarker last = s->elements[i];
00078
00079
00080 if (flagMarker_isIgnoreCount (last))
00081 {
00082 if (!flagMarker_isIgnoreOff (fm))
00083 {
00084 if (flagMarker_isLocalSet (fm))
00085 {
00086 llforceerror
00087 (FLG_WARNFLAGS,
00088 cstring_makeLiteral ("Cannot set flag inside ignore "
00089 "count region."),
00090 flagMarker_getLoc (fm));
00091 llgenindentmsg
00092 (cstring_makeLiteral ("Ignore count region starts"),
00093 flagMarker_getLoc (last));
00094
00095 }
00096 else
00097 {
00098 if (flagMarker_isIgnoreOn (fm))
00099 {
00100 llforceerror
00101 (FLG_WARNFLAGS,
00102 cstring_makeLiteral ("Cannot nest ignore regions."),
00103 flagMarker_getLoc (fm));
00104 llgenindentmsg
00105 (cstring_makeLiteral ("Previous ignore region starts"),
00106 flagMarker_getLoc (last));
00107 }
00108 }
00109
00110 flagMarker_free (fm);
00111 return;
00112 }
00113 }
00114 else
00115 {
00116 if (flagMarker_isIgnoreOff (last))
00117 {
00118 flagMarker nlast = s->elements [i - 1];
00119
00120 if (flagMarker_isIgnoreCount (nlast))
00121 {
00122 if (fileloc_sameFile (flagMarker_getLoc (fm),
00123 flagMarker_getLoc (last))
00124 && fileloc_notAfter (flagMarker_getLoc (fm),
00125 flagMarker_getLoc (last)))
00126 {
00127 if (flagMarker_isLocalSet (fm))
00128 {
00129 llforceerror
00130 (FLG_WARNFLAGS,
00131 cstring_makeLiteral ("Cannot set flag inside ignore "
00132 "count region."),
00133 flagMarker_getLoc (fm));
00134 llgenindentmsg
00135 (cstring_makeLiteral ("Ignore count region starts"),
00136 flagMarker_getLoc (nlast));
00137
00138 }
00139 else
00140 {
00141 if (flagMarker_isIgnoreOn (fm))
00142 {
00143 llforceerror
00144 (FLG_WARNFLAGS,
00145 cstring_makeLiteral ("Cannot nest ignore regions."),
00146 flagMarker_getLoc (fm));
00147 llgenindentmsg
00148 (cstring_makeLiteral ("Previous ignore region starts"),
00149 flagMarker_getLoc (nlast));
00150 }
00151 }
00152
00153 flagMarker_free (fm);
00154 return;
00155 }
00156 }
00157 }
00158 }
00159 }
00160
00161
00162
00163
00164
00165
00166 while (i > 0
00167 && !flagMarker_sameFile (s->elements[i],
00168 flagMarker_getLoc (fm)))
00169 {
00170 i--;
00171 }
00172
00173
00174
00175
00176
00177 if (i >= 0 && !fileloc_isHeader (flagMarker_getLoc (fm)))
00178 {
00179
00180
00181
00182
00183
00184 }
00185
00186 if (s->nspace <= 0)
00187 {
00188 flagMarkerList_grow (s);
00189 }
00190
00191 s->nspace--;
00192 s->elements[s->nelements] = fm;
00193 s->nelements++;
00194 }
00195
00196 void flagMarkerList_checkSuppressCounts (flagMarkerList s)
00197 {
00198 int nexpected = 0;
00199 int nsuppressed = 0;
00200 fileloc loc = fileloc_undefined;
00201 bool inCount = FALSE;
00202 int i;
00203
00204
00205 for (i = 0; i < s->nelements; i++)
00206 {
00207 flagMarker current = s->elements[i];
00208
00209 if (flagMarker_isIgnoreCount (current))
00210 {
00211 llassert (!inCount);
00212 inCount = TRUE;
00213 nexpected = flagMarker_getCount (current);
00214 loc = flagMarker_getLoc (current);
00215 nsuppressed = 0;
00216 }
00217 else if (flagMarker_isIgnoreOff (current))
00218 {
00219 if (inCount)
00220 {
00221 inCount = FALSE;
00222 llassert (fileloc_isDefined (loc));
00223
00224 if (nexpected > 0 && nexpected != nsuppressed)
00225 {
00226 llforceerror
00227 (FLG_SUPCOUNTS,
00228 message
00229 ("Line expects to suppress %d error%p, found %d error%p",
00230 nexpected, nsuppressed),
00231 loc);
00232 }
00233 }
00234 }
00235 else if (flagMarker_isSuppress (current))
00236 {
00237 nsuppressed++;
00238 }
00239 else
00240 {
00241 ;
00242 }
00243 }
00244
00245 llassert (!inCount);
00246 }
00247
00248 static void flagMarkerList_splice (flagMarkerList s,
00249 int index,
00250 flagMarker fm)
00251 {
00252 fileloc loc = flagMarker_getLoc (fm);
00253 fileloc beforeloc, afterloc;
00254 int i;
00255
00256 llassert (index >= 0 && (index + 1 < s->nelements));
00257
00258 beforeloc = flagMarker_getLoc (s->elements[index]);
00259 afterloc = flagMarker_getLoc (s->elements[index + 1]);;
00260
00261 llassert (fileloc_sameFile (beforeloc, loc));
00262 llassert (fileloc_sameFile (afterloc, loc));
00263
00264 if (s->nspace <= 0)
00265 {
00266 flagMarkerList_grow (s);
00267 }
00268
00269 for (i = s->nelements; i > index + 1; i--)
00270 {
00271 s->elements[i] = s->elements[i - 1];
00272 }
00273
00274 s->elements[index + 1] = fm;
00275 s->nelements++;
00276 s->nspace--;
00277
00278 }
00279
00280 cstring
00281 flagMarkerList_unparse (flagMarkerList s)
00282 {
00283 int i;
00284 cstring st = cstring_makeLiteral ("[");
00285
00286 for (i = 0; i < s->nelements; i++)
00287 {
00288 if (i == 0)
00289 {
00290 st = message ("%q %q", st, flagMarker_unparse (s->elements[i]));
00291 }
00292 else
00293 st = message ("%q, %q", st, flagMarker_unparse (s->elements[i]));
00294 }
00295
00296 st = message ("%q ]", st);
00297 return st;
00298 }
00299
00300 void
00301 flagMarkerList_free (flagMarkerList s)
00302 {
00303 int i;
00304 for (i = 0; i < s->nelements; i++)
00305 {
00306 flagMarker_free (s->elements[i]);
00307 }
00308
00309 sfree (s->elements);
00310 sfree (s);
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 static int
00331 flagMarkerList_lastBeforeLoc (flagMarkerList s, fileloc loc)
00332 {
00333 int i;
00334
00335 for (i = s->nelements - 1; i >= 0; i--)
00336 {
00337 flagMarker current = s->elements[i];
00338
00339 if (fileloc_sameFile (current->loc, loc)
00340 && (!flagMarker_beforeMarker (current, loc)))
00341 {
00342 return i;
00343 }
00344
00345
00346
00347
00348
00349
00350
00351 }
00352
00353 return -1;
00354 }
00355
00356 ynm
00357 flagMarkerList_suppressError (flagMarkerList s, flagcode code, fileloc loc)
00358 {
00359 int i;
00360 bool ignoreOff = FALSE;
00361 bool nameChecksOff = FALSE;
00362 bool flagOff = FALSE;
00363 ynm flagSet = MAYBE;
00364 bool islib = FALSE;
00365 bool isNameChecksFlag = flagcode_isNameChecksFlag (code);
00366
00367 if (fileloc_isLib (loc))
00368 {
00369 i = s->nelements - 1;
00370 islib = TRUE;
00371 }
00372 else
00373 {
00374 i = flagMarkerList_lastBeforeLoc (s, loc);
00375 }
00376
00377
00378 if (i < 0)
00379 {
00380 return MAYBE;
00381 }
00382
00383
00384
00385
00386
00387 for (; i >= 0; i--)
00388 {
00389 flagMarker current = s->elements[i];
00390
00391
00392 if (!islib && !flagMarker_sameFile (current, loc))
00393 {
00394 break;
00395 }
00396
00397 if (flagMarker_isIgnoreOff (current))
00398 {
00399 ignoreOff = TRUE;
00400 }
00401 else if (flagMarker_isIgnoreOn (current))
00402 {
00403 if (!ignoreOff)
00404 {
00405 return YES;
00406 }
00407 }
00408 else if (flagMarker_isIgnoreCount (current))
00409 {
00410 if (!ignoreOff)
00411 {
00412 flagMarkerList_splice (s, i,
00413 flagMarker_createSuppress (code, loc));
00414 return YES;
00415 }
00416 }
00417 else if (flagMarker_isLocalSet (current))
00418 {
00419
00420 if (!flagOff && flagMarker_getCode (current) == code)
00421 {
00422 ynm set = flagMarker_getSet (current);
00423
00424 if (ynm_isOff (set))
00425 {
00426 return YES;
00427 }
00428 else
00429 {
00430 if (ynm_isOn (set))
00431 {
00432 flagOff = TRUE;
00433 flagSet = NO;
00434 }
00435 else
00436 {
00437 flagOff = TRUE;
00438 flagSet = MAYBE;
00439 }
00440
00441 if (ignoreOff)
00442 {
00443 if (isNameChecksFlag && !nameChecksOff)
00444 {
00445 ;
00446 }
00447 else
00448 {
00449 return flagSet;
00450 }
00451 }
00452 }
00453 }
00454
00455 if (flagMarker_getCode (current) == FLG_NAMECHECKS
00456 && !nameChecksOff && isNameChecksFlag)
00457 {
00458 ynm set = flagMarker_getSet (current);
00459
00460 if (ynm_isOff (set))
00461 {
00462 return YES;
00463 }
00464 else
00465 {
00466 if (ynm_isOn (set))
00467 {
00468 nameChecksOff = TRUE;
00469 flagSet = NO;
00470 }
00471 else
00472 {
00473 nameChecksOff = TRUE;
00474 flagSet = MAYBE;
00475 }
00476
00477 if (ignoreOff && flagOff)
00478 {
00479 return flagSet;
00480 }
00481 }
00482 }
00483 }
00484 else
00485 {
00486 llassert (flagMarker_isSuppress (current));
00487 }
00488 }
00489
00490 return flagSet;
00491 }
00492
00493 bool
00494 flagMarkerList_inIgnore (flagMarkerList s, fileloc loc)
00495 {
00496 int i;
00497
00498 if (fileloc_isLib (loc))
00499 {
00500 return FALSE;
00501 }
00502
00503 i = flagMarkerList_lastBeforeLoc (s, loc);
00504
00505
00506
00507
00508
00509 for (; i >= 0; i--)
00510 {
00511 flagMarker current = s->elements[i];
00512
00513 if (!flagMarker_sameFile (current, loc))
00514 {
00515 break;
00516 }
00517
00518 if (flagMarker_isIgnoreOff (current))
00519 {
00520 return FALSE;;
00521 }
00522 else if (flagMarker_isIgnoreOn (current))
00523 {
00524 return TRUE;
00525 }
00526 else if (flagMarker_isIgnoreCount (current))
00527 {
00528 flagMarkerList_splice (s, i,
00529 flagMarker_createSuppress (SKIP_FLAG, loc));
00530 return TRUE;
00531 }
00532 else
00533 {
00534 llassert (flagMarker_isLocalSet (current)
00535 || flagMarker_isSuppress (current));
00536 }
00537 }
00538
00539 return FALSE;
00540 }
00541