2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 University of Virginia,
4 ** Massachusetts Institute of Technology
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.
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.
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.
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
27 ** Main module for Splint annotation-assisted program checker
33 ** Ensure that WIN32 and _WIN32 are both defined or both undefined.
38 # error "Inconsistent definitions."
42 # error "Inconsistent definitions."
51 # include "splintMacros.nf"
59 # include "scanline.h"
60 # include "lclscanline.h"
61 # include "lclsyntable.h"
62 # include "lcltokentable.h"
63 # include "lslparse.h"
65 # include "syntable.h"
66 # include "tokentable.h"
73 # include "Headers/version.h" /* Visual C++ finds the wrong version.h */
75 # include "cgrammar.h"
80 extern /*@external@*/ int yydebug;
81 static void cleanupFiles (void);
83 ** evans 2002-07-03: renamed from interrupt to avoid conflict with WATCOM compiler keyword
84 ** (Suggested by Adam Clarke)
87 static void llinterrupt (int p_i);
89 static void describeVars (void);
90 static bool specialFlagsHelp (char *p_next);
91 static bool hasShownHerald = FALSE;
92 static char *specFullName (char *p_specfile, /*@out@*/ char **p_inpath)
93 /*@modifies *p_inpath@*/ ;
95 static bool anylcl = FALSE;
96 static clock_t inittime;
98 static fileIdList preprocessFiles (fileIdList, bool)
99 /*@modifies fileSystem@*/ ;
101 static void warnSysFiles(fileIdList p_files) /*@modifies fileSystem@*/;
106 void lslCleanup (void)
107 /*@globals killed g_symtab@*/
108 /*@modifies internalState, g_symtab@*/
111 ** Cleanup all the LCL/LSL.
114 static bool didCleanup = FALSE;
116 llassert (!didCleanup);
121 lsymbol_destroyMod ();
122 LCLSynTableCleanup ();
123 LCLTokenTableCleanup ();
124 LCLScanLineCleanup ();
127 /* clean up LSL parsing */
130 ltokenTableCleanup ();
134 symtable_free (g_symtab);
139 lslProcess (fileIdList lclfiles)
140 /*@globals undef g_currentSpec, undef g_currentSpecName, g_currentloc,
141 undef killed g_symtab; @*/
142 /*@modifies g_currentSpec, g_currentSpecName, g_currentloc, internalState, fileSystem; @*/
145 bool parser_status = FALSE;
146 bool overallStatus = FALSE;
151 context_resetSpecLines ();
153 fileIdList_elements (lclfiles, fid)
155 cstring actualName = cstring_undefined;
156 cstring fname = fileTable_fileName (fid);
158 if (osd_getPath (cstring_fromChars (g_localSpecPath),
159 fname, &actualName) == OSD_FILENOTFOUND)
161 if (mstring_equal (g_localSpecPath, "."))
163 lldiagmsg (message ("Spec file not found: %q", osd_outputPath (fname)));
167 lldiagmsg (message ("Spec file not found: %q (on %s)",
168 osd_outputPath (fname),
169 cstring_fromChars (g_localSpecPath)));
174 inputStream specFile;
176 char *namePtr = actualName;
178 while (*namePtr == '.' && *(namePtr + 1) == CONNECTCHAR)
182 /*@noaccess cstring@*/
184 g_currentSpec = cstring_fromCharsNew (namePtr);
186 specFile = inputStream_create (cstring_copy (g_currentSpec),
187 LCL_EXTENSION, TRUE);
189 llassert (inputStream_isDefined (specFile));
191 g_currentSpecName = specFullName
192 (cstring_toCharsSafe (g_currentSpec),
197 displayScan (message ("reading spec %s", g_currentSpec));
199 /* Open the source file */
201 if (!inputStream_open (specFile))
203 lldiagmsg (message ("Cannot open file: %q",
204 osd_outputPath (inputStream_fileName (specFile))));
205 inputStream_free (specFile);
209 scopeInfo dummy_scope = (scopeInfo) dmalloc (sizeof (*dummy_scope));
210 dummy_scope->kind = SPE_INVALID;
213 LCLScanReset (specFile);
216 ** Minor hacks to allow more than one LCL file to
217 ** be scanned, while keeping initializations
220 symtable_enterScope (g_symtab, dummy_scope);
221 resetImports (cstring_fromChars (g_currentSpecName));
222 context_enterLCLfile ();
223 (void) lclHadNewError ();
225 parser_status = (ylparse () != 0);
226 context_exitLCLfile ();
228 overallStatus = parser_status || lclHadNewError ();
230 if (context_getFlag (FLG_DOLCS))
234 outputLCSFile (path, "%FAILED Output from ",
239 outputLCSFile (path, "%PASSED Output from ",
244 (void) inputStream_close (specFile);
245 inputStream_free (specFile);
247 symtable_exitScope (g_symtab);
250 cstring_free (actualName);
251 } end_fileIdList_elements;
253 /* Can cleanup lsl stuff right away */
257 g_currentSpec = cstring_undefined;
258 g_currentSpecName = NULL;
262 static void handlePassThroughFlag (char *arg)
265 char *quotechar = strchr (curarg, '\"');
268 char *freearg = NULL;
270 while (quotechar != NULL)
272 if (*(quotechar - 1) == '\\')
274 char *tp = quotechar - 2;
285 curarg = quotechar + 1;
286 quotechar = strchr (curarg, '\"');
291 llassert (quotechar != NULL);
293 offset = (quotechar - arg) + 2;
297 arg = cstring_toCharsSafe
298 (message ("%s\"\'%s",
299 cstring_fromChars (arg),
300 cstring_fromChars (quotechar + 1)));
306 arg = cstring_toCharsSafe
307 (message ("%s\'\"%s",
308 cstring_fromChars (arg),
309 cstring_fromChars (quotechar + 1)));
314 curarg = arg + offset;
315 quotechar = strchr (curarg, '\"');
321 voptgenerror (FLG_BADFLAG,
322 message ("Unclosed quote in flag: %s",
323 cstring_fromChars (arg)),
332 ** If the value is surrounded by single quotes ('), remove
333 ** them. This is an artifact of UNIX command line?
336 def = osd_fixDefine (cstring_fromChars (arg + 1));
337 DPRINTF (("Do define: %s", def));
339 DPRINTF (("After define"));
341 } else if (arg[0] == 'U') {
342 cppDoUndefine (cstring_fromChars (arg + 1));
351 void showHerald (void)
353 if (hasShownHerald || context_getFlag (FLG_QUIET))
359 fprintf (g_messagestream, "%s\n\n", SPLINT_VERSION);
360 hasShownHerald = TRUE;
366 ** Disable MSVC++ warning about return value. Methinks humbly splint control
367 ** comments are a mite more legible.
371 # pragma warning (disable:4035)
374 int main (int argc, char *argv[])
376 /*@globals killed undef g_currentloc,
378 undef g_warningstream, g_messagestream, g_errorstream;
380 /*@modifies g_currentloc, fileSystem,
384 /*@globals killed undef g_currentloc,
385 killed g_localSpecPath,
386 killed undef g_currentSpec,
387 killed undef g_currentSpecName,
389 undef g_warningstream, g_messagestream, g_errorstream;
391 /*@modifies g_currentloc, g_localSpecPath, g_currentSpec, g_currentSpecName,
396 bool first_time = TRUE;
398 inputStream sourceFile = inputStream_undefined;
400 fileIdList dercfiles;
401 cstringSList passThroughArgs = cstringSList_undefined;
402 fileIdList cfiles, xfiles, lclfiles, mtfiles;
403 clock_t before, lcltime, libtime, pptime, cptime, rstime;
407 _wildcard (&argc, &argv);
410 g_warningstream = stdout;
411 g_messagestream = stderr;
412 g_errorstream = stderr;
414 (void) signal (SIGINT, llinterrupt);
415 (void) signal (SIGSEGV, llinterrupt);
418 clabstract_initMod ();
419 typeIdSet_initMod ();
420 cppReader_initMod ();
425 g_currentloc = fileloc_createBuiltin ();
430 context_setInCommandLine ();
434 help_showAvailableHelp ();
438 /* -help must be the first flag to get help */
439 if (flagcode_isHelpFlag (flags_identifyFlag (cstring_fromChars (argv[1]))))
442 ** Skip first flag and help flag
445 help_processFlags (argc - 2, argv + 2);
453 ** Add include directories from environment.
457 cstring incval = cstring_copy (osd_getEnvironmentVariable (INCLUDEPATH_VAR));
458 cstring oincval = incval;
460 if (cstring_isDefined (incval))
463 ** Each directory on the include path is a system include directory.
466 DPRINTF (("include: %s", incval));
467 context_setString (FLG_SYSTEMDIRS, cstring_copy (incval));
469 while (cstring_isDefined (incval))
472 char *nextsep = strchr (incval, PATH_SEPARATOR);
478 dir = cstring_copy (incval);
480 if (cstring_length (dir) == 0
481 || !isalpha ((int) cstring_firstChar (dir)))
484 ** win32 environment values can have special values,
490 cppAddIncludeDir (dir);
493 *nextsep = PATH_SEPARATOR;
494 incval = cstring_fromChars (nextsep + 1);
502 /*@noaccess cstring@*/
505 else /* 2001-09-09: herbert */
507 /* Put C_INCLUDE_PATH directories in sysdirs */
508 cstring cincval = osd_getEnvironmentVariable (cstring_makeLiteralTemp ("C_INCLUDE_PATH"));
510 if (cstring_isDefined (cincval))
512 context_setString (FLG_SYSTEMDIRS, cstring_copy (cincval));
517 cstring_free (oincval);
521 ** check RCFILE for default flags
525 ** Process command line message formatting flags before reading rc file
529 cstring home = osd_getHomeDir ();
530 cstring fname = cstring_undefined;
531 bool defaultf = TRUE;
534 for (i = 1; i < argc; i++)
539 if (*thisarg == '-' || *thisarg == '+')
541 bool set = (*thisarg == '+');
547 ** Don't report warnings this time
550 opt = flags_identifyFlagQuiet (cstring_fromChars (thisarg));
556 else if (flagcode_isMessageControlFlag (opt))
559 ** Need to set it immediately, so rc file scan is displayed
562 context_userSetFlag (opt, set);
564 if (flagcode_hasArgument (opt))
566 llassert (flagcode_hasString (opt));
570 fname = cstring_fromChars (argv[i]);
571 setStringFlag (opt, fname);
578 ("Flag %s must be followed by a string",
579 flagcode_unparse (opt)),
584 else if (opt == FLG_OPTF)
589 fname = cstring_fromChars (argv[i]);
590 (void) rcfiles_read (fname, &passThroughArgs, TRUE);
594 (cstring_makeLiteral ("Flag f to select options file "
595 "requires an argument"));
599 ; /* wait to process later */
606 if (!nof && defaultf)
609 ** No explicit rc file, first try reading ~/.splintrc
612 if (cstring_isUndefined (fname))
614 if (!cstring_isEmpty (home))
616 bool readhomerc, readaltrc;
617 cstring homename, altname;
619 homename = message ("%s%h%s", home, CONNECTCHAR,
620 cstring_fromChars (RCFILE));
621 readhomerc = rcfiles_read (homename, &passThroughArgs, FALSE);
624 ** Try ~/.splintrc also for historical accuracy
627 altname = message ("%s%h%s", home, CONNECTCHAR,
628 cstring_fromChars (ALTRCFILE));
629 readaltrc = rcfiles_read (altname, &passThroughArgs, FALSE);
631 if (readhomerc && readaltrc)
636 message ("Found both %s and %s files. Using both files, "
637 "but recommend using only %s to avoid confusion.",
638 homename, altname, homename),
642 cstring_free (homename);
643 cstring_free (altname);
648 ** Next, read .splintrc in the current working directory
652 cstring rcname = message ("%s%s",osd_getCurrentDirectory (), cstring_fromChars (RCFILE));
653 cstring altname = message ("%s%s",osd_getCurrentDirectory (), cstring_fromChars (ALTRCFILE));
654 bool readrc, readaltrc;
656 readrc = rcfiles_read (rcname, &passThroughArgs, FALSE);
657 readaltrc = rcfiles_read (altname, &passThroughArgs, FALSE);
659 if (readrc && readaltrc)
661 voptgenerror (FLG_WARNRC,
662 message ("Found both %s and %s files. Using both files, "
663 "but recommend using only %s to avoid confusion.",
664 rcname, altname, rcname),
669 cstring_free (rcname);
670 cstring_free (altname);
676 llassert (fileloc_isBuiltin (g_currentloc));
678 cfiles = fileIdList_create ();
679 xfiles = fileIdList_create ();
680 lclfiles = fileIdList_create ();
681 mtfiles = fileIdList_create ();
683 /* argv[0] is the program name, don't pass it to flags_processFlags */
684 flags_processFlags (TRUE, xfiles, cfiles,
697 context_resetErrors ();
698 context_clearInCommandLine ();
700 anylcl = !fileIdList_isEmpty (lclfiles);
702 if (context_doMerge ())
704 cstring m = context_getMerge ();
706 displayScanOpen (message ("< loading %s ", m));
710 if (!usymtab_existsType (context_getBoolName ()))
717 if (!context_getFlag (FLG_NOLIB) && loadStandardState ())
726 /* setup bool type and constants */
730 fileloc_free (g_currentloc);
731 g_currentloc = fileloc_createBuiltin ();
734 ** Read metastate files (must happen before loading libraries)
737 fileIdList_elements (mtfiles, mtfile)
739 context_setFileId (mtfile);
740 displayScan (message ("processing %s", fileTable_rootFileName (mtfile)));
741 mtreader_readFile (cstring_copy (fileTable_fileName (mtfile)));
742 } end_fileIdList_elements;
749 llfatalerror (cstring_makeLiteral ("This version of Splint does not handle LCL files."));
751 lslProcess (lclfiles);
755 usymtab_initGlobalMarker ();
760 ** call the pre-preprocessor and /lib/cpp to generate appropriate
765 context_setInCommandLine ();
767 DPRINTF (("Pass through: %s", cstringSList_unparse (passThroughArgs)));
769 cstringSList_elements (passThroughArgs, thisarg)
771 handlePassThroughFlag (cstring_toCharsSafe (thisarg));
773 end_cstringSList_elements;
775 cstringSList_free (passThroughArgs);
779 DPRINTF (("Initializing cpp reader!"));
780 cppReader_initialize ();
781 cppReader_saveDefinitions ();
783 context_clearInCommandLine ();
785 if (!context_getFlag (FLG_NOPP))
791 displayScanOpen (cstring_makeLiteral ("preprocessing"));
795 context_setPreprocessing ();
796 dercfiles = preprocessFiles (xfiles, TRUE);
797 tfiles = preprocessFiles (cfiles, FALSE);
798 warnSysFiles(cfiles);
799 dercfiles = fileIdList_append (dercfiles, tfiles);
800 fileIdList_free (tfiles);
802 context_clearPreprocessing ();
804 fileIdList_free (cfiles);
812 dercfiles = fileIdList_append (cfiles, xfiles);
817 ** now, check all the corresponding C files
819 ** (for now these are just <file>.c, but after pre-processing
820 ** will be <tmpprefix>.<file>.c)
825 int nfiles = /*@-unrecog@*/ _fcloseall (); /*@=unrecog@*/
829 llbug (message ("Files unclosed: %d", nfiles));
834 DPRINTF (("Initializing..."));
838 DPRINTF (("Okay..."));
840 fileIdList_elements (dercfiles, fid)
842 sourceFile = inputStream_create (cstring_copy (fileTable_fileName (fid)), C_EXTENSION, TRUE);
843 context_setFileId (fid);
845 /* Open source file */
847 if (inputStream_isUndefined (sourceFile) || (!inputStream_open (sourceFile)))
849 /* previously, this was ignored ?! */
850 llbug (message ("Could not open temp file: %s", fileTable_fileName (fid)));
854 yyin = inputStream_getFile (sourceFile); /*< shared <- only */
856 llassert (yyin != NULL);
858 displayScan (message ("checking %q", osd_outputPath (fileTable_rootFileName (fid))));
861 ** Every time, except the first time, through the loop,
862 ** need to call yyrestart to clean up the parse buffer.
867 (void) yyrestart (yyin);
874 DPRINTF (("Entering..."));
875 context_enterFile ();
877 context_exitCFile ();
879 (void) inputStream_close (sourceFile);
881 } end_fileIdList_elements;
885 /* process any leftover macros */
887 context_processAllMacros ();
889 /* check everything that was specified was defined */
891 /* don't check if no c files were processed ?
892 ** is this correct behaviour?
895 displayScan (cstring_makeLiteral ("global checks"));
899 if (context_getLinesProcessed () > 0)
901 usymtab_allDefined ();
904 if (context_maybeSet (FLG_TOPUNUSED))
906 uentry ue = usymtab_lookupSafe (cstring_makeLiteralTemp ("main"));
908 if (uentry_isValid (ue))
910 uentry_setUsed (ue, fileloc_observeBuiltin ());
916 if (context_maybeSet (FLG_EXPORTLOCAL))
918 usymtab_exportLocal ();
922 if (context_maybeSet (FLG_EXPORTHEADER))
924 usymtab_exportHeader ();
927 if (context_getFlag (FLG_SHOWUSES))
929 usymtab_displayAllUses ();
932 context_checkSuppressCounts ();
934 if (context_doDump ())
936 cstring dump = context_getDump ();
947 if (context_getFlag (FLG_SHOWSUMMARY))
954 bool isQuiet = context_getFlag (FLG_QUIET);
955 cstring specErrors = cstring_undefined;
957 int nspecErrors = lclNumberErrors ();
962 if (context_neednl ())
963 fprintf (g_warningstream, "\n");
968 if (nspecErrors == context_getLCLExpect ())
971 message ("%d spec warning%&, as expected\n ",
976 if (context_getLCLExpect () > 0)
979 message ("%d spec warning%&, expected %d\n ",
981 (int) context_getLCLExpect ());
985 specErrors = message ("%d spec warning%&\n ",
993 if (context_getLCLExpect () > 0)
995 specErrors = message ("No spec warnings, expected %d\n ",
996 (int) context_getLCLExpect ());
1002 if (context_anyErrors ())
1004 if (context_numErrors () == context_getExpect ())
1007 llmsg (message ("Finished checking --- "
1008 "%s%d code warning%&, as expected",
1009 specErrors, context_numErrors ()));
1014 if (context_getExpect () > 0)
1018 ("Finished checking --- "
1019 "%s%d code warning%&, expected %d",
1020 specErrors, context_numErrors (),
1021 (int) context_getExpect ()));
1031 llmsg (message ("Finished checking --- "
1032 "%s%d code warning%&",
1033 specErrors, context_numErrors ()));
1042 if (context_getExpect () > 0)
1046 ("Finished checking --- "
1047 "%sno code warnings, expected %d",
1049 (int) context_getExpect ()));
1056 if (context_getLinesProcessed () > 0)
1058 if (cstring_isEmpty (specErrors))
1062 llmsg (message ("Finished checking --- no warnings"));
1069 llmsg (message ("Finished checking --- %sno code warnings",
1077 llmsg (message ("Finished checking --- %sno code processed",
1084 cstring_free (specErrors);
1087 if (context_getFlag (FLG_STATS))
1089 clock_t ttime = clock () - before;
1090 int specLines = context_getSpecLinesProcessed ();
1091 cstring specmsg = cstring_undefined;
1097 specmsg = message ("%d spec, ", specLines);
1100 # ifndef CLOCKS_PER_SEC
1101 lldiagmsg (message ("%s%d source lines in %d time steps (steps/sec unknown)\n",
1103 context_getLinesProcessed (),
1106 lldiagmsg (message ("%s%d source lines in %f s.\n",
1108 context_getLinesProcessed (),
1109 (double) ttime / CLOCKS_PER_SEC));
1117 if (context_getFlag (FLG_TIMEDIST))
1119 clock_t ttime = clock () - before;
1123 char *msg = (char *) dmalloc (256 * sizeof (*msg));
1127 (void) snprintf (msg, 256,
1128 "Time distribution (percent): initialize %.2f / lcl %.2f / "
1129 "pre-process %.2f / c check %.2f / finalize %.2f \n",
1130 (100.0 * (double) (libtime - before) / ttime),
1131 (100.0 * (double) (lcltime - libtime) / ttime),
1132 (100.0 * (double) (pptime - lcltime) / ttime),
1133 (100.0 * (double) (cptime - pptime) / ttime),
1134 (100.0 * (double) (rstime - cptime) / ttime));
1138 (void) snprintf (msg, 256,
1139 "Time distribution (percent): initialize %.2f / "
1140 "pre-process %.2f / c check %.2f / finalize %.2f \n",
1141 (100.0 * (double) (libtime - before) / ttime),
1142 (100.0 * (double) (pptime - libtime) / ttime),
1143 (100.0 * (double) (cptime - pptime) / ttime),
1144 (100.0 * (double) (rstime - cptime) / ttime));
1147 llgenindentmsgnoloc (cstring_fromCharsO (msg));
1151 llexit (expsuccess ? LLSUCCESS : LLFAILURE);
1152 BADBRANCHRET (LLFAILURE);
1157 ** Reenable return value warnings.
1159 # pragma warning (default:4035)
1168 fprintf (g_errorstream, "*** Interrupt\n");
1169 llexit (LLINTERRUPT);
1174 /* Cheat when there are parse errors */
1177 fprintf (g_errorstream, "*** Segmentation Violation\n");
1179 /* Don't catch it if fileloc_unparse causes a signal */
1180 (void) signal (SIGSEGV, NULL);
1182 loc = fileloc_unparse (g_currentloc);
1184 fprintf (g_errorstream, "*** Location (not trusted): %s\n",
1185 cstring_toCharsSafe (loc));
1188 fprintf (g_errorstream, "*** Please report bug to %s\n", SPLINT_MAINTAINER);
1192 fprintf (g_errorstream, "*** Signal: %d\n", i);
1194 fprintf (g_errorstream, "*** Location (not trusted): %s\n",
1195 cstring_toCharsSafe (fileloc_unparse (g_currentloc)));
1198 fprintf (g_errorstream, "*** Please report bug to %s ***\n", SPLINT_MAINTAINER);
1206 static bool doneCleanup = FALSE;
1208 /* make sure this is only called once! */
1210 if (doneCleanup) return;
1215 ** Close all open files
1216 ** (There should only be open files, if we exited after a fatal error.)
1219 fileTable_closeAll (context_fileTable ());
1221 if (context_getFlag (FLG_KEEP))
1223 check (fputs ("Temporary files kept:\n", g_messagestream) != EOF);
1224 fileTable_printTemps (context_fileTable ());
1229 int nfiles = /*@-unrecog@*/ _fcloseall (); /*@=unrecog@*/
1233 llbug (message ("Files unclosed: %d", nfiles));
1236 fileTable_cleanup (context_fileTable ());
1243 ** cleans up temp files (if necessary) and exits
1249 DPRINTF (("llexit: %d", status));
1252 if (status == LLFAILURE)
1260 if (status != LLFAILURE)
1262 context_destroyMod ();
1263 exprNode_destroyMod ();
1266 uentry_destroyMod ();
1267 typeIdSet_destroyMod ();
1270 dmalloc_shutdown ();
1274 exit ((status == LLSUCCESS) ? EXIT_SUCCESS : EXIT_FAILURE);
1277 static fileIdList preprocessFiles (fileIdList fl, bool xhfiles)
1278 /*@modifies fileSystem@*/
1280 bool msg = (context_getFlag (FLG_SHOWSCAN) && fileIdList_size (fl) > 10);
1281 int skip = (fileIdList_size (fl) / 5);
1282 int filesprocessed = 0;
1283 fileIdList dfiles = fileIdList_create ();
1285 fileloc_free (g_currentloc);
1286 g_currentloc = fileloc_createBuiltin ();
1288 fileIdList_elements (fl, fid)
1290 cstring ppfname = fileTable_fileName (fid);
1292 if (!(osd_fileIsReadable (ppfname)))
1294 lldiagmsg (message ("Cannot open file: %q", osd_outputPath (ppfname)));
1295 ppfname = cstring_undefined;
1298 if (cstring_isDefined (ppfname))
1300 fileId dfile = fileTable_addCTempFile (context_fileTable (), fid);
1304 llassert (fileTable_isXHFile (context_fileTable (), dfile));
1307 llassert (cstring_isNonEmpty (ppfname));
1311 if ((filesprocessed % skip) == 0)
1313 if (filesprocessed == 0) {
1314 displayScanContinue (cstring_makeLiteral (" "));
1317 displayScanContinue (cstring_makeLiteral ("."));
1323 DPRINTF (("outfile: %s", fileTable_fileName (dfile)));
1325 if (cppProcess (ppfname, fileTable_fileName (dfile)) != 0)
1327 llfatalerror (message ("Preprocessing error for file: %s",
1328 fileTable_rootFileName (fid)));
1331 fileIdList_add (dfiles, dfile);
1333 } end_fileIdList_elements;
1338 /* This should be in an lclUtils.c file... */
1340 char *specFullName (char *specfile, /*@out@*/ char **inpath)
1342 /* extract the path and the specname associated with the given file */
1343 char *specname = (char *) dmalloc (sizeof (*specname)
1344 * (strlen (specfile) + 9));
1345 char *ospecname = specname;
1346 char *path = (char *) dmalloc (sizeof (*path) * (strlen (specfile)));
1350 /* initialized path to empty string or may have accidental garbage */
1353 /*@-mayaliasunique@*/
1354 strcpy (specname, specfile);
1355 /*@=mayaliasunique@*/
1357 /* trim off pathnames in specfile */
1358 size = strlen (specname);
1360 for (i = size_toInt (size) - 1; i >= 0; i--)
1362 if (specname[i] == CONNECTCHAR)
1364 /* strcpy (specname, (char *)specname+i+1); */
1365 for (j = 0; j <= i; j++) /* include '/' */
1367 path[j] = specname[j];
1377 ** also remove .lcl file extension, assume it's the last extension
1381 size = strlen (specname);
1383 for (i = size_toInt (size) - 1; i >= 0; i--)
1385 if (specname[i] == '.')
1395 ** If specname no longer points to the original char,
1396 ** we need to allocate a new pointer and copy the string.
1399 if (specname != ospecname) {
1400 char *rspecname = (char *) dmalloc (sizeof (*rspecname) * (strlen (specname) + 1));
1401 strcpy (rspecname, specname); /* evs 2000-05-16: Bug: was ospecname! */
1410 void warnSysFiles(fileIdList files)
1412 fileIdList_elements (files, file)
1415 if (fileTable_isSystemFile (context_fileTable (), file) )
1417 if (!context_getFlag( FLG_SYSTEMDIRERRORS ) )
1419 voptgenerror (FLG_WARNSYSFILES, message ("Warning %s is a considered a system file. No errors in this file will be reported.", fileTable_rootFileName (file) ), g_currentloc);
1423 end_fileIdList_elements;