Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

source.c

Go to the documentation of this file.
00001 /*
00002 ** LCLint - annotation-assisted static program checker
00003 ** Copyright (C) 1994-2000 University of Virginia,
00004 **         Massachusetts Institute of Technology
00005 **
00006 ** This program is free software; you can redistribute it and/or modify it
00007 ** under the terms of the GNU General Public License as published by the
00008 ** Free Software Foundation; either version 2 of the License, or (at your
00009 ** option) any later version.
00010 ** 
00011 ** This program is distributed in the hope that it will be useful, but
00012 ** WITHOUT ANY WARRANTY; without even the implied warranty of
00013 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 ** General Public License for more details.
00015 ** 
00016 ** The GNU General Public License is available from http://www.gnu.org/ or
00017 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00018 ** MA 02111-1307, USA.
00019 **
00020 ** For information on lclint: lclint-request@cs.virginia.edu
00021 ** To report a bug: lclint-bug@cs.virginia.edu
00022 ** For more information: http://lclint.cs.virginia.edu
00023 */
00024 /*
00025 ** source.c
00026 **
00027 ** Interface to source file abstraction
00028 **
00029 **      NOTE:       This module is almost identical to the one for LCL.  The
00030 **                  only difference is that a couple of source lines have been
00031 **                  commented out.
00032 **
00033 **                  This module has too many dependencies to be in the common
00034 **                  source area.  Any of the solutions that would allow this
00035 **                  module to be common had its own set of compromises.  It
00036 **                  seemed best and most straightforward to just keep separte
00037 **                  copies for LSL and LCL.  We should examine this again if we
00038 **                  ever reorganize the module structure.
00039 **
00040 **  AUTHORS:
00041 **
00042 **     Steve Garland,
00043 **         Massachusetts Institute of Technology
00044 **     Joe Wild, Technical Languages and Environments, DECspec project
00045 */
00046 
00047 # include "lclintMacros.nf"
00048 # include "llbasic.h"
00049 # include "osd.h"
00050 # include "portab.h"
00051 
00052 extern bool
00053 tsource_close (tsource *s)
00054 {
00055   if (s->file != NULL)
00056     {
00057       check (fclose (s->file) == 0);
00058       s->file = NULL;
00059       return TRUE;
00060     }
00061 
00062   return FALSE;
00063 }
00064 
00065 extern void
00066 tsource_free (/*@null@*/ /*@only@*/ tsource *s)
00067 {
00068   if (s != NULL)
00069     {
00070       sfree (s->name);
00071       sfree (s->stringSource);
00072       sfree (s);
00073     }
00074 }
00075 
00076 extern /*@only@*/ tsource *
00077   tsource_create (char *name, char *suffix, bool echo)
00078 {
00079   char *ps;
00080   tsource *s = (tsource *) dmalloc (sizeof (*s));
00081   
00082   s->name = (char *) dmalloc (strlen (name) + strlen (suffix) + 1);
00083   s->file = 0;
00084   strcpy (s->name, name);
00085 
00086   ps = strrchr (s->name, CONNECTCHAR);
00087 
00088   if (ps == (char *) 0)
00089     {
00090       ps = s->name;
00091     }
00092 
00093   if (strchr (ps, '.') == NULL)
00094     {
00095       strcat (s->name, suffix);
00096     }
00097 
00098   
00099 
00100   s->lineNo = 0;
00101   s->echo = echo;
00102   s->fromString = FALSE;
00103   s->stringSource = NULL;
00104   s->stringSourceTail = NULL;
00105   
00106 
00107   return s;
00108 }
00109 
00110 extern /*@only@*/ tsource *
00111 tsource_fromString (char *name, char *str)
00112 {
00113   tsource *s = (tsource *) dmalloc (sizeof (*s));
00114 
00115   s->name = mstring_copy (name);
00116   s->stringSource = mstring_copy (str);
00117   s->stringSourceTail = s->stringSource;
00118   s->file = 0;
00119   s->echo = FALSE;
00120   s->fromString = TRUE;
00121   s->lineNo = 0;
00122 
00123     return s;
00124 }
00125 
00126 extern /*@dependent@*/ /*@null@*/ 
00127 char *tsource_nextLine (tsource *s)
00128 {
00129   char *currentLine;
00130   int len;
00131 
00132   if (s->fromString)
00133     {
00134       if (s->stringSourceTail == NULL || (strlen (s->stringSourceTail) == 0))
00135         {
00136           currentLine = 0;
00137         }
00138       else
00139         {
00140           char *c = strchr (s->stringSourceTail, '\n');
00141           
00142           
00143           /* in case line is terminated not by newline */ 
00144           if (c == 0)
00145             {
00146               c = strchr (s->stringSourceTail, '\0');
00147             }
00148 
00149           len = c - s->stringSourceTail + 1;
00150 
00151           if (len > STUBMAXRECORDSIZE - 2)
00152             {
00153               len = (STUBMAXRECORDSIZE - 2);
00154             }
00155 
00156           currentLine = &(s->buffer)[0];
00157           strncpy (currentLine, s->stringSourceTail, size_fromInt (len));
00158           currentLine[len] = '\0';
00159           s->stringSourceTail += len;
00160         }
00161       
00162     }
00163   else
00164     {
00165       llassert (s->file != NULL);
00166       currentLine = fgets (&(s->buffer)[0], STUBMAXRECORDSIZE, s->file);
00167     }
00168   if (currentLine == 0)
00169     {
00170       strcpy (s->buffer, "*** End of File ***");
00171     }
00172   else
00173     {
00174       s->lineNo++;
00175       len = strlen (currentLine) - 1;
00176       if (s->buffer[len] == '\n')
00177         {
00178           s->buffer[len] = '\0';
00179         }
00180       else 
00181         {
00182           if (len >= STUBMAXRECORDSIZE - 2)
00183             {
00184               lldiagmsg (message ("Input line too long: %s",
00185                                   cstring_fromChars (currentLine)));
00186             }
00187         }
00188     }
00189   /* if (s->echo) slo_echoLine (currentLine);           only needed in LCL */
00190     return currentLine;
00191 }
00192 
00193 extern bool
00194 tsource_open (tsource *s)
00195 {
00196   if (s->fromString)
00197     {
00198       /* not an error: tail is dependent */
00199       s->stringSourceTail = s->stringSource; 
00200       return TRUE;
00201     }
00202 
00203   DPRINTF (("Open: %s", s->name));
00204   s->file = fopen (s->name, "r");
00205   return (s->file != 0 || s->fromString);
00206 }
00207 
00208 /*
00209 ** requires
00210 **  path != NULL \and
00211 **  s != NULL \and
00212 **  *s.name == filename (*s.name) || filetype (*s.name)
00213 **      *s.name consists of a file name and type only ("<filename>.<type>)
00214 **      No path name is included
00215 **
00216 ** ensures
00217 **  if filefound (*path, *s) then
00218 **      result = true \and *s.name = filespec_where_file_found (*path, *s)
00219 **  else
00220 **      result = false
00221 */
00222 
00223 extern bool tsource_getPath (char *path, tsource *s)
00224 {
00225   char *returnPath;
00226   filestatus status;            /* return status of osd_getEnvPath.*/
00227   bool rVal;                    /* return value of this procedure. */
00228 
00229  /* Check if requires met. */
00230   if (path == NULL || s == NULL || s->name == NULL)
00231     {
00232       llbugexitlit ("tsource_getPath: invalid parameter");
00233     }
00234 
00235   status = osd_getPath (path, s->name, &returnPath);
00236 
00237   if (status == OSD_FILEFOUND)
00238     {                           /* Should be majority of cases. */
00239       rVal = TRUE;
00240       
00241       sfree (s->name);
00242       s->name = returnPath;
00243     }
00244   else if (status == OSD_FILENOTFOUND)
00245     {
00246       rVal = FALSE;
00247     }
00248   else if (status == OSD_PATHTOOLONG)
00249     {
00250       rVal = FALSE;
00251      /* Directory and filename are too long.  Report error. */
00252      llbuglit ("soure_getPath: Filename plus directory from search path too long");
00253  }
00254   else
00255     {
00256       rVal = FALSE;
00257       llbuglit ("tsource_getPath: invalid return status");
00258     }
00259   return rVal;
00260 }
00261 
00262 # ifndef NOLCL
00263 char *specFullName (char *specfile, /*@out@*/ char **inpath)
00264 {
00265   /* extract the path and the specname associated with the given file */
00266   char *specname = (char *) dmalloc (sizeof (*specname) 
00267                                      * (strlen (specfile) + 9));
00268   char *ospecname = specname;
00269   char *path = (char *) dmalloc (sizeof (*path) * (strlen (specfile)));
00270   size_t size;
00271   long int i, j;
00272   
00273   /* initialized path to empty string or may have accidental garbage */
00274   *path = '\0';
00275 
00276   /*@-mayaliasunique@*/ 
00277   strcpy (specname, specfile);
00278   /*@=mayaliasunique@*/ 
00279 
00280   /* trim off pathnames in specfile */
00281   size = strlen (specname);
00282 
00283   for (i = size_toInt (size) - 1; i >= 0; i--)
00284     {
00285       if (specname[i] == CONNECTCHAR)
00286         {
00287           /* strcpy (specname, (char *)specname+i+1); */
00288           for (j = 0; j <= i; j++)      /* include '/'  */
00289             {
00290               path[j] = specname[j];
00291             }
00292 
00293           path[i + 1] = '\0';
00294           specname += i + 1;
00295           break;
00296         }
00297     }
00298 
00299   /* 
00300   ** also remove .lcl file extension, assume it's the last extension
00301   ** of the file name 
00302   */
00303 
00304   size = strlen (specname);
00305 
00306   for (i = size_toInt (size) - 1; i >= 0; i--)
00307     {
00308       if (specname[i] == '.')
00309         {
00310           specname[i] = '\0';
00311           break;
00312         }
00313     }
00314   
00315   *inpath = path;
00316 
00317   /*
00318   ** If specname no longer points to the original char,
00319   ** we need to allocate a new pointer and copy the string.
00320   */
00321 
00322   if (specname != ospecname) {
00323     char *rspecname = (char *) dmalloc (sizeof (*rspecname) * (strlen (specname) + 1));
00324     strcpy (rspecname, specname); /* evs 2000-05-16: Bug: was ospecname! */
00325     sfree (ospecname);
00326     return rspecname;
00327   } 
00328 
00329   return specname;
00330 }
00331 # endif
00332 

Generated at Fri Nov 3 18:57:43 2000 for LCLint by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000