]> andersk Git - splint.git/blob - src/messageLog.c
4bc12d56b5eb81b870efe8d153d60919fbd513ee
[splint.git] / src / messageLog.c
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 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 splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
23 */
24 /*
25 ** messageLog.c (from slist_template.c)
26 */
27
28 # include "splintMacros.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 # ifdef S_SPLINT_S
55 static /*@unused@*/ cstring msgentry_unparse (msgentry msg) /*@*/
56 {
57   return message ("%q:%s", fileloc_unparse (msg->loc), msg->msg);
58 }
59 # endif
60
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           DPRINTF (("Messages equivalent: %s / %s",
163                     msgentry_unparse (msg),
164                     msgentry_unparse (s->elements[ind+1])));
165           msgentry_free (msg);
166           return FALSE;
167         }
168     }
169
170   if (s->nspace <= 0) {
171     messageLog_grow (s);
172   }
173
174   for (i = s->nelements; i > ind + 1; i--)
175     {
176       s->elements[i] = s->elements[i-1];
177     }
178   
179   s->elements[ind + 1] = msg;
180   s->nspace--;
181   s->nelements++;
182
183   return TRUE;
184 }
185
186 /*@only@*/ cstring
187 messageLog_unparse (messageLog s)
188 {
189    int i;
190    cstring st = cstring_makeLiteral ("[");
191
192    if (messageLog_isDefined (s))
193      {
194        for (i = 0; i < s->nelements; i++)
195          {
196            if (i == 0)
197              {
198                st = message ("%q %q", st, fileloc_unparseDirect (s->elements[i]->loc));
199              }
200            else
201              st = message ("%q, %q", st, fileloc_unparseDirect (s->elements[i]->loc));
202          }
203      }
204
205    st = message ("%q ]", st);
206    return st;
207 }
208
209 void
210 messageLog_free (messageLog s)
211 {
212   if (s != NULL)
213     {
214       int i;
215
216       for (i = 0; i < s->nelements; i++)
217         {
218           msgentry_free (s->elements[i]);
219         }
220       
221       sfree (s->elements); 
222       sfree (s);
223     }
224 }
This page took 0.07878 seconds and 3 git commands to generate.