]>
Commit | Line | Data |
---|---|---|
616915dd | 1 | /* |
2 | ** LCLint - annotation-assisted static program checker | |
28bf4b0b | 3 | ** Copyright (C) 1994-2001 University of Virginia, |
616915dd | 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 | ** messageLog.c (from slist_template.c) | |
26 | */ | |
27 | ||
28 | # include "lclintMacros.nf" | |
29 | # include "basic.h" | |
30 | ||
31 | /*@only@*/ messageLog | |
32 | messageLog_new () | |
33 | { | |
34 | messageLog s = (messageLog) dmalloc (sizeof (*s)); | |
35 | ||
36 | s->nelements = 0; | |
37 | s->nspace = messageLogBASESIZE; | |
38 | s->elements = (msgentry *) dmalloc (sizeof (*s->elements) * messageLogBASESIZE); | |
39 | ||
40 | return (s); | |
41 | } | |
42 | ||
43 | static /*@only@*/ msgentry | |
44 | msgentry_create (fileloc loc, cstring mess) | |
45 | { | |
46 | msgentry msg = (msgentry) dmalloc (sizeof (*msg)); | |
47 | ||
48 | msg->loc = fileloc_copy (loc); | |
49 | msg->msg = cstring_copy (mess); | |
50 | ||
51 | return msg; | |
52 | } | |
53 | ||
28bf4b0b | 54 | static /*@unused@*/ cstring msgentry_unparse (msgentry msg) /*@*/ |
55 | { | |
56 | return message ("%q:%s", fileloc_unparse (msg->loc), msg->msg); | |
57 | } | |
58 | ||
616915dd | 59 | static void msgentry_free (/*@only@*/ msgentry msg) |
60 | { | |
61 | fileloc_free (msg->loc); | |
62 | cstring_free (msg->msg); | |
63 | sfree (msg); | |
64 | } | |
65 | ||
66 | /* | |
67 | ** returns TRUE if m1 < m2 | |
68 | */ | |
69 | ||
70 | static bool | |
71 | msgentry_lessthan (msgentry m1, msgentry m2) | |
72 | { | |
73 | return (fileloc_lessthan (m1->loc, m2->loc) | |
74 | || (fileloc_equal (m1->loc, m2->loc) | |
75 | && (cstring_lessthan (m1->msg, m2->msg)))); | |
76 | } | |
77 | ||
78 | static bool | |
79 | msgentry_equal (msgentry m1, msgentry m2) | |
80 | { | |
81 | return (fileloc_equal (m1->loc, m2->loc) && | |
82 | cstring_equal (m1->msg, m2->msg)); | |
83 | } | |
84 | ||
85 | /* | |
86 | ** returns highest index of element less than msg | |
87 | */ | |
88 | ||
89 | static int | |
90 | messageLog_index (messageLog s, msgentry msg) | |
91 | { | |
92 | int high; | |
93 | int low = 0; | |
94 | ||
95 | llassert (messageLog_isDefined (s)); | |
96 | ||
97 | high = s->nelements - 1; | |
98 | ||
99 | for (low = high; low >= 0; low--) | |
100 | { | |
101 | if (msgentry_lessthan (s->elements[low], msg)) | |
102 | { | |
103 | return low; | |
104 | } | |
105 | } | |
106 | ||
107 | return -1; | |
108 | # if 0 | |
109 | while (low < high) | |
110 | { | |
111 | int mid = (low + high + 1) / 2; | |
112 | ||
113 | if (msgentry_lessthan (s->elements[mid], msg)) /* mid < msg */ | |
114 | { | |
115 | if (high == mid) break; | |
116 | high = mid; | |
117 | } | |
118 | else | |
119 | { | |
120 | if (low == mid) break; | |
121 | low = mid; | |
122 | } | |
123 | } | |
124 | ||
125 | return low - 1; | |
126 | # endif | |
127 | } | |
128 | ||
129 | static void | |
130 | messageLog_grow (/*@notnull@*/ messageLog s) | |
131 | { | |
132 | int i; | |
133 | msgentry *newelements; | |
134 | ||
135 | s->nspace += messageLogBASESIZE; | |
136 | newelements = (msgentry *) dmalloc (sizeof (*newelements) * (s->nelements + s->nspace)); | |
137 | ||
138 | for (i = 0; i < s->nelements; i++) | |
139 | { | |
140 | newelements[i] = s->elements[i]; | |
141 | } | |
142 | ||
143 | sfree (s->elements); | |
144 | s->elements = newelements; | |
145 | } | |
146 | ||
147 | bool messageLog_add (messageLog s, fileloc fl, cstring mess) | |
148 | { | |
149 | msgentry msg = msgentry_create (fl, mess); | |
150 | int ind, i; | |
151 | ||
152 | llassert (messageLog_isDefined (s)); | |
153 | ||
154 | ind = messageLog_index (s, msg); | |
155 | ||
156 | if (ind + 1 < s->nelements) | |
157 | { | |
158 | if (msgentry_equal (msg, s->elements[ind + 1])) | |
159 | { | |
28bf4b0b | 160 | DPRINTF (("Messages equivalent: %s / %s", |
161 | msgentry_unparse (msg), | |
162 | msgentry_unparse (s->elements[ind+1]))); | |
616915dd | 163 | msgentry_free (msg); |
164 | return FALSE; | |
165 | } | |
166 | } | |
167 | ||
168 | if (s->nspace <= 0) { | |
169 | messageLog_grow (s); | |
170 | } | |
171 | ||
172 | for (i = s->nelements; i > ind + 1; i--) | |
173 | { | |
174 | s->elements[i] = s->elements[i-1]; | |
175 | } | |
176 | ||
177 | s->elements[ind + 1] = msg; | |
178 | s->nspace--; | |
179 | s->nelements++; | |
180 | ||
181 | return TRUE; | |
182 | } | |
183 | ||
184 | /*@only@*/ cstring | |
185 | messageLog_unparse (messageLog s) | |
186 | { | |
187 | int i; | |
188 | cstring st = cstring_makeLiteral ("["); | |
189 | ||
190 | if (messageLog_isDefined (s)) | |
191 | { | |
192 | for (i = 0; i < s->nelements; i++) | |
193 | { | |
194 | if (i == 0) | |
195 | { | |
196 | st = message ("%q %q", st, fileloc_unparseDirect (s->elements[i]->loc)); | |
197 | } | |
198 | else | |
199 | st = message ("%q, %q", st, fileloc_unparseDirect (s->elements[i]->loc)); | |
200 | } | |
201 | } | |
202 | ||
203 | st = message ("%q ]", st); | |
204 | return st; | |
205 | } | |
206 | ||
207 | void | |
208 | messageLog_free (messageLog s) | |
209 | { | |
210 | if (s != NULL) | |
211 | { | |
212 | int i; | |
213 | ||
214 | for (i = 0; i < s->nelements; i++) | |
215 | { | |
216 | msgentry_free (s->elements[i]); | |
217 | } | |
218 | ||
219 | sfree (s->elements); | |
220 | sfree (s); | |
221 | } | |
222 | } |