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