]> andersk Git - splint.git/blame - src/inputStream.c
Fixed inclusion problems with osd.h.
[splint.git] / src / inputStream.c
CommitLineData
28bf4b0b 1/*
11db3170 2** Splint - annotation-assisted static program checker
c59f5181 3** Copyright (C) 1994-2003 University of Virginia,
28bf4b0b 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
28bf4b0b 23*/
24/*
25** source.c
26**
27** Interface to source file abstraction
28**
29** NOTE: This module is almost identical to the one for LCL. The
30** only difference is that a couple of source lines have been
31** commented out.
32**
33** This module has too many dependencies to be in the common
34** source area. Any of the solutions that would allow this
35** module to be common had its own set of compromises. It
36** seemed best and most straightforward to just keep separte
37** copies for LSL and LCL. We should examine this again if we
38** ever reorganize the module structure.
39**
40** AUTHORS:
41**
42** Steve Garland,
43** Massachusetts Institute of Technology
44** Joe Wild, Technical Languages and Environments, DECspec project
45*/
46
1b8ae690 47# include "splintMacros.nf"
b73d1009 48# include "basic.h"
28bf4b0b 49# include "osd.h"
28bf4b0b 50
51extern bool
52inputStream_close (inputStream s)
53{
54 llassert (inputStream_isDefined (s));
55
56 if (s->file != NULL)
57 {
dfd82dce 58 check (fileTable_closeFile (context_fileTable (), s->file));
28bf4b0b 59 s->file = NULL;
60 return TRUE;
61 }
62
63 return FALSE;
64}
65
66extern void
67inputStream_free (/*@null@*/ /*@only@*/ inputStream s)
68{
69 if (inputStream_isDefined (s))
70 {
71 cstring_free (s->name);
72 cstring_free (s->stringSource);
73 sfree (s);
74 }
75}
76
77extern /*@only@*/ inputStream
6fcd0b1e 78inputStream_create (cstring name, cstring suffix, bool echo)
28bf4b0b 79{
80 char *ps;
81 inputStream s = (inputStream) dmalloc (sizeof (*s));
6fcd0b1e 82
28bf4b0b 83 s->name = name;
84 s->file = NULL;
85
86 /*@access cstring@*/
87 llassert (cstring_isDefined (s->name));
28bf4b0b 88 ps = strrchr (s->name, CONNECTCHAR);
89
90 if (ps == NULL)
91 {
92 ps = s->name;
93 }
94 /*@noaccess cstring@*/
95
96 if (strchr (ps, '.') == NULL)
97 {
98 s->name = cstring_concatFree1 (s->name, suffix);
99 }
100
101 s->name = fileLib_cleanName (s->name);
102
103 s->lineNo = 0;
104 s->charNo = 0;
105 s->curLine = NULL;
106 s->echo = echo;
107 s->fromString = FALSE;
108 s->stringSource = NULL;
109 s->stringSourceTail = NULL;
6fcd0b1e 110 s->buffer[0] = '\0';
111
b73d1009 112 return s;
28bf4b0b 113}
114
115extern /*@only@*/ inputStream
116inputStream_fromString (cstring name, cstring str)
117{
118 inputStream s = (inputStream) dmalloc (sizeof (*s));
119
120 s->name = cstring_copy (name);
121 s->stringSource = cstring_copy (str);
122 s->stringSourceTail = s->stringSource;
123 s->file = 0;
124 s->echo = FALSE;
125 s->fromString = TRUE;
126 s->lineNo = 0;
127 s->charNo = 0;
128 s->curLine = NULL;
3120b462 129 s->buffer[0] = '\0';
28bf4b0b 130
131 return s;
132}
133
134extern int inputStream_nextChar (inputStream s)
135{
136 int res;
137
138 llassert (inputStream_isDefined (s));
139 res = inputStream_peekChar (s);
140
141 if (res != EOF)
142 {
143 if (res == (int) '\n')
144 {
145 s->curLine = NULL;
146 s->charNo = 0;
147 incLine ();
148 }
149 else
150 {
151 s->charNo++;
152 incColumn ();
153 }
154 }
155
156 DPRINTF (("Next char: %c [%d]", (char) res, res));
157 return res;
158}
159
160extern int inputStream_peekNChar (inputStream s, int n)
161 /* Doesn't work across lines! */
162{
abd7f895 163 llassert (inputStream_isDefined (s));
28bf4b0b 164 llassert (s->curLine != NULL);
165 llassert (s->charNo + n < strlen (s->curLine));
166 return ((int) s->curLine [s->charNo + n]);
167}
168
169extern int inputStream_peekChar (inputStream s)
170{
abd7f895 171 llassert (inputStream_isDefined (s));
172
28bf4b0b 173 if (s->curLine == NULL)
174 {
175 char *cur;
176 s->curLine = NULL;
177 cur = inputStream_nextLine (s);
178 s->curLine = cur; /* split this to avoid possible undefined behavior */
179 s->charNo = 0;
180 }
181
182 if (s->curLine == NULL)
183 {
184 return EOF;
185 }
186
187 llassert (s->charNo <= strlen (s->curLine));
188
189 if (s->curLine[s->charNo] == '\0')
190 {
191 return (int) '\n';
192 }
193
194 return ((int) s->curLine [s->charNo]);
195}
196
197extern /*@dependent@*/ /*@null@*/
198char *inputStream_nextLine (inputStream s)
199{
200 char *currentLine;
e5081f8c 201 size_t len;
28bf4b0b 202
abd7f895 203 llassert (inputStream_isDefined (s));
28bf4b0b 204 llassert (s->curLine == NULL);
205 s->charNo = 0;
206
207 if (s->fromString)
208 {
209 if (cstring_isEmpty (s->stringSourceTail))
210 {
211 currentLine = 0;
212 }
213 else
214 {
215 /*@access cstring@*/
216 char *c = strchr (s->stringSourceTail, '\n');
217
218 /* in case line is terminated not by newline */
219 if (c == 0)
220 {
221 c = strchr (s->stringSourceTail, '\0');
222 }
223
e5081f8c 224 len = size_fromInt (c - s->stringSourceTail + 1);
28bf4b0b 225
e5081f8c 226 if (len > size_fromInt (STUBMAXRECORDSIZE - 2))
28bf4b0b 227 {
e5081f8c 228 len = size_fromInt (STUBMAXRECORDSIZE - 2);
28bf4b0b 229 }
230
231 currentLine = &(s->buffer)[0];
e5081f8c 232 strncpy (currentLine, s->stringSourceTail, len);
28bf4b0b 233 currentLine[len] = '\0';
234 s->stringSourceTail += len;
235 /*@noaccess cstring@*/
236 }
237
238 }
239 else
240 {
241 llassert (s->file != NULL);
242 currentLine = fgets (&(s->buffer)[0], STUBMAXRECORDSIZE, s->file);
243 }
244 if (currentLine == 0)
245 {
246 strcpy (s->buffer, "*** End of File ***");
247 }
248 else
249 {
250 s->lineNo++;
251 len = strlen (currentLine) - 1;
252 if (s->buffer[len] == '\n')
253 {
254 s->buffer[len] = '\0';
255 }
256 else
257 {
e5081f8c 258 if (len >= size_fromInt (STUBMAXRECORDSIZE - 2))
28bf4b0b 259 {
260 lldiagmsg (message ("Input line too long: %s",
261 cstring_fromChars (currentLine)));
262 }
263 }
264 }
265
266 /* if (s->echo) slo_echoLine (currentLine); only needed in LCL */
267 return currentLine;
268}
269
270extern bool
271inputStream_open (inputStream s)
272{
abd7f895 273 llassert (inputStream_isDefined (s));
28bf4b0b 274 if (s->fromString)
275 {
276 /* not an error: tail is dependent */
277 s->stringSourceTail = s->stringSource;
278 return TRUE;
279 }
280
d5047b91 281 DPRINTF (("Opening: %s", s->name));
282 s->file = fileTable_openReadFile (context_fileTable (), s->name);
28bf4b0b 283 return (s->file != 0 || s->fromString);
284}
285
286/*
287** requires
288** path != NULL \and
289** s != NULL \and
290** *s.name == filename (*s.name) || filetype (*s.name)
291** *s.name consists of a file name and type only ("<filename>.<type>)
292** No path name is included
293**
294** ensures
295** if filefound (*path, *s) then
296** result = true \and *s.name = filespec_where_file_found (*path, *s)
297** else
298** result = false
299*/
300
301extern bool inputStream_getPath (cstring path, inputStream s)
302{
303 cstring returnPath;
304 filestatus status; /* return status of osd_getEnvPath.*/
305 bool rVal; /* return value of this procedure. */
306
307 llassert (cstring_isDefined (path));
308 llassert (inputStream_isDefined (s));
309 llassert (cstring_isDefined (s->name));
310
311 status = osd_getPath (path, s->name, &returnPath);
312
313 if (status == OSD_FILEFOUND)
314 { /* Should be majority of cases. */
315 rVal = TRUE;
316
317 cstring_free (s->name);
318 s->name = fileLib_cleanName (returnPath);
319 }
320 else if (status == OSD_FILENOTFOUND)
321 {
322 rVal = FALSE;
323 }
324 else if (status == OSD_PATHTOOLONG)
325 {
326 rVal = FALSE;
327 /* Directory and filename are too long. Report error. */
328 llbuglit ("soure_getPath: Filename plus directory from search path too long");
329 }
330 else
331 {
332 rVal = FALSE;
333 llbuglit ("inputStream_getPath: invalid return status");
334 }
335
336 return rVal;
337}
338
15b3d2b2 339/*:open:*/ FILE *inputStream_getFile (inputStream s)
28bf4b0b 340{
341 llassert (inputStream_isDefined (s));
abd7f895 342 llassert (s->file != NULL);
28bf4b0b 343 return s->file;
344}
345
346cstring inputStream_fileName (inputStream s)
347{
348 llassert (inputStream_isDefined (s));
349 return s->name;
350}
351
352bool inputStream_isOpen (inputStream s)
353{
354 return (inputStream_isDefined (s) && (s->file != 0 || s->fromString));
355}
356
357int inputStream_thisLineNumber (inputStream s)
358{
359 llassert (inputStream_isDefined (s));
360 return s->lineNo;
361}
362
363
364
365
This page took 0.144578 seconds and 5 git commands to generate.