]> andersk Git - splint.git/blame - src/source.c
commitng to fix cvs archive. Code works with gcc272 but not 295. Currently passed...
[splint.git] / src / source.c
CommitLineData
885824d3 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** 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
47# include "lclintMacros.nf"
48# include "llbasic.h"
49# include "osd.h"
50# include "portab.h"
51
52extern bool
53tsource_close (tsource *s)
54{
55 if (s->file != NULL)
56 {
57 check (fclose (s->file) == 0);
58 s->file = NULL;
59 return TRUE;
60 }
61
62 return FALSE;
63}
64
65extern void
66tsource_free (/*@null@*/ /*@only@*/ tsource *s)
67{
68 if (s != NULL)
69 {
70 sfree (s->name);
71 sfree (s->stringSource);
72 sfree (s);
73 }
74}
75
76extern /*@only@*/ tsource *
77 tsource_create (char *name, char *suffix, bool echo)
78{
79 char *ps;
80 tsource *s = (tsource *) dmalloc (sizeof (*s));
81
82 s->name = (char *) dmalloc (strlen (name) + strlen (suffix) + 1);
83 s->file = 0;
84 strcpy (s->name, name);
85
86 ps = strrchr (s->name, CONNECTCHAR);
87
88 if (ps == (char *) 0)
89 {
90 ps = s->name;
91 }
92
93 if (strchr (ps, '.') == NULL)
94 {
95 strcat (s->name, suffix);
96 }
97
98
99
100 s->lineNo = 0;
101 s->echo = echo;
102 s->fromString = FALSE;
103 s->stringSource = NULL;
104 s->stringSourceTail = NULL;
105
106
107 return s;
108}
109
110extern /*@only@*/ tsource *
111tsource_fromString (char *name, char *str)
112{
113 tsource *s = (tsource *) dmalloc (sizeof (*s));
114
115 s->name = mstring_copy (name);
116 s->stringSource = mstring_copy (str);
117 s->stringSourceTail = s->stringSource;
118 s->file = 0;
119 s->echo = FALSE;
120 s->fromString = TRUE;
121 s->lineNo = 0;
122
123 return s;
124}
125
126extern /*@dependent@*/ /*@null@*/
127char *tsource_nextLine (tsource *s)
128{
129 char *currentLine;
130 int len;
131
132 if (s->fromString)
133 {
134 if (s->stringSourceTail == NULL || (strlen (s->stringSourceTail) == 0))
135 {
136 currentLine = 0;
137 }
138 else
139 {
140 char *c = strchr (s->stringSourceTail, '\n');
141
142
143 /* in case line is terminated not by newline */
144 if (c == 0)
145 {
146 c = strchr (s->stringSourceTail, '\0');
147 }
148
149 len = c - s->stringSourceTail + 1;
150
151 if (len > STUBMAXRECORDSIZE - 2)
152 {
153 len = (STUBMAXRECORDSIZE - 2);
154 }
155
156 currentLine = &(s->buffer)[0];
157 strncpy (currentLine, s->stringSourceTail, size_fromInt (len));
158 currentLine[len] = '\0';
159 s->stringSourceTail += len;
160 }
161
162 }
163 else
164 {
165 llassert (s->file != NULL);
166 currentLine = fgets (&(s->buffer)[0], STUBMAXRECORDSIZE, s->file);
167 }
168 if (currentLine == 0)
169 {
170 strcpy (s->buffer, "*** End of File ***");
171 }
172 else
173 {
174 s->lineNo++;
175 len = strlen (currentLine) - 1;
176 if (s->buffer[len] == '\n')
177 {
178 s->buffer[len] = '\0';
179 }
180 else
181 {
182 if (len >= STUBMAXRECORDSIZE - 2)
183 {
184 lldiagmsg (message ("Input line too long: %s",
185 cstring_fromChars (currentLine)));
186 }
187 }
188 }
189 /* if (s->echo) slo_echoLine (currentLine); only needed in LCL */
190 return currentLine;
191}
192
193extern bool
194tsource_open (tsource *s)
195{
196 if (s->fromString)
197 {
198 /* not an error: tail is dependent */
199 s->stringSourceTail = s->stringSource;
200 return TRUE;
201 }
202
203 DPRINTF (("Open: %s", s->name));
204 s->file = fopen (s->name, "r");
205 return (s->file != 0 || s->fromString);
206}
207
208/*
209** requires
210** path != NULL \and
211** s != NULL \and
212** *s.name == filename (*s.name) || filetype (*s.name)
213** *s.name consists of a file name and type only ("<filename>.<type>)
214** No path name is included
215**
216** ensures
217** if filefound (*path, *s) then
218** result = true \and *s.name = filespec_where_file_found (*path, *s)
219** else
220** result = false
221*/
222
223extern bool tsource_getPath (char *path, tsource *s)
224{
225 char *returnPath;
226 filestatus status; /* return status of osd_getEnvPath.*/
227 bool rVal; /* return value of this procedure. */
228
229 /* Check if requires met. */
230 if (path == NULL || s == NULL || s->name == NULL)
231 {
232 llbugexitlit ("tsource_getPath: invalid parameter");
233 }
234
235 status = osd_getPath (path, s->name, &returnPath);
236
237 if (status == OSD_FILEFOUND)
238 { /* Should be majority of cases. */
239 rVal = TRUE;
240
241 sfree (s->name);
242 s->name = returnPath;
243 }
244 else if (status == OSD_FILENOTFOUND)
245 {
246 rVal = FALSE;
247 }
248 else if (status == OSD_PATHTOOLONG)
249 {
250 rVal = FALSE;
251 /* Directory and filename are too long. Report error. */
252 llbuglit ("soure_getPath: Filename plus directory from search path too long");
253 }
254 else
255 {
256 rVal = FALSE;
257 llbuglit ("tsource_getPath: invalid return status");
258 }
259 return rVal;
260}
261
262# ifndef NOLCL
263char *specFullName (char *specfile, /*@out@*/ char **inpath)
264{
265 /* extract the path and the specname associated with the given file */
266 char *specname = (char *) dmalloc (sizeof (*specname)
267 * (strlen (specfile) + 9));
268 char *ospecname = specname;
269 char *path = (char *) dmalloc (sizeof (*path) * (strlen (specfile)));
270 size_t size;
271 long int i, j;
272
273 /* initialized path to empty string or may have accidental garbage */
274 *path = '\0';
275
276 /*@-mayaliasunique@*/
277 strcpy (specname, specfile);
278 /*@=mayaliasunique@*/
279
280 /* trim off pathnames in specfile */
281 size = strlen (specname);
282
283 for (i = size_toInt (size) - 1; i >= 0; i--)
284 {
285 if (specname[i] == CONNECTCHAR)
286 {
287 /* strcpy (specname, (char *)specname+i+1); */
288 for (j = 0; j <= i; j++) /* include '/' */
289 {
290 path[j] = specname[j];
291 }
292
293 path[i + 1] = '\0';
294 specname += i + 1;
295 break;
296 }
297 }
298
299 /*
300 ** also remove .lcl file extension, assume it's the last extension
301 ** of the file name
302 */
303
304 size = strlen (specname);
305
306 for (i = size_toInt (size) - 1; i >= 0; i--)
307 {
308 if (specname[i] == '.')
309 {
310 specname[i] = '\0';
311 break;
312 }
313 }
314
315 *inpath = path;
316
317 /*
318 ** If specname no longer points to the original char,
319 ** we need to allocate a new pointer and copy the string.
320 */
321
322 if (specname != ospecname) {
323 char *rspecname = (char *) dmalloc (sizeof (*rspecname) * (strlen (specname) + 1));
324 strcpy (rspecname, specname); /* evs 2000-05-16: Bug: was ospecname! */
325 sfree (ospecname);
326 return rspecname;
327 }
328
329 return specname;
330}
331# endif
332
This page took 0.436721 seconds and 5 git commands to generate.