]> andersk Git - splint.git/blob - src/context.c
86b6af9116a73fc20016290a05e83687060f8978
[splint.git] / src / context.c
1 /*
2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2001 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 ** context.c
26 */
27 /*
28  * Modified by Herbert 04/19/97:
29  * - added include for new header portab.h containing OS dependent stuff.
30  * - changed occurrances of '/' as path delimiters to macro from portab.h
31  * - changed the handling of the tmp directory -- will no longer always be
32  *   ".", if possible, environment variables "TMP" or, if not set, "TMP", 
33  *   or, if not set "." will be used.
34  */
35
36 # include "lclintMacros.nf"
37 # include "llbasic.h"
38
39 # ifndef NOLCL
40 # include "usymtab_interface.h"
41 # endif
42
43 # include "exprChecks.h"
44 # include "filelocStack.h"
45 # include "fileIdList.h"
46 # include "llmain.h"
47 # include "intSet.h"
48 # include "osd.h"
49 # include "portab.h"
50
51 extern /*@external@*/ int yydebug;
52 extern /*@external@*/ int mtdebug;
53
54 typedef struct
55
56   cstring file; 
57   typeIdSet daccess ; 
58 } maccesst;
59
60 typedef enum { 
61   CX_ERROR,
62
63   CX_GLOBAL, CX_INNER, 
64   CX_FUNCTION, CX_FCNDECLARATION,
65   CX_MACROFCN, CX_MACROCONST, CX_UNKNOWNMACRO, 
66   CX_ITERDEF, CX_ITEREND, 
67   CX_OLDSTYLESCOPE, /* Parsing old-style parameter declarations */
68   CX_LCL, CX_LCLLIB, CX_MT
69 } kcontext;
70
71 static struct
72 {
73   int linesprocessed;
74   int speclinesprocessed;
75
76   flagMarkerList markers;
77
78   /*
79   **  used to record state where a macro must match a function name
80   **   (i.e., no params were listed in the macro definition
81   */
82
83   bool macroMissingParams BOOLBITS;
84   bool preprocessing BOOLBITS;
85   bool incommandline BOOLBITS;
86   bool insuppressregion  BOOLBITS;
87   bool inDerivedFile BOOLBITS;
88   bool instandardlib  BOOLBITS;
89   bool inimport  BOOLBITS;
90   bool inheader  BOOLBITS;
91   bool inmacrocache  BOOLBITS;
92   bool protectVars  BOOLBITS;
93   bool neednl  BOOLBITS;
94   bool showfunction  BOOLBITS;
95   bool savedFlags  BOOLBITS;
96   bool justpopped  BOOLBITS;
97   bool anyExports BOOLBITS;
98   bool inFunctionHeader BOOLBITS;
99
100   flagcode library;
101
102   ynm isNullGuarded;
103   fileloc saveloc;
104   fileloc pushloc;
105
106   clauseStack clauses; 
107   clause inclause;
108
109   int numerrors;
110
111   filelocStack locstack;
112   fileTable ftab;
113   cstring msgAnnote;
114   /*@observer@*/ sRef aliasAnnote;
115   /*@observer@*/ sRef aliasAnnoteAls;
116   messageLog  msgLog;
117
118   macrocache  mc;
119   /*@observer@*/ sRefSet mods;
120
121   /* file access types */
122   typeIdSet facct;   
123
124   /* local access types (this function) */
125   typeIdSet acct;  
126
127   /* no access types (@noaccess) */
128   typeIdSet nacct; 
129
130   /*@observer@*/ globSet globs;
131   /*@only@*/ globSet globs_used;
132   
133   int nmods;
134   int maxmods;
135   /*@reldef@*/ maccesst *moduleaccess; /* Not defined is nmods == 0. */
136   
137   kcontext kind;
138
139   ctype boolType;
140
141   bool flags[NUMFLAGS];
142   bool saveflags[NUMFLAGS];
143   bool setGlobally[NUMFLAGS];
144   bool setLocally[NUMFLAGS];
145
146   int values[NUMVALUEFLAGS];
147   int counters[NUMVALUEFLAGS];
148
149   o_cstring strings[NUMSTRINGFLAGS];
150   sRefSetList modrecs; /*@i32 ???? what is this for? */
151
152   metaStateTable stateTable; /* User-defined state information. */
153   annotationTable annotTable; /* User-defined annotations table. */
154   union u_cont
155     {
156       bool glob;
157       int  cdepth;
158       /*@dependent@*/ /*@exposed@*/ uentry  fcn;
159     } cont;
160
161   kcontext savekind;
162   union u_cont savecont;
163 } gc;
164
165 static /*@exposed@*/ cstring context_exposeString (flagcode p_flag) ;
166 static void context_restoreFlagSettings (void) /*@modifies gc@*/ ;
167 static void context_saveFlagSettings (void) /*@modifies gc@*/ ;
168 static void context_exitClauseAux (exprNode p_pred, exprNode p_tbranch)
169    /*@modifies gc@*/ ;
170 static void context_exitClauseSimp (void)  /*@modifies gc@*/ ;
171 static void context_exitClausePlain (void) /*@modifies gc@*/ ;
172 static void context_setJustPopped (void) /*@modifies gc.justpopped@*/ ;
173 static void context_setValue (flagcode p_flag, int p_val) /*@modifies gc.flags@*/ ;
174 static void context_setFlag (flagcode p_f, bool p_b)
175   /*@modifies gc.flags@*/ ;
176
177 static void
178   context_setFlagAux (flagcode p_f, bool p_b, bool p_inFile, bool p_isRestore)
179   /*@modifies gc.flags@*/ ;
180
181 static void context_restoreFlag (flagcode p_f) /*@modifies gc.flags@*/ ;
182
183 /*@+enumindex@*/ 
184
185 cstring context_unparseFlagMarkers ()
186 {
187   return (flagMarkerList_unparse (gc.markers));
188 }
189
190 void context_setPreprocessing (void)
191 {
192   llassert (!gc.preprocessing);
193   gc.preprocessing = TRUE;
194 }
195
196 void context_clearPreprocessing (void)
197 {
198   llassert (gc.preprocessing);
199   gc.preprocessing = FALSE;
200 }
201
202 bool context_isPreprocessing (void)
203 {
204   return gc.preprocessing;
205 }
206
207 bool context_loadingLibrary (void)
208 {
209   return (fileloc_isLib (g_currentloc));
210 }
211
212 bool context_inXHFile (void)
213 {
214   return (fileloc_isXHFile (g_currentloc));
215 }
216
217 void context_setInCommandLine (void)
218 {
219   llassert (!gc.incommandline);
220   gc.incommandline = TRUE;
221 }
222
223 void context_clearInCommandLine (void)
224 {
225   llassert (gc.incommandline);
226   gc.incommandline = FALSE;
227 }
228
229 bool context_isInCommandLine (void)
230 {
231   return gc.incommandline;
232 }
233
234 static
235 void pushClause (clause c) /*@modifies gc.clauses, gc.inclause@*/
236 {
237   gc.inclause = c;
238   clauseStack_push (gc.clauses, c);
239
240   if (clause_isConditional (c)
241       && context_getFlag (FLG_CONTROLNESTDEPTH))
242     {
243       int maxdepth = context_getValue (FLG_CONTROLNESTDEPTH);
244       int depth = clauseStack_controlDepth (gc.clauses);
245       
246       if (depth == maxdepth + 1)
247         {
248           voptgenerror 
249             (FLG_CONTROLNESTDEPTH,
250              message ("Maximum control nesting depth "
251                       "(%d) exceeded",
252                       maxdepth),
253              g_currentloc);
254         }
255     }
256 }
257
258 static
259 clause topClause (clauseStack s) /*@*/
260 {
261   if (clauseStack_isEmpty (s)) return NOCLAUSE;
262   return ((clause) clauseStack_top (s));
263 }
264
265 void
266 context_addMacroCache (/*@only@*/ cstring def)
267 {
268   DPRINTF (("macro cache: %s", def));
269   macrocache_addEntry (gc.mc, fileloc_copy (g_currentloc), def);
270 }
271
272 void
273 context_addComment (/*@only@*/ cstring def)
274 {
275   DPRINTF (("macro comment: %s", def));
276   macrocache_addComment (gc.mc, fileloc_copy (g_currentloc), def);
277 }
278
279 /*
280 ** returns TRUE is fl is in ignore region, or region where -code
281 **
282 ** the logic is fuzzy...
283 */
284
285 static bool
286 context_inSuppressFlagZone (fileloc fl, flagcode code)
287 {
288   ynm ret = flagMarkerList_suppressError (gc.markers, code, fl);
289   bool res = FALSE;
290   
291   if (ynm_isMaybe (ret))
292     {
293       /*
294       ** whas is dis?
295       */
296
297       if (gc.savedFlags)
298         {
299           res = !gc.saveflags[code];
300         }
301       else
302         {
303           res = !context_getFlag (code);
304         }
305     }
306   else
307     {
308       res = ynm_toBoolStrict (ret);
309     }
310   
311     return res;
312 }
313
314 static bool
315 context_suppressSystemMsg (fileloc fl)
316 {
317   if (context_getFlag (FLG_SYSTEMDIRERRORS))
318     {
319       return FALSE;
320     }
321   else
322     {
323       return (fileloc_isSystemFile (fl));
324     }
325 }
326
327 bool 
328 context_suppressFlagMsg (flagcode flag, fileloc fl)
329 {
330   if (context_suppressSystemMsg (fl))
331     {
332       return TRUE;
333     }
334
335   DPRINTF (("Checking suppress: %s / %s", fileloc_unparse (fl), fileloc_unparse (g_currentloc)));
336
337   /* want same object compare here */
338
339   if (fileloc_equal (fl, g_currentloc) || gc.inDerivedFile)
340     {
341       DPRINTF (("In derived file: %s", bool_unparse (gc.inDerivedFile)));
342
343       return (!context_getFlag (flag)
344               || context_inSuppressRegion ()
345               || context_inSuppressZone (fl)
346               || (/*@!@@#@ gc.inDerivedFile && */ context_inSuppressFlagZone (fl, flag)));
347     }
348   else
349     {
350       return (context_inSuppressFlagZone (fl, flag));
351     }
352 }
353
354 bool 
355 context_suppressNotFlagMsg (flagcode flag, fileloc fl)
356 {
357   
358   if (context_suppressSystemMsg (fl))
359     {
360       return TRUE;
361     }
362
363   /*@access fileloc@*/ 
364   if (fl == g_currentloc)
365     /*@noaccess fileloc@*/
366     {
367       return (context_getFlag (flag) || context_inSuppressRegion ());
368     }
369   else
370     {
371       /* for now... */
372       return (context_getFlag (flag) || context_inSuppressRegion ());
373     }
374 }
375
376 bool
377 context_inSuppressZone (fileloc fl) 
378 {
379   if (context_suppressSystemMsg (fl))
380     {
381       return TRUE;
382     }
383
384   return (flagMarkerList_inIgnore (gc.markers, fl));
385 }
386
387 bool
388 context_inSuppressRegion (void)
389 {
390   return (gc.insuppressregion);
391 }
392
393 void
394 context_enterSuppressRegion (void)
395 {
396   if (gc.insuppressregion)
397     {
398       gc.insuppressregion = FALSE;      /* get this msg! */
399       llmsg (message
400              ("%q: New ignore errors region entered while in ignore errors region",
401               fileloc_unparse (g_currentloc)));
402     }
403   
404   gc.insuppressregion = TRUE;
405   flagMarkerList_add (gc.markers, flagMarker_createIgnoreOn (g_currentloc));
406 }
407
408 static void
409 context_addFlagMarker (flagcode code, ynm set)
410 {
411   flagMarkerList_add (gc.markers,
412                       flagMarker_createLocalSet (code, set, g_currentloc));
413 }
414
415 void
416 context_enterSuppressLine (int count)
417 {
418   fileloc nextline = fileloc_copy (g_currentloc);
419
420   flagMarkerList_add (gc.markers,
421                       flagMarker_createIgnoreCount (count, g_currentloc));
422
423   fileloc_nextLine (nextline);
424   flagMarkerList_add (gc.markers,
425                       flagMarker_createIgnoreOff (nextline));
426   fileloc_free (nextline);
427 }
428
429 void context_checkSuppressCounts (void)
430 {
431   if (context_getFlag (FLG_SUPCOUNTS))
432     {
433       flagMarkerList_checkSuppressCounts (gc.markers);
434     }
435 }
436
437 void context_incLineno (void)
438 {
439   gc.linesprocessed++;
440   incLine ();
441 }
442
443 void
444 context_exitSuppressRegion (void)
445 {
446   if (!gc.insuppressregion)
447     {
448       llerrorlit (FLG_SYNTAX, 
449                   "End ignore errors in region while not ignoring errors");
450     }
451
452     gc.insuppressregion = FALSE;
453   flagMarkerList_add (gc.markers, flagMarker_createIgnoreOff (g_currentloc));
454 }
455
456 void
457 context_enterMTfile (void)
458 {
459   gc.kind = CX_MT;
460 }
461
462 void
463 context_exitMTfile (void)
464 {
465   llassert (gc.kind == CX_MT);
466   gc.kind = CX_GLOBAL;
467 }
468
469 # ifndef NOLCL
470 void
471 context_enterLCLfile (void)
472 {
473   gc.kind = CX_LCL;
474   gc.facct = typeIdSet_emptySet ();
475 }
476 # endif
477
478 static void
479 addModuleAccess (/*@only@*/ cstring fname, typeIdSet mods)
480 {
481   int i;
482
483   for (i = 0; i < gc.nmods; i++)
484     {
485       if (cstring_equal (gc.moduleaccess[i].file, fname))
486         {
487           gc.moduleaccess[i].daccess = typeIdSet_union (gc.moduleaccess[i].daccess, mods);
488           cstring_free (fname);
489           return;
490         }
491     }
492   
493   if (gc.nmods == gc.maxmods)
494     {
495       maccesst *oldmods;
496       
497       gc.maxmods = gc.maxmods + DEFAULTMAXMODS;      
498       oldmods = gc.moduleaccess;
499       
500       gc.moduleaccess = (maccesst *) dmalloc (sizeof (*gc.moduleaccess) * (gc.maxmods));
501       
502       for (i = 0; i < gc.nmods; i++)
503         {
504           gc.moduleaccess[i] = oldmods[i];
505         }
506       
507       sfree (oldmods);
508     }
509   
510   gc.moduleaccess[gc.nmods].file = fname;
511   gc.moduleaccess[gc.nmods].daccess = mods;
512   
513   gc.nmods++;
514 }
515
516 static void
517 insertModuleAccess (cstring fname, typeId t)
518 {
519   int i;
520   
521   for (i = 0; i < gc.nmods; i++)
522     {
523       if (cstring_equal (gc.moduleaccess[i].file, fname))
524         {
525           gc.moduleaccess[i].daccess = typeIdSet_insert (gc.moduleaccess[i].daccess, t);
526           break;
527         }
528     }
529   
530     addModuleAccess (cstring_copy (fname), typeIdSet_single (t));
531 }
532
533 # ifndef NOLCL
534 void
535 context_exitLCLfile (void)
536 {
537   if (gc.kind != CX_LCLLIB)
538     {
539       cstring lclname =  
540         fileLib_withoutExtension (fileName (currentFile ()), LCL_EXTENSION);
541       
542       addModuleAccess (fileLib_removePath (lclname), gc.facct);
543       cstring_free (lclname);
544     }
545   
546   gc.kind = CX_LCL;
547   gc.kind = CX_GLOBAL;
548   gc.facct = typeIdSet_emptySet ();
549 }
550 # endif
551
552 void
553 context_dumpModuleAccess (FILE *fout)
554 {
555   int i = 0;
556
557   for (i = 0; i < gc.nmods; i++)
558     {
559       cstring td = typeIdSet_dump (gc.moduleaccess[i].daccess);
560
561       fprintf (fout, "%s#%s@\n", 
562                cstring_toCharsSafe (gc.moduleaccess[i].file), 
563                cstring_toCharsSafe (td));
564       
565       cstring_free (td);
566     }
567 }
568
569 bool context_usingPosixLibrary ()
570 {
571   return (gc.library == FLG_POSIXLIB 
572           || gc.library == FLG_POSIXSTRICTLIB
573           || gc.library == FLG_UNIXLIB
574           || gc.library == FLG_UNIXSTRICTLIB);
575 }
576
577 bool context_usingAnsiLibrary ()
578 {
579   return (gc.library != FLG_NOLIB);
580 }
581
582 flagcode context_getLibrary ()
583 {
584   return gc.library;
585 }
586
587 void context_setLibrary (flagcode code)
588 {
589   gc.library = code;
590 }
591
592 /*@observer@*/ cstring context_selectedLibrary ()
593 {
594   switch (gc.library)
595     {
596     case FLG_STRICTLIB:
597       return cstring_makeLiteralTemp (LLSTRICTLIBS_NAME);
598     case FLG_POSIXLIB:
599       return cstring_makeLiteralTemp (LLPOSIXLIBS_NAME);
600     case FLG_POSIXSTRICTLIB:
601       return cstring_makeLiteralTemp (LLPOSIXSTRICTLIBS_NAME);
602     case FLG_UNIXLIB:
603       return cstring_makeLiteralTemp (LLUNIXLIBS_NAME);    
604     case FLG_UNIXSTRICTLIB:
605       return cstring_makeLiteralTemp (LLUNIXSTRICTLIBS_NAME);
606     case FLG_ANSILIB:
607       return cstring_makeLiteralTemp (LLSTDLIBS_NAME);
608     BADDEFAULT;
609     }
610 }
611   
612
613 void
614 context_loadModuleAccess (FILE *in)
615 {
616   char *s = mstring_create (MAX_DUMP_LINE_LENGTH);
617   char *lasts = s;
618   char *name = mstring_create (MAX_NAME_LENGTH);
619   char *oname = name;
620 # ifndef NOFREE
621   char *os = s;
622 # endif
623
624   while ((reader_readLine (in, s, MAX_DUMP_LINE_LENGTH) != NULL )
625          && *s == ';')
626     {
627       ;
628     }
629
630   while (s != NULL && *s != ';' && *s != '\0')
631     {
632       name = oname;
633       
634       while (*s != '#' && *s != '\0')
635         {
636           *name++ = *s++;
637         }
638
639       *name = '\0';
640
641       if (*s != '#')
642         {
643           llcontbug (message ("context_loadModuleAccess: bad library line: %s\n", 
644                               cstring_fromChars (s)));
645           break;
646         }
647
648       s++;
649
650       addModuleAccess (cstring_copy (cstring_fromChars (oname)), 
651                        typeIdSet_undump (&s)); 
652
653       (void) reader_readLine (in, s, MAX_DUMP_LINE_LENGTH);
654       llassert (s != lasts);
655       lasts = s;
656     }
657
658   sfree (oname);
659 # ifndef NOFREE
660   sfree (os);
661 # endif
662 }
663
664 typeIdSet context_fileAccessTypes (void)
665 {
666   return gc.facct;
667 }
668
669 void
670 context_resetModeFlags (void)
671 {
672   
673   allFlagCodes (code)
674     {
675       if (flagcode_isModeFlag (code))
676         {
677           context_setFlag (code, FALSE);
678         }
679     } end_allFlagCodes;
680
681   }
682
683 /*
684 ** resetAllFlags
685 **
686 ** Set all flags to FALSE, except for a few which are
687 ** true by default.
688 **
689 ** Set all values and strings to appropriate defaults.
690 ** Set all counters to 0.
691 */
692
693 static void
694 conext_resetAllCounters (void)
695 {
696   int i;
697
698   for (i = 0; i < NUMVALUEFLAGS; i++)
699     {
700       gc.counters[i] = 0;
701     }
702 }
703
704 void
705 context_resetAllFlags (void) 
706 {
707   allFlagCodes (code)
708     {
709       gc.flags[code] = FALSE;
710
711       if (flagcode_hasValue (code))
712         {
713           int val = 0;
714           
715           /*@-loopswitchbreak@*/
716           switch (code)
717             {
718             case FLG_LIMIT: 
719               val = DEFAULT_LIMIT; break;
720             case FLG_BUGSLIMIT:
721               val = DEFAULT_BUGSLIMIT; break;
722             case FLG_LINELEN: 
723               val = DEFAULT_LINELEN; break;
724             case FLG_INDENTSPACES: 
725               val = DEFAULT_INDENTSPACES; break;
726             case FLG_EXTERNALNAMELEN:
727               val = DEFAULT_EXTERNALNAMELEN; break;
728             case FLG_INTERNALNAMELEN:
729               val = DEFAULT_INTERNALNAMELEN; break;
730             case FLG_COMMENTCHAR: 
731               val = (int) DEFAULT_COMMENTCHAR; break;
732             case FLG_CONTROLNESTDEPTH:
733               val = (int) DEFAULT_CONTROLNESTDEPTH; break;
734             case FLG_STRINGLITERALLEN:
735               val = (int) DEFAULT_STRINGLITERALLEN; break;
736             case FLG_INCLUDENEST:
737               val = (int) DEFAULT_INCLUDENEST; break;
738             case FLG_NUMSTRUCTFIELDS:
739               val = (int) DEFAULT_NUMSTRUCTFIELDS; break;
740             case FLG_NUMENUMMEMBERS:
741               val = (int) DEFAULT_NUMENUMMEMBERS; break;
742             case FLG_EXPECT:
743             case FLG_LCLEXPECT:
744               break;
745             default:
746               llbug (message ("Bad value flag: %s", flagcode_unparse (code)));
747             }
748           /*@=loopswitchbreak@*/          
749
750           context_setValue (code, val);
751         }
752       else if (flagcode_hasString (code))
753         {
754           cstring val = cstring_undefined;
755           
756           switch (code)
757             { /*@-loopswitchbreak@*/
758             case FLG_LARCHPATH:
759               {
760                 cstring larchpath = osd_getEnvironmentVariable (LARCH_PATH);
761                 
762                 if (cstring_isDefined (larchpath))
763                   {
764                     val = cstring_copy (larchpath);
765                   }
766                 else
767                   {
768                     val = cstring_makeLiteral (DEFAULT_LARCHPATH);
769                   }
770                 
771                 break;
772               }
773             case FLG_LCLIMPORTDIR:
774               {
775                 val = cstring_copy (osd_getEnvironment (cstring_makeLiteralTemp (LCLIMPORTDIR), cstring_makeLiteralTemp (DEFAULT_LCLIMPORTDIR)));
776                 break;
777               }
778             case FLG_TMPDIR: 
779 # if defined(OS2) || defined(MSDOS) || defined(WIN32)
780               {
781                 char *env = osd_getEnvironmentVariable ("TMP");
782
783                 if (env == NULL)
784                   {
785                     env = osd_getEnvironmentVariable ("TEMP");
786                   }
787
788                 val = cstring_makeLiteral (env != NULL ? env : DEFAULT_TMPDIR);
789               }
790 # else
791               val = cstring_makeLiteral (DEFAULT_TMPDIR);
792 # endif /* !defined(OS2) && !defined(MSDOS) */
793
794               break;
795             case FLG_BOOLTYPE:
796               val = cstring_makeLiteral (DEFAULT_BOOLTYPE); break;
797             case FLG_BOOLFALSE:
798               val = cstring_makeLiteral ("FALSE"); break;
799             case FLG_BOOLTRUE:
800               val = cstring_makeLiteral ("TRUE"); break;
801             case FLG_MACROVARPREFIX: 
802               val = cstring_makeLiteral ("m_"); break;
803             case FLG_SYSTEMDIRS:
804               val = cstring_makeLiteral (DEFAULT_SYSTEMDIR); break;
805             default:
806               break;
807             } /*@=loopswitchbreak@*/
808           
809           context_setString (code, val);
810         }
811       else
812         { 
813           ; /* nothing to set */
814         }
815     } end_allFlagCodes;
816   
817   /*
818   ** These flags are true by default.
819   */
820
821   /*@i34 move this into flags.def */
822     
823   gc.flags[FLG_MODIFIES] = TRUE;
824   gc.flags[FLG_NESTCOMMENT] = TRUE;
825   gc.flags[FLG_GLOBALS] = TRUE;
826   gc.flags[FLG_FULLINITBLOCK] = TRUE;
827   gc.flags[FLG_INITSIZE] = TRUE;
828   gc.flags[FLG_INITALLELEMENTS] = TRUE;
829
830   gc.flags[FLG_STRINGLITTOOLONG] = TRUE;
831
832   gc.flags[FLG_LIKELYBOOL] = TRUE;
833   gc.flags[FLG_ZEROPTR] = TRUE;
834   gc.flags[FLG_NUMLITERAL] = TRUE;
835   gc.flags[FLG_DUPLICATEQUALS] = TRUE;
836   gc.flags[FLG_SKIPANSIHEADERS] = TRUE;
837   gc.flags[FLG_SKIPPOSIXHEADERS] = TRUE;
838   gc.flags[FLG_SYSTEMDIREXPAND] = TRUE;
839   gc.flags[FLG_UNRECOGCOMMENTS] = TRUE;
840   gc.flags[FLG_UNRECOGFLAGCOMMENTS] = TRUE;
841   gc.flags[FLG_CASTFCNPTR] = TRUE;
842   gc.flags[FLG_DOLCS] = TRUE;
843   gc.flags[FLG_USEVARARGS] = TRUE;
844   gc.flags[FLG_MAINTYPE] = TRUE;
845   gc.flags[FLG_SPECMACROS] = TRUE;
846   gc.flags[FLG_REDEF] = TRUE;
847   gc.flags[FLG_MACRONEXTLINE] = TRUE;
848
849   gc.flags[FLG_SIZEOFFORMALARRAY] = TRUE;
850   gc.flags[FLG_FIXEDFORMALARRAY] = TRUE;
851
852   gc.flags[FLG_WARNUSE] = TRUE;
853   gc.flags[FLG_PREDASSIGN] = TRUE;
854   gc.flags[FLG_MODOBSERVER] = TRUE;
855   gc.flags[FLG_MACROVARPREFIXEXCLUDE] = TRUE;
856   gc.flags[FLG_EXTERNALNAMECASEINSENSITIVE] = TRUE;
857
858   gc.flags[FLG_PARAMIMPTEMP] = TRUE;
859   gc.flags[FLG_RETIMPONLY] = TRUE;
860   gc.flags[FLG_GLOBIMPONLY] = TRUE;
861   gc.flags[FLG_STRUCTIMPONLY] = TRUE;
862   gc.flags[FLG_PREPROC] = TRUE;
863   gc.flags[FLG_NAMECHECKS] = TRUE;
864   gc.flags[FLG_FORMATCODE] = TRUE;
865   gc.flags[FLG_FORMATTYPE] = TRUE;
866   gc.flags[FLG_BADFLAG] = TRUE;
867   gc.flags[FLG_WARNFLAGS] = TRUE;
868   gc.flags[FLG_FILEEXTENSIONS] = TRUE;
869   gc.flags[FLG_WARNUNIXLIB] = TRUE;
870   gc.flags[FLG_WARNPOSIX] = TRUE;
871   gc.flags[FLG_SHOWCOL] = TRUE;
872   gc.flags[FLG_SHOWFUNC] = TRUE;
873   gc.flags[FLG_SUPCOUNTS] = TRUE;
874   gc.flags[FLG_HINTS] = TRUE;
875   gc.flags[FLG_SYNTAX] = TRUE;
876   gc.flags[FLG_TYPE] = TRUE;
877   gc.flags[FLG_INCOMPLETETYPE] = TRUE;
878   gc.flags[FLG_ABSTRACT] = TRUE;
879   gc.flags[FLG_ITER] = TRUE;
880   gc.flags[FLG_CONTROL] = TRUE;
881   gc.flags[FLG_UNRECOG] = TRUE;
882   gc.flags[FLG_SYSTEMUNRECOG] = TRUE;
883   gc.flags[FLG_LINTCOMMENTS] = TRUE;
884   gc.flags[FLG_ACCESSCZECH] = TRUE;
885   gc.flags[FLG_ACCESSMODULE] = TRUE;
886   gc.flags[FLG_ACCESSFILE] = TRUE;
887   gc.flags[FLG_MACROVARPREFIX] = TRUE;
888
889   gc.flags[FLG_ANNOTATIONERROR] = TRUE;
890   gc.flags[FLG_COMMENTERROR] = TRUE;
891
892   /*
893   ** Changed for version 2.4.
894   */
895
896   gc.flags[FLG_GNUEXTENSIONS] = TRUE;
897
898   /*
899   ** On by default for Win32, but not Unix (to support MS/VC++ error message format).
900   */
901
902 # ifdef WIN32
903   gc.flags[FLG_PARENFILEFORMAT] = TRUE;
904 # endif
905 }
906
907 /*
908 ** C is way-lame, and you can initialize an array to a constant except where
909 ** it is declared.  Hence, a macro is used to set the modeflags.
910 */
911
912 /*@notfunction@*/
913 # define SETFLAGS() \
914   { int i = 0; while (modeflags[i] != INVALID_FLAG) { \
915       if (!flagcode_isModeFlag (modeflags[i])) \
916         { llbug (message ("not a mode flag: %s", \
917                           flagcode_unparse (modeflags[i]))); } \
918       else { context_setFlag (modeflags[i], TRUE); }  i++; }}
919
920 void
921 context_setMode (cstring s)
922 {
923   intSet setflags = intSet_new ();
924   
925   allFlagCodes (code)
926     {
927       if (flagcode_isModeFlag (code))
928         {
929           if (gc.setGlobally[code])
930             {
931               (void) intSet_insert (setflags, (int) code);
932             }
933         }
934     } end_allFlagCodes;
935   
936   if (!intSet_isEmpty (setflags))
937     {
938       cstring rflags = cstring_undefined;
939       int num = 0;
940
941       intSet_elements (setflags, el)
942         {
943           if (cstring_isUndefined (rflags))
944             {
945               rflags = cstring_copy (flagcode_unparse ((flagcode) (el)));
946             }
947           else
948             {
949               rflags = message ("%q, %s", rflags, 
950                                 flagcode_unparse ((flagcode) el));
951             }
952
953           num++;
954           if (num > 4 && intSet_size (setflags) > 6)
955             {
956               rflags = message ("%q, (%d others) ...", rflags, 
957                                 intSet_size (setflags) - num);
958               break;
959             }
960         } end_intSet_elements ;
961       
962       voptgenerror (FLG_WARNFLAGS,
963                     message ("Setting mode %s after setting mode flags will "
964                              "override set values of flags: %s",
965                              s, rflags),
966                     g_currentloc);
967
968       cstring_free (rflags);
969     }
970
971   intSet_free (setflags);
972
973   context_resetModeFlags ();
974
975   if (cstring_equalLit (s, "standard"))
976     {
977       flagcode modeflags[] = 
978         {
979           FLG_ENUMINT, FLG_MACROMATCHNAME,
980           FLG_STRINGLITNOROOM,
981           FLG_MACROUNDEF, FLG_RELAXQUALS, 
982           FLG_USEALLGLOBS, FLG_CHECKSTRICTGLOBALS,
983           FLG_CHECKSTRICTGLOBALIAS,
984           FLG_CHECKEDGLOBALIAS,
985           FLG_CHECKMODGLOBALIAS,
986           FLG_PREDBOOLOTHERS, FLG_PREDBOOLINT,
987           FLG_UNSIGNEDCOMPARE,
988           FLG_PARAMUNUSED, FLG_VARUNUSED, FLG_FUNCUNUSED, 
989           FLG_TYPEUNUSED,
990           FLG_CONSTUNUSED, FLG_ENUMMEMUNUSED, FLG_FIELDUNUSED,
991           FLG_PTRNUMCOMPARE, FLG_BOOLCOMPARE, FLG_UNSIGNEDCOMPARE,
992           FLG_MUTREP, FLG_NOEFFECT, FLG_IMPTYPE,
993           FLG_RETVALOTHER, FLG_RETVALBOOL, FLG_RETVALINT,
994           FLG_SPECUNDEF, FLG_INCONDEFS, FLG_INCONDEFSLIB, FLG_MISPLACEDSHAREQUAL,
995           FLG_MATCHFIELDS,
996           FLG_FORMATCONST,
997           FLG_MACROPARAMS, FLG_MACROASSIGN, FLG_SEFPARAMS, 
998           FLG_MACROSTMT, FLG_MACROPARENS, 
999           FLG_MACROFCNDECL,
1000           FLG_MACROCONSTDECL,
1001           FLG_MACROREDEF, FLG_INFLOOPS, FLG_UNREACHABLE, 
1002           FLG_NORETURN, FLG_CASEBREAK, FLG_MISSCASE, FLG_USEDEF, 
1003           FLG_FIRSTCASE,
1004           FLG_NESTEDEXTERN, 
1005           FLG_NUMLITERAL,
1006           FLG_ZEROBOOL,
1007           /* memchecks flags */
1008           FLG_NULLDEREF, 
1009           FLG_NULLSTATE, FLG_NULLASSIGN,
1010           FLG_NULLPASS, FLG_NULLRET,        
1011
1012           FLG_COMPDEF, FLG_COMPMEMPASS, FLG_UNIONDEF,
1013           FLG_RETSTACK,
1014
1015           /* memtrans flags */
1016           FLG_EXPOSETRANS,
1017           FLG_OBSERVERTRANS,
1018           FLG_DEPENDENTTRANS,
1019           FLG_NEWREFTRANS,
1020           FLG_ONLYTRANS,
1021           FLG_OWNEDTRANS,
1022           FLG_FRESHTRANS,
1023           FLG_SHAREDTRANS,
1024           FLG_TEMPTRANS,
1025           FLG_KEPTTRANS,
1026           FLG_REFCOUNTTRANS,
1027           FLG_STATICTRANS,
1028           FLG_UNKNOWNTRANS,
1029           FLG_KEEPTRANS,
1030           FLG_IMMEDIATETRANS,
1031
1032           FLG_EXPORTLOCAL,
1033
1034           FLG_USERELEASED, FLG_ALIASUNIQUE, FLG_MAYALIASUNIQUE,
1035           FLG_MUSTFREE, FLG_MUSTDEFINE, FLG_GLOBSTATE, 
1036           FLG_COMPDESTROY, FLG_MUSTNOTALIAS,
1037           FLG_MEMIMPLICIT,
1038           FLG_BRANCHSTATE, 
1039           FLG_STATETRANSFER, FLG_STATEMERGE,
1040           FLG_EVALORDER, FLG_SHADOW, FLG_READONLYSTRINGS,
1041           FLG_EXITARG,
1042           FLG_IMPCHECKEDSPECGLOBALS,
1043           FLG_MODGLOBS, FLG_WARNLINTCOMMENTS,
1044           FLG_IFEMPTY, FLG_REALCOMPARE,
1045           FLG_BOOLOPS, FLG_PTRNEGATE,
1046           FLG_SHIFTSIGNED,
1047           FLG_BUFFEROVERFLOWHIGH,
1048           FLG_BUFFEROVERFLOW,
1049           INVALID_FLAG 
1050         } ;
1051
1052       SETFLAGS ();
1053     }
1054   else if (cstring_equalLit (s, "weak"))
1055     {
1056       flagcode modeflags[] = 
1057         { 
1058           FLG_BOOLINT, FLG_CHARINT, FLG_FLOATDOUBLE,
1059           FLG_ENUMINT, FLG_RELAXQUALS, FLG_FORWARDDECL, 
1060           FLG_CHARINDEX, FLG_ABSTVOIDP, FLG_USEALLGLOBS, 
1061           FLG_CHARUNSIGNEDCHAR,
1062           FLG_PREDBOOLOTHERS, 
1063           FLG_VARUNUSED, FLG_FUNCUNUSED, 
1064           FLG_TYPEUNUSED,
1065           FLG_CHECKSTRICTGLOBALS, FLG_MACROMATCHNAME,
1066           FLG_RETVALOTHER,
1067           FLG_IFEMPTY, 
1068           FLG_BUFFEROVERFLOWHIGH,
1069           FLG_RETSTACK, FLG_PTRNEGATE,
1070           FLG_STATETRANSFER, FLG_STATEMERGE,
1071           FLG_LONGUNSIGNEDINTEGRAL,
1072           FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL,
1073           FLG_NUMLITERAL,
1074           FLG_CHARINTLITERAL,
1075           FLG_ZEROBOOL,
1076           FLG_BUFFEROVERFLOWHIGH,
1077           INVALID_FLAG 
1078           } ;
1079
1080       SETFLAGS ();
1081     }
1082   else if (cstring_equalLit (s, "checks"))
1083     {
1084       flagcode modeflags[] = 
1085         { 
1086           FLG_EXPORTLOCAL, FLG_IMPTYPE,
1087           FLG_STATETRANSFER, FLG_STATEMERGE,
1088           FLG_CHECKSTRICTGLOBALIAS,
1089           FLG_CHECKEDGLOBALIAS,
1090           FLG_CHECKMODGLOBALIAS,
1091           FLG_UNCHECKEDGLOBALIAS,
1092           FLG_FORMATCONST,
1093           FLG_STRINGLITNOROOM,
1094           FLG_STRINGLITSMALLER,
1095           FLG_EXITARG, FLG_PTRNUMCOMPARE, 
1096           FLG_BOOLCOMPARE, FLG_UNSIGNEDCOMPARE, 
1097           FLG_MACROUNDEF, FLG_MUSTMOD, FLG_ALLGLOBALS,
1098           FLG_PREDBOOLOTHERS, FLG_PREDBOOLPTR, FLG_PREDBOOLINT,
1099           FLG_USEALLGLOBS, FLG_MUTREP, FLG_RETALIAS, 
1100           FLG_RETEXPOSE, FLG_ASSIGNEXPOSE, FLG_CASTEXPOSE,
1101           FLG_FUNCUNUSED, FLG_GLOBALSIMPMODIFIESNOTHING,
1102           FLG_TYPEUNUSED, FLG_FIELDUNUSED, FLG_PARAMUNUSED, FLG_VARUNUSED,
1103           FLG_CONSTUNUSED, FLG_ENUMMEMUNUSED,
1104           FLG_NOEFFECT, FLG_EXPORTHEADER, FLG_EXPORTHEADERVAR,
1105           FLG_RETVALOTHER, FLG_RETVALBOOL, FLG_RETVALINT,
1106           FLG_SPECUNDEF, FLG_IMPCHECKMODINTERNALS,
1107           FLG_DECLUNDEF, FLG_INCONDEFS, FLG_INCONDEFSLIB, 
1108           FLG_MISPLACEDSHAREQUAL, FLG_REDUNDANTSHAREQUAL,
1109           FLG_MATCHFIELDS, 
1110           FLG_MACROPARAMS,
1111           FLG_MACROASSIGN,
1112           FLG_DECLPARAMMATCH,
1113           FLG_FCNDEREF,
1114           FLG_FIRSTCASE,
1115           FLG_SEFPARAMS, FLG_SEFUNSPEC, FLG_MACROSTMT, FLG_MACROPARENS, 
1116           FLG_MACROCONSTDECL,
1117           FLG_MACROFCNDECL,
1118           FLG_MACROREDEF, 
1119           FLG_INFLOOPS, FLG_INFLOOPSUNCON,
1120           FLG_UNREACHABLE, 
1121           FLG_NORETURN, FLG_CASEBREAK, FLG_MISSCASE,
1122           FLG_EVALORDER, FLG_USEDEF, 
1123
1124           FLG_NESTEDEXTERN, 
1125
1126           /* warn use flags */
1127           FLG_MULTITHREADED, FLG_PORTABILITY, FLG_SUPERUSER, FLG_IMPLEMENTATIONOPTIONAL,
1128           FLG_BUFFEROVERFLOWHIGH,
1129
1130           /* memchecks flags */
1131
1132           FLG_NULLSTATE, FLG_NULLDEREF, FLG_NULLASSIGN,
1133           FLG_NULLPASS, FLG_NULLRET,
1134
1135           FLG_COMPDEF, FLG_COMPMEMPASS, FLG_UNIONDEF, FLG_RETSTACK,       
1136
1137           /* memtrans flags */
1138           FLG_EXPOSETRANS,
1139           FLG_OBSERVERTRANS,
1140           FLG_DEPENDENTTRANS,
1141           FLG_NEWREFTRANS,
1142           FLG_ONLYTRANS,
1143           FLG_OWNEDTRANS,
1144           FLG_FRESHTRANS,
1145           FLG_SHAREDTRANS,
1146           FLG_TEMPTRANS,
1147           FLG_KEPTTRANS,
1148           FLG_REFCOUNTTRANS,
1149           FLG_STATICTRANS,
1150           FLG_UNKNOWNTRANS,
1151           FLG_STATICINITTRANS,
1152           FLG_UNKNOWNINITTRANS,
1153           FLG_KEEPTRANS,
1154           FLG_IMMEDIATETRANS,
1155           FLG_ONLYUNQGLOBALTRANS,
1156           FLG_USERELEASED, FLG_ALIASUNIQUE, FLG_MAYALIASUNIQUE,
1157           FLG_MUSTFREE, FLG_MUSTDEFINE, FLG_GLOBSTATE, 
1158           FLG_COMPDESTROY, FLG_MUSTNOTALIAS,
1159           FLG_MEMIMPLICIT,
1160           FLG_BRANCHSTATE, 
1161           FLG_NULLPOINTERARITH,
1162           FLG_SHADOW, FLG_DEPARRAYS,
1163           FLG_REDECL, FLG_READONLYSTRINGS, FLG_READONLYTRANS,
1164           FLG_LOOPLOOPBREAK, FLG_SWITCHLOOPBREAK, FLG_MODGLOBS,
1165           FLG_CHECKSTRICTGLOBALS, FLG_IMPCHECKEDSPECGLOBALS,
1166           FLG_MACROMATCHNAME, FLG_WARNLINTCOMMENTS,
1167           FLG_INCLUDENEST, FLG_ANSIRESERVED, FLG_CPPNAMES, 
1168           FLG_NOPARAMS, FLG_IFEMPTY, FLG_WHILEEMPTY, FLG_REALCOMPARE,
1169           FLG_BOOLOPS, FLG_SHIFTSIGNED,
1170           FLG_BUFFEROVERFLOWHIGH, FLG_BUFFEROVERFLOW,
1171           INVALID_FLAG } ;
1172
1173       SETFLAGS ();
1174     }
1175   else if (cstring_equalLit (s, "strict"))
1176     {
1177       flagcode modeflags[] = 
1178         { 
1179           FLG_CHECKSTRICTGLOBALIAS,
1180           FLG_CHECKEDGLOBALIAS,
1181           FLG_CHECKMODGLOBALIAS,
1182           FLG_UNCHECKEDGLOBALIAS,
1183           FLG_MODFILESYSTEM,
1184           FLG_MACROMATCHNAME,
1185           FLG_FORMATCONST,
1186           FLG_STRINGLITNOROOM,
1187           FLG_STRINGLITSMALLER,
1188           FLG_STATETRANSFER, FLG_STATEMERGE,
1189           FLG_MACROUNDEF, FLG_MUTREP, FLG_MUSTMOD,
1190           FLG_ALLGLOBALS, FLG_IMPTYPE,
1191           FLG_MODNOMODS, FLG_MODGLOBSUNSPEC, FLG_MODSTRICTGLOBSUNSPEC,
1192           FLG_GLOBUNSPEC, FLG_SIZEOFTYPE,
1193           FLG_EXPORTHEADER, FLG_EXPORTHEADERVAR,
1194           FLG_NOPARAMS, FLG_OLDSTYLE, FLG_EXITARG, 
1195           FLG_RETSTACK,
1196           FLG_FCNDEREF,
1197           FLG_ONLYUNQGLOBALTRANS,
1198           FLG_GLOBALSIMPMODIFIESNOTHING,
1199           FLG_PREDBOOLOTHERS, FLG_PREDBOOLPTR, FLG_PREDBOOLINT,
1200           FLG_INTERNALGLOBS, FLG_INTERNALGLOBSNOGLOBS,
1201           FLG_USEALLGLOBS, FLG_RETALIAS, 
1202           FLG_MODGLOBS, FLG_MODGLOBSUNSPEC, FLG_MODGLOBSUNCHECKED,
1203           FLG_RETEXPOSE, FLG_ASSIGNEXPOSE, FLG_CASTEXPOSE,
1204           FLG_NOEFFECTUNCON, FLG_EVALORDERUNCON,
1205           FLG_FUNCUNUSED,
1206           FLG_EXPORTITER, FLG_EXPORTCONST,
1207           FLG_TYPEUNUSED, FLG_FIELDUNUSED, FLG_PARAMUNUSED, FLG_TOPUNUSED,
1208           FLG_CONSTUNUSED, FLG_ENUMMEMUNUSED,
1209           FLG_VARUNUSED, 
1210           FLG_NULLPOINTERARITH, FLG_POINTERARITH, 
1211           FLG_PTRNUMCOMPARE, 
1212           FLG_BOOLCOMPARE, FLG_UNSIGNEDCOMPARE,
1213           FLG_NOEFFECT, FLG_RETVALINT, FLG_RETVALBOOL, FLG_RETVALOTHER, 
1214           FLG_ANSIRESERVED, FLG_ANSIRESERVEDLOCAL, FLG_CPPNAMES,
1215           FLG_RETVALBOOL, FLG_RETVALINT, FLG_SPECUNDEF, 
1216           FLG_DECLUNDEF, FLG_STRICTOPS, FLG_INCONDEFS, 
1217           FLG_MISPLACEDSHAREQUAL, FLG_REDUNDANTSHAREQUAL,
1218           FLG_INCONDEFSLIB, FLG_MATCHFIELDS, FLG_EXPORTMACRO, FLG_EXPORTVAR, 
1219           FLG_EXPORTFCN, FLG_EXPORTTYPE, FLG_EXPORTLOCAL, FLG_MACROPARAMS, 
1220           FLG_MACROASSIGN,
1221           FLG_SEFPARAMS, FLG_SEFUNSPEC, FLG_MACROSTMT, FLG_MACROPARENS, 
1222           FLG_MACROFCNDECL,
1223           FLG_MACROCONSTDECL,
1224           FLG_MACROREDEF, FLG_MACROEMPTY,
1225           FLG_INFLOOPS, FLG_INFLOOPSUNCON,
1226           FLG_UNREACHABLE, 
1227           FLG_NORETURN, FLG_CASEBREAK, FLG_MISSCASE, FLG_USEDEF,
1228           FLG_EVALORDER,
1229           FLG_MODUNCON, FLG_MODUNCONNOMODS, FLG_MODINTERNALSTRICT,
1230           FLG_MODOBSERVERUNCON,
1231
1232           FLG_NESTEDEXTERN, 
1233           FLG_FIRSTCASE,
1234
1235           /* warn use flags */
1236           FLG_MULTITHREADED, FLG_PORTABILITY, FLG_SUPERUSER, FLG_IMPLEMENTATIONOPTIONAL,
1237           FLG_BUFFEROVERFLOWHIGH,
1238           FLG_BUFFEROVERFLOW, FLG_TOCTOU,
1239
1240           /* memchecks flags */
1241           FLG_NULLSTATE, FLG_NULLDEREF, FLG_NULLASSIGN,
1242           FLG_NULLPASS, FLG_NULLRET,
1243
1244           FLG_COMPDEF, FLG_COMPMEMPASS, FLG_UNIONDEF,
1245
1246           /* memtrans flags */
1247           FLG_EXPOSETRANS,
1248           FLG_OBSERVERTRANS,
1249           FLG_DEPENDENTTRANS,
1250           FLG_NEWREFTRANS,
1251           FLG_ONLYTRANS,
1252           FLG_OWNEDTRANS,
1253           FLG_FRESHTRANS,
1254           FLG_SHAREDTRANS,
1255           FLG_TEMPTRANS,
1256           FLG_KEPTTRANS,
1257           FLG_REFCOUNTTRANS,
1258           FLG_STATICTRANS,
1259           FLG_UNKNOWNTRANS,
1260           FLG_KEEPTRANS,
1261           FLG_IMMEDIATETRANS,
1262           FLG_STATICINITTRANS,
1263           FLG_UNKNOWNINITTRANS,
1264
1265           FLG_USERELEASED, FLG_ALIASUNIQUE, FLG_MAYALIASUNIQUE,
1266           FLG_MUSTFREE, FLG_MUSTDEFINE, FLG_GLOBSTATE, 
1267           FLG_COMPDESTROY, FLG_MUSTNOTALIAS,
1268           FLG_MEMIMPLICIT,
1269           FLG_BRANCHSTATE, 
1270
1271           FLG_DECLPARAMNAME, FLG_DECLPARAMMATCH,
1272
1273           FLG_SHADOW, FLG_DEPARRAYS, 
1274           FLG_STRICTDESTROY, FLG_STRICTUSERELEASED, FLG_STRICTBRANCHSTATE,
1275           FLG_REDECL, FLG_READONLYSTRINGS, FLG_READONLYTRANS,
1276           FLG_LOOPLOOPBREAK, FLG_LOOPSWITCHBREAK, FLG_SWITCHLOOPBREAK,
1277           FLG_SWITCHSWITCHBREAK, FLG_LOOPLOOPCONTINUE,
1278           FLG_CHECKSTRICTGLOBALS, FLG_IMPCHECKEDSPECGLOBALS,
1279           FLG_ALLGLOBALS, FLG_IMPCHECKEDSTRICTGLOBALS,
1280           FLG_IMPCHECKEDSTRICTSTATICS,
1281           FLG_IMPCHECKEDSTRICTSPECGLOBALS,
1282           FLG_IMPCHECKMODINTERNALS,
1283           FLG_WARNMISSINGGLOBALS, FLG_WARNMISSINGGLOBALSNOGLOBS,
1284           FLG_WARNLINTCOMMENTS, FLG_ANSIRESERVEDLOCAL,
1285           FLG_INCLUDENEST, FLG_STRINGLITERALLEN,
1286           FLG_NUMSTRUCTFIELDS, FLG_NUMENUMMEMBERS,
1287           FLG_CONTROLNESTDEPTH,
1288           FLG_FORBLOCK, FLG_WHILEBLOCK,
1289           FLG_FOREMPTY, FLG_WHILEEMPTY,
1290           FLG_IFEMPTY, FLG_IFBLOCK,
1291           FLG_ELSEIFCOMPLETE,
1292           FLG_REALCOMPARE, FLG_BOOLOPS,
1293           FLG_SYSTEMDIRERRORS, FLG_UNUSEDSPECIAL,
1294
1295           FLG_SHIFTSIGNED, FLG_BITWISEOPS,
1296           FLG_BUFFEROVERFLOWHIGH, FLG_BUFFEROVERFLOW,
1297           INVALID_FLAG
1298         } ;
1299
1300       SETFLAGS ();
1301     }
1302   else
1303     {
1304       llcontbug (message ("context_setMode: bad mode: %s", s));
1305      }
1306 }
1307
1308 bool
1309 context_isSpecialFile (cstring fname)
1310 {
1311   cstring ext = fileLib_getExtension (fname);
1312   
1313   return (cstring_equalLit (ext, ".y") 
1314           || cstring_equalLit (ext, ".l")
1315           || cstring_equalLit (fname, "lex.yy.c"));
1316 }
1317
1318 bool
1319 context_isSystemDir (cstring dir)
1320 {
1321   cstring thisdir = cstring_copy (context_getString (FLG_SYSTEMDIRS));
1322   cstring savedir = thisdir;
1323   cstring nextdir = cstring_afterChar (thisdir, PATH_SEPARATOR);
1324   
1325   if (cstring_isDefined (nextdir))
1326     {
1327       /*@access cstring@*/
1328       *nextdir = '\0'; /* closes thisdir */
1329       nextdir += 1;
1330       /*@noaccess cstring@*/
1331     }
1332
1333   /* 2001-09-09: added thisdir[0] != '\0' 
1334   **   herbert: don't compare with an empty name! 
1335   **   should return false for empty directory path
1336   */
1337
1338   while (!cstring_isEmpty (thisdir))
1339     {
1340       DPRINTF (("Test: %s / %s", dir, thisdir));
1341
1342       if (osd_equalCanonicalPrefix (dir, thisdir))
1343         {
1344           cstring_free (savedir);
1345           return TRUE;
1346         }
1347
1348       if (cstring_isDefined (nextdir))
1349         {
1350           thisdir = nextdir;
1351           nextdir = cstring_afterChar (thisdir, PATH_SEPARATOR);
1352           
1353           if (cstring_isDefined (nextdir))
1354             {
1355               /*@access cstring@*/
1356               *nextdir = '\0';
1357               nextdir += 1;
1358               /*@noaccess cstring@*/
1359             } 
1360         }
1361       else
1362         {
1363           break;
1364         }
1365     } 
1366
1367   DPRINTF (("Returns FALSE"));
1368   cstring_free (savedir);
1369   return FALSE;
1370 }
1371
1372 void
1373 context_addFileAccessType (typeId t)
1374 {
1375   cstring base;
1376
1377   if (context_inFunctionLike ())
1378     {
1379       gc.acct = typeIdSet_insert (gc.acct, t);
1380     }
1381   
1382   gc.facct = typeIdSet_insert (gc.facct, t);
1383   
1384   base = fileloc_getBase (g_currentloc);
1385   insertModuleAccess (base, t);
1386   DPRINTF (("Add file access: %s / %s", typeIdSet_unparse (gc.facct),
1387             typeIdSet_unparse (gc.acct)));
1388 }
1389
1390 void
1391 context_removeFileAccessType (typeId t)
1392 {
1393   if (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN 
1394       || gc.kind == CX_UNKNOWNMACRO)
1395     {
1396       gc.acct = typeIdSet_removeFresh (gc.acct, t);
1397     }
1398   
1399   gc.facct = typeIdSet_removeFresh (gc.facct, t);
1400   gc.nacct = typeIdSet_insert (gc.nacct, t);
1401 }
1402
1403 void context_enterFunctionHeader (void)
1404 {
1405   if (context_getFlag (FLG_GRAMMAR))
1406     {
1407       lldiagmsg (message ("Enter function header: %q", context_unparse ()));
1408     }
1409
1410   if (gc.kind != CX_GLOBAL)
1411     {
1412       llparseerror (cstring_makeLiteral
1413                     ("Likely parse error.  Function header outside global context."));
1414     }
1415   else
1416     {
1417       llassert (gc.kind == CX_GLOBAL);
1418       DPRINTF (("Enter function header!"));
1419       gc.inFunctionHeader = TRUE;
1420     }
1421 }
1422
1423 void context_exitFunctionHeader (void)
1424 {
1425   if (context_getFlag (FLG_GRAMMAR))
1426     {
1427       lldiagmsg (message ("Exit function header: %q", context_unparse ()));
1428     }
1429
1430   DPRINTF (("Exit function header!"));
1431   gc.inFunctionHeader = FALSE;
1432 }
1433
1434 bool context_inFunctionHeader (void)
1435 {
1436   return (gc.inFunctionHeader);
1437 }
1438
1439 void context_enterFunctionDeclaration (uentry e)
1440 {
1441   if (context_getFlag (FLG_GRAMMAR))
1442     {
1443       lldiagmsg (message ("Enter function declaration: %q", context_unparse ()));
1444     }
1445
1446   DPRINTF (("Enter function decl"));
1447   llassert (gc.savekind == CX_ERROR);
1448   gc.savekind = gc.kind;
1449   gc.savecont = gc.cont;
1450   gc.kind = CX_FCNDECLARATION;
1451   gc.cont.fcn = e;
1452 }
1453
1454 void context_exitFunctionDeclaration (void)
1455 {
1456   if (context_getFlag (FLG_GRAMMAR))
1457     {
1458       lldiagmsg (message ("Exit function declaration: %q", context_unparse ()));
1459     }
1460
1461   DPRINTF (("Exit function decl"));
1462   llassert (gc.savekind != CX_ERROR);
1463   llassert (gc.kind == CX_FCNDECLARATION);
1464   gc.kind = gc.savekind;
1465   gc.cont = gc.savecont;
1466
1467   gc.savekind = CX_ERROR;
1468
1469   if (context_getFlag (FLG_GRAMMAR))
1470     {
1471       lldiagmsg (message ("After exit function declaration: %q", context_unparse ()));
1472     }
1473 }
1474
1475 bool context_inFunctionDeclaration (void)
1476 {
1477   return (gc.kind == CX_FCNDECLARATION);
1478 }
1479
1480
1481 void
1482 context_enterMacro (/*@observer@*/ uentry e)
1483 {
1484   context_enterFunction (e);
1485   gc.kind = CX_MACROFCN;
1486 }
1487
1488 void
1489 context_enterUnknownMacro (/*@dependent@*/ uentry e)
1490 {
1491   llassert (uentry_isFunction (e));
1492   context_enterFunction (e);
1493   gc.kind = CX_UNKNOWNMACRO;
1494 }
1495
1496 void context_enterAndClause (exprNode e)
1497 {
1498   
1499   usymtab_trueBranch (guardSet_copy (exprNode_getGuards (e)));
1500   pushClause (ANDCLAUSE);
1501 }
1502
1503 void context_enterOrClause (exprNode e)
1504 {
1505   usymtab_trueBranch (guardSet_invert (exprNode_getGuards (e)));
1506   pushClause (ORCLAUSE);
1507 }
1508
1509 bool context_inDeepLoop (void)
1510 {
1511   bool inLoop = FALSE;
1512
1513   clauseStack_elements (gc.clauses, el)
1514     {
1515       if (clause_isLoop (el))
1516         {
1517           if (inLoop)
1518             {
1519               return TRUE;
1520             }
1521
1522           inLoop = TRUE;
1523         }
1524     } end_clauseStack_elements;
1525
1526   return FALSE;
1527 }
1528
1529 bool context_inDeepSwitch (void)
1530 {
1531   bool inLoop = FALSE;
1532
1533   clauseStack_elements (gc.clauses, el)
1534     {
1535       if (clause_isSwitch (el))
1536         {
1537           if (inLoop)
1538             {
1539               return TRUE;
1540             }
1541
1542           inLoop = TRUE;
1543         }
1544     } end_clauseStack_elements;
1545
1546   return FALSE;
1547 }
1548
1549 bool context_inDeepLoopSwitch (void)
1550 {
1551   bool inLoop = FALSE;
1552
1553   clauseStack_elements (gc.clauses, el)
1554     {
1555       if (clause_isBreakable (el))
1556         {
1557           if (inLoop)
1558             {
1559               return TRUE;
1560             }
1561
1562           inLoop = TRUE;
1563         }
1564     } end_clauseStack_elements;
1565
1566   return FALSE;
1567 }
1568
1569 clause context_breakClause (void)
1570 {
1571   clauseStack_elements (gc.clauses, el)
1572     {
1573       if (clause_isSwitch (el))
1574         {
1575           return el;
1576         }
1577       else if (clause_isLoop (el))
1578         {
1579           return el;
1580         }
1581       else
1582         {
1583           ;
1584         }
1585     } end_clauseStack_elements;
1586
1587   return NOCLAUSE;
1588 }
1589
1590 clause context_nextBreakClause (void)
1591 {
1592   bool hasOne = FALSE;
1593
1594   clauseStack_elements (gc.clauses, el)
1595     {
1596       if (clause_isBreakable (el))
1597         {
1598           if (hasOne)
1599             {
1600               return el;
1601             }
1602           else
1603             {
1604               hasOne = TRUE;
1605             }
1606         }
1607     } end_clauseStack_elements;
1608
1609   return NOCLAUSE;
1610 }
1611   
1612 bool context_inConditional (void)
1613 {
1614   clauseStack_elements (gc.clauses, el)
1615     {
1616       /*
1617       ** Should also include TRUECLAUSE and FALSECLAUSE, but need
1618       ** to distinguish if from ? for this
1619       */
1620
1621       if (clause_isBreakable (el) && (el != DOWHILECLAUSE))
1622         {
1623           return TRUE;
1624         }
1625     } end_clauseStack_elements;
1626
1627   return FALSE;
1628 }
1629
1630 void context_exitAndClause (exprNode pred, exprNode tbranch)
1631 {
1632   context_setJustPopped ();
1633   
1634   llassert (gc.inclause == ANDCLAUSE);
1635   
1636   usymtab_popAndBranch (pred, tbranch);
1637   clauseStack_pop (gc.clauses);
1638   gc.inclause = topClause (gc.clauses);
1639 }
1640
1641 void context_exitOrClause (exprNode pred, exprNode tbranch)
1642 {
1643   context_setJustPopped ();
1644   
1645   llassert (gc.inclause == ORCLAUSE);
1646   
1647   usymtab_popOrBranch (pred, tbranch);
1648   clauseStack_pop (gc.clauses);
1649   gc.inclause = topClause (gc.clauses);
1650 }
1651
1652 static void context_enterCondClauseAux (clause cl)
1653      /*@modifies gc@*/
1654 {
1655   pushClause (cl);
1656 }
1657
1658 static void context_enterTrueAux (exprNode e, clause cl)
1659    /*@modifies gc@*/
1660 {
1661   usymtab_trueBranch (guardSet_copy (exprNode_getGuards (e)));
1662   pushClause (cl);
1663 }
1664
1665 void context_enterIterClause (void)
1666 {
1667   context_enterTrueAux (exprNode_undefined, ITERCLAUSE);
1668 }
1669
1670 void context_enterDoWhileClause (void)
1671 {
1672   pushClause (DOWHILECLAUSE);
1673 }
1674
1675 void context_enterWhileClause (exprNode e)
1676 {
1677   context_enterTrueAux (e, WHILECLAUSE);
1678 }
1679
1680 void context_enterForClause (exprNode e)
1681 {
1682   context_enterTrueAux (e, FORCLAUSE);
1683 }
1684
1685 void context_enterTrueClause (exprNode e)
1686 {
1687   context_enterTrueAux (e, TRUECLAUSE);
1688 }
1689
1690 void context_enterSwitch (exprNode e)
1691 {
1692   
1693   usymtab_switchBranch (e);
1694   context_enterCondClauseAux (SWITCHCLAUSE);
1695 }
1696
1697 void context_exitSwitch (exprNode e, bool allpaths)
1698 {
1699     usymtab_exitSwitch (e, allpaths);
1700   
1701   while (clause_isCase (clauseStack_top (gc.clauses)))
1702     {
1703       clauseStack_pop (gc.clauses);
1704     }
1705   
1706   context_exitClauseSimp ();
1707 }
1708
1709 void context_enterCaseClause (exprNode e)
1710 {
1711   bool branch = FALSE;
1712  
1713   DPRINTF (("Enter case clause!"));
1714
1715   branch = usymtab_newCase (exprNode_undefined, e);
1716   
1717   if (branch)
1718     {
1719       context_enterCondClauseAux (CASECLAUSE);
1720     }
1721 }
1722
1723 static void context_enterFalseClauseAux (exprNode e, clause cl)
1724      /*@modifies gc@*/
1725 {
1726   usymtab_altBranch (guardSet_invert (exprNode_getGuards (e)));
1727   gc.inclause = cl;
1728   clauseStack_switchTop (gc.clauses, cl);
1729 }
1730
1731 void context_enterFalseClause (exprNode e)
1732 {
1733   
1734   context_enterFalseClauseAux (e, FALSECLAUSE);
1735 }
1736
1737 void
1738 context_enterConstantMacro (/*@exposed@*/ /*@dependent@*/ uentry e)
1739 {
1740   gc.kind = CX_MACROCONST;
1741   gc.cont.fcn = e;
1742   gc.showfunction = context_getFlag (FLG_SHOWFUNC);
1743
1744   gc.acct = typeIdSet_subtract (typeIdSet_union (gc.facct, uentry_accessType (e)), 
1745                                 gc.nacct);
1746
1747   
1748   usymtab_enterScope ();
1749   sRef_enterFunctionScope ();
1750
1751   gc.globs = globSet_undefined;
1752   globSet_clear (gc.globs_used);
1753   gc.mods = sRefSet_undefined;
1754 }
1755
1756 uentry context_getHeader (void)
1757 {
1758   if (!(context_inFunctionLike () || (gc.kind == CX_MACROCONST)))
1759     {
1760       llfatalbug (message ("context_getHeader: bad call: %q",
1761                            context_unparse ()));
1762     }
1763
1764   return (gc.cont.fcn);
1765 }
1766
1767 void
1768 context_setFunctionDefined (fileloc loc)
1769 {
1770   switch (gc.kind)
1771     {
1772     case CX_UNKNOWNMACRO:
1773     case CX_FUNCTION:
1774     case CX_MACROFCN:
1775       uentry_setFunctionDefined (gc.cont.fcn, loc);
1776       break;
1777     default:
1778       /* (not a bug because of parse errors) */
1779       break;
1780     }
1781 }
1782
1783 void
1784 context_enterFunction (/*@exposed@*/ uentry e)
1785 {
1786   gc.kind = CX_FUNCTION;
1787   gc.cont.fcn = e;
1788
1789   DPRINTF (("Enter function: %s", uentry_unparse (e)));
1790
1791   if (uentry_hasAccessType (e))
1792     {
1793       gc.acct = typeIdSet_subtract (typeIdSet_union (gc.facct, uentry_accessType (e)), 
1794                                     gc.nacct);
1795     }
1796   else
1797     {
1798       gc.acct = gc.facct;
1799     }
1800
1801   DPRINTF (("Enter function: %s / %s", uentry_unparse (e), 
1802             typeIdSet_unparse (gc.acct)));
1803
1804   gc.showfunction = context_getFlag (FLG_SHOWFUNC);
1805   
1806   gc.globs = uentry_getGlobs (e);
1807   globSet_clear (gc.globs_used);
1808   gc.mods = uentry_getMods (e);
1809
1810   usymtab_enterFunctionScope (e);
1811   sRef_enterFunctionScope ();
1812 }
1813
1814 void
1815 context_enterOldStyleScope (void)
1816 {
1817   gc.kind = CX_OLDSTYLESCOPE;
1818   DPRINTF (("Enter old style scope!"));
1819   usymtab_enterFunctionScope (uentry_undefined);
1820 }
1821
1822 void 
1823 context_completeOldStyleFunction (uentry e)
1824 {
1825   llassert (gc.kind == CX_OLDSTYLESCOPE);
1826
1827   gc.kind = CX_FUNCTION;
1828   gc.cont.fcn = e;
1829   
1830   DPRINTF (("Enter function: %s", uentry_unparse (e)));
1831   
1832   if (uentry_hasAccessType (e))
1833     {
1834       gc.acct = typeIdSet_subtract (typeIdSet_union (gc.facct, uentry_accessType (e)), 
1835                                     gc.nacct);
1836     }
1837   else
1838     {
1839       gc.acct = gc.facct;
1840     }
1841   
1842   DPRINTF (("Enter function: %s / %s", uentry_unparse (e), 
1843             typeIdSet_unparse (gc.acct)));
1844   
1845   gc.showfunction = context_getFlag (FLG_SHOWFUNC);
1846   
1847   if (!globSet_isEmpty (uentry_getGlobs (e))) 
1848     {
1849       llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
1850                              fileloc_unparse (g_currentloc), uentry_unparse (e)));
1851     }
1852
1853   gc.showfunction = context_getFlag (FLG_SHOWFUNC);
1854   
1855   gc.globs = uentry_getGlobs (e);
1856   globSet_clear (gc.globs_used);
1857
1858   gc.mods = uentry_getMods (e);
1859
1860   if (!sRefSet_isEmpty (gc.mods))
1861     {
1862       llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
1863                              fileloc_unparse (g_currentloc), uentry_unparse (e)));
1864     }
1865
1866   sRef_enterFunctionScope ();
1867 }
1868
1869 static bool context_checkStrictGlobals (void)
1870 {
1871   return (context_getFlag (FLG_CHECKSTRICTGLOBALS));
1872 }
1873
1874 static bool context_hasGlobs (void)
1875 {
1876   if (context_inFunctionLike ())
1877     {
1878       return (uentry_hasGlobs (gc.cont.fcn));
1879     }
1880   else
1881     {
1882       return (FALSE);
1883     }
1884 }
1885
1886 static bool context_checkCheckedGlobals (void)
1887 {
1888   return (context_getFlag (FLG_GLOBALS)
1889           && (context_getFlag (FLG_GLOBUNSPEC)
1890               || context_hasGlobs ()));
1891 }
1892
1893 static bool context_checkUnknownGlobals (void)
1894 {
1895   /* should be uentry_hasGlobs ? */
1896
1897   return (context_getFlag (FLG_ALLGLOBALS)
1898           && (context_getFlag (FLG_GLOBUNSPEC)
1899               || context_hasGlobs ()));
1900 }      
1901
1902 static bool context_checkUncheckedGlobals (void)
1903 {
1904   return (FALSE);
1905 }      
1906
1907 bool 
1908 context_checkExport (uentry e)
1909 {
1910   if (!gc.anyExports) return FALSE;
1911
1912   if (uentry_isFunction (e)
1913       || (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))))
1914     {
1915       return context_maybeSet (FLG_EXPORTFCN);
1916     }
1917   else if (uentry_isExpandedMacro (e))
1918     {
1919       return context_maybeSet (FLG_EXPORTMACRO);
1920     }
1921   else if (uentry_isVariable (e))
1922     {
1923       return context_maybeSet (FLG_EXPORTVAR);
1924     }
1925   else if (uentry_isEitherConstant (e))
1926     {
1927       return context_maybeSet (FLG_EXPORTCONST);
1928     }
1929   else if (uentry_isIter (e) || uentry_isEndIter (e))
1930     {
1931       return context_maybeSet (FLG_EXPORTITER);
1932     }
1933   else if (uentry_isDatatype (e))
1934     {
1935       return context_maybeSet (FLG_EXPORTTYPE);
1936     }
1937   else
1938     {
1939       BADEXIT;
1940     }
1941 }
1942               
1943 bool
1944 context_checkGlobUse (uentry glob)
1945 {
1946   
1947   if (uentry_isCheckedStrict (glob))
1948     {
1949       return context_checkStrictGlobals ();
1950     }
1951   else if (uentry_isChecked (glob))
1952     {
1953       return context_checkCheckedGlobals ();
1954     }
1955   else if (uentry_isCheckedUnknown (glob) || uentry_isCheckMod (glob))
1956     {
1957       return context_checkUnknownGlobals ();
1958     }
1959   else 
1960     {
1961       llassert (uentry_isUnchecked (glob));
1962
1963       return context_checkUncheckedGlobals ();
1964     }
1965 }
1966
1967 bool
1968 context_checkAliasGlob (uentry glob)
1969 {
1970   if (uentry_isCheckedStrict (glob))
1971     {
1972       return gc.flags[FLG_CHECKSTRICTGLOBALIAS];
1973     }
1974   else if (uentry_isChecked (glob))
1975     {
1976       return gc.flags[FLG_CHECKEDGLOBALIAS];
1977     }
1978   else if (uentry_isCheckMod (glob))
1979     {
1980       return gc.flags[FLG_CHECKMODGLOBALIAS];
1981     }
1982   else 
1983     {
1984       llassert (uentry_isUnchecked (glob) || uentry_isCheckedUnknown (glob));
1985
1986       return gc.flags[FLG_UNCHECKEDGLOBALIAS];
1987     }
1988 }
1989
1990 bool context_checkInternalUse (void)
1991 {
1992   if (context_hasGlobs ())
1993     {
1994       return (gc.flags[FLG_INTERNALGLOBS]);
1995     }
1996   else
1997     {
1998       return (gc.flags[FLG_INTERNALGLOBSNOGLOBS]);
1999     }
2000 }
2001
2002 bool
2003 context_checkGlobMod (sRef el)
2004 {
2005   uentry ue = sRef_getUentry (el);
2006
2007   /* no: llassert (sRef_isFileOrGlobalScope (el)); also check local statics */
2008
2009   if (uentry_isCheckedModify (ue)
2010       || (!uentry_isUnchecked (ue) && (gc.flags[FLG_ALLGLOBALS])))
2011     {
2012       if (context_hasMods ())
2013         {
2014           return (gc.flags[FLG_MODGLOBS]);
2015         }
2016       else
2017         {
2018           if (uentry_isCheckedStrict (ue))
2019             {
2020               return (gc.flags[FLG_MODGLOBSUNSPEC]);
2021             }
2022           else
2023             {
2024               return (gc.flags[FLG_MODSTRICTGLOBSUNSPEC]);
2025             }
2026         }
2027     }
2028   else
2029     {
2030       if (context_hasMods ())
2031         {
2032           return (gc.flags[FLG_MODGLOBSUNCHECKED]);
2033         }
2034       else
2035         {
2036           return FALSE;
2037         }
2038     }
2039 }
2040
2041 void
2042 context_usedGlobal (/*@exposed@*/ sRef el)
2043 {
2044   if (!globSet_member (gc.globs_used, el))
2045     {
2046       /* 
2047       ** The first time a global is used in a function, we need
2048       ** to clear the derived sRefs, since they were set for the
2049       ** previous function.
2050       */
2051
2052       sRef_clearDerived (el);
2053       gc.globs_used = globSet_insert (gc.globs_used, el);
2054     }
2055 }
2056
2057 /*@observer@*/ sRefSet
2058 context_modList (void)
2059 {
2060   return gc.mods;
2061 }
2062
2063 bool
2064 context_globAccess (sRef s)
2065 {
2066   llassert (sRef_isFileOrGlobalScope (s) || sRef_isKindSpecial (s));
2067   return (globSet_member (gc.globs, s));
2068 }
2069
2070 bool
2071 context_hasAccess (typeId t)
2072 {
2073   if (context_inFunctionLike ())
2074     {
2075       DPRINTF (("Access %d / %s",
2076                 t, typeIdSet_unparse (gc.acct)));
2077       return (typeIdSet_member (gc.acct, t));
2078     }
2079   else
2080     {
2081       return (context_hasFileAccess (t));
2082     }
2083 }
2084
2085 bool
2086 context_hasFileAccess (typeId t)
2087 {
2088   return (typeIdSet_member (gc.facct, t));
2089 }
2090
2091 /*@only@*/ cstring
2092 context_unparseAccess (void)
2093 {
2094   return (message ("%q / %q", typeIdSet_unparse (gc.acct),
2095                    typeIdSet_unparse (gc.facct)));
2096 }
2097
2098 /*@only@*/ cstring
2099 context_unparseClauses (void)
2100 {
2101   return (clauseStack_unparse (gc.clauses));
2102 }
2103
2104 bool
2105 context_couldHaveAccess (typeId t)
2106 {
2107   if (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN || gc.kind == CX_UNKNOWNMACRO)
2108     {
2109       return (typeIdSet_member (gc.acct, t));
2110     }
2111   else
2112     {
2113       return (typeIdSet_member (gc.facct, t)); 
2114     }
2115 }
2116
2117 ctype
2118 context_getRetType (void)
2119 {
2120   ctype f = ctype_undefined;
2121
2122   if (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN)
2123     {
2124       f = uentry_getType (gc.cont.fcn);
2125     }
2126   else if (gc.kind == CX_UNKNOWNMACRO)
2127     {
2128       return ctype_unknown;
2129     }
2130   else
2131     {
2132       llcontbuglit ("context_getRetType: not in a function context");
2133       return ctype_unknown;
2134     }
2135
2136   if (!ctype_isFunction (f))
2137     {
2138       if (ctype_isKnown (f))
2139         {
2140           llbuglit ("context_getRetType: not a function");
2141         }
2142
2143       return ctype_unknown;
2144     }
2145   return (ctype_getReturnType (f));
2146 }    
2147
2148 bool
2149 context_hasMods (void)
2150 {
2151   if (context_inFunctionLike ())
2152     {
2153       return (uentry_hasMods (gc.cont.fcn));
2154     }
2155   else
2156     {
2157       return FALSE;
2158     }
2159 }
2160
2161 void
2162 context_exitAllClauses (void)
2163 {  
2164   while (!clauseStack_isEmpty (gc.clauses))
2165     {
2166       clause el = clauseStack_top (gc.clauses);
2167       gc.inclause = el;
2168
2169       if (clause_isNone (el))
2170         {
2171           usymtab_quietExitScope (g_currentloc);
2172           clauseStack_pop (gc.clauses);
2173         }
2174       else
2175         {
2176           context_exitClausePlain ();
2177         }
2178     }
2179
2180   clauseStack_clear (gc.clauses);  
2181   gc.inclause = NOCLAUSE;
2182 }
2183
2184 void
2185 context_exitAllClausesQuiet (void)
2186 {  
2187   while (!clauseStack_isEmpty (gc.clauses))
2188     {
2189       clause el = clauseStack_top (gc.clauses);
2190       gc.inclause = el;
2191
2192       usymtab_quietExitScope (g_currentloc);
2193       clauseStack_pop (gc.clauses);
2194     }
2195
2196   clauseStack_clear (gc.clauses);  
2197   gc.inclause = NOCLAUSE;
2198 }
2199
2200 static
2201 void context_exitClauseSimp (void)
2202 {
2203   
2204   context_setJustPopped ();
2205   clauseStack_pop (gc.clauses);
2206   gc.inclause = topClause (gc.clauses);
2207 }
2208
2209 static
2210 void context_exitCaseClause (void)
2211 {
2212   context_setJustPopped ();
2213   usymtab_popCaseBranch ();
2214   clauseStack_pop (gc.clauses);
2215   gc.inclause = topClause (gc.clauses);
2216 }
2217
2218 static
2219 void context_exitClauseAux (exprNode pred, exprNode tbranch)
2220 {
2221   context_setJustPopped ();
2222   /*@i32 was makeAlt */
2223   usymtab_popTrueBranch (pred, tbranch, gc.inclause);
2224   clauseStack_pop (gc.clauses);
2225   gc.inclause = topClause (gc.clauses);
2226 }
2227
2228 void context_exitTrueClause (exprNode pred, exprNode tbranch)
2229 {
2230   DPRINTF (("Exit true clause: %s", exprNode_unparse (tbranch)));
2231
2232   if (gc.inclause != TRUECLAUSE)
2233     {
2234       llparseerror (cstring_makeLiteral
2235                     ("Likely parse error.  Conditional clauses are inconsistent."));
2236       return;
2237     }
2238   
2239   context_setJustPopped ();  
2240   usymtab_popTrueBranch (pred, tbranch, TRUECLAUSE);
2241   clauseStack_pop (gc.clauses);
2242   gc.inclause = topClause (gc.clauses);  
2243 }
2244
2245 void context_exitIterClause (exprNode body)
2246 {
2247   llassert (gc.inclause == ITERCLAUSE);
2248
2249   context_setJustPopped ();
2250
2251   if (context_getFlag (FLG_LOOPEXEC))
2252     {
2253       usymtab_popTrueExecBranch (exprNode_undefined, body, ITERCLAUSE);
2254     }
2255   else
2256     {
2257       usymtab_popTrueBranch (exprNode_undefined, body, ITERCLAUSE);
2258     }
2259
2260   clauseStack_pop (gc.clauses);
2261   gc.inclause = topClause (gc.clauses);
2262 }
2263
2264 static void context_popCase (void) {
2265   /*
2266   ** If we are exiting an outer clause, sometimes still in a switch case.
2267   **
2268   ** e.g.: 
2269   **
2270   ** switch(a)
2271   ** {
2272   **   case 1:
2273   **     while (c>3)
2274   **       {
2275   **         case 3: ++c;
2276   **       }
2277   ** }     
2278   */
2279
2280   DPRINTF (("Popping case clause: %s",
2281             clauseStack_unparse (gc.clauses)));
2282   
2283   if (gc.inclause == CASECLAUSE) {
2284     context_exitCaseClause ();
2285   }
2286 }
2287
2288 void context_exitWhileClause (exprNode pred, exprNode body)
2289 {
2290   guardSet invGuards = guardSet_invert (exprNode_getGuards (pred));
2291
2292   context_popCase (); 
2293
2294   if (gc.inclause != WHILECLAUSE) {
2295     DPRINTF (("Clause: %s / %s", clause_unparse (gc.inclause),
2296               clauseStack_unparse (gc.clauses)));
2297   }
2298
2299   llassert (gc.inclause == WHILECLAUSE);
2300
2301   context_setJustPopped ();
2302
2303   
2304   /*
2305   ** predicate must be false after while loop (unless there are breaks)
2306   */
2307
2308   if (context_getFlag (FLG_LOOPEXEC))
2309     {
2310       usymtab_popTrueExecBranch (pred, body, WHILECLAUSE);
2311     }
2312   else
2313     {
2314       usymtab_popTrueBranch (pred, body, WHILECLAUSE);
2315     }
2316
2317   
2318   usymtab_addGuards (invGuards);
2319   guardSet_free (invGuards);
2320
2321   clauseStack_pop (gc.clauses);
2322   gc.inclause = topClause (gc.clauses);  
2323 }
2324
2325 void context_exitDoWhileClause (exprNode pred)
2326 {
2327   guardSet invGuards = guardSet_invert (exprNode_getGuards (pred));
2328
2329   if (gc.inclause == CASECLAUSE) {
2330     /* handle Duff's device */
2331     clauseStack_pop (gc.clauses);
2332     gc.inclause = topClause (gc.clauses);
2333   }
2334
2335   llassert (gc.inclause == DOWHILECLAUSE);
2336
2337   context_setJustPopped ();
2338
2339     
2340   usymtab_addGuards (invGuards);
2341   guardSet_free (invGuards);
2342
2343   clauseStack_pop (gc.clauses);
2344   gc.inclause = topClause (gc.clauses);  
2345 }
2346
2347 void context_exitForClause (exprNode forPred, exprNode body)
2348 {
2349   guardSet invGuards = guardSet_invert (exprNode_getForGuards (forPred));
2350
2351   llassert (gc.inclause == FORCLAUSE);
2352   context_setJustPopped ();
2353
2354   /*
2355   ** predicate must be false after while loop (unless there are breaks)
2356   */
2357
2358   if (context_getFlag (FLG_LOOPEXEC))
2359     {
2360       usymtab_popTrueExecBranch (forPred, body, FORCLAUSE);
2361     }
2362   else
2363     {
2364       usymtab_popTrueBranch (forPred, body, FORCLAUSE);
2365     }
2366
2367   usymtab_addGuards (invGuards);
2368   guardSet_free (invGuards);
2369   clauseStack_pop (gc.clauses);
2370   gc.inclause = topClause (gc.clauses);
2371 }
2372
2373 static void context_exitClausePlain (void)
2374 {
2375   llassert (gc.inclause != NOCLAUSE);
2376   
2377   if (gc.inclause == FALSECLAUSE)
2378     {
2379       context_exitClause (exprNode_undefined, exprNode_undefined, exprNode_undefined);
2380     }
2381   else
2382     {
2383       context_exitClauseAux (exprNode_undefined, exprNode_undefined);
2384     }
2385 }
2386
2387 void context_exitClause (exprNode pred, exprNode tbranch, exprNode fbranch)
2388 {
2389   context_setJustPopped ();
2390   
2391   if (gc.inclause == FALSECLAUSE)
2392     {
2393       usymtab_popBranches (pred, tbranch, fbranch, FALSE, FALSECLAUSE);
2394       
2395       llassert (clauseStack_top (gc.clauses) == FALSECLAUSE);
2396
2397       clauseStack_pop (gc.clauses);
2398       gc.inclause = topClause (gc.clauses);
2399     }
2400   else
2401     {
2402       context_exitTrueClause (pred, tbranch);
2403     }
2404 }
2405
2406 void
2407 context_returnFunction (void)
2408 {
2409   usymtab_checkFinalScope (TRUE);
2410 }
2411
2412 void
2413 context_exitFunction (void)
2414 {    
2415   DPRINTF (("Exit function: %s", context_unparse ()));
2416
2417   if (!context_inFunction () && !context_inMacroConstant () 
2418       && !context_inUnknownMacro () 
2419       && !context_inIterDef () && !context_inIterEnd ())
2420     {
2421       /*
2422       ** not a bug because of parse errors
2423       */
2424
2425       BADBRANCH;
2426     }
2427   else
2428     {
2429       if (context_inMacro () && usymtab_inFunctionScope ())
2430         {
2431           usymtab_exitScope (exprNode_undefined);
2432         }
2433       
2434       if (uentry_hasGlobs (gc.cont.fcn))
2435         {
2436           exprChecks_checkUsedGlobs (gc.globs, gc.globs_used);
2437         }
2438       
2439             
2440       if (uentry_hasMods (gc.cont.fcn))
2441         {
2442           if (context_getFlag (FLG_MUSTMOD))
2443             {
2444               exprNode_checkAllMods (gc.mods, gc.cont.fcn);
2445             }
2446         }
2447
2448       DPRINTF (("Exit function: %s", uentry_unparse (gc.cont.fcn)));
2449
2450       /*
2451       ** clear file static modifies
2452       */
2453       
2454       /* do this first to get unused error messages */
2455
2456       usymtab_exitScope (exprNode_undefined);
2457       sRef_exitFunctionScope ();
2458       
2459       gc.showfunction = FALSE;
2460       gc.kind = CX_GLOBAL;
2461       gc.cont.glob = TRUE;
2462       gc.acct = gc.facct; 
2463       gc.globs = globSet_new ();
2464       globSet_clear (gc.globs_used);
2465       gc.mods = sRefSet_new ();
2466     }
2467
2468   llassert (clauseStack_isEmpty (gc.clauses));
2469   llassert (gc.inclause == NOCLAUSE);
2470   DPRINTF (("After exit function: %s", context_unparse ()));
2471 }
2472
2473 void
2474 context_quietExitFunction (void)
2475 {
2476   while (gc.kind == CX_INNER)
2477     { 
2478       context_exitInnerPlain ();
2479     }
2480
2481   if (!context_inFunction () && !context_inMacroConstant () && !context_inUnknownMacro () 
2482       && !context_inIterDef () && !context_inIterEnd ())
2483     {
2484     }
2485   else
2486     {
2487       usymtab_quietExitScope (g_currentloc);
2488
2489       gc.showfunction = FALSE;
2490       gc.kind = CX_GLOBAL;
2491       gc.cont.glob = TRUE;
2492       gc.acct = gc.facct; 
2493       gc.globs = globSet_new ();
2494       globSet_clear (gc.globs_used);
2495       gc.mods = sRefSet_new ();
2496
2497       sRef_exitFunctionScope ();
2498     }
2499 }
2500
2501 /*@observer@*/ uentryList
2502 context_getParams (void)
2503 {
2504   if (context_inFunctionLike ())
2505     {
2506       return (uentry_getParams (gc.cont.fcn));
2507     }
2508   else
2509     {
2510       llcontbug (message ("context_getParams: not in function: %q", context_unparse ()));
2511       return uentryList_undefined;
2512     }
2513 }
2514
2515 /*@observer@*/ globSet
2516 context_getUsedGlobs (void)
2517 {
2518   llassert (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN 
2519             || gc.kind == CX_UNKNOWNMACRO || gc.kind == CX_ITERDEF);
2520
2521   return (gc.globs_used);
2522 }
2523
2524 cstring
2525 context_moduleName ()
2526 {
2527   return (fileloc_getBase (g_currentloc));
2528 }
2529
2530 /*@observer@*/ globSet
2531 context_getGlobs (void)
2532 {
2533   llassert (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN 
2534             || gc.kind == CX_UNKNOWNMACRO || gc.kind == CX_ITERDEF);
2535
2536   return (gc.globs);
2537 }
2538
2539 void
2540 context_addBoolAccess (void)
2541 {
2542   cstring bname = context_getString (FLG_BOOLTYPE);
2543   typeIdSet boolt = typeIdSet_single (usymtab_getTypeId (bname));
2544   
2545   addModuleAccess (cstring_copy (bname), boolt);
2546
2547   /* for sys/types (perhaps, this is bogus!) */ 
2548   addModuleAccess (cstring_makeLiteral ("types"), boolt); 
2549 }
2550
2551 # if 0
2552 bool
2553 context_canAccessBool (void)
2554 {
2555   return TRUE;
2556 }
2557 # endif
2558
2559 /*
2560   static typeId boolType = typeId_invalid;
2561
2562   if (typeId_isInvalid (boolType))
2563     { 
2564       boolType = usymtab_getTypeId (context_getBoolName ());
2565     }
2566
2567   if (typeId_isInvalid (boolType)) {
2568     return FALSE;
2569   } else {
2570     return (typeIdSet_member (gc.acct, boolType));
2571   }
2572 }
2573 */
2574
2575 /* evs 2000-07-25: old version - replaced */
2576
2577 ctype
2578 context_boolImplementationType () {
2579   /* For now, this is bogus! */
2580   return ctype_int;
2581 }
2582
2583 bool
2584 context_canAccessBool (void)
2585 {
2586   static typeId boolType = typeId_invalid;
2587
2588   if (typeId_isInvalid (boolType))
2589     { 
2590       boolType = usymtab_getTypeId (context_getBoolName ());
2591     }
2592
2593   if (!typeId_isInvalid (boolType))
2594     { 
2595       return context_hasAccess (boolType);
2596     }
2597   else 
2598     {
2599       ;
2600     }
2601
2602   return FALSE; 
2603 }
2604
2605 void
2606 context_setMessageAnnote (/*@only@*/ cstring s)
2607 {
2608   llassert (cstring_isUndefined (gc.msgAnnote));
2609     gc.msgAnnote = s;
2610 }
2611
2612 bool
2613 context_hasMessageAnnote (void)
2614 {
2615   return (cstring_isDefined (gc.msgAnnote));
2616 }
2617
2618 void
2619 context_clearMessageAnnote (void)
2620 {
2621   if (cstring_isDefined (gc.msgAnnote))
2622     {
2623       cstring_free (gc.msgAnnote);
2624       gc.msgAnnote = cstring_undefined;
2625     }
2626 }
2627
2628 /*@only@*/ cstring
2629 context_getMessageAnnote (void)
2630 {
2631   cstring st = gc.msgAnnote;
2632
2633     gc.msgAnnote = cstring_undefined;
2634   return st;
2635 }
2636
2637 void
2638 context_setAliasAnnote (/*@observer@*/ sRef s, /*@observer@*/ sRef t)
2639 {
2640     llassert (sRef_isInvalid (gc.aliasAnnote));
2641   llassert (!sRef_sameName (s, t));
2642   gc.aliasAnnote = s;
2643   gc.aliasAnnoteAls = t;
2644 }
2645
2646 bool
2647 context_hasAliasAnnote (void)
2648 {
2649   return (sRef_isValid (gc.aliasAnnote));
2650 }
2651
2652 void
2653 context_clearAliasAnnote (void)
2654 {
2655   gc.aliasAnnote = sRef_undefined;
2656 }
2657
2658 cstring
2659 context_getAliasAnnote (void)
2660 {
2661   sRef ret = gc.aliasAnnote;
2662   sRef als = gc.aliasAnnoteAls;
2663
2664   llassert (sRef_isValid (ret) && sRef_isValid (als));
2665
2666   gc.aliasAnnote = sRef_undefined;
2667   return (message ("%q aliases %q", sRef_unparse (als), sRef_unparse (ret)));
2668 }
2669
2670 void
2671 context_recordFileModifies (sRefSet mods)
2672 {
2673   gc.modrecs = sRefSetList_add (gc.modrecs, mods);
2674 }
2675
2676 void
2677 context_recordFileGlobals (globSet mods)
2678 {
2679   DPRINTF (("Recording file globals: %s", globSet_unparse (mods)));
2680   /*@access globSet@*/ context_recordFileModifies (mods); /*@noaccess globSet@*/
2681 }
2682
2683 void
2684 context_setCommentMarkerChar (char c)
2685 {
2686   llassert (c != '\0');
2687
2688   context_setValue (FLG_COMMENTCHAR, (int) c);
2689 }
2690
2691 char
2692 context_getCommentMarkerChar (void)
2693 {
2694   return ((char) context_getValue (FLG_COMMENTCHAR));
2695 }
2696
2697 static void
2698 context_setValue (flagcode flag, int val)
2699 {
2700   int index = flagcode_valueIndex (flag);
2701
2702   llassert (index >= 0 && index <= NUMVALUEFLAGS);
2703
2704   switch (flag)
2705     {
2706     case FLG_LINELEN:
2707       if (val <= 0)
2708         {
2709           
2710           llerror_flagWarning (message ("Value for %s must be a positive "
2711                                     "number (given %d)",
2712                                     flagcode_unparse (flag), val));
2713           return;
2714         }
2715       if (flag == FLG_LINELEN && val < MINLINELEN)
2716         {
2717           llerror_flagWarning (message ("Value for %s must be at least %d (given %d)",
2718                                     flagcode_unparse (flag), 
2719                                     MINLINELEN, val));
2720           val = MINLINELEN;
2721         }
2722       break;
2723
2724     case FLG_INCLUDENEST:
2725     case FLG_CONTROLNESTDEPTH:
2726     case FLG_STRINGLITERALLEN:
2727     case FLG_NUMSTRUCTFIELDS:
2728     case FLG_NUMENUMMEMBERS:      
2729     case FLG_INDENTSPACES:
2730       if (val < 0)
2731         {
2732           
2733           llerror_flagWarning (message ("Value for %s must be a non-negative "
2734                                     "number (given %d)",
2735                                     flagcode_unparse (flag), val));
2736           return;
2737         }
2738
2739       break;
2740     default:
2741       break;
2742     }
2743     
2744   gc.values[index] = val;
2745 }
2746
2747 void
2748 context_setValueAndFlag (flagcode flag, int val)
2749 {
2750   gc.flags[flag] = TRUE;
2751   context_setValue (flag, val);
2752 }
2753
2754 int
2755 context_getValue (flagcode flag)
2756 {
2757   int index = flagcode_valueIndex (flag);
2758
2759   llassert (index >= 0 && index <= NUMVALUEFLAGS);
2760   return (gc.values[index]);
2761 }
2762
2763 int
2764 context_getCounter (flagcode flag)
2765 {
2766   int index = flagcode_valueIndex (flag);
2767
2768   llassert (index >= 0 && index <= NUMVALUEFLAGS);
2769   return (gc.counters[index]);
2770 }
2771
2772 void
2773 context_incCounter (flagcode flag)
2774 {
2775   int index = flagcode_valueIndex (flag);
2776
2777   llassert (index >= 0 && index <= NUMVALUEFLAGS);
2778   /* check limit */
2779   gc.counters[index]++;
2780 }
2781
2782 void
2783 context_decCounter (flagcode flag)
2784 {
2785   int index = flagcode_valueIndex (flag);
2786
2787   llassert (index >= 0 && index <= NUMVALUEFLAGS);
2788   gc.counters[index]--;
2789 }
2790
2791 bool context_showFunction (void)
2792 {
2793   return (gc.showfunction);
2794 }
2795
2796 void
2797 context_setString (flagcode flag, cstring val)
2798 {
2799   int index = flagcode_stringIndex (flag);
2800
2801   llassert (index >= 0 && index <= NUMSTRINGFLAGS);
2802
2803   if (flag == FLG_SYSTEMDIRS)
2804     {
2805       llassert (cstring_isDefined (val));
2806
2807       if (cstring_firstChar (val) == '\"')
2808         {
2809           cstring oval = val;
2810           cstring tval = cstring_copy (cstring_suffix (val, 1));
2811         
2812           if (cstring_lastChar (tval) != '\"')
2813             {
2814               int n = cstring_length (tval) - 1;
2815
2816               while (isspace ((int) cstring_getChar (tval, n)))
2817                 {
2818                   n--;
2819                 }
2820
2821               if (cstring_getChar (tval, n) != '\"')
2822                 {
2823                   llerror_flagWarning (message ("Setting -systemdirs to string with unmatching quotes: %s", val));
2824                 }
2825               else
2826                 {
2827                   cstring otval = tval;
2828                   tval = cstring_prefix (tval, n);
2829                   cstring_free (otval);
2830                 }
2831             }
2832           
2833           val = cstring_copy (cstring_clip (tval, cstring_length (tval) - 1));
2834           DPRINTF (("val = %s", val));
2835           cstring_free (tval);
2836           cstring_free (oval);
2837         }
2838     }
2839
2840   if (flag == FLG_TMPDIR)
2841     {
2842       llassert (cstring_isDefined (val));
2843       
2844       if (cstring_length (val) == 0)
2845         {
2846           cstring_free (val);
2847           val = message (".%s", cstring_makeLiteralTemp (CONNECTSTR));
2848         }
2849       else if (cstring_lastChar (val) != CONNECTCHAR)
2850         {
2851           val = cstring_appendChar (val, CONNECTCHAR);
2852         }
2853       else
2854         {
2855           ;
2856         }
2857     }
2858
2859   if (cstring_length (val) >= 1
2860       && cstring_firstChar (val) == '\"')
2861     {
2862       llerror_flagWarning (message
2863                        ("setting %s to string beginning with \".  You probably "
2864                         "don't meant to have the \"'s.",
2865                         flagcode_unparse (flag)));
2866     }
2867
2868   if (flag == FLG_BOOLTYPE)
2869     {
2870
2871     }
2872
2873   gc.strings[index] = val;
2874 }
2875
2876 static /*@exposed@*/ cstring
2877 context_exposeString (flagcode flag)
2878 {
2879   int index = flagcode_stringIndex (flag);
2880
2881   llassert (index >= 0 && index <= NUMSTRINGFLAGS);
2882   return (gc.strings[index]);
2883 }
2884
2885 cstring
2886 context_getString (flagcode flag)
2887 {
2888   return (context_exposeString (flag));
2889 }
2890
2891 void
2892 context_resetErrors (void)
2893 {
2894   gc.numerrors = 0;
2895 }
2896
2897 void context_initMod (void)
2898    /*@globals undef gc; @*/
2899 {
2900   gc.kind = CX_GLOBAL;
2901
2902   gc.savekind = CX_ERROR;
2903   gc.savecont.glob = FALSE;
2904
2905   gc.instandardlib = FALSE;
2906   gc.numerrors = 0;
2907   gc.neednl = FALSE;
2908   gc.linesprocessed = 0;
2909   gc.speclinesprocessed = 0;
2910   gc.insuppressregion = FALSE;
2911   gc.macroMissingParams = FALSE;
2912   gc.preprocessing = FALSE;
2913   gc.incommandline = FALSE;
2914   gc.mc = macrocache_create ();
2915   gc.nmods = 0;
2916   gc.maxmods = DEFAULTMAXMODS;
2917   gc.moduleaccess = (maccesst *) dmalloc (sizeof (*gc.moduleaccess) * (gc.maxmods));
2918   
2919   gc.library = FLG_ANSILIB;
2920
2921   gc.locstack = filelocStack_new ();
2922   gc.modrecs = sRefSetList_undefined;
2923   gc.anyExports = FALSE;
2924
2925   gc.ftab = fileTable_create ();
2926   gc.msgLog = messageLog_new ();
2927   gc.inimport = FALSE;
2928   gc.inDerivedFile = FALSE;
2929   gc.inheader = FALSE;
2930   gc.markers = flagMarkerList_new ();
2931   gc.cont.glob = TRUE;
2932   gc.showfunction = FALSE;
2933   gc.msgAnnote = cstring_undefined;
2934   gc.aliasAnnote = sRef_undefined;
2935   gc.aliasAnnoteAls = sRef_undefined;
2936   gc.boolType = ctype_bool;
2937   gc.mods = sRefSet_new ();
2938
2939   gc.saveloc = fileloc_undefined;
2940
2941   gc.inmacrocache = FALSE;
2942   gc.inclause = NOCLAUSE;
2943   gc.clauses = clauseStack_new ();
2944   gc.globs = globSet_new ();
2945   gc.nacct = typeIdSet_emptySet ();
2946   gc.acct = typeIdSet_emptySet ();
2947   gc.facct = typeIdSet_emptySet ();
2948   gc.savedFlags = FALSE;
2949   gc.pushloc = fileloc_undefined;
2950   gc.protectVars = FALSE;
2951   gc.justpopped = FALSE;
2952   gc.isNullGuarded = NO;
2953   gc.globs_used = globSet_undefined;
2954   
2955   allFlagCodes (code)
2956     {
2957       gc.setGlobally[code] = FALSE;
2958       gc.setLocally[code] = FALSE;
2959     } end_allFlagCodes ;
2960
2961   usymtab_initMod ();
2962
2963   context_resetAllFlags ();
2964   assertSet (gc.flags); /* Can't use global in defines */
2965   assertSet (gc.saveflags);
2966   assertSet (gc.values);
2967   assertSet (gc.strings);
2968
2969   conext_resetAllCounters ();
2970   assertSet (gc.counters);
2971
2972   context_setMode (DEFAULT_MODE);
2973
2974   gc.stateTable = metaStateTable_create ();
2975   gc.annotTable = annotationTable_create ();
2976
2977   gc.inFunctionHeader = FALSE;
2978
2979   DPRINTF (("Annotations: \n%s",
2980             cstring_toCharsSafe (annotationTable_unparse (gc.annotTable))));
2981   DPRINTF (("State: \n%s",
2982             cstring_toCharsSafe (metaStateTable_unparse (gc.stateTable))));
2983
2984 }
2985
2986 ctype
2987 context_typeofZero (void)
2988 {
2989   ctype ct = ctype_int;
2990
2991   if (context_getFlag (FLG_ZEROPTR))
2992     {
2993       ct = ctype_makeConj (ct, ctype_voidPointer);
2994     }
2995   
2996   if (context_getFlag (FLG_ZEROBOOL)) {
2997     ct = ctype_makeConj (ct, ctype_bool); 
2998   }
2999
3000   return ct;
3001 }
3002
3003 ctype
3004 context_typeofOne (void)
3005 {
3006   ctype ct = ctype_int;
3007
3008   /* 1 is on longer a bool (was before 2.4)
3009      if (!context_getFlag (FLG_ABSTRACTBOOL))
3010      {
3011      ct = ctype_makeConj (ct, ctype_bool);
3012      }
3013      */
3014
3015   return (ct);
3016 }
3017
3018 /*@only@*/ cstring
3019 context_unparse (void)
3020 {
3021   cstring s;
3022
3023   switch (gc.kind)
3024     {
3025     case CX_LCL:
3026       s = message ("LCL File: %q", fileloc_unparse (g_currentloc));
3027       break;
3028     case CX_LCLLIB:
3029       s = message ("LCL Lib File: %q", fileloc_unparse (g_currentloc));
3030       break;
3031     case CX_GLOBAL:
3032       s = message ("Global Context:%q", fileloc_unparse (g_currentloc));
3033       break;
3034     case CX_INNER:
3035       s = message ("Inner Context [%d] : %q", 
3036                    gc.cont.cdepth,
3037                    fileloc_unparse (g_currentloc));
3038       break;
3039     case CX_FUNCTION:
3040       s = message ("Function %q :%q \n\taccess %q\n\tmodifies %q",
3041                    uentry_unparse (gc.cont.fcn),
3042                    fileloc_unparse (g_currentloc),
3043                    typeIdSet_unparse (gc.acct),
3044                    sRefSet_unparse (gc.mods));
3045       break;
3046     case CX_MACROFCN:
3047       s = message ("Function Macro %q", uentry_unparse (gc.cont.fcn));
3048       break;
3049     case CX_UNKNOWNMACRO:
3050       s = message ("Forward Specified Macro %q", uentry_unparse (gc.cont.fcn));
3051       break;
3052     case CX_MACROCONST:
3053       s = message ("Constant Macro %q", uentry_unparse (gc.cont.fcn));
3054       break;
3055     case CX_ITERDEF:
3056       s = message ("Iter definition %q", uentry_unparse (gc.cont.fcn));
3057       break;
3058     case CX_ITEREND:
3059       s = message ("Iter end %q", uentry_unparse (gc.cont.fcn));
3060       break;
3061     case CX_FCNDECLARATION:
3062       s = message ("Function declaration %q", uentry_unparse (gc.cont.fcn));
3063       break;
3064     default:
3065       s = message ("Un-unparseable context: %d", (int) gc.kind);
3066       break;
3067     }
3068   
3069   s = message ("%q\naccess: %q", s, context_unparseAccess ());
3070   return (s);
3071 }
3072
3073 extern ctype
3074 context_currentFunctionType (void)
3075 {
3076   if (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN)
3077     {
3078             return (uentry_getType (gc.cont.fcn));
3079     }
3080   else if (gc.kind == CX_INNER)
3081     {
3082       llcontbuglit ("context_currentFunctionType: inner context");
3083       do { context_exitInnerPlain (); } while (gc.kind == CX_INNER);
3084       return (context_currentFunctionType ());
3085     }
3086   else
3087     {
3088       llcontbuglit ("context_currentFunctionType: not in function");
3089       return (ctype_undefined);
3090     }
3091 }
3092
3093 void
3094 context_enterInnerContext (void)
3095 {
3096   if (context_getFlag (FLG_GRAMMAR))
3097     {
3098       lldiagmsg (message ("Enter inner context: %q", context_unparse ()));
3099     }
3100
3101   if (gc.kind == CX_GLOBAL)
3102     {
3103       gc.kind = CX_INNER;
3104       gc.cont.cdepth = 1;
3105     }
3106   else if (gc.kind == CX_INNER)
3107     {
3108       gc.cont.cdepth++;
3109     }
3110   else
3111     {
3112       ;
3113     }
3114
3115   usymtab_enterScope ();
3116   pushClause (NOCLAUSE);
3117 }
3118
3119 void
3120 context_exitInnerPlain (void) /*@modifies gc;@*/
3121 {
3122   context_exitInner (exprNode_undefined);
3123 }
3124
3125 void
3126 context_exitInner (exprNode exp)
3127 {
3128    if (context_getFlag (FLG_GRAMMAR))
3129     {
3130       lldiagmsg (message ("Enter inner context: %q", context_unparse ()));
3131     }
3132  
3133   llassertprint (gc.inclause == NOCLAUSE || gc.inclause == CASECLAUSE,
3134                  ("inclause = %s", clause_nameTaken (gc.inclause)));
3135
3136   clauseStack_removeFirst (gc.clauses, NOCLAUSE);
3137   gc.inclause = topClause (gc.clauses);
3138
3139   if (gc.kind == CX_INNER)
3140     {
3141       if (--gc.cont.cdepth == 0)
3142         {
3143           gc.kind = CX_GLOBAL;
3144           gc.cont.glob = TRUE;
3145         }
3146     }
3147   else 
3148     {
3149       if (gc.kind == CX_GLOBAL)
3150         {
3151           llcontbuglit ("Attempt to exit global context");
3152           return;
3153         }
3154     }
3155
3156     usymtab_exitScope (exp);
3157 }
3158
3159
3160 void
3161 context_enterStructInnerContext (void)
3162 {
3163   if (context_getFlag (FLG_GRAMMAR))
3164     {
3165       lldiagmsg (message ("Enter struct inner context: %q", context_unparse ()));
3166     }
3167
3168   if (gc.kind == CX_GLOBAL)
3169     {
3170       gc.kind = CX_INNER;
3171       gc.cont.cdepth = 1;
3172     }
3173   else if (gc.kind == CX_INNER)
3174     {
3175       gc.cont.cdepth++;
3176     }
3177   else
3178     {
3179       ;
3180     }
3181
3182   usymtab_enterScope ();
3183
3184   if (context_getFlag (FLG_GRAMMAR))
3185     {
3186       lldiagmsg (message ("Enter struct inner context: %q", context_unparse ()));
3187     }
3188 }
3189
3190 void
3191 context_exitStructInnerContext (void)
3192 {
3193   if (context_getFlag (FLG_GRAMMAR))
3194     {
3195       lldiagmsg (message ("Exit struct inner context: %q [%d]", context_unparse (), gc.cont.cdepth));
3196     }
3197
3198   if (gc.kind == CX_INNER)
3199     {
3200       if (gc.cont.cdepth <= 0)
3201         {
3202           llcontbuglit ("Attempt to exit inner context with no depth");
3203           gc.kind = CX_GLOBAL;
3204           gc.cont.glob = TRUE;
3205           gc.cont.cdepth = 0;
3206         }
3207       else {
3208         gc.cont.cdepth--;
3209
3210         if (gc.cont.cdepth == 0)
3211           {
3212             gc.kind = CX_GLOBAL;
3213             gc.cont.glob = TRUE;
3214           }
3215       }
3216     }
3217   else 
3218     {
3219       if (gc.kind == CX_GLOBAL)
3220         {
3221           llcontbuglit ("Attempt to exit global context");
3222           return;
3223         }
3224     }
3225
3226   usymtab_exitScope (exprNode_undefined);
3227
3228   if (context_getFlag (FLG_GRAMMAR))
3229     {
3230       lldiagmsg (message ("After exit struct inner context: %q [%d]", context_unparse (), gc.cont.cdepth));
3231     }
3232 }
3233
3234 void
3235 context_exitInnerSafe (void)
3236 {
3237   if (context_getFlag (FLG_GRAMMAR))
3238     {
3239       lldiagmsg (message ("Exit inner safe: %q", context_unparse ()));
3240     }
3241
3242   if (gc.kind == CX_INNER)
3243     {
3244       if (--gc.cont.cdepth <= 0)
3245         {
3246           gc.cont.cdepth = 0;
3247         }
3248     }
3249   else if (gc.kind == CX_GLOBAL)
3250     {
3251       llcontbuglit ("Attempt to exit global context");
3252       return;
3253     }
3254   else
3255     {
3256       if (usymtab_inDeepScope ())
3257         {
3258           usymtab_exitScope (exprNode_undefined);
3259         }
3260     }
3261 }
3262
3263 static
3264 void setModuleAccess (void)
3265 {
3266   gc.facct = typeIdSet_emptySet ();
3267
3268   if (fileId_isValid (currentFile ()))
3269     {
3270       cstring baseName = fileloc_getBase (g_currentloc);
3271       
3272       if (context_getFlag (FLG_ACCESSFILE))
3273         {
3274           if (usymtab_existsType (baseName))
3275             {
3276               gc.facct = typeIdSet_insert (gc.facct, 
3277                                            usymtab_getTypeId (baseName));
3278             }
3279           else 
3280             {
3281               ;
3282             }
3283         }
3284       
3285       if (context_getFlag (FLG_ACCESSMODULE))
3286         {
3287           int i;
3288           bool hasaccess = FALSE;
3289           
3290           for (i = 0; i < gc.nmods; i++)
3291             {
3292               if (cstring_equal (baseName, gc.moduleaccess[i].file))
3293                 {
3294                   gc.facct = typeIdSet_union (gc.facct, gc.moduleaccess[i].daccess);
3295
3296                   hasaccess = TRUE;
3297                   break;
3298                 }
3299             }
3300         }
3301       
3302       gc.acct = gc.facct;
3303       gc.inheader = fileId_isHeader (currentFile ());
3304     }
3305   else
3306     {
3307       llcontbuglit ("Current file not defined\n");
3308       gc.facct = typeIdSet_emptySet ();
3309       gc.acct = gc.facct;
3310       gc.inheader = FALSE;
3311     }
3312   
3313   /* 17 Jan 1995: forgot to clear nacct */
3314   
3315   gc.nacct = typeIdSet_emptySet ();
3316 }
3317
3318 static void
3319 context_enterFileAux (void)
3320 {
3321   setModuleAccess ();
3322 }
3323
3324 void
3325 context_enterFile (void)
3326 {
3327   context_enterFileAux ();
3328   usymtab_enterFile ();
3329 }
3330
3331 void
3332 context_enterMacroFile (void)
3333 {
3334   context_enterFileAux ();
3335 }
3336
3337 bool 
3338 context_inFunction (void)
3339 {
3340   kcontext ck = gc.kind;
3341   
3342   return ((ck == CX_FUNCTION) || (ck == CX_MACROFCN) || (ck == CX_INNER));
3343 }
3344
3345 bool 
3346 context_inFunctionLike (void)
3347 {
3348   return (gc.kind == CX_FUNCTION || gc.kind == CX_MACROFCN 
3349           || gc.kind == CX_FCNDECLARATION
3350           || gc.kind == CX_UNKNOWNMACRO || gc.kind == CX_ITERDEF);
3351 }
3352
3353 bool 
3354 context_inRealFunction (void)
3355 {
3356   kcontext ck = gc.kind;
3357   
3358   return ((ck == CX_FUNCTION) || (ck == CX_MACROFCN));
3359 }
3360   
3361 void
3362 context_processAllMacros (void)
3363 {
3364   usymtab_enterFile ();
3365
3366   gc.inmacrocache = TRUE; 
3367   macrocache_processUndefinedElements (gc.mc);
3368   cleanupMessages ();  
3369   usymtab_exitFile ();
3370
3371   gc.inmacrocache = FALSE;
3372   macrocache_finalize ();
3373 }
3374
3375 /*
3376 ** this happens once at the end of each C file
3377 **
3378 ** check each Macro that was defined in current file.c or current file.h
3379 **
3380 */
3381
3382 static void
3383 context_processMacros (void)
3384 {
3385   if (fileId_isValid (currentFile ()))
3386     {
3387       fileloc lastfl;
3388       cstring cbase = fileLib_removePathFree (fileLib_removeAnyExtension (fileName (currentFile ())));
3389       
3390       gc.inmacrocache = TRUE;
3391
3392       DPRINTF (("Processing macros: %s", cbase));
3393       lastfl = macrocache_processFileElements (gc.mc, cbase);
3394       DPRINTF (("Processing macros: %s", fileloc_unparse (lastfl)));
3395
3396       cstring_free (cbase);
3397       
3398       if (fileloc_isDefined (lastfl))
3399         {
3400           g_currentloc = fileloc_update (g_currentloc, lastfl);
3401           cleanupMessages ();
3402         }
3403
3404       gc.inmacrocache = FALSE;
3405     }
3406 }
3407
3408 bool
3409 context_processingMacros (void)
3410 {
3411   return (gc.inmacrocache);
3412 }
3413
3414 void
3415 context_exitCFile (void)
3416 {
3417   if (gc.kind != CX_GLOBAL)
3418     {
3419       llfatalerrorLoc
3420         (cstring_makeLiteral ("File ended outside global scope"));
3421     }
3422
3423   if (gc.insuppressregion)
3424     {
3425      /* gack...don't reverse the order of these lines! ;-> */
3426       gc.insuppressregion = FALSE;
3427       llerrorlit (FLG_SYNTAX, 
3428                   "File ended in ignore errors region, "
3429                   "possible missing /*@end*/");
3430     }
3431
3432   /* fix up parse errors */
3433
3434   while (!usymtab_inFileScope ())
3435     {
3436       usymtab_quietExitScope (g_currentloc);
3437     }
3438
3439   /*
3440   ** Clear the file-specific modifies information.
3441   */
3442   
3443   sRefSetList_elements (gc.modrecs, mods)
3444     {
3445       sRefSet_clearStatics (mods);
3446     } end_sRefSetList_elements ;
3447   
3448   sRefSetList_clear (gc.modrecs);
3449   
3450   context_processMacros ();
3451   cleanupMessages (); 
3452   
3453   usymtab_exitFile ();
3454   
3455   gc.inDerivedFile = FALSE;
3456   filelocStack_clear (gc.locstack);
3457   
3458   gc.nacct = typeIdSet_emptySet (); /* empty noaccess */
3459   
3460   gc.cont.glob = TRUE;
3461   
3462   if (gc.savedFlags)
3463     {
3464       context_restoreFlagSettings ();
3465       gc.savedFlags = FALSE;
3466     }
3467   
3468   /*
3469     DPRINTF (("After exiting file: "));
3470     usymtab_printAll ();
3471   */
3472 }
3473
3474 void
3475 context_exitMacroCache (void)
3476 {
3477   if (gc.kind != CX_GLOBAL)
3478     {
3479       if (context_inMacro ()) 
3480         /* this is okay, file could end without newline in macro */
3481         {
3482           DPRINTF (("Still in macro: %s",
3483                     context_unparse ()));
3484           context_exitFunction ();
3485         }
3486       else
3487         {
3488           llcontbug (message ("context_exitMacroCache: outside global scope: %q", 
3489                               context_unparse ()));
3490           gc.kind = CX_GLOBAL; 
3491         }
3492     }
3493
3494   /*
3495   ** no longer valid here
3496   ** if (gc.insuppressregion)
3497   **   {
3498   **     gc.insuppressregion = FALSE;
3499   **     llerror ("File ended in ignore errors region, possible missing @");
3500   **   }
3501   */
3502
3503   gc.cont.glob = TRUE;
3504 }
3505
3506 void
3507 context_saveLocation (void)
3508 {
3509   /* was llassert (fileloc_isUndefined (gc.saveloc)) */
3510   fileloc_free (gc.saveloc);
3511   gc.saveloc = fileloc_copy (g_currentloc);
3512 }
3513
3514 fileloc
3515 context_getSaveLocation (void)
3516 {
3517   fileloc fl = gc.saveloc;
3518   gc.saveloc = fileloc_undefined;
3519   return fl;
3520 }
3521
3522 /*@observer@*/ cstring
3523 context_inFunctionName (void)
3524 {
3525   if (gc.kind == CX_FUNCTION
3526       || gc.kind == CX_MACROFCN || gc.kind == CX_UNKNOWNMACRO 
3527       || gc.kind == CX_MACROCONST 
3528       || gc.kind == CX_ITERDEF || gc.kind == CX_ITEREND)
3529     {
3530       return (uentry_rawName (gc.cont.fcn));
3531     }
3532   else
3533     {
3534       llcontbuglit ("context_inFunctionName: not in function");
3535       return (cstring_undefined);
3536     }
3537 }
3538
3539 void
3540 context_userSetFlag (flagcode f, bool b)
3541 {
3542   DPRINTF (("set flag: %s", flagcode_unparse (f)));
3543
3544   if (f == FLG_NEVERINCLUDE && b)
3545     {
3546       if (gc.flags[FLG_EXPORTHEADER])
3547         {
3548           llerror_flagWarning (cstring_makeLiteral
3549                            ("setting +neverinclude after +exportheader.  "
3550                             "Turning off exportheader, since headers are not checked "
3551                             "when +neverinclude is used."));
3552
3553           gc.flags[FLG_EXPORTHEADER] = FALSE;
3554         }
3555     }
3556   else 
3557     {
3558       if (f == FLG_EXPORTHEADER && b)
3559         {
3560           if (gc.flags[FLG_NEVERINCLUDE])
3561             {
3562               llerror_flagWarning (cstring_makeLiteral
3563                                ("setting +exportheader after +neverinclude.  "
3564                                 "Not setting exportheader, since headers are not checked "
3565                                 "when +neverinclude is used."));
3566               gc.flags[FLG_EXPORTHEADER] = FALSE;
3567               return;
3568             }
3569         }
3570     }
3571   
3572   if (context_getFlag (FLG_WARNFLAGS) && f != FLG_NOF && f != FLG_OPTF)
3573     {
3574       bool lastsetting = context_getFlag (f);
3575       
3576       if (bool_equal (lastsetting, b)
3577           && !flagcode_isSpecialFlag (f) 
3578           && !flagcode_isIdemFlag (f)
3579           && !flagcode_hasArgument (f))
3580         {
3581           llerror_flagWarning (message ("setting %s%s redundant with current value", 
3582                                     cstring_makeLiteralTemp (b ? "+" : "-"),
3583                                     flagcode_unparse (f)));
3584         }
3585     }
3586
3587   if (flagcode_isWarnUseFlag (f) && b)
3588     {
3589       if (!context_getFlag (FLG_WARNUSE))
3590         {
3591           llerror_flagWarning (message ("flag +%s is canceled by -warnuse",
3592                                     flagcode_unparse (f)));
3593           
3594         }
3595     }
3596
3597
3598   if (flagcode_isLibraryFlag (f)) 
3599     {
3600       if (gc.library != FLG_ANSILIB
3601           && gc.library != f)
3602         {
3603           llerror_flagWarning (message ("selecting library %s after library %s was "
3604                                         "selected (only one library may be used)",
3605                                         flagcode_unparse (f),
3606                                         flagcode_unparse (gc.library)));
3607         }
3608
3609       if (f == FLG_UNIXLIB)
3610         {
3611           if (context_getFlag (FLG_WARNUNIXLIB))
3612             {
3613               llerror_flagWarning (cstring_makeLiteral
3614                                    ("selecting unix library.  Unix library is "
3615                                     "ad hoc addition to POSIX library.  Recommend "
3616                                     "use +posixlib to select POSIX library instead. "
3617                                     "Use -warnunixlib to suppress this message."));
3618             }
3619         }
3620       
3621       gc.library = f;
3622     }
3623
3624   if (flagcode_isNameChecksFlag (f) && b && !context_maybeSet (FLG_NAMECHECKS))
3625     {
3626       llerror_flagWarning (message
3627                            ("setting +%s will not produce warnings with -namechecks. Must set +namechecks also.",
3628                             flagcode_unparse (f)));
3629     }
3630
3631   gc.setGlobally[f] = TRUE;
3632   context_setFlag (f, b);
3633 }
3634
3635 void
3636 context_fileSetFlag (flagcode f, ynm set)
3637 {
3638   if (!gc.savedFlags)
3639     {
3640       context_saveFlagSettings ();
3641     }
3642
3643   if (ynm_isOff (set))
3644     {
3645       context_setFlagAux (f, FALSE, TRUE, FALSE);
3646     }
3647   else if (ynm_isOn (set))
3648     {
3649       context_setFlagAux (f, TRUE, TRUE, FALSE);
3650       gc.setLocally[f] = TRUE;
3651     }
3652   else
3653     {
3654       context_restoreFlag (f);
3655     }
3656 }
3657
3658 static void
3659 context_restoreFlag (flagcode f)
3660 {
3661   
3662   if (!gc.savedFlags)
3663     {
3664       voptgenerror 
3665         (FLG_SYNTAX,
3666          message ("Attempt to restore flag %s when no file scope flags "
3667                   "have been set.",
3668                   flagcode_unparse (f)),
3669          g_currentloc);
3670     }
3671   else
3672     {
3673       context_addFlagMarker (f, MAYBE);
3674       context_setFlagAux (f, gc.saveflags[f], FALSE, TRUE);
3675     }
3676
3677   }
3678
3679 static void
3680 context_setFlag (flagcode f, bool b)
3681 {
3682   context_setFlagAux (f, b, FALSE, FALSE);
3683 }
3684
3685 void
3686 context_setFlagTemp (flagcode f, bool b)
3687 {
3688   DPRINTF (("Set flag temp: %s / %s", flagcode_unparse (f), bool_unparse (b)));
3689   gc.flags[f] = b;
3690 }
3691
3692 /*@notfunction@*/
3693 # define DOSET(ff,b) \
3694    do { if (inFile) { gc.setLocally[ff] = TRUE; \
3695                       context_addFlagMarker (ff, ynm_fromBool (b)); } \
3696         DPRINTF (("set flag: %s / %s", flagcode_unparse (ff), bool_unparse (b))); \
3697         gc.flags[ff] = b; } while (FALSE)
3698
3699 static void
3700   context_setFlagAux (flagcode f, bool b, bool 
3701                       inFile, /*@unused@*/ bool isRestore)
3702 {
3703   DPRINTF (("set flag: %s / %s", flagcode_unparse (f), bool_unparse (b)));
3704
3705   if (f == FLG_USESTDERR) 
3706     {
3707       if (b) {
3708         g_msgstream = stderr;
3709       } else {
3710         g_msgstream = stdout;
3711       }
3712     }
3713
3714   /*
3715   ** Removed test for special flags.
3716   */
3717
3718   if (flagcode_isIdemFlag (f))
3719     {
3720       DOSET (f, TRUE);
3721     }
3722   else
3723     {
3724       DOSET (f, b);
3725     }
3726
3727   if (f >= FLG_ITS4MOSTRISKY && f <= FLG_ITS4LOWRISK)
3728     {
3729       if (b) /* Turing higher level on, turns on all lower levels */
3730         {
3731           switch (f)
3732             {
3733             case FLG_ITS4MOSTRISKY:
3734               DOSET (FLG_ITS4VERYRISKY, b);
3735               /*@fallthrough@*/ 
3736             case FLG_ITS4VERYRISKY:
3737               DOSET (FLG_ITS4RISKY, b);
3738               /*@fallthrough@*/ 
3739             case FLG_ITS4RISKY:
3740               DOSET (FLG_ITS4MODERATERISK, b);
3741               /*@fallthrough@*/ 
3742             case FLG_ITS4MODERATERISK:
3743               DOSET (FLG_ITS4LOWRISK, b);
3744               /*@fallthrough@*/ 
3745             case FLG_ITS4LOWRISK:
3746               break;
3747               BADDEFAULT;
3748             }
3749         }
3750       else /* Turning level off, turns off all higher levels */
3751         {
3752           switch (f)
3753             {
3754             case FLG_ITS4LOWRISK:
3755               DOSET (FLG_ITS4MODERATERISK, b);
3756               /*@fallthrough@*/ 
3757             case FLG_ITS4MODERATERISK:
3758               DOSET (FLG_ITS4RISKY, b);
3759               /*@fallthrough@*/ 
3760             case FLG_ITS4RISKY:
3761               DOSET (FLG_ITS4VERYRISKY, b);
3762               /*@fallthrough@*/ 
3763             case FLG_ITS4VERYRISKY:
3764               DOSET (FLG_ITS4MOSTRISKY, b);
3765               /*@fallthrough@*/ 
3766             case FLG_ITS4MOSTRISKY:
3767               break;
3768               BADDEFAULT;
3769             }
3770         }
3771     }
3772   
3773   switch (f)
3774     {     
3775     case FLG_ALLEMPTY:
3776       DOSET (FLG_ALLEMPTY, b);
3777       DOSET (FLG_IFEMPTY, b);
3778       DOSET (FLG_WHILEEMPTY, b);
3779       DOSET (FLG_FOREMPTY, b);
3780       break;
3781     case FLG_PREDBOOL:
3782       DOSET (FLG_PREDBOOL, b);
3783       DOSET (FLG_PREDBOOLINT, b);
3784       DOSET (FLG_PREDBOOLPTR, b);
3785       DOSET (FLG_PREDBOOLOTHERS, b);
3786       break;
3787     case FLG_GLOBALIAS:
3788       DOSET (FLG_CHECKSTRICTGLOBALIAS, b);
3789       DOSET (FLG_CHECKEDGLOBALIAS, b);
3790       DOSET (FLG_CHECKMODGLOBALIAS, b);
3791       DOSET (FLG_UNCHECKEDGLOBALIAS, b);
3792       break;
3793     case FLG_ALLBLOCK:
3794       DOSET (FLG_ALLBLOCK, b);
3795       DOSET (FLG_IFBLOCK, b);
3796       DOSET (FLG_WHILEBLOCK, b);
3797       DOSET (FLG_FORBLOCK, b);
3798       break;
3799     case FLG_GRAMMAR:
3800       if (b)
3801         {
3802           yydebug = 1;
3803           mtdebug = 1;
3804         }
3805       else
3806         {
3807           yydebug = 0;
3808           mtdebug = 0;
3809         }
3810       
3811       DOSET (FLG_GRAMMAR, b);
3812       break;
3813     case FLG_CODEIMPONLY:
3814       DOSET (FLG_CODEIMPONLY, b);
3815       DOSET (FLG_GLOBIMPONLY, b);
3816       DOSET (FLG_RETIMPONLY, b);
3817       DOSET (FLG_STRUCTIMPONLY, b);
3818       break;
3819     case FLG_SPECALLIMPONLY:
3820       DOSET (FLG_SPECALLIMPONLY, b);
3821       DOSET (FLG_SPECGLOBIMPONLY, b);
3822       DOSET (FLG_SPECRETIMPONLY, b);
3823       DOSET (FLG_SPECSTRUCTIMPONLY, b);
3824       break;
3825     case FLG_ALLIMPONLY:
3826       DOSET (FLG_ALLIMPONLY, b);
3827       DOSET (FLG_GLOBIMPONLY, b);
3828       DOSET (FLG_RETIMPONLY, b);
3829       DOSET (FLG_STRUCTIMPONLY, b);
3830       DOSET (FLG_SPECGLOBIMPONLY, b);
3831       DOSET (FLG_SPECRETIMPONLY, b);
3832       DOSET (FLG_SPECSTRUCTIMPONLY, b);
3833       break;
3834     case FLG_ANSILIMITS: 
3835       DOSET (FLG_ANSILIMITS, b);
3836       DOSET (FLG_CONTROLNESTDEPTH, b);
3837       DOSET (FLG_STRINGLITERALLEN, b);
3838       DOSET (FLG_INCLUDENEST, b);
3839       DOSET (FLG_NUMSTRUCTFIELDS, b);
3840       DOSET (FLG_NUMENUMMEMBERS, b);
3841       
3842       if (b)
3843         {
3844           context_setValue (FLG_CONTROLNESTDEPTH, DEFAULT_CONTROLNESTDEPTH);
3845           context_setValue (FLG_STRINGLITERALLEN, DEFAULT_STRINGLITERALLEN);
3846           context_setValue (FLG_INCLUDENEST, DEFAULT_INCLUDENEST);
3847           context_setValue (FLG_NUMSTRUCTFIELDS, DEFAULT_NUMSTRUCTFIELDS);
3848           context_setValue (FLG_NUMENUMMEMBERS, DEFAULT_NUMENUMMEMBERS);
3849         }
3850       break;
3851     case FLG_EXTERNALNAMELEN:
3852       DOSET (FLG_DISTINCTEXTERNALNAMES, TRUE);
3853       DOSET (FLG_EXTERNALNAMELEN, TRUE);
3854       break;
3855     case FLG_INTERNALNAMELEN:
3856       DOSET (FLG_DISTINCTINTERNALNAMES, TRUE);
3857       DOSET (FLG_INTERNALNAMELEN, TRUE);
3858       break;
3859     case FLG_EXTERNALNAMECASEINSENSITIVE:
3860       DOSET (FLG_EXTERNALNAMECASEINSENSITIVE, b);
3861       
3862       if (b && !gc.flags[FLG_DISTINCTEXTERNALNAMES])
3863         {
3864           DOSET (FLG_DISTINCTEXTERNALNAMES, TRUE);
3865           context_setValue (FLG_EXTERNALNAMELEN, 0);
3866         }
3867       break;
3868     case FLG_INTERNALNAMECASEINSENSITIVE:
3869       DOSET (FLG_INTERNALNAMECASEINSENSITIVE, b);
3870       
3871       if (b && !gc.flags[FLG_DISTINCTINTERNALNAMES])
3872         {
3873           DOSET (FLG_DISTINCTINTERNALNAMES, TRUE);
3874           context_setValue (FLG_INTERNALNAMELEN, 0);
3875         }
3876       break;
3877     case FLG_INTERNALNAMELOOKALIKE:
3878       DOSET (FLG_INTERNALNAMELOOKALIKE, b);
3879       
3880       if (b && !gc.flags[FLG_DISTINCTINTERNALNAMES])
3881         {
3882           DOSET (FLG_DISTINCTINTERNALNAMES, TRUE);
3883           context_setValue (FLG_INTERNALNAMELEN, 0);
3884         }
3885       break;
3886     case FLG_MODUNSPEC:
3887       DOSET (FLG_MODNOMODS, b);
3888       DOSET (FLG_MODGLOBSUNSPEC, b);
3889       DOSET (FLG_MODSTRICTGLOBSUNSPEC, b);
3890       break;
3891     case FLG_EXPORTANY: 
3892       DOSET (FLG_EXPORTVAR, b);
3893       DOSET (FLG_EXPORTFCN, b);
3894       DOSET (FLG_EXPORTTYPE, b);
3895       DOSET (FLG_EXPORTMACRO, b);
3896       DOSET (FLG_EXPORTCONST, b);
3897       gc.anyExports = TRUE;
3898       break;
3899     case FLG_REPEXPOSE:
3900       DOSET (FLG_RETEXPOSE, b); 
3901       DOSET (FLG_ASSIGNEXPOSE, b); 
3902       DOSET (FLG_CASTEXPOSE, b); 
3903       break;
3904     case FLG_RETVAL:
3905       DOSET (FLG_RETVALBOOL, b);
3906       DOSET (FLG_RETVALINT, b);
3907       DOSET (FLG_RETVALOTHER, b);
3908       break;
3909     case FLG_PARTIAL:
3910       if (b)
3911         {
3912           DOSET (FLG_EXPORTLOCAL, FALSE);
3913           DOSET (FLG_DECLUNDEF, FALSE);
3914           DOSET (FLG_SPECUNDEF, FALSE);
3915           DOSET (FLG_TOPUNUSED, FALSE);
3916         }
3917       break;
3918     case FLG_DEEPBREAK:
3919       DOSET (FLG_LOOPLOOPBREAK, b);
3920       DOSET (FLG_LOOPSWITCHBREAK, b);
3921       DOSET (FLG_SWITCHLOOPBREAK, b);
3922       DOSET (FLG_SWITCHSWITCHBREAK, b);
3923       DOSET (FLG_LOOPLOOPCONTINUE, b);
3924       DOSET (FLG_DEEPBREAK, b);
3925       break;
3926     case FLG_ACCESSALL:
3927       DOSET (FLG_ACCESSMODULE, b);
3928       DOSET (FLG_ACCESSFILE, b);
3929       DOSET (FLG_ACCESSCZECH, b);
3930       break;
3931     case FLG_ALLMACROS:
3932       DOSET (FLG_ALLMACROS, b);
3933       DOSET (FLG_FCNMACROS, b);
3934       DOSET (FLG_CONSTMACROS, b);
3935       break;
3936     case FLG_CZECH:
3937       if (b) { DOSET (FLG_ACCESSCZECH, b); }
3938       DOSET (FLG_CZECHFUNCTIONS, b);
3939       DOSET (FLG_CZECHVARS, b);
3940       DOSET (FLG_CZECHCONSTANTS, b);
3941       DOSET (FLG_CZECHTYPES, b);
3942       break;
3943     case FLG_SLOVAK:
3944       if (b) { DOSET (FLG_ACCESSSLOVAK, b); }
3945       DOSET (FLG_SLOVAKFUNCTIONS, b);
3946       DOSET (FLG_SLOVAKVARS, b);
3947       DOSET (FLG_SLOVAKCONSTANTS, b);
3948       DOSET (FLG_SLOVAKTYPES, b);
3949       break;
3950     case FLG_CZECHOSLOVAK:
3951       if (b) { DOSET (FLG_ACCESSCZECHOSLOVAK, b); }
3952       DOSET (FLG_CZECHOSLOVAKFUNCTIONS, b);
3953       DOSET (FLG_CZECHOSLOVAKVARS, b);
3954       DOSET (FLG_CZECHOSLOVAKCONSTANTS, b);
3955       DOSET (FLG_CZECHOSLOVAKTYPES, b);
3956       break;
3957     case FLG_NULL:
3958       DOSET (FLG_NULLSTATE, b);
3959       DOSET (FLG_NULLDEREF, b);
3960       DOSET (FLG_NULLASSIGN, b);
3961       DOSET (FLG_NULLPASS, b);
3962       DOSET (FLG_NULLRET, b);
3963       break;
3964     case FLG_MEMCHECKS:
3965       DOSET (FLG_NULLSTATE, b);
3966       DOSET (FLG_NULLDEREF, b);
3967       DOSET (FLG_NULLASSIGN, b);
3968       DOSET (FLG_NULLPASS, b);
3969       DOSET (FLG_NULLRET, b);
3970       DOSET (FLG_COMPDEF, b);
3971       DOSET (FLG_COMPMEMPASS, b);
3972       DOSET (FLG_UNIONDEF, b);
3973       DOSET (FLG_MEMTRANS, b);
3974       DOSET (FLG_USERELEASED, b);
3975       DOSET (FLG_ALIASUNIQUE, b);
3976       DOSET (FLG_MAYALIASUNIQUE, b);
3977       DOSET (FLG_MUSTFREE, b);
3978       DOSET (FLG_MUSTDEFINE, b);
3979       DOSET (FLG_GLOBSTATE, b); 
3980       DOSET (FLG_COMPDESTROY, b);
3981       DOSET (FLG_MUSTNOTALIAS, b);
3982       DOSET (FLG_MEMIMPLICIT, b);
3983       DOSET (FLG_BRANCHSTATE, b); 
3984       /*@fallthrough@*/ /* also sets memtrans flags */
3985     case FLG_MEMTRANS:
3986       DOSET (FLG_MEMTRANS, b);
3987       DOSET (FLG_EXPOSETRANS, b);
3988       DOSET (FLG_OBSERVERTRANS, b);
3989       DOSET (FLG_DEPENDENTTRANS, b);
3990       DOSET (FLG_NEWREFTRANS, b);
3991       DOSET (FLG_ONLYTRANS, b);
3992       DOSET (FLG_OWNEDTRANS, b);
3993       DOSET (FLG_FRESHTRANS, b);
3994       DOSET (FLG_SHAREDTRANS, b);
3995       DOSET (FLG_TEMPTRANS, b);
3996       DOSET (FLG_KEPTTRANS, b);
3997       DOSET (FLG_REFCOUNTTRANS, b);
3998       DOSET (FLG_STATICTRANS, b);
3999       DOSET (FLG_UNKNOWNTRANS, b);
4000       DOSET (FLG_KEEPTRANS, b);
4001       DOSET (FLG_IMMEDIATETRANS, b);
4002       break;
4003       
4004     default:
4005       break;
4006     }
4007
4008   if (b && !gc.anyExports
4009       && (f == FLG_EXPORTVAR || f == FLG_EXPORTFCN
4010           || f == FLG_EXPORTTYPE || f == FLG_EXPORTMACRO
4011           || f == FLG_EXPORTCONST
4012           || f == FLG_EXPORTANY))
4013     {
4014       gc.anyExports = TRUE;
4015     }
4016 }
4017
4018 bool 
4019 context_maybeSet (flagcode d)
4020 {
4021   return (gc.flags[d] || gc.setLocally[d]);
4022 }
4023
4024 bool
4025 context_getFlag (flagcode d)
4026 {
4027   return (gc.flags[d]);
4028 }
4029
4030 bool
4031 context_flagOn (flagcode f, fileloc loc)
4032 {
4033   return (!context_suppressFlagMsg (f, loc));
4034 }
4035
4036 static void context_saveFlagSettings (void)
4037 {
4038   gc.savedFlags = TRUE;
4039   llassert (sizeof (gc.saveflags) == sizeof (gc.flags));
4040   memcpy (gc.saveflags, gc.flags, sizeof (gc.flags));
4041 }
4042
4043 static void context_restoreFlagSettings (void)
4044 {
4045   llassert (sizeof (gc.saveflags) == sizeof (gc.flags));
4046   memcpy (gc.flags, gc.saveflags, sizeof (gc.flags));
4047   gc.savedFlags = FALSE;
4048 }
4049
4050 void context_setFilename (fileId fid, int lineno) 
4051    /*@globals fileloc g_currentloc;@*/
4052    /*@modifies g_currentloc@*/
4053 {
4054   if (fileId_baseEqual (currentFile (), fid))
4055     {
4056       setLine (lineno);
4057       return;
4058     }
4059   else
4060     {
4061       fileloc_setColumn (g_currentloc, 0);
4062
4063       if (fileloc_isSpecialFile (g_currentloc))
4064         {
4065           gc.inDerivedFile = TRUE;
4066         }
4067
4068       if (filelocStack_popPushFile (gc.locstack, g_currentloc))
4069         {
4070           int maxdepth = context_getValue (FLG_INCLUDENEST);
4071
4072           if (filelocStack_size (gc.locstack) > maxdepth)
4073             {
4074               int depth = filelocStack_includeDepth (gc.locstack);
4075               
4076               if (depth > maxdepth)
4077                 {
4078                   if (optgenerror 
4079                       (FLG_INCLUDENEST,
4080                        message ("Maximum include nesting depth "
4081                                 "(%d, current depth %d) exceeded",
4082                                 maxdepth,
4083                                 depth),
4084                        filelocStack_nextTop (gc.locstack)))
4085                     {
4086                       filelocStack_printIncludes (gc.locstack);
4087                     }
4088                 }
4089             }
4090         }
4091       
4092       g_currentloc = fileloc_create (fid, lineno, 1);
4093       gc.inheader = fileId_isHeader (currentFile ());
4094
4095       context_enterFileAux ();
4096     }
4097 }
4098
4099 void context_enterIterDef (/*@observer@*/ uentry le)
4100 {
4101   context_enterMacro (le);
4102   gc.acct = typeIdSet_subtract (gc.facct, gc.nacct);
4103   gc.kind = CX_ITERDEF;
4104 }
4105
4106 void context_enterIterEnd (/*@observer@*/ uentry le)
4107 {
4108   context_enterMacro (le);
4109   gc.kind = CX_ITEREND;
4110 }
4111
4112 void 
4113 context_destroyMod (void) 
4114    /*@globals killed gc@*/
4115 {
4116   setCodePoint ();
4117   ctype_destroyMod ();
4118   setCodePoint ();
4119   usymtab_free ();
4120   setCodePoint ();
4121   fileTable_free (gc.ftab);
4122   filelocStack_free (gc.locstack);
4123   setCodePoint ();
4124   gc.ftab = fileTable_undefined;
4125
4126   macrocache_free (gc.mc);
4127   sfree (gc.moduleaccess);
4128   setCodePoint ();
4129
4130   fileloc_free (gc.saveloc); gc.saveloc = fileloc_undefined;
4131   fileloc_free (gc.pushloc); gc.pushloc = fileloc_undefined;
4132
4133   setCodePoint ();
4134   sRefSetList_free (gc.modrecs);
4135   setCodePoint ();
4136   flagMarkerList_free (gc.markers); 
4137   setCodePoint ();
4138   messageLog_free (gc.msgLog);
4139   setCodePoint ();
4140   clauseStack_free (gc.clauses);
4141   setCodePoint ();
4142   
4143   cstring_free (gc.msgAnnote);
4144   globSet_free (gc.globs_used);
4145   metaStateTable_free (gc.stateTable);
4146   annotationTable_free (gc.annotTable);
4147 }
4148
4149 /*
4150 ** Flag shortcuts.
4151 */
4152
4153 bool context_msgBoolInt (void)
4154 {
4155   return gc.flags [FLG_BOOLINT];
4156 }
4157
4158 bool context_msgCharInt (void)
4159 {
4160   return gc.flags [FLG_CHARINT];
4161 }
4162
4163 bool context_msgEnumInt (void)
4164 {
4165   return gc.flags [FLG_ENUMINT];
4166 }
4167
4168 bool context_msgPointerArith (void) 
4169 {
4170   return gc.flags [FLG_POINTERARITH];
4171 }
4172
4173 bool context_msgStrictOps (void) 
4174 {
4175   return gc.flags [FLG_STRICTOPS];
4176 }
4177
4178 # ifndef NOLCL
4179 bool context_msgLh (void)           
4180 {
4181   return gc.flags [FLG_DOLH];
4182 }
4183 # endif
4184
4185 void context_pushLoc (void) 
4186 {
4187   fileloc_free (gc.pushloc);
4188   gc.pushloc = gc.saveloc;
4189   gc.saveloc = fileloc_undefined;
4190 }
4191
4192 void context_popLoc (void) 
4193 {
4194   gc.saveloc = fileloc_update (gc.saveloc, gc.pushloc);
4195 }
4196
4197 bool context_inGlobalScope (void)
4198 {
4199   return (usymtab_inFileScope() || usymtab_inGlobalScope ());
4200 }
4201
4202 bool context_inInnerScope (void)
4203 {
4204   return (gc.kind == CX_INNER);
4205 }
4206
4207 void context_setProtectVars (void)
4208 {
4209   gc.protectVars = TRUE;
4210 }
4211
4212 bool context_anyErrors (void)
4213 {
4214   return (gc.numerrors > 0);
4215 }
4216
4217 void context_hasError (void)
4218 {
4219   gc.numerrors++;
4220   DPRINTF (("num errors: %d", gc.numerrors));
4221 }
4222
4223 int context_numErrors (void)
4224 {
4225   return gc.numerrors;
4226 }
4227
4228 bool context_neednl (void)
4229 {
4230   return gc.neednl;
4231 }
4232
4233 void context_setNeednl (void)
4234 {
4235   gc.neednl = TRUE;
4236 }
4237
4238 int context_getExpect (void)
4239 {
4240   return (context_getValue (FLG_EXPECT));
4241 }
4242
4243 # ifndef NOLCL
4244 int context_getLCLExpect (void)
4245 {
4246   return (context_getValue (FLG_LCLEXPECT));
4247 }
4248 # endif
4249
4250 int context_getLimit (void)
4251 {
4252   return (context_getValue (FLG_LIMIT));
4253 }
4254
4255 bool context_unlimitedMessages (void)
4256 {
4257   return (context_getLimit () < 0);
4258 }
4259
4260 void context_releaseVars (void)
4261 {
4262   llassert (gc.protectVars);
4263   gc.protectVars = FALSE;
4264 }
4265
4266 void context_sizeofReleaseVars (void)
4267 {
4268   /* If there is a nested sizeof, this might not hold:
4269      llassert (gc.protectVars);
4270      */
4271
4272   gc.protectVars = FALSE;
4273 }
4274
4275 bool context_inProtectVars (void)
4276 {
4277   return (gc.protectVars);
4278 }
4279
4280 void context_hideShowscan (void) 
4281 {
4282   gc.flags[FLG_SHOWSCAN] = FALSE;
4283 }
4284
4285 void context_unhideShowscan (void)
4286 {
4287   gc.flags[FLG_SHOWSCAN] = TRUE;
4288 }
4289
4290 bool context_inHeader (void)
4291 {
4292   return (gc.inheader);
4293 }
4294
4295 fileTable context_fileTable (void)
4296 {
4297   return gc.ftab;
4298 }
4299
4300 cstring context_tmpdir (void)
4301 {
4302   return (context_getString (FLG_TMPDIR));
4303 }
4304
4305 messageLog context_messageLog (void)
4306 {
4307   return gc.msgLog;
4308 }
4309
4310 bool context_inMacroFunction (void)
4311 {
4312   return (gc.kind == CX_MACROFCN);
4313 }
4314
4315 bool context_inMacroConstant (void)
4316 {   
4317   return (gc.kind == CX_MACROCONST);
4318 }
4319
4320 bool context_inUnknownMacro (void)
4321 {   
4322   return (gc.kind == CX_UNKNOWNMACRO);
4323 }
4324
4325 void context_setShownFunction (void)
4326 {
4327   gc.showfunction = FALSE;
4328 }
4329
4330 bool context_doDump (void)
4331 {   
4332   return cstring_isNonEmpty (context_getString (FLG_DUMP));
4333 }
4334
4335 bool context_doMerge (void)
4336 {
4337   return cstring_isNonEmpty (context_getString (FLG_MERGE));
4338 }
4339
4340 cstring context_getDump (void)
4341 {           
4342   return context_getString (FLG_DUMP);
4343 }
4344
4345 cstring context_getMerge (void)
4346 {
4347   return context_getString (FLG_MERGE);
4348 }
4349
4350 # ifndef NOLCL
4351 bool context_inLCLLib (void)
4352 {   
4353   return (gc.kind == CX_LCLLIB);
4354 }
4355
4356 bool context_inImport (void)
4357 {
4358   return (gc.inimport);
4359 }
4360
4361 void context_enterImport (void)
4362
4363   gc.inimport = TRUE;
4364 }
4365
4366 void context_leaveImport (void)
4367
4368   gc.inimport = FALSE;
4369 }
4370 # endif
4371
4372 bool context_inMacro (void) 
4373 {
4374   return (gc.kind == CX_MACROFCN || gc.kind == CX_MACROCONST 
4375           || gc.kind == CX_UNKNOWNMACRO
4376           || gc.kind == CX_ITERDEF || gc.kind == CX_ITEREND);
4377 }
4378
4379 bool context_inIterDef (void)
4380 {
4381   return (gc.kind == CX_ITERDEF);
4382 }
4383
4384 bool context_inIterEnd (void)
4385 {
4386   return (gc.kind == CX_ITEREND);
4387 }
4388
4389 int context_getLinesProcessed (void)    
4390 {
4391   return (gc.linesprocessed);
4392 }
4393
4394 int context_getSpecLinesProcessed (void)    
4395 {
4396   return (gc.speclinesprocessed);
4397 }
4398
4399 # ifndef NOLCL
4400 void context_processedSpecLine (void)
4401 {
4402   gc.speclinesprocessed++;
4403 }
4404
4405 void context_resetSpecLines (void)    
4406 {
4407   gc.speclinesprocessed = 0;
4408 }
4409 # endif
4410
4411 bool context_inGlobalContext (void)
4412 {
4413   return (gc.kind == CX_GLOBAL);
4414 }
4415
4416 static void context_quietExitScopes (void)
4417 {
4418   /*
4419   ** Try to restore the global scope (after an error).
4420   */
4421
4422   while (!usymtab_inFileScope ())
4423     {
4424       usymtab_quietExitScope (g_currentloc);
4425     }
4426
4427   gc.cont.glob = TRUE;
4428   gc.kind = CX_GLOBAL;
4429 }
4430
4431 void context_checkGlobalScope (void)
4432 {
4433   if (gc.kind != CX_GLOBAL)
4434     {
4435       if (context_inMacro ())
4436         {
4437           ; /* evans 2001-10-14: Okay to be in a macro here! */ 
4438         }
4439       else
4440         {
4441           llcontbug (message ("Not in global scope as expected: %q", context_unparse ()));
4442           context_quietExitScopes ();
4443         }
4444     }
4445 }
4446
4447 void context_setFileId (fileId s)
4448 {
4449   g_currentloc = fileloc_updateFileId (g_currentloc, s); 
4450 }
4451
4452 bool context_setBoolName (void)
4453 {
4454   return (!cstring_equalLit (context_getString (FLG_BOOLTYPE),
4455                              DEFAULT_BOOLTYPE));
4456 }
4457
4458 cstring context_printBoolName (void)
4459 {
4460   if (context_setBoolName ()) 
4461     {
4462       return context_getBoolName ();
4463     }
4464   else
4465     {
4466       return cstring_makeLiteralTemp ("boolean");
4467     }
4468 }
4469
4470 cstring context_getBoolName (void)
4471 {
4472   return (context_getString (FLG_BOOLTYPE));
4473 }
4474
4475 cstring context_getFalseName (void)
4476 {
4477   return (context_getString (FLG_BOOLFALSE));
4478 }
4479
4480 cstring context_getTrueName (void)
4481 {
4482   return (context_getString (FLG_BOOLTRUE));
4483 }
4484
4485 cstring context_getLarchPath (void)
4486 {
4487   return (context_getString (FLG_LARCHPATH));
4488 }
4489
4490 cstring context_getLCLImportDir (void)
4491 {
4492   return (context_getString (FLG_LCLIMPORTDIR));
4493 }
4494
4495 static void context_setJustPopped (void)
4496 {
4497   gc.justpopped = TRUE;
4498 }
4499
4500 void context_clearJustPopped (void)
4501 {
4502   gc.justpopped = FALSE;
4503 }
4504
4505 bool context_justPopped (void)
4506 {
4507   return (gc.justpopped);
4508 }
4509
4510 void context_setMacroMissingParams (void)
4511 {
4512   gc.macroMissingParams = TRUE;
4513 }
4514
4515 void context_resetMacroMissingParams (void)
4516 {
4517   gc.macroMissingParams = FALSE;
4518 }
4519
4520 bool context_isMacroMissingParams (void)
4521 {
4522   return (gc.macroMissingParams);
4523 }
4524
4525 void context_showFilelocStack (void) 
4526 {
4527   filelocStack_printIncludes (gc.locstack);
4528 }
4529
4530 metaStateTable context_getMetaStateTable (void) 
4531 {
4532   return gc.stateTable;
4533 }
4534
4535 metaStateInfo context_lookupMetaStateInfo (cstring key)
4536 {
4537   return metaStateTable_lookup (gc.stateTable, key);
4538 }
4539
4540 /*@null@*/ annotationInfo context_lookupAnnotation (cstring annot) 
4541 {
4542   annotationInfo ainfo;
4543
4544   ainfo = annotationTable_lookup (gc.annotTable, annot);
4545
4546   return ainfo;
4547 }
4548
4549 void context_addAnnotation (annotationInfo ainfo)
4550 {
4551   if (annotationTable_contains (gc.annotTable, annotationInfo_getName (ainfo)))
4552     {
4553       voptgenerror 
4554         (FLG_SYNTAX,
4555          message ("Duplicate annotation declaration: %s", annotationInfo_getName (ainfo)),
4556          annotationInfo_getLoc (ainfo));
4557
4558       annotationInfo_free (ainfo);
4559     }
4560   else
4561     {
4562       annotationTable_insert (gc.annotTable, ainfo);
4563     }
4564 }
4565
4566 void context_addMetaState (cstring mname, metaStateInfo msinfo)
4567 {
4568   if (metaStateTable_contains (gc.stateTable, mname))
4569     {
4570       voptgenerror 
4571         (FLG_SYNTAX,
4572          message ("Duplicate metastate declaration: %s", mname),
4573          metaStateInfo_getLoc (msinfo));
4574       cstring_free (mname);
4575       metaStateInfo_free (msinfo);
4576     }
4577   else
4578     {
4579       DPRINTF (("Adding meta state: %s", mname));
4580       metaStateTable_insert (gc.stateTable, mname, msinfo); 
4581     }
4582 }
4583
4584 valueTable context_createValueTable (sRef s, stateInfo sinfo)
4585 {
4586   if (metaStateTable_size (gc.stateTable) > 0)
4587     {
4588       valueTable res = valueTable_create (metaStateTable_size (gc.stateTable));
4589       /*@i32 should use smaller value... */
4590       DPRINTF (("Value table for: %s", sRef_unparse (s)));
4591       
4592       metaStateTable_elements (gc.stateTable, msname, msi)
4593         {
4594           mtContextNode context = metaStateInfo_getContext (msi);
4595
4596           if (mtContextNode_matchesRefStrict (context, s))
4597             {
4598               DPRINTF (("Create: %s", metaStateInfo_unparse (msi)));
4599               llassert (cstring_equal (msname, metaStateInfo_getName (msi)));
4600               
4601               valueTable_insert 
4602                 (res,
4603                  cstring_copy (metaStateInfo_getName (msi)),
4604                  stateValue_createImplicit (metaStateInfo_getDefaultValue (msi, s), 
4605                                             stateInfo_copy (sinfo)));
4606             }
4607           else
4608             {
4609               DPRINTF (("No match: %s", metaStateInfo_unparse (msi)));
4610             }
4611         } 
4612       end_metaStateTable_elements ;
4613       
4614       stateInfo_free (sinfo);
4615       DPRINTF (("Value table: %s", valueTable_unparse (res)));
4616       return res;
4617     }
4618   else
4619     {
4620       stateInfo_free (sinfo);
4621       return valueTable_undefined;
4622     }
4623 }
4624
4625 valueTable context_createGlobalMarkerValueTable (stateInfo sinfo)
4626 {
4627   if (metaStateTable_size (gc.stateTable) > 0)
4628     {
4629       valueTable res = valueTable_create (metaStateTable_size (gc.stateTable));
4630       /*@i32 should use smaller value... */
4631       
4632       metaStateTable_elements (gc.stateTable, msname, msi)
4633         {
4634           /*@i23 only add global...*/
4635           DPRINTF (("Create: %s", metaStateInfo_unparse (msi)));
4636           llassert (cstring_equal (msname, metaStateInfo_getName (msi)));
4637           
4638           valueTable_insert (res,
4639                              cstring_copy (metaStateInfo_getName (msi)),
4640                              stateValue_create (metaStateInfo_getDefaultGlobalValue (msi),
4641                                                 stateInfo_copy (sinfo)));
4642         } 
4643       end_metaStateTable_elements ;
4644       
4645       stateInfo_free (sinfo);
4646       DPRINTF (("Value table: %s", valueTable_unparse (res)));
4647       return res;
4648     }
4649   else
4650     {
4651       stateInfo_free (sinfo);
4652       return valueTable_undefined;
4653     }
4654 }
4655
4656
4657
This page took 0.560271 seconds and 3 git commands to generate.