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

cppmain.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 ** cppmain.c
00026 */
00027 /* CPP main program, using CPP Library.
00028    Copyright (C) 1995 Free Software Foundation, Inc.
00029    Written by Per Bothner, 1994-95.
00030 
00031 This program is free software; you can redistribute it and/or modify it
00032 under the terms of the GNU General Public License as published by the
00033 Free Software Foundation; either version 2, or (at your option) any
00034 later version.
00035 
00036 This program is distributed in the hope that it will be useful,
00037 but WITHOUT ANY WARRANTY; without even the implied warranty of
00038 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00039 GNU General Public License for more details.
00040 
00041 You should have received a copy of the GNU General Public License
00042 along with this program; if not, write to the Free Software
00043 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00044 
00045  In other words, you are welcome to use, share and improve this program.
00046  You are forbidden to forbid anyone else to use, share and improve
00047  what you give them.   Help stamp out software-hoarding!  */
00048 
00049 # include "lclintMacros.nf"
00050 # include "llbasic.h"
00051 # include "cpp.h"
00052 # include "cpplib.h"
00053 # include "cpphash.h"
00054 # include "cpperror.h"
00055 # include "llmain.h"
00056 
00057 # include <stdio.h>
00058 
00059 # ifdef WIN32
00060 /*@-ansireserved@*/
00061 extern /*@external@*/ /*@observer@*/ char *getenv (const char *);
00062 /*@=ansireserved@*/
00063 # endif
00064 
00065 /* char *progname; */
00066 
00067 cppReader g_cppState;
00068 
00069 #ifdef abort
00070 /* More 'friendly' abort that prints the line and file.
00071    config.h can #define abort fancy_abort if you like that sort of thing.  */
00072 
00073 void
00074 fancy_abort ()
00075 {
00076   fatal ("Internal gcc abort.");
00077 }
00078 #endif
00079 
00080 void cppReader_initMod ()
00081 {
00082   struct cppOptions *opts = (struct cppOptions *) dmalloc (sizeof (*opts));
00083 
00084   cppReader_init (&g_cppState);
00085   llassert (g_cppState.opts == NULL);
00086   g_cppState.opts = opts;
00087 
00088   cppOptions_init (opts);
00089   /*@-compdef@*/ /* g_cppState is not yet innitialized */
00090 } /*@=compdef@*/
00091 
00092 void cppReader_initialize ()
00093 {
00094   cppReader_initializeReader (&g_cppState);
00095 }
00096 
00097 int cppProcess (/*@dependent@*/ cstring infile, 
00098                 /*@dependent@*/ cstring outfile) 
00099 {
00100   FILE *ofile;
00101   struct cppOptions *opts = CPPOPTIONS (&g_cppState);
00102   
00103   opts->out_fname = outfile;
00104   opts->in_fname = infile;
00105   opts->out_fname = outfile;
00106   
00107   if (cppFatalErrors (&g_cppState))
00108     {
00109       llexit (LLFAILURE);
00110     }
00111   
00112   g_cppState.show_column = TRUE;
00113 
00114   if (cppReader_startProcess (&g_cppState, opts->in_fname) == 0) 
00115     {
00116       llexit (LLFAILURE);
00117     }
00118 
00119   ofile = fopen (cstring_toCharsSafe (outfile), "w");
00120   
00121   if (ofile == NULL) 
00122     {
00123       fileTable_noDelete (context_fileTable (), outfile);
00124       llfatalerror (message ("Cannot create temporary file for "
00125                              "pre-processor output.  Trying to "
00126                              "open: %s.  Use -tmpdir to change "
00127                              "the directory for temporary files.",
00128                              outfile));
00129     }
00130   
00131   for (;;)
00132     {
00133       enum cpp_token kind;
00134       
00135       llassert (g_cppState.token_buffer != NULL);
00136 
00137       if (!opts->no_output)
00138         {
00139           (void) fwrite (g_cppState.token_buffer, (size_t) 1,
00140                          cppReader_getWritten (&g_cppState), ofile);
00141         }
00142       
00143       cppReader_setWritten (&g_cppState, 0);
00144       kind = cppGetToken (&g_cppState);
00145       
00146       if (kind == CPP_EOF)
00147         break;
00148     }
00149 
00150   cppReader_finish (&g_cppState);
00151   check (fclose (ofile) == 0);
00152 
00153   /* Resotre the original definition table. */
00154 
00155   if (!context_getFlag (FLG_SINGLEINCLUDE))
00156     {
00157       cppReader_restoreHashtab ();  
00158     }
00159 
00160   
00161   /* Undefine everything from this file! */
00162 
00163   if (g_cppState.errors != 0) {
00164     return -1;
00165   }
00166 
00167   return 0;
00168 }
00169 
00170 void cppAddIncludeDir (cstring dir) 
00171 {
00172   /* -I option (Add directory to include path) */
00173   struct file_name_list *dirtmp = (struct file_name_list *) dmalloc (sizeof (*dirtmp));
00174 
00175   DPRINTF (("Add include: %s", dir));
00176 
00177   dirtmp->next = 0;             /* New one goes on the end */
00178   dirtmp->control_macro = 0;
00179   dirtmp->c_system_include_path = FALSE;
00180   
00181   /* This copy is necessary...but shouldn't be? */
00182   /*@-onlytrans@*/
00183   dirtmp->fname = cstring_copy (dir);
00184   /*@=onlytrans@*/
00185   
00186   dirtmp->got_name_map = FALSE;
00187   cppReader_addIncludeChain (&g_cppState, dirtmp);
00188 }
00189 
00190 void cppDoDefine (cstring str)
00191 {
00192   cppBuffer *tbuf = g_cppState.buffer;
00193 
00194   g_cppState.buffer = NULL;
00195   cppReader_define (&g_cppState, cstring_toCharsSafe (str));
00196   g_cppState.buffer = tbuf;
00197 }
00198 
00199 void cppDoUndefine (cstring str)
00200 {
00201   int sym_length;
00202   HASHNODE *hp;
00203   char *buf = cstring_toCharsSafe (str);
00204 
00205   sym_length = cppReader_checkMacroName (&g_cppState, buf,
00206                                  cstring_makeLiteralTemp ("macro"));
00207   
00208   while ((hp = cppReader_lookup (buf, sym_length, -1)) != NULL)
00209     {
00210       /*@-exposetrans@*/ /*@-dependenttrans@*/
00211       cppReader_deleteMacro (hp);
00212       /*@=exposetrans@*/ /*@=dependenttrans@*/
00213     }
00214 }
00215 
00216 void cppReader_saveDefinitions ()
00217 {
00218   if (!context_getFlag (FLG_SINGLEINCLUDE))
00219     {
00220       cppReader_saveHashtab ();
00221     }
00222 }

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