]> andersk Git - splint.git/blame - src/llmain.c
Added in test case files. (Merge should be complete now.)
[splint.git] / src / llmain.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** llmain.c
26**
27** Main module for LCLint checker
28*/
29
30# include <signal.h>
31
32/*
33** Ensure that WIN32 and _WIN32 are both defined or both undefined.
34*/
35
36# ifdef WIN32
37# ifndef _WIN32
38# error "Inconsistent definitions."
39# endif
40# else
41# ifdef _WIN32
42# error "Inconsistent definitions."
43# endif
44# endif
45
46# ifdef WIN32
47# include <windows.h>
48# include <process.h>
49# endif
50
51# include "lclintMacros.nf"
52# include "llbasic.h"
53# include "osd.h"
54
55# ifndef NOLCL
56# include "gram.h"
57# include "lclscan.h"
58# include "scanline.h"
59# include "lclscanline.h"
60# include "lclsyntable.h"
61# include "lcltokentable.h"
62# include "lslparse.h"
63# include "scan.h"
64# include "syntable.h"
65# include "tokentable.h"
66# include "lslinit.h"
67# include "lclinit.h"
68# include "lh.h"
69# include "imports.h"
70# endif
71
72# include "version.h"
73# include "herald.h"
74# include "fileIdList.h"
75# include "lcllib.h"
76# include "cgrammar.h"
77# include "llmain.h"
78# include "portab.h"
79# include "cpp.h"
80# include <time.h>
81
82extern /*@external@*/ int yydebug;
83
84static void printMail (void);
85static void printMaintainer (void);
86static void printReferences (void);
87static void printFlags (void);
88static void printAnnotations (void);
89static void printParseErrors (void);
90static void printComments (void);
91static void describePrefixCodes (void);
92static void cleanupFiles (void);
93static void showHelp (void);
94static void interrupt (int p_i);
95static void loadrc (FILE *p_rcfile, cstringSList *p_passThroughArgs);
96static void describeVars (void);
97static bool specialFlagsHelp (char *p_next);
98static bool hasShownHerald = FALSE;
99
100static bool anylcl = FALSE;
101static clock_t inittime;
102
103static /*@only@*/ /*@null@*/ tsource *initFile = (tsource *) 0;
104
105static fileIdList preprocessFiles (fileIdList)
106 /*@modifies fileSystem@*/ ;
107
108# ifndef NOLCL
109
110static
111void lslCleanup (void)
112 /*@globals killed g_symtab@*/
113 /*@modifies internalState, g_symtab@*/
114{
115 /*
116 ** Cleanup all the LCL/LSL.
117 */
118
119 static bool didCleanup = FALSE;
120
121 llassert (!didCleanup);
122 llassert (anylcl);
123
124 didCleanup = TRUE;
125
126 lsymbol_destroyMod ();
127 LCLSynTableCleanup ();
128 LCLTokenTableCleanup ();
129 LCLScanLineCleanup ();
130 LCLScanCleanup ();
131
132 /* clean up LSL parsing */
133
134 lsynTableCleanup ();
135 ltokenTableCleanup ();
136 lscanLineCleanup ();
137 LSLScanCleanup ();
138
139 symtable_free (g_symtab);
140 sort_destroyMod ();
141}
142
143static
144 void lslInit (void)
145 /*@globals undef g_symtab; @*/
146 /*@modifies g_symtab, internalState, fileSystem; @*/
147{
148 /*
149 ** Open init file provided by user, or use the default LCL init file
150 */
151
152 cstring larchpath = context_getLarchPath ();
153 tsource *LSLinitFile = (tsource *) 0;
154
155 setCodePoint ();
156
157 if (initFile == (tsource *) 0)
158 {
159 initFile = tsource_create (INITFILENAME, LCLINIT_SUFFIX, FALSE);
160
161 if (!tsource_getPath (cstring_toCharsSafe (larchpath), initFile))
162 {
163 lldiagmsg (message ("Continuing without LCL init file: %s",
164 cstring_fromChars (tsource_fileName (initFile))));
165 }
166 else
167 {
168 if (!tsource_open (initFile))
169 {
170 lldiagmsg (message ("Continuing without LCL init file: %s",
171 cstring_fromChars (tsource_fileName (initFile))));
172 }
173 }
174 }
175 else
176 {
177 if (!tsource_open (initFile))
178 {
179 lldiagmsg (message ("Continuing without LCL init file: %s",
180 cstring_fromChars (tsource_fileName (initFile))));
181 }
182 }
183
184 /* Initialize checker */
185
186 lsymbol_initMod ();
187 LCLSynTableInit ();
188
189 setCodePoint ();
190
191 LCLSynTableReset ();
192 LCLTokenTableInit ();
193
194 setCodePoint ();
195
196 LCLScanLineInit ();
197 setCodePoint ();
198 LCLScanLineReset ();
199 setCodePoint ();
200 LCLScanInit ();
201
202 setCodePoint ();
203
204 /* need this to initialize LCL checker */
205 llassert (initFile != NULL);
206
207 if (tsource_isOpen (initFile))
208 {
209 setCodePoint ();
210
211 LCLScanReset (initFile);
212 LCLProcessInitFileInit ();
213 LCLProcessInitFileReset ();
214
215 setCodePoint ();
216 LCLProcessInitFile ();
217 LCLProcessInitFileCleanup ();
218
219 setCodePoint ();
220 check (tsource_close (initFile));
221 }
222
223 /* Initialize LSL init files, for parsing LSL signatures from LSL */
224
225 LSLinitFile = tsource_create ("lslinit.lsi", ".lsi", FALSE);
226
227 if (!tsource_getPath (cstring_toCharsSafe (larchpath), LSLinitFile))
228 {
229 lldiagmsg (message ("Continuing without LSL init file: %s",
230 cstring_fromChars (tsource_fileName (LSLinitFile))));
231 }
232 else
233 {
234 if (!tsource_open (LSLinitFile))
235 {
236 lldiagmsg (message ("Continuing without LSL init file: %s",
237 cstring_fromChars (tsource_fileName (LSLinitFile))));
238 }
239 }
240
241 setCodePoint ();
242 lsynTableInit ();
243 lsynTableReset ();
244
245 setCodePoint ();
246 ltokenTableInit ();
247
248 setCodePoint ();
249 lscanLineInit ();
250 lscanLineReset ();
251 LSLScanInit ();
252
253 if (tsource_isOpen (LSLinitFile))
254 {
255 setCodePoint ();
256 LSLScanReset (LSLinitFile);
257 LSLProcessInitFileInit ();
258 setCodePoint ();
259 LSLProcessInitFile ();
260 setCodePoint ();
261 check (tsource_close (LSLinitFile));
262 }
263
264 tsource_free (LSLinitFile);
265
266 if (lclHadError ())
267 {
268 lclplainerror
269 (cstring_makeLiteral ("LSL init file error. Attempting to continue."));
270 }
271
272 setCodePoint ();
273 g_symtab = symtable_new ();
274
275 /*
276 ** sort_init must come after symtab has been initialized
277 */
278 sort_init ();
279 abstract_init ();
280 setCodePoint ();
281
282 inittime = clock ();
283
284 /*
285 ** Equivalent to importing old spec_csupport.lcl
286 ** define immutable LCL type "bool" and bool constants TRUE and FALSE
287 ** and initialized them to be equal to LSL's "true" and "false".
288 **
289 ** Reads in CTrait.syms (derived from CTrait.lsl) on LARCH_PATH.
290 */
291
292 LCLBuiltins ();
293 LCLReportEolTokens (FALSE);
294}
295
296static void
297lslProcess (fileIdList lclfiles)
298 /*@globals undef g_currentSpec, undef g_currentSpecName, g_currentloc,
299 undef killed g_symtab; @*/
300 /*@modifies g_currentSpec, g_currentSpecName, g_currentloc, internalState, fileSystem; @*/
301{
302 char *path = NULL;
303 bool parser_status = FALSE;
304 bool overallStatus = FALSE;
305
306 lslInit ();
307
308 context_resetSpecLines ();
309
310 fileIdList_elements (lclfiles, fid)
311 {
312 char *actualName = (char *) dmalloc (sizeof (*actualName));
313 char *oactualName = actualName;
314 char *fname = cstring_toCharsSafe (fileName (fid));
315
316 if (osd_getPath (g_localSpecPath, fname, &actualName) == OSD_FILENOTFOUND)
317 {
318 if (mstring_equal (g_localSpecPath, "."))
319 {
320 lldiagmsg (message ("Spec file not found: %s",
321 cstring_fromChars (fname)));
322 }
323 else
324 {
325 lldiagmsg (message ("Spec file not found: %s (on %s)",
326 cstring_fromChars (fname),
327 cstring_fromChars (g_localSpecPath)));
328 }
329 }
330 else
331 {
332 tsource *specFile;
333
334 while (*actualName == '.' && *(actualName + 1) == CONNECTCHAR)
335 {
336 actualName += 2;
337 }
338
339 specFile = tsource_create (actualName, LCL_SUFFIX, TRUE);
340 llassert (specFile != (tsource *) 0);
341
342 g_currentSpec = cstring_fromChars (mstring_copy (actualName));
343
344 g_currentSpecName = specFullName
345 (cstring_toCharsSafe (g_currentSpec),
346 &path);
347
348 setSpecFileId (fid);
349
350 if (context_getFlag (FLG_SHOWSCAN))
351 {
352 lldiagmsg (message ("< reading spec %s >", g_currentSpec));
353 }
354
355 /* Open source file */
356
357 if (!tsource_open (specFile))
358 {
359 lldiagmsg (message ("Cannot open file: %s",
360 cstring_fromChars (tsource_fileName (specFile))));
361 tsource_free (specFile);
362 }
363 else
364 {
365 scopeInfo dummy_scope = (scopeInfo) dmalloc (sizeof (*dummy_scope));
366 dummy_scope->kind = SPE_INVALID;
367
368 lhInit (specFile);
369 LCLScanReset (specFile);
370
371 /*
372 ** Minor hacks to allow more than one LCL file to
373 ** be scanned, while keeping initializations
374 */
375
376 symtable_enterScope (g_symtab, dummy_scope);
377 resetImports (cstring_fromChars (g_currentSpecName));
378 context_enterLCLfile ();
379 (void) lclHadNewError ();
380
381 parser_status = (ylparse () != 0);
382 context_exitLCLfile ();
383 lhCleanup ();
384 overallStatus = parser_status || lclHadNewError ();
385
386 if (context_getFlag (FLG_DOLCS))
387 {
388 if (overallStatus)
389 {
390 outputLCSFile (path, "%%FAILED Output from ",
391 g_currentSpecName);
392 }
393 else
394 {
395 outputLCSFile (path, "%%PASSED Output from ",
396 g_currentSpecName);
397 }
398 }
399
400 (void) tsource_close (specFile);
401 tsource_free (specFile);
402
403 symtable_exitScope (g_symtab);
404 }
405 }
406
407 sfree (oactualName);
408 } end_fileIdList_elements;
409
410 /* Can cleanup lsl stuff right away */
411
412 lslCleanup ();
413
414 g_currentSpec = cstring_undefined;
415 g_currentSpecName = NULL;
416}
417# endif
418
419static void handlePassThroughFlag (char *arg)
420{
421 char *curarg = arg;
422 char *quotechar = strchr (curarg, '\"');
423 int offset = 0;
424 bool open = FALSE;
425
426 while (quotechar != NULL)
427 {
428 if (*(quotechar - 1) == '\\')
429 {
430 char *tp = quotechar - 2;
431 bool escape = TRUE;
432
433 while (*tp == '\\')
434 {
435 escape = !escape;
436 tp--;
437 }
438
439 if (escape)
440 {
441 curarg = quotechar + 1;
442 quotechar = strchr (curarg, '\"');
443 continue;
444 }
445 }
446
447 *quotechar = '\0';
448 offset = (quotechar - arg) + 2;
449
450 if (open)
451 {
452 arg = cstring_toCharsSafe
453 (message ("%s\"\'%s",
454 cstring_fromChars (arg),
455 cstring_fromChars (quotechar + 1)));
456 open = FALSE;
457 }
458 else
459 {
460 arg = cstring_toCharsSafe
461 (message ("%s\'\"%s",
462 cstring_fromChars (arg),
463 cstring_fromChars (quotechar + 1)));
464 open = TRUE;
465 }
466
467 curarg = arg + offset;
468 quotechar = strchr (curarg, '\"');
469 }
470
471 if (open)
472 {
473 showHerald ();
474 llerror (FLG_BADFLAG,
475 message ("Unclosed quote in flag: %s",
476 cstring_fromChars (arg)));
477 }
478 else
479 {
480 if (arg[0] == 'D') {
481 cstring def;
482
483 /*
484 ** If the value is surrounded by single quotes ('), remove
485 ** them. This is an artifact of UNIX command line?
486 */
487
488 def = osd_fixDefine (arg + 1);
489 DPRINTF (("Do define: %s", def));
490 cppDoDefine (def);
491 DPRINTF (("After define"));
492 cstring_free (def);
493 } else if (arg[0] == 'U') {
494 cppDoUndefine (cstring_fromChars (arg + 1));
495 } else {
496 BADBRANCH;
497 }
498 }
499}
500
501void showHerald (void)
502{
503 if (hasShownHerald || context_getFlag (FLG_QUIET)) return;
504
505 else
506 {
507 fprintf (g_msgstream, "%s\n\n", LCL_VERSION);
508 hasShownHerald = TRUE;
509 llflush ();
510 }
511}
512
513static void addFile (fileIdList files, /*@only@*/ cstring s)
514{
515 if (fileTable_exists (context_fileTable (), s))
516 {
517 showHerald ();
518 lldiagmsg (message ("File listed multiple times: %s", s));
519 cstring_free (s);
520 }
521 else
522 {
523 fileIdList_add (files, fileTable_addFileOnly (context_fileTable (), s));
524 }
525}
526
527/*
528** Disable MSVC++ warning about return value. Methinks humbly lclint control
529** comments are a mite more legible.
530*/
531
532# ifdef WIN32
533# pragma warning (disable:4035)
534# endif
535
536int main (int argc, char *argv[])
537# ifdef NOLCL
538 /*@globals killed undef g_currentloc,
539 killed undef yyin,
540 undef g_msgstream;
541 @*/
542 /*@modifies g_currentloc, fileSystem,
543 yyin;
544 @*/
545# else
546 /*@globals killed undef g_currentloc,
547 killed undef initFile,
548 killed g_localSpecPath,
549 killed undef g_currentSpec,
550 killed undef g_currentSpecName,
551 killed undef yyin,
552 undef g_msgstream;
553 @*/
554 /*@modifies g_currentloc, initFile,
555 g_localSpecPath, g_currentSpec, g_currentSpecName, fileSystem,
556 yyin;
557 @*/
558# endif
559{
560 bool first_time = TRUE;
561 bool showhelp = FALSE;
562 bool allhelp = TRUE;
563 tsource *sourceFile = (tsource *) 0;
564
565 fileIdList dercfiles;
566 cstringSList fl = cstringSList_undefined;
567 cstringSList passThroughArgs = cstringSList_undefined;
568 fileIdList cfiles;
569 fileIdList lclfiles;
570 clock_t before, lcltime, libtime, pptime, cptime, rstime;
571 int i = 0;
572
573 g_msgstream = stdout;
574
575 (void) signal (SIGINT, interrupt);
576 (void) signal (SIGSEGV, interrupt);
577
578 cfiles = fileIdList_create ();
579 lclfiles = fileIdList_create ();
580
581 flags_initMod ();
582 typeIdSet_initMod ();
583 cppReader_initMod ();
584
585 setCodePoint ();
586
587 g_currentloc = fileloc_createBuiltin ();
588
589 before = clock ();
590 context_initMod ();
591 context_setInCommandLine ();
592
593 if (argc <= 1)
594 {
595 showHelp ();
596 llexit (LLGIVEUP);
597 }
598
599 setCodePoint ();
600 yydebug = 0;
601
602 /*
603 ** Add include directories from environment.
604 */
605
606 {
607 char *incval = mstring_copy (osd_getEnvironmentVariable (INCLUDE_VAR));
608
609 if (incval != NULL)
610 {
611 /*
612 ** Each directory on the include path is a system include directory.
613 */
614
615 DPRINTF (("include: %s", incval));
616 context_setString (FLG_SYSTEMDIRS, cstring_fromCharsNew (incval));
617
618 while (incval != NULL)
619 {
620 char *nextsep = strchr (incval, SEPCHAR);
621
622 if (nextsep != NULL)
623 {
624 cstring dir;
625 *nextsep = '\0';
626 dir = cstring_fromCharsNew (incval);
627
628 if (cstring_length (dir) == 0
629 || !isalpha ((int) cstring_firstChar (dir)))
630 {
631 /*
632 ** win32 environment values can have special values,
633 ** ignore them
634 */
635 }
636 else
637 {
638 DPRINTF (("Add include: %s", dir));
639 cppAddIncludeDir (dir);
640 }
641
642 *nextsep = SEPCHAR;
643 incval = nextsep + 1;
644 cstring_free (dir);
645 }
646 else
647 {
648 break;
649 }
650 }
651 }
652 }
653
654 /*
655 ** check RCFILE for default flags
656 */
657
658 {
659 cstring home = cstring_fromChars (osd_getHomeDir ());
660 char *fname = NULL;
661 FILE *rcfile;
662 bool defaultf = TRUE;
663 bool nof = FALSE;
664
665 for (i = 1; i < argc; i++)
666 {
667 char *thisarg;
668 thisarg = argv[i];
669
670 if (*thisarg == '-' || *thisarg == '+')
671 {
672 thisarg++;
673
674 if (mstring_equal (thisarg, "nof"))
675 {
676 nof = TRUE;
677 }
678 else if (mstring_equal (thisarg, "f"))
679 {
680 if (++i < argc)
681 {
682 defaultf = FALSE;
683 fname = argv[i];
684 rcfile = fopen (fname, "r");
685
686 if (rcfile != NULL)
687 {
688 fileloc oloc = g_currentloc;
689
690 g_currentloc = fileloc_createRc (cstring_fromChars (fname));
691 loadrc (rcfile, &passThroughArgs);
692 fileloc_reallyFree (g_currentloc);
693 g_currentloc = oloc;
694 }
695 else
696 {
697 showHerald ();
698 lldiagmsg (message ("Options file not found: %s",
699 cstring_fromChars (fname)));
700 }
701 }
702 else
703 llfatalerror
704 (cstring_makeLiteral ("Flag f to select options file "
705 "requires an argument"));
706 }
707 else
708 {
709 ; /* wait to process later */
710 }
711 }
712 }
713
714 if (fname == NULL)
715 {
716 if (!cstring_isEmpty (home)) {
717 fname = cstring_toCharsSafe (message ("%s%h%s", home, CONNECTCHAR,
718 cstring_fromChars (RCFILE)));
719 mstring_markFree (fname);
720 }
721 }
722
723 setCodePoint ();
724
725 if (!nof && defaultf)
726 {
727 if (!mstring_isEmpty (fname)) {
728 rcfile = fopen (fname, "r");
729
730 if (rcfile != NULL)
731 {
732 fileloc oloc = g_currentloc;
733
734 g_currentloc = fileloc_createRc (cstring_fromChars (fname));
735 loadrc (rcfile, &passThroughArgs);
736 fileloc_reallyFree (g_currentloc);
737 g_currentloc = oloc;
738 }
739 }
740
741# if defined(MSDOS) || defined(OS2)
742 fname = cstring_toCharsSafe (message ("%s",
743 cstring_fromChars (RCFILE)));
744# else
745 fname = cstring_toCharsSafe (message ("./%s",
746 cstring_fromChars (RCFILE)));
747# endif
748
749 rcfile = fopen (fname, "r");
750
751 if (rcfile != NULL)
752 {
753 fileloc oloc = g_currentloc;
754
755 g_currentloc = fileloc_createRc (cstring_fromChars (fname));
756 loadrc (rcfile, &passThroughArgs);
757 fileloc_reallyFree (g_currentloc);
758 g_currentloc = oloc;
759 }
760
761 sfree (fname);
762 }
763 }
764
765 setCodePoint ();
766
767 for (i = 1; i < argc; i++)
768 {
769 char *thisarg;
770 flagcode opt;
771
772 thisarg = argv[i];
773
774 if (showhelp)
775 {
776 if (allhelp)
777 {
778 showHerald ();
779 }
780
781 allhelp = FALSE;
782
783 if (*thisarg == '-' || *thisarg == '+')
784 {
785 thisarg++; /* skip '-' */
786 }
787 if (mstring_equal (thisarg, "modes"))
788 {
789 llmsg (describeModes ());
790 }
791 else if (mstring_equal (thisarg, "vars")
792 || mstring_equal (thisarg, "env"))
793 {
794 describeVars ();
795 }
796 else if (mstring_equal (thisarg, "annotations"))
797 {
798 printAnnotations ();
799 }
800 else if (mstring_equal (thisarg, "parseerrors"))
801 {
802 printParseErrors ();
803 }
804 else if (mstring_equal (thisarg, "comments"))
805 {
806 printComments ();
807 }
808 else if (mstring_equal (thisarg, "prefixcodes"))
809 {
810 describePrefixCodes ();
811 }
812 else if (mstring_equal (thisarg, "references")
813 || mstring_equal (thisarg, "refs"))
814 {
815 printReferences ();
816 }
817 else if (mstring_equal (thisarg, "mail"))
818 {
819 printMail ();
820 }
821 else if (mstring_equal (thisarg, "maintainer")
822 || mstring_equal (thisarg, "version"))
823 {
824 printMaintainer ();
825 }
826 else if (mstring_equal (thisarg, "flags"))
827 {
828 if (i + 1 < argc)
829 {
830 char *next = argv[i + 1];
831
832 if (specialFlagsHelp (next))
833 {
834 i++;
835 }
836 else
837 {
838 flagkind k = identifyCategory (cstring_fromChars (next));
839
840 if (k != FK_NONE)
841 {
842 printCategory (k);
843 i++;
844 }
845 }
846 }
847 else
848 {
849 printFlags ();
850 }
851 }
852 else
853 {
854 cstring s = describeFlag (cstring_fromChars (thisarg));
855
856 if (cstring_isDefined (s))
857 {
858 llmsg (s);
859 }
860 }
861 }
862 else
863 {
864 if (*thisarg == '-' || *thisarg == '+')
865 {
866 bool set = (*thisarg == '+');
867 cstring flagname;
868
869 thisarg++; /* skip '-' */
870 flagname = cstring_fromChars (thisarg);
871
872 opt = identifyFlag (flagname);
873
874 if (flagcode_isSkip (opt))
875 {
876 ;
877 }
878 else if (flagcode_isInvalid (opt))
879 {
880 if (isMode (flagname))
881 {
882 context_setMode (flagname);
883 }
884 else
885 {
886 llgloberror (message ("Unrecognized option: %s",
887 cstring_fromChars (thisarg)));
888 }
889 }
890 else
891 {
892 context_userSetFlag (opt, set);
893
894 if (flagcode_hasArgument (opt))
895 {
896 if (opt == FLG_HELP)
897 {
898 showhelp = TRUE;
899 }
900 else if (flagcode_isPassThrough (opt)) /* -D or -U */
901 {
902 passThroughArgs = cstringSList_add
903 (passThroughArgs, cstring_fromChars (thisarg));
904 }
905 else if (flagcode_hasValue (opt))
906 {
907 if (++i < argc)
908 {
909 setValueFlag (opt, cstring_fromChars (argv[i]));
910 }
911 else
912 {
913 llfatalerror
914 (message
915 ("Flag %s must be followed by a number",
916 flagcode_unparse (opt)));
917 }
918 }
919 else if (opt == FLG_INCLUDEPATH || opt == FLG_SPECPATH)
920 {
921 cstring dir = cstring_suffix (cstring_fromChars (thisarg), 1); /* skip over I */
922
923 switch (opt)
924 {
925 case FLG_INCLUDEPATH:
926 cppAddIncludeDir (dir);
927 /*@switchbreak@*/ break;
928 case FLG_SPECPATH:
929 /*@-mustfree@*/
930 g_localSpecPath = cstring_toCharsSafe
931 (message ("%s%h%s",
932 cstring_fromChars (g_localSpecPath),
933 SEPCHAR,
934 dir));
935 /*@=mustfree@*/
936 /*@switchbreak@*/ break;
937 BADDEFAULT;
938 }
939 }
940 else if (flagcode_hasString (opt)
941 || opt == FLG_INIT || opt == FLG_OPTF)
942 {
943 if (++i < argc)
944 {
945 cstring arg = cstring_fromChars (argv[i]);
946
947 if (opt == FLG_OPTF)
948 {
949 ; /* -f already processed */
950 }
951 else if (opt == FLG_INIT)
952 {
953# ifndef NOLCL
954 initFile = tsource_create
955 (cstring_toCharsSafe (arg),
956 LCLINIT_SUFFIX, FALSE);
957# endif
958 break;
959 }
960 else
961 {
962 setStringFlag (opt, arg);
963 }
964 }
965 else
966 {
967 llfatalerror
968 (message
969 ("Flag %s must be followed by a string",
970 flagcode_unparse (opt)));
971 }
972 }
973 else
974 {
975 /* no argument */
976 }
977 }
978 }
979 }
980 else /* its a filename */
981 {
982 fl = cstringSList_add (fl, cstring_fromChars (thisarg));
983 }
984 }
985 }
986
987 setCodePoint ();
988
989 /*
990 ** create lists of C and LCL files
991 */
992
993 cstringSList_elements (fl, current)
994 {
995 char *fname = cstring_toCharsSafe (current);
996 char *ext = strrchr (fname, '.');
997
998 if (ext == NULL)
999 {
1000 /* no extension --- both C and LCL with default extensions */
1001
1002 addFile (cfiles, message ("%s.c", cstring_fromChars (fname)));
1003 addFile (lclfiles, message ("%s.lcl", cstring_fromChars (fname)));
1004 }
1005 else if (isCext (ext))
1006 {
1007 addFile (cfiles, cstring_fromCharsNew (fname));
1008 }
1009 else
1010 {
1011 if (!mstring_equal (ext, ".lcl"))
1012 {
1013 lldiagmsg (message ("Unrecognized file extension: %s (assuming lcl)",
1014 cstring_fromChars (ext)));
1015 }
1016
1017 addFile (lclfiles, cstring_fromCharsNew (fname));
1018 }
1019 } end_cstringSList_elements;
1020
1021
1022 showHerald ();
1023
1024
1025 if (showhelp)
1026 {
1027 if (allhelp)
1028 {
1029 showHelp ();
1030 }
1031 fprintf (g_msgstream, "\n");
1032
1033 fileIdList_free (cfiles);
1034 fileIdList_free (lclfiles);
1035
1036 llexit (LLSUCCESS);
1037 }
1038
1039# ifdef DOANNOTS
1040 initAnnots ();
1041# endif
1042
1043 inittime = clock ();
1044
1045 context_resetErrors ();
1046 context_clearInCommandLine ();
1047
1048 anylcl = !fileIdList_isEmpty (lclfiles);
1049
1050 if (context_doMerge ())
1051 {
1052 cstring m = context_getMerge ();
1053
1054 if (context_getFlag (FLG_SHOWSCAN))
1055 {
1056 fprintf (g_msgstream, "< loading %s ", cstring_toCharsSafe (m));
1057 }
1058
1059 loadState (m);
1060
1061 if (context_getFlag (FLG_SHOWSCAN))
1062 {
1063 fprintf (g_msgstream, " >\n");
1064 }
1065
1066 if (!usymtab_existsType (context_getBoolName ()))
1067 {
1068 usymtab_initBool ();
1069 }
1070 }
1071 else
1072 {
1073 if (!context_getFlag (FLG_NOLIB) && loadStandardState ())
1074 {
1075 ;
1076 }
1077 else
1078 {
1079 ctype_initTable ();
1080 }
1081
1082 /* setup bool type and constants */
1083 usymtab_initBool ();
1084 }
1085
1086 fileloc_free (g_currentloc);
1087 g_currentloc = fileloc_createBuiltin ();
1088
1089 libtime = clock ();
1090
1091 if (anylcl)
1092 {
1093# ifdef NOLCL
1094 llfatalerror (cstring_makeLiteral ("This version of LCLint does not handle LCL files."));
1095# else
1096 lslProcess (lclfiles);
1097# endif
1098 }
1099
1100 /*
1101 ** pre-processing
1102 **
1103 ** call the pre-preprocessor and /lib/cpp to generate appropriate
1104 ** files
1105 **
1106 */
1107
1108 context_setInCommandLine ();
1109
1110 cppReader_initialize ();
1111
1112 DPRINTF (("Pass through: %s", cstringSList_unparse (passThroughArgs)));
1113
1114 cstringSList_elements (passThroughArgs, thisarg) {
1115 handlePassThroughFlag (cstring_toCharsSafe (thisarg));
1116 } end_cstringSList_elements;
1117
1118 cstringSList_free (passThroughArgs);
1119
1120 cleanupMessages ();
1121
1122 cppReader_saveDefinitions ();
1123
1124 context_clearInCommandLine ();
1125
1126 if (!context_getFlag (FLG_NOPP))
1127 {
1128 llflush ();
1129
1130 if (context_getFlag (FLG_SHOWSCAN))
1131 {
1132 fprintf (stderr, "< preprocessing");
1133 }
1134
1135 lcltime = clock ();
1136
1137 context_setPreprocessing ();
1138 dercfiles = preprocessFiles (cfiles);
1139 context_clearPreprocessing ();
1140
1141 fileIdList_free (cfiles);
1142
1143 if (context_getFlag (FLG_SHOWSCAN))
1144 {
1145 fprintf (stderr, " >\n");
1146 }
1147
1148 pptime = clock ();
1149 }
1150 else
1151 {
1152 lcltime = clock ();
1153 dercfiles = cfiles;
1154 pptime = clock ();
1155 }
1156
1157 /*
1158 ** now, check all the corresponding C files
1159 **
1160 ** (for now these are just <file>.c, but after pre-processing
1161 ** will be <tmpprefix>.<file>.c)
1162 */
1163
1164 {
1165# ifdef WIN32
1166 int nfiles = /*@-unrecog@*/ _fcloseall (); /*@=unrecog@*/
1167
1168 if (nfiles != 0)
1169 {
1170 llbug (message ("Files unclosed: %d", nfiles));
1171 }
1172# endif
1173 }
1174
1175 exprNode_initMod ();
1176
1177 fileIdList_elements (dercfiles, fid)
1178 {
1179 sourceFile = tsource_create (cstring_toCharsSafe (fileName (fid)),
1180 C_SUFFIX, TRUE);
1181 context_setFileId (fid);
1182
1183 /* Open source file */
1184
1185 if (sourceFile == (tsource *) 0 || (!tsource_open (sourceFile)))
1186 {
1187 /* previously, this was ignored ?! */
1188 llbug (message ("Could not open temp file: %s", fileName (fid)));
1189 }
1190 else
1191 {
1192 yyin = sourceFile->file; /*< shared <- only */
1193
1194 llassert (yyin != NULL);
1195
1196 if (context_getFlag (FLG_SHOWSCAN))
1197 {
1198 lldiagmsg (message ("< checking %s >", rootFileName (fid)));
1199 }
1200
1201 /*
1202 ** Every time, except the first time, through the loop,
1203 ** need to call yyrestart to clean up the parse buffer.
1204 */
1205
1206 if (!first_time)
1207 {
1208 (void) yyrestart (yyin);
1209 }
1210 else
1211 {
1212 first_time = FALSE;
1213 }
1214
1215 context_enterFile ();
1216 (void) yyparse ();
1217 context_exitFile ();
1218
1219 (void) tsource_close (sourceFile);
1220 }
1221
1222 } end_fileIdList_elements;
1223
1224 cptime = clock ();
1225
1226 /* process any leftover macros */
1227
1228 context_processAllMacros ();
1229
1230 /* check everything that was specified was defined */
1231
1232 /* don't check if no c files were processed ?
1233 ** is this correct behaviour?
1234 */
1235
1236 if (context_getFlag (FLG_SHOWSCAN))
1237 {
1238 lldiagmsg (cstring_makeLiteral ("< global checks >"));
1239 }
1240
1241 cleanupMessages ();
1242
1243 if (context_getLinesProcessed () > 0)
1244 {
1245 usymtab_allDefined ();
1246 }
1247
1248 if (context_maybeSet (FLG_TOPUNUSED))
1249 {
1250 uentry ue = usymtab_lookupSafe (cstring_makeLiteralTemp ("main"));
1251
1252 if (uentry_isValid (ue))
1253 {
1254 uentry_setUsed (ue, fileloc_observeBuiltin ());
1255 }
1256
1257 usymtab_allUsed ();
1258 }
1259
1260 if (context_maybeSet (FLG_EXPORTLOCAL))
1261 {
1262 usymtab_exportLocal ();
1263 }
1264
1265
1266 if (context_maybeSet (FLG_EXPORTHEADER))
1267 {
1268 usymtab_exportHeader ();
1269 }
1270
1271 if (context_getFlag (FLG_SHOWUSES))
1272 {
1273 usymtab_displayAllUses ();
1274 }
1275
1276 context_checkSuppressCounts ();
1277
1278 if (context_doDump ())
1279 {
1280 cstring dump = context_getDump ();
1281
1282 dumpState (dump);
1283 }
1284
1285# ifdef DOANNOTS
1286 printAnnots ();
1287# endif
1288
1289 cleanupFiles ();
1290
1291 if (context_getFlag (FLG_SHOWSUMMARY))
1292 {
1293 summarizeErrors ();
1294 }
1295
1296 if (!context_getFlag (FLG_QUIET))
1297 {
1298 cstring specErrors = cstring_undefined;
1299# ifndef NOLCL
1300 int nspecErrors = lclNumberErrors ();
1301# endif
1302
1303 if (context_neednl ())
1304 fprintf (g_msgstream, "\n");
1305
1306# ifndef NOLCL
1307 if (nspecErrors > 0)
1308 {
1309 if (nspecErrors == context_getLCLExpect ())
1310 {
1311 specErrors =
1312 message ("%d spec error%p found, as expected\n ",
1313 nspecErrors);
1314 }
1315 else
1316 {
1317 if (context_getLCLExpect () > 0)
1318 {
1319 specErrors =
1320 message ("%d spec error%p found, expected %d\n ",
1321 nspecErrors,
1322 (int) context_getLCLExpect ());
1323 }
1324 else
1325 {
1326 specErrors = message ("%d spec error%p found\n ",
1327 nspecErrors);
1328 }
1329 }
1330 }
1331 else
1332 {
1333 if (context_getLCLExpect () > 0)
1334 {
1335 specErrors = message ("No spec errors found, expected %d\n ",
1336 (int) context_getLCLExpect ());
1337 }
1338 }
1339# endif
1340
1341 if (context_anyErrors ())
1342 {
1343 if (context_numErrors () == context_getExpect ())
1344 {
1345 llmsg (message ("Finished LCLint checking --- "
1346 "%s%d code error%p found, as expected",
1347 specErrors, context_numErrors ()));
1348 }
1349 else
1350 {
1351 if (context_getExpect () > 0)
1352 {
1353 llmsg (message
1354 ("Finished LCLint checking --- "
1355 "%s%d code error%p found, expected %d",
1356 specErrors, context_numErrors (),
1357 (int) context_getExpect ()));
1358 }
1359 else
1360 {
1361 llmsg (message ("Finished LCLint checking --- "
1362 "%s%d code error%p found",
1363 specErrors, context_numErrors ()));
1364 }
1365 }
1366 }
1367 else
1368 {
1369 if (context_getExpect () > 0)
1370 {
1371 llmsg (message
1372 ("Finished LCLint checking --- "
1373 "%sno code errors found, expected %d",
1374 specErrors,
1375 (int) context_getExpect ()));
1376 }
1377 else
1378 {
1379 if (context_getLinesProcessed () > 0)
1380 {
1381 llmsg (message ("Finished LCLint checking --- %sno code errors found",
1382 specErrors));
1383 }
1384 else
1385 {
1386 llmsg (message ("Finished LCLint checking --- %sno code processed",
1387 specErrors));
1388 }
1389 }
1390 }
1391
1392 cstring_free (specErrors);
1393 }
1394
1395 if (context_getFlag (FLG_STATS))
1396 {
1397 clock_t ttime = clock () - before;
1398 int specLines = context_getSpecLinesProcessed ();
1399
1400 rstime = clock ();
1401
1402 if (specLines > 0)
1403 {
1404 fprintf (g_msgstream, "%d spec, ", specLines);
1405 }
1406
1407# ifndef CLOCKS_PER_SEC
1408 fprintf (g_msgstream, "%d source lines in %ld time steps (steps/sec unknown)\n",
1409 context_getLinesProcessed (),
1410 (long) ttime);
1411# else
1412 fprintf (g_msgstream, "%d source lines in %.2f s.\n",
1413 context_getLinesProcessed (),
1414 (double) ttime / CLOCKS_PER_SEC);
1415# endif
1416 }
1417 else
1418 {
1419 rstime = clock ();
1420 }
1421
1422 if (context_getFlag (FLG_TIMEDIST))
1423 {
1424 clock_t ttime = clock () - before;
1425
1426 if (ttime > 0)
1427 {
1428 char *msg = (char *) dmalloc (256 * sizeof (*msg));
1429
1430 if (anylcl)
1431 {
1432 sprintf (msg,
1433 "Time distribution (percent): initialize %.2f / lcl %.2f / "
1434 "pre-process %.2f / c check %.2f / finalize %.2f \n",
1435 (100.0 * (double) (libtime - before) / ttime),
1436 (100.0 * (double) (lcltime - libtime) / ttime),
1437 (100.0 * (double) (pptime - lcltime) / ttime),
1438 (100.0 * (double) (cptime - pptime) / ttime),
1439 (100.0 * (double) (rstime - cptime) / ttime));
1440 }
1441 else
1442 {
1443 sprintf (msg,
1444 "Time distribution (percent): initialize %.2f / "
1445 "pre-process %.2f / c check %.2f / finalize %.2f \n",
1446 (100.0 * (double) (libtime - before) / ttime),
1447 (100.0 * (double) (pptime - libtime) / ttime),
1448 (100.0 * (double) (cptime - pptime) / ttime),
1449 (100.0 * (double) (rstime - cptime) / ttime));
1450 }
1451
1452 llgenindentmsgnoloc (cstring_fromCharsO (msg));
1453 }
1454 }
1455
1456 llexit (LLSUCCESS);
1457}
1458
1459/*
1460** Reenable return value warnings.
1461*/
1462
1463#pragma warning (default:4035)
1464
1465void
1466showHelp (void)
1467{
1468 showHerald ();
1469
1470 llmsglit ("Source files are .c, .h and .lcl files. If there is no suffix,");
1471 llmsglit (" LCLint will look for <file>.c and <file>.lcl.");
1472 llmsglit ("");
1473 llmsglit ("Use lclint -help <topic or flag name> for more information");
1474 llmsglit ("");
1475 llmsglit ("Topics:");
1476 llmsglit ("");
1477 llmsglit (" annotations (describes source-code annotations)");
1478 llmsglit (" comments (describes control comments)");
1479 llmsglit (" flags (describes flag categories)");
1480 llmsglit (" flags <category> (describes flags in category)");
1481 llmsglit (" flags all (short description of all flags)");
1482 llmsglit (" flags alpha (list all flags alphabetically)");
1483 llmsglit (" flags full (full description of all flags)");
1484 llmsglit (" mail (information on mailing lists)");
1485 llmsglit (" modes (show mode settings)");
1486 llmsglit (" parseerrors (help on handling parser errors)");
1487 llmsglit (" prefixcodes (character codes in namespace prefixes)");
1488 llmsglit (" references (sources for more information)");
1489 llmsglit (" vars (environment variables)");
1490 llmsglit (" version (information on compilation, maintainer)");
1491 llmsglit ("");
1492}
1493
1494static bool
1495specialFlagsHelp (char *next)
1496{
1497 if ((next != NULL) && (*next != '-') && (*next != '+'))
1498 {
1499 if (mstring_equal (next, "alpha"))
1500 {
1501 printAlphaFlags ();
1502 return TRUE;
1503 }
1504 else if (mstring_equal (next, "all"))
1505 {
1506 printAllFlags (TRUE, FALSE);
1507 return TRUE;
1508 }
1509 else if (mstring_equal (next, "categories")
1510 || mstring_equal (next, "cats"))
1511 {
1512 listAllCategories ();
1513 return TRUE;
1514 }
1515 else if (mstring_equal (next, "full"))
1516 {
1517 printAllFlags (FALSE, TRUE);
1518 return TRUE;
1519 }
1520 else
1521 {
1522 return FALSE;
1523 }
1524 }
1525 else
1526 {
1527 return FALSE;
1528 }
1529}
1530
1531void
1532printParseErrors (void)
1533{
1534 llmsglit ("Parse Errors");
1535 llmsglit ("------------");
1536 llmsglit ("");
1537 llmsglit ("LCLint will sometimes encounter a parse error for code that "
1538 "can be parsed with a local compiler. There are a few likely "
1539 "causes for this and a number of techniques that can be used "
1540 "to work around the problem.");
1541 llmsglit ("");
1542 llmsglit ("Compiler extensions --- compilers sometimes extend the C "
1543 "language with compiler-specific keywords and syntax. While "
1544 "it is not advisible to use these, oftentimes one has no choice "
1545 "when the system header files use compiler extensions. ");
1546 llmsglit ("");
1547 llmsglit ("LCLint supports some of the GNU (gcc) compiler extensions, "
1548 "if the +gnuextensions flag is set. You may be able to workaround "
1549 "other compiler extensions by using a pre-processor define. "
1550 "Alternately, you can surround the unparseable code with");
1551 llmsglit ("");
1552 llmsglit (" # ifndef __LCLINT__");
1553 llmsglit (" ...");
1554 llmsglit (" # endif");
1555 llmsglit ("");
1556 llmsglit ("Missing type definitions --- an undefined type name will usually "
1557 "lead to a parse error. This ofter occurs when a standard header "
1558 "file defines some type that is not part of the standard library. ");
1559 llmsglit ("By default, LCLint does not process the local files corresponding "
1560 "to standard library headers, but uses a library specification "
1561 "instead so dependencies on local system headers can be detected. "
1562 "If another system header file that does not correspond to a "
1563 "standard library header uses one of these superfluous types, "
1564 "a parse error will result.");
1565 llmsglit ("");
1566 llmsglit ("If the parse error is inside a posix standard header file, the "
1567 "first thing to try is +posixlib. This make LCLint use "
1568 "the posix library specification instead of reading the posix "
1569 "header files.");
1570 llmsglit ("");
1571 llmsglit ("Otherwise, you may need to either manually define the problematic "
1572 "type (e.g., add -Dmlink_t=int to your .lclintrc file) or force "
1573 "lclint to process the header file that defines it. This is done "
1574 "by setting -skipansiheaders or -skipposixheaders before "
1575 "the file that defines the type is #include'd.");
1576 llmsglit ("(See lclint -help "
1577 "skipansiheaders and lclint -help skipposixheaders for a list of "
1578 "standard headers.) For example, if <sys/local.h> uses a type "
1579 "defined by posix header <sys/types.h> but not defined by the "
1580 "posix library, we might do: ");
1581 llmsglit ("");
1582 llmsglit (" /*@-skipposixheaders@*/");
1583 llmsglit (" # include <sys/types.h>");
1584 llmsglit (" /*@=skipposixheaders@*/");
1585 llmsglit (" # include <sys/local.h>");
1586 llmsglit ("");
1587 llmsglit ("to force LCLint to process <sys/types.h>.");
1588 llmsglit ("");
1589 llmsglit ("At last resort, +trytorecover can be used to make LCLint attempt "
1590 "to continue after a parse error. This is usually not successful "
1591 "and the author does not consider assertion failures when +trytorecover "
1592 "is used to be bugs.");
1593}
1594
1595void
1596printAnnotations (void)
1597{
1598 llmsglit ("Annotations");
1599 llmsglit ("-----------");
1600 llmsglit ("");
1601 llmsglit ("Annotations are stylized comments that document certain "
1602 "assumptions about functions, variables, parameters, and types. ");
1603 llmsglit ("");
1604 llmsglit ("They may be used to indicate where the representation of a "
1605 "user-defined type is hidden, to limit where a global variable may "
1606 "be used or modified, to constrain what a function implementation "
1607 "may do to its parameters, and to express checked assumptions about "
1608 "variables, types, structure fields, function parameters, and "
1609 "function results.");
1610 llmsglit ("");
1611 llmsglit ("Annotations are introduced by \"/*@\". The role of the @ may be "
1612 "played by any printable character, selected using -commentchar <char>.");
1613 llmsglit ("");
1614 llmsglit ("Consult the User's Guide for descriptions of checking associated with each annotation.");
1615 llmsglit ("");
1616 llmsglit ("Globals: (in function declarations)");
1617 llmsglit (" /*@globals <globitem>,+ @*/");
1618 llmsglit (" globitem is an identifier, internalState or fileSystem");
1619 llmsglit ("");
1620 llmsglit ("Modifies: (in function declarations)");
1621 llmsglit (" /*@modifies <moditem>,+ @*/");
1622 llmsglit (" moditem is an lvalue");
1623 llmsglit (" /*@modifies nothing @*/");
1624 llmsglit (" /*@*/ (Abbreviation for no globals and modifies nothing.)");
1625 llmsglit ("");
1626 llmsglit ("Iterators:");
1627 llmsglit (" /*@iter <identifier> (<parameter-type-list>) @*/ - declare an iterator");
1628 llmsglit ("");
1629 llmsglit ("Constants:");
1630 llmsglit (" /*@constant <declaration> @*/ - declares a constant");
1631 llmsglit ("");
1632 llmsglit ("Alternate Types:");
1633 llmsglit (" /*@alt <basic-type>,+ @*/");
1634 llmsglit (" (e.g., int /*@alt char@*/ is a type matching either int or char)");
1635 llmsglit ("");
1636 llmsglit ("Declarator Annotations");
1637 llmsglit ("");
1638 llmsglit ("Type Definitions:");
1639 llmsglit (" /*@abstract@*/ - representation is hidden from clients");
1640 llmsglit (" /*@concrete@*/ - representation is visible to clients");
1641 llmsglit (" /*@immutable@*/ - instances of the type cannot change value");
1642 llmsglit (" /*@mutable@*/ - instances of the type can change value");
1643 llmsglit (" /*@refcounted@*/ - reference counted type");
1644 llmsglit ("");
1645 llmsglit ("Global Variables:");
1646 llmsglit (" /*@unchecked@*/ - weakest checking for global use");
1647 llmsglit (" /*@checkmod@*/ - check modification by not use of global");
1648 llmsglit (" /*@checked@*/ - check use and modification of global");
1649 llmsglit (" /*@checkedstrict@*/ - check use of global strictly");
1650 llmsglit ("");
1651 llmsglit ("Memory Management:");
1652 llmsglit (" /*@dependent@*/ - a reference to externally-owned storage");
1653 llmsglit (" /*@keep@*/ - a parameter that is kept by the called function");
1654 llmsglit (" /*@killref@*/ - a refcounted parameter, killed by the call");
1655 llmsglit (" /*@only@*/ - an unshared reference");
1656 llmsglit (" /*@owned@*/ - owner of storage that may be shared by /*@dependent@*/ references");
1657 llmsglit (" /*@shared@*/ - shared reference that is never deallocated");
1658 llmsglit (" /*@temp@*/ - temporary parameter");
1659 llmsglit ("");
1660 llmsglit ("Aliasing:");
1661 llmsglit (" /*@unique@*/ - may not be aliased by any other visible reference");
1662 llmsglit (" /*@returned@*/ - may be aliased by the return value");
1663 llmsglit ("");
1664 llmsglit ("Exposure:");
1665 llmsglit (" /*@observer@*/ - reference that cannot be modified");
1666 llmsglit (" /*@exposed@*/ - exposed reference to storage in another object");
1667 llmsglit ("");
1668 llmsglit ("Definition State:");
1669 llmsglit (" /*@out@*/ - storage reachable from reference need not be defined");
1670 llmsglit (" /*@in@*/ - all storage reachable from reference must be defined");
1671 llmsglit (" /*@partial@*/ - partially defined, may have undefined fields");
1672 llmsglit (" /*@reldef@*/ - relax definition checking");
1673 llmsglit ("");
1674 llmsglit ("Global State: (for globals lists, no /*@, since list is already in /*@\'s)");
1675 llmsglit (" undef - variable is undefined before the call");
1676 llmsglit (" killed - variable is undefined after the call");
1677 llmsglit ("");
1678 llmsglit ("Null State:");
1679 llmsglit (" /*@null@*/ - possibly null pointer");
1680 llmsglit (" /*@notnull@*/ - non-null pointer");
1681 llmsglit (" /*@relnull@*/ - relax null checking");
1682 llmsglit ("");
1683 llmsglit ("Null Predicates:");
1684 llmsglit (" /*@truenull@*/ - if result is TRUE, first parameter is NULL");
1685 llmsglit (" /*@falsenull@*/ - if result is TRUE, first parameter is not NULL");
1686 llmsglit ("");
1687 llmsglit ("Execution:");
1688 llmsglit (" /*@exits@*/ - function never returns");
1689 llmsglit (" /*@mayexit@*/ - function may or may not return");
1690 llmsglit (" /*@trueexit@*/ - function does not return if first parameter is TRUE");
1691 llmsglit (" /*@falseexit@*/ - function does not return if first parameter if FALSE");
1692 llmsglit (" /*@neverexit@*/ - function always returns");
1693 llmsglit ("");
1694 llmsglit ("Side-Effects:");
1695 llmsglit (" /*@sef@*/ - corresponding actual parameter has no side effects");
1696 llmsglit ("");
1697 llmsglit ("Declaration:");
1698 llmsglit (" /*@unused@*/ - need not be used (no unused errors reported)");
1699 llmsglit (" /*@external@*/ - defined externally (no undefined error reported)");
1700 llmsglit ("");
1701 llmsglit ("Case:");
1702 llmsglit (" /*@fallthrough@*/ - fall-through case");
1703 llmsglit ("");
1704 llmsglit ("Break:");
1705 llmsglit (" /*@innerbreak@*/ - break is breaking an inner loop or switch");
1706 llmsglit (" /*@loopbreak@*/ - break is breaking a loop");
1707 llmsglit (" /*@switchbreak@*/ - break is breaking a switch");
1708 llmsglit (" /*@innercontinue@*/ - continue is continuing an inner loop");
1709 llmsglit ("");
1710 llmsglit ("Unreachable Code:");
1711 llmsglit (" /*@notreached@*/ - statement may be unreachable.");
1712 llmsglit ("");
1713 llmsglit ("Special Functions:");
1714 llmsglit (" /*@printflike@*/ - check variable arguments like printf");
1715 llmsglit (" /*@scanflike@*/ - check variable arguments like scanf");
1716}
1717
1718void
1719printComments (void)
1720{
1721 llmsglit ("Control Comments");
1722 llmsglit ("----------------");
1723 llmsglit ("");
1724 llmsglit ("Setting Flags");
1725 llmsglit ("");
1726 llmsglit ("Most flags (all except those characterized as \"globally-settable only\") can be set locally using control comments. A control comment can set flags locally to override the command line settings. The original flag settings are restored before processing the next file.");
1727 llmsglit ("");
1728 llmsglit ("The syntax for setting flags in control comments is the same as that of the command line, except that flags may also be preceded by = to restore their setting to the original command-line value. For instance,");
1729 llmsglit (" /*@+boolint -modifies =showfunc@*/");
1730 llmsglit ("sets boolint on (this makes bool and int indistinguishable types), sets modifies off (this prevents reporting of modification errors), and sets showfunc to its original setting (this controls whether or not the name of a function is displayed before a message).");
1731 llmsglit ("");
1732 llmsglit ("Error Suppression");
1733 llmsglit ("");
1734 llmsglit ("Several comments are provided for suppressing messages. In general, it is usually better to use specific flags to suppress a particular error permanently, but the general error suppression flags may be more convenient for quickly suppressing messages for code that will be corrected or documented later.");
1735 llmsglit ("");
1736 llmsglit ("/*@ignore@*/ ... /*@end@*/");
1737 llgenindentmsgnoloc
1738 (cstring_makeLiteral
1739 ("No errors will be reported in code regions between /*@ignore@*/ and /*@end@*/. These comments can be used to easily suppress an unlimited number of messages."));
1740 llmsglit ("/*@i@*/");
1741 llgenindentmsgnoloc
1742 (cstring_makeLiteral
1743 ("No errors will be reported from an /*@i@*/ comment to the end of the line."));
1744 llmsglit ("/*@i<n>@*/");
1745 llgenindentmsgnoloc
1746 (cstring_makeLiteral
1747 ("No errors will be reported from an /*@i<n>@*/ (e.g., /*@i3@*/) comment to the end of the line. If there are not exactly n errors suppressed from the comment point to the end of the line, LCLint will report an error."));
1748 llmsglit ("/*@t@*/, /*@t<n>@*/");
1749 llgenindentmsgnoloc
1750 (cstring_makeLiteral
1751 ("Like i and i<n>, except controlled by +tmpcomments flag. These can be used to temporarily suppress certain errors. Then, -tmpcomments can be set to find them again."));
1752 llmsglit ("");
1753 llmsglit ("Type Access");
1754 llmsglit ("");
1755 llmsglit ("/*@access <type>@*/");
1756 llmsglit (" Allows the following code to access the representation of <type>");
1757 llmsglit ("/*@noaccess <type>@*/");
1758 llmsglit (" Hides the representation of <type>");
1759 llmsglit ("");
1760 llmsglit ("Macro Expansion");
1761 llmsglit ("");
1762 llmsglit ("/*@notfunction@*/");
1763 llgenindentmsgnoloc
1764 (cstring_makeLiteral
1765 ("Indicates that the next macro definition is not intended to be a "
1766 "function, and should be expanded in line instead of checked as a "
1767 "macro function definition."));
1768}
1769
1770
1771void
1772printFlags (void)
1773{
1774 llmsglit ("Flag Categories");
1775 llmsglit ("---------------");
1776 listAllCategories ();
1777 llmsglit ("\nTo see the flags in a flag category, do\n lclint -help flags <category>");
1778 llmsglit ("To see a list of all flags in alphabetical order, do\n lclint -help flags alpha");
1779 llmsglit ("To see a full description of all flags, do\n lclint -help flags full");
1780}
1781
1782void
1783printMaintainer (void)
1784{
1785 llmsg (message ("Maintainer: %s", cstring_makeLiteralTemp (LCLINT_MAINTAINER)));
1786 llmsglit (LCL_COMPILE);
1787}
1788
1789void
1790printMail (void)
1791{
1792 llmsglit ("Mailing Lists");
1793 llmsglit ("-------------");
1794 llmsglit ("");
1795 llmsglit ("There are two mailing lists associated with LCLint: ");
1796 llmsglit ("");
1797 llmsglit (" lclint-announce@virginia.edu");
1798 llmsglit ("");
1799 llmsglit (" Reserved for announcements of new releases and bug fixes.");
1800 llmsglit (" To subscribe, send a message to majordomo@virginia.edu with body: ");
1801 llmsglit (" subscribe lclint-announce");
1802 llmsglit ("");
1803 llmsglit (" lclint-interest@virginia.edu");
1804 llmsglit ("");
1805 llmsglit (" Informal discussions on the use and development of lclint.");
1806 llmsglit (" To subscribe, send a message to majordomo@virginia.edu with body: ");
1807 llmsglit (" subscribe lclint-interest");
1808}
1809
1810void
1811printReferences (void)
1812{
1813 llmsglit ("References");
1814 llmsglit ("----------");
1815 llmsglit ("");
1816 llmsglit ("The LCLint web site is http://lclint.cs.virginia.edu");
1817 llmsglit ("");
1818 llmsglit ("Technical papers relating to LCLint include:");
1819 llmsglit ("");
1820 llmsglit (" David Evans. \"Static Detection of Dynamic Memory Errors\".");
1821 llmsglit (" SIGPLAN Conference on Programming Language Design and ");
1822 llmsglit (" Implementation (PLDI '96), Philadelphia, PA, May 1996.");
1823 llmsglit ("");
1824 llmsglit (" David Evans, John Guttag, Jim Horning and Yang Meng Tan. ");
1825 llmsglit (" \"LCLint: A Tool for Using Specifications to Check Code\".");
1826 llmsglit (" SIGSOFT Symposium on the Foundations of Software Engineering,");
1827 llmsglit (" December 1994.");
1828 llmsglit ("");
1829 llmsglit ("A general book on Larch is:");
1830 llmsglit ("");
1831 llmsglit (" Guttag, John V., Horning, James J., (with Garland, S. J., Jones, ");
1832 llmsglit (" K. D., Modet, A., and Wing, J. M.), \"Larch: Languages and Tools ");
1833 llmsglit (" for Formal Specification\", Springer-Verlag, 1993.");
1834}
1835
1836void
1837describePrefixCodes (void)
1838{
1839 llmsglit ("Prefix Codes");
1840 llmsglit ("------------");
1841 llmsglit ("");
1842 llmsglit ("These characters have special meaning in name prefixes:");
1843 llmsglit ("");
1844 llmsg (message (" %h Any uppercase letter [A-Z]", PFX_UPPERCASE));
1845 llmsg (message (" %h Any lowercase letter [a-z]", PFX_LOWERCASE));
1846 llmsg (message (" %h Any character (valid in a C identifier)", PFX_ANY));
1847 llmsg (message (" %h Any digit [0-9]", PFX_DIGIT));
1848 llmsg (message (" %h Any non-uppercase letter [a-z0-9_]", PFX_NOTUPPER));
1849 llmsg (message (" %h Any non-lowercase letter [A-Z0-9_]", PFX_NOTLOWER));
1850 llmsg (message (" %h Any letter [A-Za-z]", PFX_ANYLETTER));
1851 llmsg (message (" %h Any letter or digit [A-Za-z0-9]", PFX_ANYLETTERDIGIT));
1852 llmsglit (" * Zero or more repetitions of the previous character class until the end of the name");
1853}
1854
1855void
1856describeVars (void)
1857{
1858 cstring eval;
1859 char *def;
1860
1861 eval = context_getLarchPath ();
1862 def = osd_getEnvironmentVariable (LARCH_PATH);
1863
1864 if (def != NULL ||
1865 !cstring_equal (eval, cstring_fromChars (DEFAULT_LARCHPATH)))
1866 {
1867 llmsg (message ("LARCH_PATH = %s", eval));
1868 }
1869 else
1870 {
1871 llmsg (message ("LARCH_PATH = <not set> (default = %s)",
1872 cstring_fromChars (DEFAULT_LARCHPATH)));
1873 }
1874
1875 llmsglit (" --- path used to find larch initialization files and LSL traits");
1876
1877 eval = context_getLCLImportDir ();
1878 def = osd_getEnvironmentVariable (LCLIMPORTDIR);
1879
1880 if (def != NULL ||
1881 !cstring_equal (eval, cstring_fromChars (DEFAULT_LCLIMPORTDIR)))
1882 {
1883 llmsg (message ("%q = %s", cstring_makeLiteral (LCLIMPORTDIR), eval));
1884 }
1885 else
1886 {
1887 llmsg (message ("%s = <not set, default: %s>", cstring_makeLiteralTemp (LCLIMPORTDIR),
1888 cstring_makeLiteralTemp (DEFAULT_LCLIMPORTDIR)));
1889 }
1890
1891 llmsglit (" --- directory containing lcl standard library files "
1892 "(import with < ... >)");;
1893
1894 {
1895 cstring dirs = context_getString (FLG_SYSTEMDIRS);
1896 llmsg (message
1897 ("systemdirs = %s (set by include envirnoment variable or -systemdirs)",
1898 dirs));
1899
1900 }
1901}
1902
1903void
1904interrupt (int i)
1905{
1906 switch (i)
1907 {
1908 case SIGINT:
1909 fprintf (stderr, "*** Interrupt\n");
1910 llexit (LLINTERRUPT);
1911 case SIGSEGV:
1912 {
1913 cstring loc;
1914
1915 /* Cheat when there are parse errors */
1916 checkParseError ();
1917
1918 fprintf (stderr, "*** Segmentation Violation\n");
1919
1920 /* Don't catch it if fileloc_unparse causes a signal */
1921 (void) signal (SIGSEGV, NULL);
1922
1923 loc = fileloc_unparse (g_currentloc);
1924
1925 fprintf (stderr, "*** Location (not trusted): %s\n",
1926 cstring_toCharsSafe (loc));
1927 cstring_free (loc);
1928 printCodePoint ();
1929 fprintf (stderr, "*** Please report bug to %s\n", LCLINT_MAINTAINER);
1930 exit (LLGIVEUP);
1931 }
1932 default:
1933 fprintf (stderr, "*** Signal: %d\n", i);
1934 /*@-mustfree@*/
1935 fprintf (stderr, "*** Location (not trusted): %s\n",
1936 cstring_toCharsSafe (fileloc_unparse (g_currentloc)));
1937 /*@=mustfree@*/
1938 printCodePoint ();
1939 fprintf (stderr, "*** Please report bug to %s ***\n", LCLINT_MAINTAINER);
1940 exit (LLGIVEUP);
1941 }
1942}
1943
1944void
1945cleanupFiles (void)
1946{
1947 static bool doneCleanup = FALSE;
1948
1949 /* make sure this is only called once! */
1950
1951 if (doneCleanup) return;
1952
1953 setCodePoint ();
1954
1955 if (context_getFlag (FLG_KEEP))
1956 {
1957 check (fputs ("Temporary files kept:\n", stderr) != EOF);
1958 fileTable_printTemps (context_fileTable ());
1959 }
1960 else
1961 {
1962# ifdef WIN32
1963 int nfiles = /*@-unrecog@*/ _fcloseall (); /*@=unrecog@*/
1964
1965 if (nfiles != 0)
1966 {
1967 llbug (message ("Files unclosed: %d", nfiles));
1968 }
1969# endif
1970 fileTable_cleanup (context_fileTable ());
1971 }
1972
1973 doneCleanup = TRUE;
1974}
1975
1976/*
1977** cleans up temp files (if necessary)
1978** exits lclint
1979*/
1980
1981/*@exits@*/ void
1982llexit (int status)
1983{
1984# ifdef WIN32
1985 if (status == LLFAILURE)
1986 {
1987 _fcloseall ();
1988 }
1989# endif
1990
1991 cleanupFiles ();
1992
1993 if (status != LLFAILURE)
1994 {
1995 context_destroyMod ();
1996 exprNode_destroyMod ();
1997
1998 sRef_destroyMod ();
1999 uentry_destroyMod ();
2000 typeIdSet_destroyMod ();
2001
2002# ifdef USEDMALLOC
2003 dmalloc_shutdown ();
2004# endif
2005 }
2006
2007 exit ((status == LLSUCCESS) ? EXIT_SUCCESS : EXIT_FAILURE);
2008}
2009
2010void
2011loadrc (FILE *rcfile, cstringSList *passThroughArgs)
2012{
2013 char *s = mstring_create (MAX_LINE_LENGTH);
2014 char *os = s;
2015
2016 DPRINTF (("Pass through: %s", cstringSList_unparse (*passThroughArgs)));
2017
2018 s = os;
2019
2020 while (fgets (s, MAX_LINE_LENGTH, rcfile) != NULL)
2021 {
2022 char c;
2023 bool set = FALSE;
2024 char *thisflag;
2025 flagcode opt;
2026
2027 DPRINTF (("Line: %s", s));
2028 DPRINTF (("Pass through: %s", cstringSList_unparse (*passThroughArgs)));
2029 incLine ();
2030
2031 while (*s == ' ' || *s == '\t' || *s == '\n')
2032 {
2033 s++;
2034 incColumn ();
2035 }
2036
2037 while (*s != '\0')
2038 {
2039 bool escaped = FALSE;
2040 bool quoted = FALSE;
2041 c = *s;
2042
2043 DPRINTF (("Process: %s", s));
2044 DPRINTF (("Pass through: %s", cstringSList_unparse (*passThroughArgs)));
2045 /* comment characters */
2046 if (c == '#' || c == ';' || c == '\n')
2047 {
2048 /*@innerbreak@*/
2049 break;
2050 }
2051
2052 if (c == '-' || c == '+')
2053 {
2054 set = (c == '+');
2055 }
2056 else
2057 {
2058 showHerald ();
2059 llerror (FLG_SYNTAX,
2060 message ("Bad flag syntax (+ or - expected, "
2061 "+ is assumed): %s",
2062 cstring_fromChars (s)));
2063 s--;
2064 set = TRUE;
2065 }
2066
2067 s++;
2068 incColumn ();
2069
2070 thisflag = s;
2071
2072 while ((c = *s) != '\0')
2073 { /* remember to handle spaces and quotes in -D and -U ... */
2074 if (escaped)
2075 {
2076 escaped = FALSE;
2077 }
2078 else if (quoted)
2079 {
2080 if (c == '\\')
2081 {
2082 escaped = TRUE;
2083 }
2084 else if (c == '\"')
2085 {
2086 quoted = FALSE;
2087 }
2088 else
2089 {
2090 ;
2091 }
2092 }
2093 else if (c == '\"')
2094 {
2095 quoted = TRUE;
2096 }
2097 else
2098 {
2099 if (c == ' ' || c == '\t' || c == '\n')
2100 {
2101 /*@innerbreak@*/ break;
2102 }
2103 }
2104
2105 s++;
2106 incColumn ();
2107 }
2108
2109 DPRINTF (("Nulling: %c", *s));
2110 *s = '\0';
2111
2112 if (mstring_isEmpty (thisflag))
2113 {
2114 llfatalerror (message ("Missing flag: %s",
2115 cstring_fromChars (os)));
2116 }
2117
2118 DPRINTF (("Flag: %s", thisflag));
2119
2120 opt = identifyFlag (cstring_fromChars (thisflag));
2121
2122 if (flagcode_isSkip (opt))
2123 {
2124 ;
2125 }
2126 else if (flagcode_isInvalid (opt))
2127 {
2128 if (isMode (cstring_fromChars (thisflag)))
2129 {
2130 context_setMode (cstring_fromChars (thisflag));
2131 }
2132 else
2133 {
2134 llerror (FLG_BADFLAG,
2135 message ("Unrecognized option: %s",
2136 cstring_fromChars (thisflag)));
2137 }
2138 }
2139 else
2140 {
2141 context_userSetFlag (opt, set);
2142
2143 if (flagcode_hasArgument (opt))
2144 {
2145 if (opt == FLG_HELP)
2146 {
2147 showHerald ();
2148 llerror (FLG_BADFLAG,
2149 message ("Cannot use help in rc files"));
2150 }
2151 else if (flagcode_isPassThrough (opt)) /* -D or -U */
2152 {
2153 cstring arg = cstring_fromCharsNew (thisflag);
2154 cstring_markOwned (arg);
2155 *passThroughArgs = cstringSList_add (*passThroughArgs, arg);
2156 DPRINTF (("Pass through: %s",
2157 cstringSList_unparse (*passThroughArgs)));
2158 }
2159 else if (opt == FLG_INCLUDEPATH
2160 || opt == FLG_SPECPATH)
2161 {
2162 cstring dir = cstring_suffix (cstring_fromChars (thisflag), 1); /* skip over I/S */
2163
2164 switch (opt)
2165 {
2166 case FLG_INCLUDEPATH:
2167 cppAddIncludeDir (dir);
2168 /*@switchbreak@*/ break;
2169 case FLG_SPECPATH:
2170 /*@-mustfree@*/
2171 g_localSpecPath = cstring_toCharsSafe
2172 (message ("%s:%s", cstring_fromChars (g_localSpecPath), dir));
2173 /*@=mustfree@*/
2174 /*@switchbreak@*/ break;
2175 BADDEFAULT;
2176 }
2177 }
2178 else if (flagcode_hasString (opt)
2179 || flagcode_hasValue (opt)
2180 || opt == FLG_INIT || opt == FLG_OPTF)
2181 {
2182 cstring extra = cstring_undefined;
2183 char *rest, *orest;
2184 char rchar;
2185
2186 *s = c;
2187 rest = mstring_copy (s);
2188 DPRINTF (("Here: rest = %s", rest));
2189 orest = rest;
2190 *s = '\0';
2191
2192 while ((rchar = *rest) != '\0'
2193 && (isspace ((int) rchar)))
2194 {
2195 rest++;
2196 s++;
2197 }
2198
2199 DPRINTF (("Yo: %s", rest));
2200
2201 while ((rchar = *rest) != '\0'
2202 && !isspace ((int) rchar))
2203 {
2204 extra = cstring_appendChar (extra, rchar);
2205 rest++;
2206 s++;
2207 }
2208
2209 DPRINTF (("Yo: %s", extra));
2210 sfree (orest);
2211
2212 if (cstring_isUndefined (extra))
2213 {
2214 showHerald ();
2215 llerror
2216 (FLG_BADFLAG,
2217 message
2218 ("Flag %s must be followed by an argument",
2219 flagcode_unparse (opt)));
2220 }
2221 else
2222 {
2223 s--;
2224
2225 DPRINTF (("Here we are: %s", extra));
2226
2227 if (flagcode_hasValue (opt))
2228 {
2229 DPRINTF (("Set value flag: %s", extra));
2230 setValueFlag (opt, extra);
2231 cstring_free (extra);
2232 }
2233 else if (opt == FLG_OPTF)
2234 {
2235 FILE *innerf = fopen (cstring_toCharsSafe (extra), "r");
2236 cstring_markOwned (extra);
2237
2238 if (innerf != NULL)
2239 {
2240 fileloc fc = g_currentloc;
2241 g_currentloc = fileloc_createRc (extra);
2242 loadrc (innerf, passThroughArgs);
2243 fileloc_reallyFree (g_currentloc);
2244 g_currentloc = fc;
2245 }
2246 else
2247 {
2248 showHerald ();
2249 llerror
2250 (FLG_SYNTAX,
2251 message ("Options file not found: %s",
2252 extra));
2253 }
2254 }
2255 else if (opt == FLG_INIT)
2256 {
2257# ifndef NOLCL
2258 llassert (initFile == NULL);
2259
2260 initFile = tsource_create
2261 (cstring_toCharsSafe (extra),
2262 LCLINIT_SUFFIX, FALSE);
2263 cstring_markOwned (extra);
2264# else
2265 cstring_free (extra);
2266# endif
2267 }
2268 else if (flagcode_hasString (opt))
2269 {
2270 if (cstring_firstChar (extra) == '"')
2271 {
2272 if (cstring_lastChar (extra) == '"')
2273 {
2274 char *extras = cstring_toCharsSafe (extra);
2275
2276 llassert (extras[strlen(extras) - 1] == '"');
2277 extras[strlen(extras) - 1] = '\0';
2278 extra = cstring_fromChars (extras + 1);
2279 DPRINTF (("Remove quites: %s", extra));
2280 }
2281 else
2282 {
2283 llerror
2284 (FLG_SYNTAX,
2285 message ("Unmatched \" in option string: %s",
2286 extra));
2287 }
2288 }
2289
2290 setStringFlag (opt, extra);
2291 }
2292 else
2293 {
2294 cstring_free (extra);
2295 BADEXIT;
2296 }
2297 }
2298 }
2299 else
2300 {
2301 BADEXIT;
2302 }
2303 }
2304 }
2305
2306 *s = c;
2307 DPRINTF (("Pass through: %s", cstringSList_unparse (*passThroughArgs)));
2308 while ((c == ' ') || (c == '\t'))
2309 {
2310 c = *(++s);
2311 incColumn ();
2312 }
2313 }
2314 DPRINTF (("Pass through: %s", cstringSList_unparse (*passThroughArgs)));
2315 s = os;
2316 }
2317
2318 DPRINTF (("Pass through: %s", cstringSList_unparse (*passThroughArgs)));
2319 sfree (os);
2320 check (fclose (rcfile) == 0);
2321}
2322
2323static fileIdList preprocessFiles (fileIdList fl)
2324 /*@modifies fileSystem@*/
2325{
2326 bool msg = (context_getFlag (FLG_SHOWSCAN) && fileIdList_size (fl) > 10);
2327 int skip = (fileIdList_size (fl) / 5);
2328 int filesprocessed = 0;
2329 fileIdList dfiles = fileIdList_create ();
2330
2331 fileloc_free (g_currentloc);
2332 g_currentloc = fileloc_createBuiltin ();
2333
2334 fileIdList_elements (fl, fid)
2335 {
2336 char *ppfname = cstring_toCharsSafe (fileName (fid));
2337
2338 if (!(osd_fileIsReadable (ppfname)))
2339 {
2340 lldiagmsg (message ("Cannot open file: %s",
2341 cstring_fromChars (ppfname)));
2342 }
2343 else
2344 {
2345 fileId dfile = fileTable_addCTempFile (context_fileTable (), fid);
2346
2347 llassert (!mstring_isEmpty (ppfname));
2348
2349 if (msg)
2350 {
2351 if ((filesprocessed % skip) == 0)
2352 {
2353 if (filesprocessed == 0) {
2354 fprintf (stderr, " ");
2355 }
2356 else {
2357 fprintf (stderr, ".");
2358 }
2359
2360 (void) fflush (stderr);
2361 }
2362 filesprocessed++;
2363 }
2364
2365 if (cppProcess (cstring_fromChars (ppfname),
2366 fileName (dfile)) != 0)
2367 {
2368 llfatalerror (message ("Preprocessing error for file: %s",
2369 rootFileName (fid)));
2370 }
2371
2372 fileIdList_add (dfiles, dfile);
2373 }
2374 } end_fileIdList_elements;
2375
2376 return dfiles;
2377}
This page took 0.367403 seconds and 5 git commands to generate.