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