]> andersk Git - splint.git/blob - src/source.c
commitng to fix cvs archive. Code works with gcc272 but not 295. Currently passed...
[splint.git] / src / source.c
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
52 extern bool
53 tsource_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
65 extern void
66 tsource_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
76 extern /*@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
110 extern /*@only@*/ tsource *
111 tsource_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
126 extern /*@dependent@*/ /*@null@*/ 
127 char *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
193 extern bool
194 tsource_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
223 extern 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
263 char *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.075754 seconds and 5 git commands to generate.