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