1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 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 ** reader.c
26 */
27
28 # include "splintMacros.nf"
29 # include "basic.h"
30
reader_getInt(char ** s)31 int reader_getInt (char **s)
32 {
33 bool gotOne = FALSE;
34 int i = 0;
35
36 while (**s == ' ')
37 {
38 (*s)++;
39 }
40
41 if (**s == '-')
42 {
43 (*s)++;
44 if (**s < '0' || **s > '9')
45 {
46 llbug (message ("getInt: bad int: %s", cstring_fromChars (*s)));
47 }
48 else
49 {
50 i = -1 * (int) (**s - '0');
51 gotOne = TRUE;
52 }
53
54 (*s)++;
55 }
56
57 while (**s >= '0' && **s <= '9')
58 {
59 i *= 10;
60 i += (int) (**s - '0');
61 (*s)++;
62 gotOne = TRUE;
63 }
64
65 if (!gotOne)
66 {
67 llbug (message ("No int to read: %s", cstring_fromChars (*s)));
68 }
69
70 while (**s == '\n' || **s == ' ' || **s == '\t')
71 {
72 (*s)++;
73 }
74
75 return i;
76 }
77
78 char
reader_loadChar(char ** s)79 reader_loadChar (char **s)
80 {
81 char ret;
82
83 while (**s == ' ')
84 {
85 (*s)++;
86 }
87
88 ret = **s;
89 (*s)++;
90 return ret;
91 }
92
93 /*
94 ** not sure if this works...
95 */
96
97 double
reader_getDouble(char ** s)98 reader_getDouble (char **s)
99 {
100 char *end = mstring_createEmpty ();
101 double ret;
102
103 ret = strtod (*s, &end);
104
105 *s = end;
106 return ret;
107 }
108
109 /*
110 ** read to ' ', '\t'. '\n', '#', ',' or '\0'
111 */
112
113 char *
reader_getWord(char ** s)114 reader_getWord (char **s)
115 {
116 char *res;
117 char *t = *s;
118 char c;
119
120 while ((c = **s) != '\0' && (c != ' ') && (c != ',')
121 && (c != '\n') && (c != '\t') && (c != '#'))
122 {
123 (*s)++;
124 }
125
126 if (*s == t)
127 {
128 return NULL;
129 }
130
131 **s = '\0';
132 res = mstring_copy (t);
133 **s = c;
134 return res;
135 }
136
137 /*
138 ** read up to x
139 */
140
141 cstring
reader_readUntil(char ** s,char x)142 reader_readUntil (char **s, char x)
143 {
144 cstring res;
145 char *t = *s;
146 char c;
147
148 while ((c = **s) != '\0' && (c != x))
149 {
150 (*s)++;
151 }
152
153 llassert (**s != '\0');
154 llassert (*s != t);
155
156 **s = '\0';
157 res = cstring_fromChars (mstring_copy (t));
158 **s = c;
159 return res;
160 }
161
162 cstring
reader_readUntilOne(char ** s,char * x)163 reader_readUntilOne (char **s, char *x)
164 {
165 cstring res;
166 char *t = *s;
167 char c;
168
169 while ((c = **s) != '\0' && (!mstring_containsChar (x, c)))
170 {
171 (*s)++;
172 }
173
174 llassert (**s != '\0');
175 llassert (*s != t);
176
177 **s = '\0';
178 res = cstring_fromChars (mstring_copy (t));
179 **s = c;
180 return res;
181 }
182
183 bool
reader_optCheckChar(char ** s,char c)184 reader_optCheckChar (char **s, char c)
185 {
186 if (**s == c)
187 {
188 (*s)++;
189 return TRUE;
190 }
191 else
192 {
193 return FALSE;
194 }
195 }
196
197 void
reader_doCheckChar(char ** s,char c,char * file,int line)198 reader_doCheckChar (char **s, char c, char *file, int line)
199 {
200 /*@unchecked@*/ static int nbadchars = 0;
201
202 if (**s == c)
203 {
204 (*s)++;
205 }
206 else
207 {
208 nbadchars++;
209
210 if (nbadchars > 5)
211 {
212 llfatalbug (cstring_makeLiteral
213 ("checkChar: Too many errors. Check library is up to date."));
214 }
215 else
216 {
217 llbug (message ("checkChar: %q: Bad char, expecting %h: %s",
218 fileloc_unparseRaw (cstring_fromChars (file), line),
219 c,
220 cstring_fromChars (*s)));
221 }
222 }
223 }
224
reader_checkUngetc(int c,FILE * f)225 void reader_checkUngetc (int c, FILE *f)
226 {
227 int res;
228
229 llassert (c != EOF);
230 res = ungetc (c, f);
231 llassert (res == c);
232 }
233
reader_readLine(FILE * f,char * s,int max)234 char *reader_readLine (FILE *f, char *s, int max)
235 {
236 char *res = fgets (s, MAX_DUMP_LINE_LENGTH, f);
237
238 if (res != NULL)
239 {
240 if (strlen (res) == size_fromInt (MAX_DUMP_LINE_LENGTH - 1))
241 {
242 llfatalerrorLoc (message ("Maximum line length exceeded (%d): %s", max,
243 cstring_fromChars (s)));
244 }
245
246 incLine ();
247 }
248
249 return res;
250 }
251